Twitch¶
Authentication¶
Official authentication support for Twitch via the --twitch-oauth-token
and --twitch-oauth-authenticate
CLI arguments
had to be disabled in Streamlink's 1.3.0 release in November 2019 and both
arguments were finally removed in the 2.0.0 release in December 2020 due to
restrictive changes on Twitch's private REST API which prevented proper authentication flows from third party applications
like Streamlink.
The issue was that authentication data generated from third party applications could not be sent while acquiring streaming access tokens which are required for watching streams. Only authentication data generated by Twitch's website was accepted by the Twitch API. Later on in January 2021, Twitch moved the respective API endpoints to their GraphQL API which was already in use by their website for several years and shut down the old, private REST API.
This means that authentication data, aka. the "OAuth token", needs to be read from the web browser after logging in on Twitch's website and it then needs to be set as a certain request header on these API endpoints. This unfortunately can't be automated easily by applications like Streamlink, so a new authentication feature was never implemented.
In order to get the personal OAuth token from Twitch's website which identifies your account, open Twitch.tv in your web
browser and after a successful login, open the developer tools by pressing F12 or CTRL+SHIFT+I. Then navigate to
the "Console" tab or its equivalent of your web browser and execute the following JavaScript snippet, which reads the value of
the auth-token
cookie, if it exists:
document.cookie.split("; ").find(item=>item.startsWith("auth-token="))?.split("=")[1]
Copy the resulting string consisting of 30 alphanumerical characters without any quotations.
The final Authorization
header which will identify your account while requesting a streaming access token can then be set
via Streamlink's --http-header
or --twitch-api-header
CLI arguments. The former will set the header on any
HTTP request made by Streamlink, even HLS Streams, while the latter will only do that on Twitch API requests, which is what
should be done when authenticating and which is the reason why this CLI argument was added.
The value of the Authorization
header must be in the format of OAuth YOUR_TOKEN
. Notice the space character in the
argument value, which requires quotation on command line shells:
$ streamlink "--twitch-api-header=Authorization=OAuth abcdefghijklmnopqrstuvwxyz0123" twitch.tv/CHANNEL best
The entire argument can optionally be added to Streamlink's (Twitch plugin specific) config file, which doesn't require quotes:
twitch-api-header=Authorization=OAuth abcdefghijklmnopqrstuvwxyz0123
Embedded ads¶
In 2019, Twitch has started sporadically embedding ads directly into streams in addition to their regular advertisement program on their website which can only overlay ads. The embedded ads situation has been an ongoing thing since then and has been turned off and on several times throughout the months and years, also with variations between regions, and it has recently been pushed more and more aggressively with long pre-roll ads.
While this may be an annoyance for end-users who are used to using ad-blocker extensions in their web-browsers for blocking regular overlaying ads, applications like Streamlink face another problem, namely stream discontinuities when there's a transition between an ad and the regular stream content or another follow-up ad.
Since Streamlink does only output a single progressive stream from reading Twitch's segmented HLS stream, ads can cause issues in certain players, as the output is not a cohesively encoded stream of audio and video data anymore during an ad transition. One of the problematic players is VLC, which is known to crash during these stream discontinuities in certain cases.
Unfortunately, entirely preventing embedded ads is not possible unless a loophole on Twitch gets discovered which can be exploited. This has been the case a couple of times now and ad-workarounds have been implemented in Streamlink (see #3210) and various ad-blockers, but the solutions did only last for a couple of weeks or even days until Twitch patched these exploits.
To filter out ads and to prevent stream discontinuities in Streamlink's output, the --twitch-disable-ads
argument
was introduced in Streamlink 1.1.0 in 2019, which filters out advertisement
segments from Twitch's HLS streams and pauses the stream output until regular content becomes available again. The filtering
logic has seen several iterations since then, with the latest big overhaul in
Streamlink 1.7.0 in 2020.
In addition to that, special API request headers can be set via --twitch-api-header
or special API request
parameters can be set via --twitch-access-token-param
that can prevent ads from being embedded into the stream,
either authentication data or other data discovered by the community.
Client-integrity token¶
In 2022, Twitch added client-integrity tokens to their web player when getting streaming access tokens. These client-integrity tokens are calculated using sophisticated JavaScript code which is infeasible to re-implement, as it not only involves obfuscated code that's much harder to reverse engineer and to extract data from, but also a custom JavaScript virtual machine implementation where bytecode gets interpreted which is encoded prior to that using randomization patterns. The interpreted bytecode performs various checks of the user's web browser and its features, and then determines whether the client is legit or not. The goal is to prevent bots and third party applications from accessing streams.
Client-integrity tokens were treated as an optional request parameter when getting streaming access tokens. This changed on 2023-05-31 when Twitch made them a requirement, and it broke Streamlink's Twitch plugin (#5370).
Since the only sensible solution for Streamlink to calculate client-integrity tokens was using a web browser, a new
implementation was needed which could automate that. So in 6.0.0
the
streamlink.webbrowser API was implemented, which requires a Chromium-based web browser being
installed on the user's system. See the --webbrowser
and related CLI arguments for more details.
However, a couple of days after Twitch made these changes, they reverted the requirement again, but in order for Streamlink
to be prepared for such requirements to be turned on again, the webbrowser API was added nevertheless. The decision was made
to only use the webbrowser API when getting an access token fails, so launching a web browser unnecessarily could be avoided,
even though it would run invisibly in "headless mode". Should client-integrity tokens be made a requirement again, then
Streamlink will cache the generated token in the plugin cache after launching the web browser once. This cache can be cleared
using the --twitch-purge-client-integrity
option.
Low latency streaming¶
Low latency streaming on Twitch can be enabled by setting the --twitch-low-latency
argument and (optionally)
configuring the player via --player-args
and reducing its own buffer to a bare minimum.
Setting --twitch-low-latency
will make Streamlink prefetch future HLS segments that are included in the HLS playlist
and which can be requested ahead of time. As soon as content becomes available, Streamlink can download it without having to
waste time on waiting for another HLS playlist refresh that might include new segments.
In addition to that, --twitch-low-latency
also reduces --hls-live-edge
to a value of at most 2
, and it
also sets the --hls-segment-stream-data
argument.
--hls-live-edge
defines how many HLS segments Streamlink should stay behind the stream's live edge, so that it can
refresh playlists and download segments in time without causing buffering. Setting the value to 1
is not advised due to how
prefetching works.
--hls-segment-stream-data
lets Streamlink write the content of in-progress segment downloads to the output buffer
instead waiting for the entire segment to complete first before data gets written. Since HLS segments on Twitch have a playback
duration of 2 seconds for most streams, this further reduces output delay.
Note
Low latency streams have to be enabled by the broadcasters on Twitch themselves. Regular streams can cause buffering issues
with this option enabled due to the reduced --hls-live-edge
value.
Unfortunately, there is no way to check whether a channel is streaming in low-latency mode before accessing the stream.
Player buffer tweaks¶
Since players do have their own input buffer, depending on how much data the player wants to keep in its buffer before it starts
playing the stream, this can cause an unnecessary delay while trying to watch low latency streams. Player buffer sizes should
therefore be tweaked via the --player-args
CLI argument or via the player's configuration options.
The delay introduced by the player depends on the stream's bitrate and how much data is necessary to allow for a smooth playback without causing any stuttering, e.g. when running out out available data.
Please refer to the player's own documentation for the available options.