-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
plugins.ustreamtv: re-implement plugin #4164
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.ustreamtv: re-implement plugin #4164
Conversation
"args": [{str: object}], | ||
}) | ||
_schema_stream_formats = validate.Schema({ | ||
"streams": [validate.any( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://video.ibm.com/nasahdtv
[plugins.ustreamtv][error]
Unable to validate result: Unable to validate key 'streams':
Unable to validate key 'contentType': 'text/vtt' does not equal 'video/mp4'
or Unable to validate key 'contentType': 'text/vtt' does not equal 'audio/mp4'
[plugins.ustreamtv][debug] Processing 'moduleInfo' - 'stream'
error: No playable streams found on this URL: https://video.ibm.com/nasahdtv
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I didn't check streams with subtitles. I'll take a look at this tomorrow. Shouldn't be too much work. One more validation schema, one more queue and stream for the muxed output, and no initialization segment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a stream with actual subtitles? The ones on the nasahdtv channel exist, but there's no/invalid content, so muxing the subtitle stream doesn't work. The language
property is set to unknown
, so maybe this needs to be filtered out.
This is the content of a WebVTT segment:
WEBVTT
I've updated the branch with new changes, but without filtering out "invalid" subtitles
two VOD URLs which work with the current Streamlink version https://video.ibm.com/recorded/131129777
http://www.ustream.tv/recorded/112470631
|
f67fdf8
to
1358b1e
Compare
This changes the cluster property and then needs to reconnect. I haven't tested the reconnect suff yet.
Looks like I have to make the |
be7b7b7
to
1bb3214
Compare
The reconnect on cluster/referrer change should now be working. I didn't add any tests for the new reconnect method because it's very hard setting up the tests correctly and covering all statements, and I don't want to do this now. Should be working fine though. Regarding the ustreamtv VODs with a cluster reconnection, sometimes stream format info is not sent in time and the stream times out. I already increased the timeout value from 6 to 10 seconds, but due to the reconnection this isn't enough sometimes. What's weird is that there are |
with all subtitles on by default, the player might not start or take forever
|
Yes, but that has nothing to do with the number of subtitles but with the subtitles themselves if they don't contain any data, as I've said before. I could add the following diff to select only the subtitles matching the locale settings while diff --git a/src/streamlink/plugins/ustreamtv.py b/src/streamlink/plugins/ustreamtv.py
index bca8fee2..6e8c5c45 100644
--- a/src/streamlink/plugins/ustreamtv.py
+++ b/src/streamlink/plugins/ustreamtv.py
@@ -496,10 +496,11 @@ class UStreamTV(Plugin):
sensitive=True,
metavar="PASSWORD",
help="A password to access password protected UStream.tv channels."
- )
+ ),
+ PluginArgument("mux-subtitles", is_global=True)
)
- STREAM_READY_TIMEOUT = 10
+ STREAM_READY_TIMEOUT = 15
def _get_media_app(self):
video_id = self.match.group("video_id")
@@ -554,12 +555,14 @@ class UStreamTV(Plugin):
wsclient.close()
return
- options = dict(
- subtitles={
+ options = {}
+ if self.get_option("mux-subtitles"):
+ locale = self.session.localization
+ options.update(subtitles={
subtitle.language: UStreamTVStream(self.session, "subtitle", wsclient, subtitle)
for subtitle in wsclient.stream_formats_subtitle
- }
- )
+ if locale.equivalent(language=subtitle.language, country=subtitle.country)
+ })
if not wsclient.stream_formats_audio:
for video in wsclient.stream_formats_video: |
af2d9c9
to
efc839e
Compare
Let's remove subtitles (for now). I don't want to unnecessarily delay this PR as it's the last barrier to removing all the flash stuff. The only issue left now are the occasional timeouts on the initial websocket client handshake, when the server doesn't send the supported stream formats in time. I've increased the timeout value from 6 to 15 seconds in order to fix this problem, but that's not a 100% guarantee. Still better than 6 seconds though, which is problematic when reconnecting the websocket. We could add a Other than that, what's been changed and what's working now which wasn't working when I first submitted the PR:
One other thing that I observed is that VODs require more time to initialize because the first video segment takes longer to load than audio segments, but they are requested at the same time, so it must be a server issue. |
- replace flvconcat with ffmpegmux - add typed namedtuples for stream formats and stream segments - implement WebsocketClient - simplify message handling and remove state polling - use validation schemas to parse messages - parse stream formats once - add subscribable thread-safe segment queues (deques) - rewrite UStreamTVStream{,Reader,Worker,Writer} - rename stream shortname from "uhs" to "ustreamtv" - simplify segment waiting logic and immediately stop worker and writer threads when the stream gets closed - find channel ID via XPath - simplify stream initialization
efc839e
to
f2f31de
Compare
based on streamlink#4164 - replace flvconcat with ffmpegmux - add typed namedtuples for stream formats and stream segments - implement WebsocketClient - simplify message handling and remove state polling - use validation schemas to parse messages - parse stream formats once - add subscribable thread-safe segment queues (deques) - rewrite UStreamTVStream{,Reader,Worker,Writer} - rename stream shortname from "uhs" to "ustreamtv" - simplify segment waiting logic and immediately stop worker and writer threads when the stream gets closed - find channel ID via XPath - simplify stream initialization
based on streamlink#4164 - replace flvconcat with ffmpegmux - add typed namedtuples for stream formats and stream segments - implement WebsocketClient - simplify message handling and remove state polling - use validation schemas to parse messages - parse stream formats once - add subscribable thread-safe segment queues (deques) - rewrite UStreamTVStream{,Reader,Worker,Writer} - rename stream shortname from "uhs" to "ustreamtv" - simplify segment waiting logic and immediately stop worker and writer threads when the stream gets closed - find channel ID via XPath - simplify stream initialization
based on streamlink#4164 - replace flvconcat with ffmpegmux - add typed namedtuples for stream formats and stream segments - implement WebsocketClient - simplify message handling and remove state polling - use validation schemas to parse messages - parse stream formats once - add subscribable thread-safe segment queues (deques) - rewrite UStreamTVStream{,Reader,Worker,Writer} - rename stream shortname from "uhs" to "ustreamtv" - simplify segment waiting logic and immediately stop worker and writer threads when the stream gets closed - find channel ID via XPath - simplify stream initialization
based on streamlink#4164 - replace flvconcat with ffmpegmux - add typed namedtuples for stream formats and stream segments - implement WebsocketClient - simplify message handling and remove state polling - use validation schemas to parse messages - parse stream formats once - add subscribable thread-safe segment queues (deques) - rewrite UStreamTVStream{,Reader,Worker,Writer} - rename stream shortname from "uhs" to "ustreamtv" - simplify segment waiting logic and immediately stop worker and writer threads when the stream gets closed - find channel ID via XPath - simplify stream initialization
threads when the stream gets closed
ref #4040
This is a complete rewrite of the ustreamtv plugin which uses muxed MPEG4 video and audio streams and finally removes the last import of flash video stuff. 🎉
The streams which I've tested are working fine, but it's possible that I've missed something, so please review carefully.
The websocket initialization has been refactored from the old code and cleaned up a lot. I only thing I checked on their website were the stream format and segment ID/hash messages, which I used for writing the new stream logic. I am not sure about the reconnect functionality (referrer and cluster change) which was already implemented, same with password protected streams.
All state is stored on the websocket client and read safely by the video and audio worker threads. The worker, writer and writer-thread-pool threads should all stop immediately after closing the stream, as they are using the event lock of the worker thread for their wait calls (delayed segment availability), which wasn't the case previously. This means there's no unnecessary dependency on dash_manifest anymore for
sleep_until
which makes the threads stall.