-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
plugins.twitch: low latency #2513
plugins.twitch: low latency #2513
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2513 +/- ##
==========================================
+ Coverage 52.78% 52.95% +0.16%
==========================================
Files 248 248
Lines 15466 15527 +61
==========================================
+ Hits 8164 8222 +58
- Misses 7302 7305 +3 |
2fd683a
to
ece453f
Compare
|
Btw, while I was adding the tests, I noticed that the plugin parameters do not get initialized properly and I had to set them explicitly. Looks like they only get initialized by streamlink_cli here: |
ece453f
to
541e99f
Compare
I think this will do for now :) I have, what I think is, a better solution in the pipeline, but it is a little way off :) |
One note: why not override |
Ideally, this should have been done in the disable-ads PR earlier this year, so that Regarding the decorator, I've added the simple if statement to the prefetch tag method first, but it made sense to disable these advertisement tags too when the other parameter is not set, so adding a decorator made things look more simple, as all methods share this same logic. Btw, using I just wanted to get things finally done here with this PR. I know that most changes are not implemented the best way, but doing it right would require a much deeper refactoring of the entire thing and you already said that you had been working on something better a few months ago. Let me fix the super class method call, though, before this gets merged. |
541e99f
to
027b228
Compare
Fair enough @bastimeyer, I think I was out of the loop on those changes, or not paying close enough attention. Hopefully the work I’m doing on the stream classes will make this kind of thing easier. |
027b228
to
c84f263
Compare
Any further concerns, comments or suggestions? If refactoring the plugin and removing the stream dependency from the parser is that important, then tell me, and I will change it. Or just push the necessary changes to my branch yourself :) |
As it's the twitch specific parser, I think it's OK. In my WIP branch, I have not used the |
This depends on the value of
Not really. Each playlist lists two prefetch segments. One of them is the previously completed one (live edge 1), and in the case that the reload/download takes too long, then the two prefetch segments are new ones. I think using
Test it on a channel where you can see an ingame timer or so (eg. dota2). I'm ahead by 2 seconds with streamlink. |
Thanks for the |
I've been thinking a little bit about the ads filtering, and I realized that we will probably have to make both parameters mutually exclusive. As I've said, I don't get any ads on Twitch, so I can't test and verify this, but the way the low latency stuff is currently implemented is that it clones the last regular segment data, replaces the URL with the additional prefetch segment URLs and adds these new segments to the sequence as regular ones. This means that we're also shifting the live-edge here and since we're limiting the live-edge value to 1 or 2 when the parameter gets set, we don't have proper metadata to work with when it comes to ads filtering. This means that once an ad appears in the regular segments, we've already processed it as a prefetch segment without metadata and we're shifting the start/end of an ad-block by the amount of prefetch tags, which is two, or in other words 4 seconds. Since players like VLC don't handle discontinuities well, this breaks the whole ads-filtering implementation and is a problem. Also, another thing I've realized is that we're also allowing low latency streaming for regular non-low-latency streams without prefetch segments. This isn't wrong per se, as it enables |
Has this been added to the nightly build? I tried a nightly from a week ago and couldn't get the --twitch-low-latency parameter to work. |
This is an open pull request, so of course not. If you want to try it, install it from the branch of this PR. See #2402 (comment) |
|
Any update on this getting pushed? |
Locking this PR now. I've already said multiple times that it's a WIP and not finished yet. This hasn't changed, so please stop asking, this is just unnecessary noise and not contributing anything. As you can see on my Github profile, I didn't have the time recently to work on any of my projects or pull requests. I will see if I can add the necessary changes this weekend, but I'm not sure. There's also @beardypig with his implementation, but I don't know anything about the status of that. What needs to be done?
|
e0c76e0
to
c1a146f
Compare
I've rebased the branch to 1.3.0. This doesn't mean though that there's anything new or that I'm confident getting this merged any time soon. If you're testing the low latency branch, you should reinstall it. Btw, the next Twitch GUI version will require 1.3.0, so if you're using that, you will have to upgrade. |
c1a146f
to
52392c3
Compare
I've force-pushed a rebase from Streamlink's current master branch, so that the MPV fixes are now included and merge conflicts solved. Don't merge though, nothing has changed. edit |
52392c3
to
33d7252
Compare
if you could detect the Ad URLs they could be ignored as you are using the prefetch URLs there shouldn't be an issue, but this is only testable with a larger user base
nice to have, but not important for testing purposes i would merge this PR and see what issues occupy on the fly. |
Hm, that is actually true.
Even if the After I've rebased the branch and fixed the merge conflicts, then I think we can merge this. In another thread somewhere here I've said that I don't really feel comfortable with the changes, because there are still a couple of issues with occasional hiccups, but to be honest, I also don't want this PR to be open and stale anymore. Merging this will probably lead to lots of further questions, but so be it then. edit: |
The current low latency streaming implementation doesn't allow for reliably filtering ads. The reason for this is that prefetch segments are cloned from the playlist's last regular segment and are treated as regular ones themselves, with incorrect metadata. In combination with the shift of the stream's live-edge, discontinuities (ads) can't be detected and the low latency streaming needs to be disabled if ad filtering is enabled.
if low latency streaming is enabled. Non-low-latency streams don't have HLS prefetch tags.
33d7252
to
d5f3c5c
Compare
After fiddling around a bit more with MPV's caching parameters (and also with python-sphinx), I've decided against adding an example command line, because it's just too variable. It's probably also unnecessary when using the latest MPV version, because not adjusting anything at all didn't cause any major hiccups when I tested it and the latency was still good. This wasn't the case a few months ago. I've also not changed the mutual exclusivity of the disable-ads parameter and also not mentioned it in the description. Since a message gets logged to |
…-latency plugins.twitch: low latency
Maybe this should be done in two separate pull requests, but here we go.
These changes are mainly based on the work of @back-to and his low latency test plugin for Twitch (see here).
Description
--hls-segment-stream-data
parameter, which makes Streamlink write the HLS segments to the output buffer while they are being downloaded.TwitchM3U8Parser
.--twitch-low-latency
shorthand plugin-parameter, which automatically sets--hls-segment-stream-data
to true and limits the value of--hls-live-edge
to a maximum of 2, as higher values (default is 3) are pointless for low latency streaming.Open questions
Is reducing the playlist refresh time by this much necessary? It's also what Twitch's web player does nowadays for regular and low latency streams and it basically refreshes the playlist after each segment download. I'm not sure if this defeats the segment prefetching idea. It seems to be right though to ignore thetargetduration
. Maybe a refresh time ofnumber_of(prefetch_segments) * duration(segment)
would make sense...Is introducing a shorthand parameter for setting other parameter values a good idea? I will have to reword the parameter description later, as segment prefetching is always being done.Tests need to be added...As for the results of the low latency changes, I'm able to beat Twitch's web player by 0-2 seconds while using MPV without additional player cache. Using a HLS live edge value of 1 sometimes results in micro-buffering though, but this can be fixed by pausing the playback for a short moment.
Resolves #2180, #1676, #2402