From 503d036b189193ba7b62648e4f807988f4ac1a77 Mon Sep 17 00:00:00 2001 From: einanderson <289327658+einanderson@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:31:32 +0200 Subject: [PATCH] usher: add optional supported_codecs parameter Adds a supported_codecs keyword argument (default None) to the live and VOD playlist requests. When set, supported_codecs= is sent to Twitch's usher endpoint, which is required to receive Enhanced Broadcasting variants (HEVC / AV1, e.g. 1440p). Default None keeps the current behaviour unchanged. Enables plugin.video.twitch to expose a codec preference setting. --- resources/lib/twitch/api/usher.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/resources/lib/twitch/api/usher.py b/resources/lib/twitch/api/usher.py index b03edff..aafc6ad 100644 --- a/resources/lib/twitch/api/usher.py +++ b/resources/lib/twitch/api/usher.py @@ -88,7 +88,7 @@ def _legacy_video(video_id): return q -def live_request(channel, platform=keys.WEB, headers={}): +def live_request(channel, platform=keys.WEB, headers={}, supported_codecs=None): token = channel_token(channel, platform=platform, headers=headers) token = get_access_token(token) @@ -112,6 +112,8 @@ def live_request(channel, platform=keys.WEB, headers={}): q.add_param(keys.PLAYLIST_INCLUDE_FRAMERATE, Boolean.TRUE) q.add_param(keys.RTQOS, keys.CONTROL) q.add_param(keys.PLAYER_BACKEND, keys.MEDIAPLAYER) + if supported_codecs: + q.add_param('supported_codecs', supported_codecs) url = '?'.join([q.url, urlencode(q.params)]) request_dict = { 'url': url, @@ -122,7 +124,7 @@ def live_request(channel, platform=keys.WEB, headers={}): @query -def _live(channel, token, headers={}): +def _live(channel, token, headers={}, supported_codecs=None): signature = token[keys.SIGNATURE] access_token = token[keys.VALUE] @@ -139,11 +141,13 @@ def _live(channel, token, headers={}): q.add_param(keys.PLAYLIST_INCLUDE_FRAMERATE, Boolean.TRUE) q.add_param(keys.RTQOS, keys.CONTROL) q.add_param(keys.PLAYER_BACKEND, keys.MEDIAPLAYER) + if supported_codecs: + q.add_param('supported_codecs', supported_codecs) return q @m3u8 -def live(channel, platform=keys.WEB, headers={}): +def live(channel, platform=keys.WEB, headers={}, supported_codecs=None): token = channel_token(channel, platform=platform, headers=headers) token = get_access_token(token) if not token: @@ -151,10 +155,10 @@ def live(channel, platform=keys.WEB, headers={}): elif isinstance(token, dict) and 'error' in token: return token else: - return _live(channel, token, headers=headers) + return _live(channel, token, headers=headers, supported_codecs=supported_codecs) -def video_request(video_id, platform=keys.WEB, headers={}): +def video_request(video_id, platform=keys.WEB, headers={}, supported_codecs=None): video_id = valid_video_id(video_id) if video_id: token = vod_token(video_id, platform=platform, headers=headers) @@ -178,6 +182,8 @@ def video_request(video_id, platform=keys.WEB, headers={}): q.add_param(keys.PLAYLIST_INCLUDE_FRAMERATE, Boolean.TRUE) q.add_param(keys.RTQOS, keys.CONTROL) q.add_param(keys.PLAYER_BACKEND, keys.MEDIAPLAYER) + if supported_codecs: + q.add_param('supported_codecs', supported_codecs) q.add_param(keys.BAKING_BREAD, Boolean.TRUE) q.add_param(keys.BAKING_BROWNIES, Boolean.TRUE) q.add_param(keys.BAKING_BROWNIES_TIMEOUT, 1050) @@ -193,7 +199,7 @@ def video_request(video_id, platform=keys.WEB, headers={}): @query -def _vod(video_id, token, headers={}): +def _vod(video_id, token, headers={}, supported_codecs=None): signature = token[keys.SIGNATURE] access_token = token[keys.VALUE] @@ -208,6 +214,8 @@ def _vod(video_id, token, headers={}): q.add_param(keys.PLAYLIST_INCLUDE_FRAMERATE, Boolean.TRUE) q.add_param(keys.RTQOS, keys.CONTROL) q.add_param(keys.PLAYER_BACKEND, keys.MEDIAPLAYER) + if supported_codecs: + q.add_param('supported_codecs', supported_codecs) q.add_param(keys.BAKING_BREAD, Boolean.TRUE) q.add_param(keys.BAKING_BROWNIES, Boolean.TRUE) q.add_param(keys.BAKING_BROWNIES_TIMEOUT, 1050) @@ -215,7 +223,7 @@ def _vod(video_id, token, headers={}): @m3u8 -def video(video_id, platform=keys.WEB, headers={}): +def video(video_id, platform=keys.WEB, headers={}, supported_codecs=None): video_id = valid_video_id(video_id) if video_id: token = vod_token(video_id, platform=platform, headers=headers) @@ -226,7 +234,7 @@ def video(video_id, platform=keys.WEB, headers={}): elif isinstance(token, dict) and 'error' in token: return token else: - return _vod(video_id, token, headers=headers) + return _vod(video_id, token, headers=headers, supported_codecs=supported_codecs) else: raise NotImplementedError('Unknown Video Type')