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

Code before:
            'thumbnail': 're:https?://.+',
        },
        'params': {'skip_download': 'm3u8'},
    }, {
        'url': 'https://vod.tvp.pl/live,1/tvp-world,399731',
        'info_dict': {
            'id': '399731',
            'ext': 'mp4',
            'title': r're:TVP WORLD \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
            'live_status': 'is_live',
            'thumbnail': 're:https?://.+',
        },
    }]

    def _real_extract(self, url):
        category, date, video_id = self._match_valid_url(url).group('category', 'date', 'id')

        entity = 'vods'
        if category == 'live,1':
            # programs broadcasted on tv can be linked to by their EPG item.
            # it's not really playable.
            if date:
                raise ExtractorError('EPG items cannot be downloaded. Find it on VOD.', expected=True)
            else:
                entity = 'lives'

        info_dict = self._parse_video(self._call_api(f'{entity}/{video_id}', video_id), with_url=False)

        playlist = self._call_api(f'{video_id}/videos/playlist', video_id, query={'videoType': 'MOVIE'})

        info_dict['formats'] = []
        for manifest_url in traverse_obj(playlist, ('sources', 'HLS', ..., 'src')):
            info_dict['formats'].extend(self._extract_m3u8_formats(manifest_url, video_id, fatal=False))
        for manifest_url in traverse_obj(playlist, ('sources', 'DASH', ..., 'src')):
            info_dict['formats'].extend(self._extract_mpd_formats(manifest_url, video_id, fatal=False))

        info_dict['subtitles'] = {}
        for sub in playlist.get('subtitles') or []:
            info_dict['subtitles'].setdefault(sub.get('language') or 'und', []).append({
                'url': sub['url'],
                'ext': 'ttml',
            })

        return info_dict


class TVPVODSeriesIE(TVPVODBaseIE):
    IE_NAME = 'tvp:vod:series'
    _VALID_URL = r'https?://vod\.tvp\.pl/[a-z\d-]+,\d+/[a-z\d-]+-odcinki,(?P<id>\d+)(?:\?[^#]+)?(?:#.+)?$'

    _TESTS = [{

Review comment (suggestion):
If we don't match URLs containing the date, we can do:
```suggestion
        entity = 'lives' if category == 'live,1' else 'vods'
```

Code after:
        },
    }]

    def _real_extract(self, url):
        category, video_id = self._match_valid_url(url).group('category', 'id')

        is_live = category == 'live,1'
        entity = 'lives' if is_live else 'vods'
        info_dict = self._parse_video(self._call_api(f'{entity}/{video_id}', video_id), with_url=False)

        playlist = self._call_api(f'{video_id}/videos/playlist', video_id, query={'videoType': 'MOVIE'})

        info_dict['formats'] = []
        for manifest_url in traverse_obj(playlist, ('sources', 'HLS', ..., 'src')):
            info_dict['formats'].extend(self._extract_m3u8_formats(manifest_url, video_id, fatal=False))
        for manifest_url in traverse_obj(playlist, ('sources', 'DASH', ..., 'src')):
            info_dict['formats'].extend(self._extract_mpd_formats(manifest_url, video_id, fatal=False))

        info_dict['subtitles'] = {}
        for sub in playlist.get('subtitles') or []:
            info_dict['subtitles'].setdefault(sub.get('language') or 'und', []).append({
                'url': sub['url'],
                'ext': 'ttml',
            })

        info_dict['is_live'] = is_live

        return info_dict


class TVPVODSeriesIE(TVPVODBaseIE):
    IE_NAME = 'tvp:vod:series'
    _VALID_URL = r'https?://vod\.tvp\.pl/[a-z\d-]+,\d+/[a-z\d-]+-odcinki,(?P<id>\d+)(?:\?[^#]+)?(?:#.+)?$'

    _TESTS = [{
        'url': 'https://vod.tvp.pl/seriale,18/ranczo-odcinki,316445',
        'info_dict': {
            'id': '316445',
            'title': 'Ranczo',
            'age_limit': 12,
            'categories': ['seriale'],
        },
        'playlist_count': 130,
    }, {
        'url': 'https://vod.tvp.pl/programy,88/rolnik-szuka-zony-odcinki,284514',
        'only_matching': True,
    }, {
        'url': 'https://vod.tvp.pl/dla-dzieci,24/laboratorium-alchemika-odcinki,309338',
        'only_matching': True,
    }]