]> jfr.im git - yt-dlp.git/commitdiff
[ie/twitch] Fix m3u8 extraction (#8960)
authorDmitryScaletta <redacted>
Tue, 9 Jan 2024 02:47:13 +0000 (05:47 +0300)
committerGitHub <redacted>
Tue, 9 Jan 2024 02:47:13 +0000 (02:47 +0000)
Closes #8958
Authored by: DmitryScaletta

yt_dlp/extractor/twitch.py

index 3297ef09179961e29794733d83fcbe75cf2007e9..6dc0993afc7f10e0b668b9ee695826072bd2ada7 100644 (file)
@@ -8,7 +8,6 @@
 from ..compat import (
     compat_parse_qs,
     compat_str,
-    compat_urllib_parse_urlencode,
     compat_urllib_parse_urlparse,
 )
 from ..utils import (
@@ -191,6 +190,20 @@ def _get_thumbnails(self, thumbnail):
             'url': thumbnail,
         }] if thumbnail else None
 
+    def _extract_twitch_m3u8_formats(self, video_id, token, signature):
+        """Subclasses must define _M3U8_PATH"""
+        return self._extract_m3u8_formats(
+            f'{self._USHER_BASE}/{self._M3U8_PATH}/{video_id}.m3u8', video_id, 'mp4', query={
+                'allow_source': 'true',
+                'allow_audio_only': 'true',
+                'allow_spectre': 'true',
+                'p': random.randint(1000000, 10000000),
+                'player': 'twitchweb',
+                'playlist_include_framerate': 'true',
+                'sig': signature,
+                'token': token,
+            })
+
 
 class TwitchVodIE(TwitchBaseIE):
     IE_NAME = 'twitch:vod'
@@ -203,6 +216,7 @@ class TwitchVodIE(TwitchBaseIE):
                         )
                         (?P<id>\d+)
                     '''
+    _M3U8_PATH = 'vod'
 
     _TESTS = [{
         'url': 'http://www.twitch.tv/riotgames/v/6528877?t=5m10s',
@@ -532,20 +546,8 @@ def _real_extract(self, url):
         info = self._extract_info_gql(video, vod_id)
         access_token = self._download_access_token(vod_id, 'video', 'id')
 
-        formats = self._extract_m3u8_formats(
-            '%s/vod/%s.m3u8?%s' % (
-                self._USHER_BASE, vod_id,
-                compat_urllib_parse_urlencode({
-                    'allow_source': 'true',
-                    'allow_audio_only': 'true',
-                    'allow_spectre': 'true',
-                    'player': 'twitchweb',
-                    'playlist_include_framerate': 'true',
-                    'nauth': access_token['value'],
-                    'nauthsig': access_token['signature'],
-                })),
-            vod_id, 'mp4', entry_protocol='m3u8_native')
-
+        formats = self._extract_twitch_m3u8_formats(
+            vod_id, access_token['value'], access_token['signature'])
         formats.extend(self._extract_storyboard(vod_id, video.get('storyboard'), info.get('duration')))
 
         self._prefer_source(formats)
@@ -924,6 +926,7 @@ class TwitchStreamIE(TwitchBaseIE):
                         )
                         (?P<id>[^/#?]+)
                     '''
+    _M3U8_PATH = 'api/channel/hls'
 
     _TESTS = [{
         'url': 'http://www.twitch.tv/shroomztv',
@@ -1026,23 +1029,10 @@ def _real_extract(self, url):
 
         access_token = self._download_access_token(
             channel_name, 'stream', 'channelName')
-        token = access_token['value']
 
         stream_id = stream.get('id') or channel_name
-        query = {
-            'allow_source': 'true',
-            'allow_audio_only': 'true',
-            'allow_spectre': 'true',
-            'p': random.randint(1000000, 10000000),
-            'player': 'twitchweb',
-            'playlist_include_framerate': 'true',
-            'segment_preference': '4',
-            'sig': access_token['signature'].encode('utf-8'),
-            'token': token.encode('utf-8'),
-        }
-        formats = self._extract_m3u8_formats(
-            '%s/api/channel/hls/%s.m3u8' % (self._USHER_BASE, channel_name),
-            stream_id, 'mp4', query=query)
+        formats = self._extract_twitch_m3u8_formats(
+            channel_name, access_token['value'], access_token['signature'])
         self._prefer_source(formats)
 
         view_count = stream.get('viewers')