Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/twitch.py (Python)

Code before:

    def _download_access_token(self, video_id, token_kind, param_name):
        method = '%sPlaybackAccessToken' % token_kind
        ops = {
            'query': '''{
              %s(
                %s: "%s",
                params: {
                  platform: "web",
                  playerBackend: "mediaplayer",
                  playerType: "site"
                }
              )
              {
                value
                signature
              }
            }''' % (method, param_name, video_id),
        }
        return self._download_base_gql(
            video_id, ops,
            'Downloading %s access token GraphQL' % token_kind)['data'][method]

    def _get_thumbnails(self, thumbnail):
        return [{
            'url': re.sub(r'\d+x\d+\.jpg', '0x0.jpg', thumbnail),
            'preference': 1,
        }, {
            'url': thumbnail,
        }] if thumbnail else None


class TwitchVodIE(TwitchBaseIE):
    IE_NAME = 'twitch:vod'
    _VALID_URL = r'''(?x)
                    https?://
                        (?:
                            (?:(?:www|go|m)\.)?twitch\.tv/(?:[^/]+/v(?:ideo)?|videos)/|
                            player\.twitch\.tv/\?.*?\bvideo=v?
                        )
                        (?P<id>\d+)
                    '''

    _TESTS = [{
        'url': 'http://www.twitch.tv/riotgames/v/6528877?t=5m10s',
        'info_dict': {
            'id': 'v6528877',
            'ext': 'mp4',
            'title': 'LCK Summer Split - Week 6 Day 1',
            'thumbnail': r're:^https?://.*\.jpg$',
            'duration': 17208,

Review comment (suggestion):
This causes problems with custom VOD thumbnails, since they do not have to be JPEGs, as such a more flexible RegEx should be used.

**Example:**
```py
'url': re.sub(r'\d+x\d+\.(jpg|jpeg|png|gif|webp)', '0x0.\g<1>', thumbnail),
```

> This would also be more future-proof in-case Twitch changes their thumbnail extension.

Code after:

    def _download_access_token(self, video_id, token_kind, param_name):
        method = '%sPlaybackAccessToken' % token_kind
        ops = {
            'query': '''{
              %s(
                %s: "%s",
                params: {
                  platform: "web",
                  playerBackend: "mediaplayer",
                  playerType: "site"
                }
              )
              {
                value
                signature
              }
            }''' % (method, param_name, video_id),
        }
        return self._download_base_gql(
            video_id, ops,
            'Downloading %s access token GraphQL' % token_kind)['data'][method]

    def _get_thumbnails(self, thumbnail):
        return [{
            'url': re.sub(r'\d+x\d+(\.\w+)($|(?=[?#]))', r'0x0\g<1>', thumbnail),
            'preference': 1,
        }, {
            'url': thumbnail,
        }] if thumbnail else None


class TwitchVodIE(TwitchBaseIE):
    IE_NAME = 'twitch:vod'
    _VALID_URL = r'''(?x)
                    https?://
                        (?:
                            (?:(?:www|go|m)\.)?twitch\.tv/(?:[^/]+/v(?:ideo)?|videos)/|
                            player\.twitch\.tv/\?.*?\bvideo=v?
                        )
                        (?P<id>\d+)
                    '''

    _TESTS = [{
        'url': 'http://www.twitch.tv/riotgames/v/6528877?t=5m10s',
        'info_dict': {
            'id': 'v6528877',
            'ext': 'mp4',
            'title': 'LCK Summer Split - Week 6 Day 1',
            'thumbnail': r're:^https?://.*\.jpg$',
            'duration': 17208,