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

Code before:
        'url': 'https://www.globalplayer.com/playlists/8bLk/',
        'info_dict': {
            'id': '8bLk',
            'ext': 'aac',
            'title': str,
            'description': 'md5:e10f5e10b01a7f2c14ba815509fbb38d',
            'live_status': 'is_live',
            'thumbnail': 'md5:0e0d47914a380577afdb4482a9561210',
        }
    }
    ]

    # very similar to live radio, but different enough that it's easier to separate them

    def _real_extract(self, url):
        video_id = self._match_id(url)
        station = self._get_pageProps(url, video_id)['playlistData']
        url = station['streamUrl']

        return {
            'url': url,
            'ext': self._request_ext(url, video_id),
            'vcodec': 'none',
            'is_live': True,
            **traverse_obj(station, {
                'id': 'id',
                'title': 'title',
                'description': 'description',
                'thumbnail': 'image',
            }),
        }


class GlobalPlayerAudioIE(GlobalPlayerBaseIE):
    _VALID_URL = r'https?://www\.globalplayer\.com/(?:(?P<podcast>podcasts)/|catchup/\w+/\w+/)(?P<id>\w+)/?$'
    _TESTS = [{
        # podcast
        'url': 'https://www.globalplayer.com/podcasts/42KuaM/',
        'info_dict': {
            'id': '42KuaM',
            'thumbnail': 'md5:60286e7d12d795bd1bbc9efc6cee643e',
            'description': 'md5:da5b918eac9ae319454a10a563afacf9',
            'uploader': 'Global',
            'title': 'Filthy Ritual',
            'categories': ['Society & Culture', 'True Crime'],
        },
        'playlist_mincount': 5,
    }, {
        # radio catchup
        'url': 'https://www.globalplayer.com/catchup/lbc/uk/46vyD7z/',
        'info_dict': {

Review comment (suggestion):
`id` is mandatory, and we can just use `video_id`, yeah?
```suggestion
        return {
            'id': video_id,
            'url': stream_url,
            'ext': self._request_ext(stream_url, video_id),
            'vcodec': 'none',
            'is_live': True,
            **traverse_obj(station, {
```

Code after:
            'title': 're:^Classic FM Hall of Fame.+$'
        },
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        station = self._get_page_props(url, video_id)['playlistData']
        stream_url = station['streamUrl']

        return {
            'id': video_id,
            'url': stream_url,
            'ext': self._request_ext(stream_url, video_id),
            'vcodec': 'none',
            'is_live': True,
            **traverse_obj(station, {
                'title': 'title',
                'description': 'description',
                'thumbnail': 'image',
            }),
        }


class GlobalPlayerAudioIE(GlobalPlayerBaseIE):
    _VALID_URL = r'https?://www\.globalplayer\.com/(?:(?P<podcast>podcasts)/|catchup/\w+/\w+/)(?P<id>\w+)/?(?:$|[?#])'
    _TESTS = [{
        # podcast
        'url': 'https://www.globalplayer.com/podcasts/42KuaM/',
        'playlist_mincount': 5,
        'info_dict': {
            'id': '42KuaM',
            'title': 'Filthy Ritual',
            'thumbnail': 'md5:60286e7d12d795bd1bbc9efc6cee643e',
            'categories': ['Society & Culture', 'True Crime'],
            'uploader': 'Global',
            'description': 'md5:da5b918eac9ae319454a10a563afacf9',
        },
    }, {
        # radio catchup
        'url': 'https://www.globalplayer.com/catchup/lbc/uk/46vyD7z/',
        'playlist_mincount': 3,
        'info_dict': {
            'id': '46vyD7z',
            'description': 'Nick Ferrari At Breakfast is Leading Britain\'s Conversation.',
            'title': 'Nick Ferrari',
            'thumbnail': 'md5:4df24d8a226f5b2508efbcc6ae874ebf',
        },
    }]

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