-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
plugins.blasttv: new plugin #6547
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
Conversation
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.
Thanks for the PR, appreciated.
Adding a plugin for this site should be fine. But next time, please open a plugin request first, so you don't risk wasting your time should a PR you've worked on be rejected.
Before this can be merged, a couple of things need to be changed, fixed and also cleaned up.
Are you fine with me pushing onto your PR branch with my changes? I had a look at the site and modified your plugin accordingly, and I also added support for VODs. Both live streams and VODs can also be hosted externally, e.g. on YouTube or Twitch, so the plugin should redirect towards that automatically. I also fixed that.
I really don't feel like annotating code in PRs for non-trivial changes that I have already fixed locally, but let me comment on some of the stuff anyway.
Results from my local changes:
$ ./script/test-plugin-urls.py blasttv
:: https://blast.tv
:: 160p, 360p, 480p, 720p, 1080p, 1440p, 2160p, worst, best
:: https://blast.tv/
:: 160p, 360p, 480p, 720p, 1080p, 1440p, 2160p, worst, best
:: https://blast.tv/cs/tournaments/open-2025-season-1/match/24ff9d6c/vitality-mouz
:: 160p, 360p, 480p, 720p, 1080p, 1440p, worst, best
:: https://blast.tv/cs/tournaments/rivals-2025-season-1/match/bfaaa42e/falcons-vitality
:: 160p, 360p, 480p, 720p, 1080p, 1440p, worst, best
:: https://blast.tv/dota/tournaments/blast-slam-iii/match/acabb915/falcons-tundra
:: audio, worst, best, 160p, 360p, 480p, 720p60, 1080p60
:: https://blast.tv/live
:: 160p, 360p, 480p, 720p, 1080p, 1440p, 2160p, worst, best
:: https://blast.tv/live/
:: 160p, 360p, 480p, 720p, 1080p, 1440p, 2160p, worst, best
:: https://blast.tv/live/a
:: 160p, 360p, 480p, 720p, 1080p, 1440p, 2160p, worst, best
:: https://blast.tv/live/americas1
!! No streams found
:: https://blast.tv/live/co-stream
!! No streams found
:: https://blast.tv/live/f
:: worst, best, 144p, 240p, 360p, 480p, 720p, 1080p
src/streamlink/plugins/blasttv.py
Outdated
schema=validate.Schema( | ||
validate.parse_json(), | ||
validate.filter(lambda v: v.get("videoSrc")), | ||
[ | ||
{ | ||
"id": str, | ||
"slug": str, | ||
"title": str, | ||
"videoSrc": validate.url(), | ||
}, | ||
], | ||
), |
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.
Parsed JSON responses require a proper data structure before you can iterate the data (validate.filter). If they don't return an array, then this will raise an ugly error.
src/streamlink/plugins/blasttv.py
Outdated
if not channel and len(live_channels) > 1: | ||
log.error("Multiple live games, please specify one in URL") | ||
return |
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.
Live streams have a priority value in the API response. This can be used to default to the stream with the highest priority (the lowest integer value).
src/streamlink/plugins/blasttv.py
Outdated
yield from HLSStream.parse_variant_playlist( | ||
self.session, | ||
live_channel["videoSrc"], | ||
).items() | ||
break |
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.
Plugin._get_streams()
can both be a generator and a regular method returning a dict[str, Stream] | Iterable[tuple[str, Stream]]
, so yield from dict.items();break
is unnecessary. Just return
the resulting dict.
tests/plugins/test_blasttv.py
Outdated
|
||
should_not_match = [ | ||
"https://blast.tv/a", | ||
"https://blast.tv", |
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.
Their front-page also embeds the primary live stream, so the plugin should support that input URL.
Co-Authored-By: bastimeyer <mail@bastimeyer.de>
Please go ahead, thank you. |
Had a second look and I think the plugin implementation should be fine. If you want, you can have a look too and see if there are any streams that don't work. Otherwise, I'm going to merge later this evening. Thanks. |
Everything seems to work great, thank you so much! |
Forgot to comment on this... It's the server's responsibility according to the HLS protocol to provide the client with new media segments within the playlist's The intention is to close streams early which don't announce the stream's end properly without causing a buffer read timeout to trigger, as it's not a graceful end of the stream. Plugins can always change session options, but it doesn't make any sense increasing this value, because it's an issue with the server. Setting the value to 8 means that the stream is allowed to stall for eight times its actual targetduration. |
Blast is a video game (mainly Counter-Strike) tournament organizer who streams their matches on their website alongside the usual Twitch and YouTube. The streams on blast.tv are usually in 4K as opposed to 1080p on other platforms.
I've been using this plugin locally for a couple years. Over time, I've recorded different API (
https://api.blast.tv/v1/broadcasts/live
) responses in comments in the plugin code to make development and testing easier, but I'm happy to move those to a more appropriate place.There are some caveats:
streamlink
was run with default options. Adding--hls-segment-queue-threshold 8
completely eliminated the issues. My understanding is that plugins can't do anything about this.