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

Code before:
        'skip': 'Geo-restricted to Canada',
    }, {
        # geo-restricted to Canada, bypassable
        # This video requires an account in the browser, but works fine in yt-dlp
        'url': 'https://gem.cbc.ca/media/schitts-creek/s01e01',
        'md5': '297a9600f554f2258aed01514226a697',
        'info_dict': {
            'id': 'schitts-creek/s01e01',
            'ext': 'mp4',
            'title': 'The Cup Runneth Over',
            'description': 'md5:9bca14ea49ab808097530eb05a29e797',
            'thumbnail': 'https://images.radio-canada.ca/v1/synps-cbc/episode/perso/cbc_schitts_creek_season_01e01_thumbnail_v01.jpg?im=Resize=(Size)',
            'series': 'Schitt\'s Creek',
            'season_number': 1,
            'season': 'Season 1',
            'episode_number': 1,
            'episode': 'The Cup Runneth Over',
            'episode_id': 'schitts-creek/s01e01',
            'duration': 1309,
            'categories': ['comedy'],
        },
        'params': {'format': 'bv'},  # No format has audio and video combined
        'skip': 'Geo-restricted to Canada',
    }, {
        # geo-restricted to Canada, bypassable
        # TV show playlist, all public videos at time of coding (2021-09)
        'url': 'https://gem.cbc.ca/media/schitts-creek/s06',
        'playlist_count': 16,
        'info_dict': {
            'id': 'schitts-creek/s06',
            'title': 'Season 6',
            'description': 'md5:6a92104a56cbeb5818cc47884d4326a2',
        },
        'skip': 'Geo-restricted to Canada',
    }]
    _API_BASE = 'https://services.radio-canada.ca/ott/cbc-api/v2/'
    _API_VIDEO = _API_BASE + 'assets/'
    _API_SHOW = _API_BASE + 'shows/'
    _BROWSER_BASE = 'https://gem.cbc.ca/media/'
    # Regexes for analyzing video_id - the id group of _VALID_URL
    _VIDEO_ID = r'[0-9a-z-]+/s[0-9]+[a-z][0-9]+'
    _PLAYLIST_ID = r'([0-9a-z-]+)/s([0-9]+)'

    def _real_extract(self, url):
        url_id = self._match_id(url)

        playlist_match = re.fullmatch(self._PLAYLIST_ID, url_id)
        if playlist_match:
            season_id = url_id
            show = playlist_match.group(1)
            show_info = self._download_json(self._API_SHOW + show, season_id)

Review comment (suggestion):
```suggestion
        # TV show playlist, all public videos
```

Code after:
            'title': 'Smoke Signals',
            'description': 'md5:929868d20021c924020641769eb3e7f1',
            'thumbnail': 'https://images.radio-canada.ca/v1/synps-cbc/episode/perso/cbc_schitts_creek_season_06e01_thumbnail_v01.jpg?im=Resize=(Size)',
            'duration': 1314,
            'categories': ['comedy'],
            'series': 'Schitt\'s Creek',
            'season': 'Season 6',
            'season_number': 6,
            'episode': 'Smoke Signals',
            'episode_number': 1,
            'episode_id': 'schitts-creek/s06e01',
        },
        'params': {'format': 'bv'},
        'skip': 'Geo-restricted to Canada',
    }, {
        # geo-restricted to Canada, bypassable
        # This video requires an account in the browser, but works fine in yt-dlp
        'url': 'https://gem.cbc.ca/media/schitts-creek/s01e01',
        'md5': '297a9600f554f2258aed01514226a697',
        'info_dict': {
            'id': 'schitts-creek/s01e01',
            'ext': 'mp4',
            'title': 'The Cup Runneth Over',
            'description': 'md5:9bca14ea49ab808097530eb05a29e797',
            'thumbnail': 'https://images.radio-canada.ca/v1/synps-cbc/episode/perso/cbc_schitts_creek_season_01e01_thumbnail_v01.jpg?im=Resize=(Size)',
            'series': 'Schitt\'s Creek',
            'season_number': 1,
            'season': 'Season 1',
            'episode_number': 1,
            'episode': 'The Cup Runneth Over',
            'episode_id': 'schitts-creek/s01e01',
            'duration': 1309,
            'categories': ['comedy'],
        },
        'params': {'format': 'bv'},
        'skip': 'Geo-restricted to Canada',
    }]
    _API_BASE = 'https://services.radio-canada.ca/ott/cbc-api/v2/assets/'

    def _real_extract(self, url):
        video_id = self._match_id(url)
        video_info = self._download_json(self._API_BASE + video_id, video_id)

        last_error = None
        attempt = -1
        retries = self.get_param('extractor_retries', 15)
        while attempt < retries:
            attempt += 1
            if last_error:
                self.report_warning('%s. Retrying ...' % last_error)
            m3u8_info = self._download_json(