Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency in UI for stream detection and state #851

Closed
4 tasks done
bigdefect opened this issue Jan 11, 2022 · 6 comments
Closed
4 tasks done

Inconsistency in UI for stream detection and state #851

bigdefect opened this issue Jan 11, 2022 · 6 comments

Comments

@bigdefect
Copy link

bigdefect commented Jan 11, 2022

Checklist

Streamlink Twitch GUI version

v1.13.0

Streamlink version

3.0.3,2.4.0,2.0.0

Operating system, environment and configuration details

Windows 10 21H2

Description

I've been happily using this setup for months. I updated streamlink tonight, and noticed this issue occur. I've fiddled with re-installing, restarting, clearing configs, and trying different streamlink versions.

I took a short video of the issue: https://streamable.com/gbl3ja
Only the first half really matters, but I also tried showing what happens with streamlink.exe instead of streamlinkw.exe.

In short:

  1. Attempt to start a stream
  2. GUI briefly shows the "stream has ended" modal, until the stream starts at which point it switches to the "watching" modal
  3. Close the stream
  4. GUI still shows Watching
  5. Navigate to "You're watching" screen, stream still shows live
  6. Click the red "Close stream" button, app does not react.
  7. Attempt to reopen the stream, "Watching" modal reopens and stream does not (I neglected to record this in the video)

As far as I can tell, this happens across multiple versions of streamlink, and mpc-hc or VLC. Debug logs are attached, nothing stands out. Since I can't get the behavior to change by changing versions, I recognize it might not be directly related to streamlink-twitch-gui, streamlink, or mpc.

Debug log

[2022-01-11T07:47:13.670Z][debug][Application]
Parameters
{
    "_": [],
    "tray": false,
    "hide": false,
    "hidden": false,
    "max": false,
    "maximize": false,
    "maximized": false,
    "min": false,
    "minimize": false,
    "minimized": false,
    "reset-window": false,
    "versioncheck": true,
    "version-check": true,
    "logfile": true,
    "l": "debug",
    "loglevel": "debug",
    "launch": "",
    "goto": ""
}

[2022-01-11T07:47:30.567Z][debug][StreamingService]
Preparing to launch stream
{
    "id": "gamesdonequick",
    "quality": "source",
    "low_latency": true,
    "disable_ads": true,
    "chat_open": false,
    "started": "2022-01-11T07:47:30.551Z",
    "stream": "22510310",
    "channel": "22510310"
}

[2022-01-11T07:47:30.584Z][debug][StreamingService]
Resolving streaming provider
{
    "provider": "streamlink",
    "providerUserData": {
        "exec": "streamlink.exe",
        "params": null,
        "pythonscript": null
    }
}

[2022-01-11T07:47:30.588Z][debug][StreamingService]
Found streaming provider
{
    "exec": "C:\\Users\\<redacted>\\scoop\\shims\\streamlink.exe",
    "params": null,
    "env": null
}

[2022-01-11T07:47:30.607Z][debug][StreamingService]
Spawning process
{
    "exec": "C:\\Users\\<redacted>\\scoop\\shims\\streamlink.exe",
    "params": [
        "--version"
    ],
    "env": null
}

[2022-01-11T07:47:30.954Z][debug][StreamingService]
Validated streaming provider
{
    "version": "3.0.3"
}

[2022-01-11T07:47:30.957Z][debug][StreamingService]
Resolving player
{
    "player": "mpc",
    "playerUserData": {
        "instance": false,
        "close": true,
        "exec": "",
        "args": "{name} {game}",
        "type": "settings-streaming-player-mpc"
    }
}

[2022-01-11T07:47:30.960Z][debug][StreamingService]
Resolved player
{
    "exec": "C:\\Program Files\\MPC-HC\\mpc-hc64.exe",
    "params": "{name} {game} /play /close",
    "env": null
}

[2022-01-11T07:47:30.983Z][debug][StreamingService]
Spawning process
{
    "exec": "C:\\Users\\<redacted>\\scoop\\shims\\streamlink.exe",
    "params": [
        "--twitch-disable-hosting",
        "--twitch-disable-ads",
        "--twitch-low-latency",
        "--player",
        "C:\\Program Files\\MPC-HC\\mpc-hc64.exe",
        "--player-args",
        "\\G\\a\\m\\e\\s\\D\\o\\n\\e\\Q\\u\\i\\c\\k \\S\\e\\r\\i\\o\\u\\s\\ \\S\\a\\m\\ \\4 /play /close",
        "--retry-open",
        "1",
        "--retry-streams",
        "1",
        "twitch.tv/gamesdonequick",
        "best"
    ],
    "env": null
}

[2022-01-11T07:47:47.560Z][debug][StreamingService]
Preparing to launch stream
{
    "id": "gamesdonequick",
    "quality": "source",
    "low_latency": true,
    "disable_ads": true,
    "chat_open": false,
    "started": "2022-01-11T07:47:47.550Z",
    "stream": "22510310",
    "channel": "22510310"
}

[2022-01-11T07:47:47.573Z][debug][StreamingService]
Resolving streaming provider
{
    "provider": "streamlink",
    "providerUserData": {
        "exec": "streamlinkw.exe",
        "params": null,
        "pythonscript": null
    }
}

[2022-01-11T07:47:47.577Z][debug][StreamingService]
Found streaming provider
{
    "exec": "C:\\Users\\<redacted>\\scoop\\shims\\streamlinkw.exe",
    "params": null,
    "env": null
}

[2022-01-11T07:47:47.583Z][debug][StreamingService]
Spawning process
{
    "exec": "C:\\Users\\<redacted>\\scoop\\shims\\streamlinkw.exe",
    "params": [
        "--version"
    ],
    "env": null
}

[2022-01-11T07:47:47.932Z][debug][StreamingService]
Validated streaming provider
{
    "version": "3.0.3"
}

[2022-01-11T07:47:47.933Z][debug][StreamingService]
Resolving player
{
    "player": "mpc",
    "playerUserData": {
        "instance": false,
        "close": true,
        "exec": "",
        "args": "{name} {game}",
        "type": "settings-streaming-player-mpc"
    }
}

[2022-01-11T07:47:47.936Z][debug][StreamingService]
Resolved player
{
    "exec": "C:\\Program Files\\MPC-HC\\mpc-hc64.exe",
    "params": "{name} {game} /play /close",
    "env": null
}

[2022-01-11T07:47:47.954Z][debug][StreamingService]
Spawning process
{
    "exec": "C:\\Users\\<redacted>\\scoop\\shims\\streamlinkw.exe",
    "params": [
        "--twitch-disable-hosting",
        "--twitch-disable-ads",
        "--twitch-low-latency",
        "--player",
        "C:\\Program Files\\MPC-HC\\mpc-hc64.exe",
        "--player-args",
        "\\G\\a\\m\\e\\s\\D\\o\\n\\e\\Q\\u\\i\\c\\k \\S\\e\\r\\i\\o\\u\\s\\ \\S\\a\\m\\ \\4 /play /close",
        "--retry-open",
        "1",
        "--retry-streams",
        "1",
        "twitch.tv/gamesdonequick",
        "best"
    ],
    "env": null
}
@bastimeyer
Copy link
Member

Thanks for the report and detailed video.

I've never seen this. And from your video alone I can't really explain what's happening. Unfortunately I don't have the time to look into this now, as I'm very busy with rewriting the app and switching from Twitch's kraken API to the helix API.

The player selection here is irrelevant, as it's only a different path passed as the player argument to Streamlink.

Regarding streamlinkw.exe and streamlink.exe, on Windows there's a subtle difference between them which is important for the Twitch GUI to work. Each of them uses different python entry points, and the one without the w suffix opens a Windows terminal window and writes the entire stdout and stderr streams to it. The application which has invoked the process then is not able to read those streams, so the Twitch GUI can't see what's going on. That's why the executable with the w suffix exists in the Streamlink installs on Windows.


This is what happens when you launch a stream:

The StreamingService will first create a new record of the Stream model, which holds the state of the stream and has a couple of computed properties for interpreting the state. The initial state is STATUS_PREPARING and error is set to null.

The StreamingService then opens the ModalStreamingComponent with the stream record as context, and the dialog shows the contents depending on the stream's state.

After the StreamingService has validated your Streamlink install (path resolving and version check) and the player config (path resolving), the stream's state gets updated to STATUS_LAUNCHING where it waits for Streamlink's log output (its stdout stream). If any of this fails, then the stream's error property will be set, which will update the hasEnded computed property which again will update the modal component's view.

As soon as Starting player: ... appears in Streamlink's log output, the onSuccess callback gets executed and the stream's state gets updated to STATUS_WATCHING.

Once Streamlink's process terminates, the state gets set to STATUS_COMPLETED.


Seeing that the modal dialog begins with "Stream has ended", this means that either the error property must have been set early, which shouldn't be possible without triggering other stuff, or the stream's state was updated to STATUS_ABORTED (which can only happen via user interaction), or the state was changed to STATUS_COMPLETED. As shown, STATUS_COMPLETED does only get set when the streamlink process has terminated.

I've been happily using this setup for months. I updated streamlink tonight, and noticed this issue occur.

According to your debug log, this is your streamlink path, which makes me wonder how you've actually installed Streamlink.

C:\Users\<redacted>\scoop\shims\streamlinkw.exe

Can you also please check and see what's in your Streamlink config file?


Also, unrelated to all this, you are using incorrect player args, and the Twitch GUI needs to unnecessarily escape every character of the stream title you've included in the player args to prevent malicious stream titles from running shell code via Streamlink on Windows. You need to put the variable(s) into (double-)quotes to fix this: "{name} {game}"

@bigdefect
Copy link
Author

Thanks for the thorough and prompt response. The callback setup explains why it can change state like that, I figured "stream ended" would be terminal. I'm happy to do legwork, just need guidance.

According to your debug log, this is your streamlink path, which makes me wonder how you've actually installed Streamlink.

I use https://github.com/ScoopInstaller/Scoop rather than Chocolatey. It copies the config file, runs in the installer into the path you saw, and creates some symlinks into that shims dir, which is in my Path. https://github.com/ScoopInstaller/Extras/blob/d87473dd2f173360f2b8b0b77dce728e7bbb7793/bucket/streamlink.json

Until whatever got screwed up last night, I had been using streamlink via this method.

Can you also please check and see what's in your Streamlink config file?

I was fiddling with the config file, going as far as to remove it and start with fresh configs for both streamlink and the gui. Here's all that's enabled in it right now.

player="C:\Program Files\MPC-HC\mpc-hc64.exe"
ffmpeg-ffmpeg=ffmpeg.exe
twitch-disable-hosting
twitch-disable-ads
twitch-low-latency

The minimal set of just those first two still produces the same behavior.

you are using incorrect player args

Gotcha. I only added those last night as I was fiddling and discovering stuff in the streamlink gui (it was fire and forget). I'll fix those. Though interestingly neither style seems to work with MPC at a glance, it's always stdin as the title. Not important.

@bastimeyer
Copy link
Member

I'm happy to do legwork, just need guidance

Run a development build (see CONTRIBUTING.md) or a debug build (see README.md), open the app's dev tools after launching it, set a breakpoint on this line (sources tab -> data/models/stream/model.js) and check the values and call stack:
https://github.com/streamlink/streamlink-twitch-gui/blob/v1.13.0/src/app/data/models/stream/model.js#L118

The computed property will be calculated every time error or status changes.


neither style seems to work with MPC at a glance

You are passing {name} {game} as the player's launch parameters, which is just a random string. Of course this will not work. MPC does not have any parameters for customizing the window title though.

VLC for example does this via the "--input-title-format=..." parameter, and MPV "--force-media-title=...", but there are already checkboxes for this in the player config presets.
https://github.com/streamlink/streamlink-twitch-gui/blob/v1.13.0/src/config/players.json#L43-L49
https://github.com/streamlink/streamlink-twitch-gui/blob/v1.13.0/src/config/players.json#L94-L107

@bigdefect
Copy link
Author

Best I can tell, it transitions as:

  1. STATUS_PREPARING
  2. STATUS_LAUNCHING
  3. STATUS_COMPLETED
  4. STATUS_WATCHING

Presumably there are no state transitions for STATUS_COMPLETED -> which is why nothing is watching for that second transition into closing the stream and the gui gets into that inconsistent state. Looking at the stack trace, it gets triggered by code 0 here https://github.com/streamlink/streamlink-twitch-gui/blob/v1.13.0/src/app/services/streaming/launch/index.js#L70

Is streamlinkw.exe supposed to immediately exit? Is it possible to invoke it myself to toy with via terminal? It immediately returns with no output regardless of what I pass in, so I can't tell if that's normal behavior or not.

@bastimeyer
Copy link
Member

Thanks.

This is not normal behavior. Streamlink should only terminate when the stream ends or errors out, or when the user sends a SIGTERM / SIGINT to the process. I don't know Scoop and what it does to its packages, but this looks like the streamlink process gets wrapped by another one which then immediately terminates and detaches the actual streamlink process.

Please try installing Streamlink via the official methods.
https://streamlink.github.io/install.html

Is it possible to invoke it myself to toy with via terminal?

This is what streamlink is built for...
https://streamlink.github.io/cli.html

@bigdefect
Copy link
Author

This is what streamlink is built for

Right, I used it via CLI until I discovered this project, I meant specifically streamlinkw.exe. I've had trouble finding any documentation on how it's meant to be used.

Please try installing Streamlink via the official methods.

I was about to reply to this saying I had, because I remembered uninstalling via scoop and just using the installer. But of course I tried it again just now and the behavior is normal.

Turns out you're right. Scoop shims are indeed a wrapper executable rather than symlinks. If I point the GUI to a symlink to the installed exe, the GUI works just fine.

I'll go ahead and close it out, this was a flavor of PEBKAC. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants