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

Code before:
        station = self._get_pageProps(url, video_id)['station']
        url = station['streamUrl']

        display_id = [station.get('brandSlug'), station.get('slug')]
        if None not in display_id:
            display_id = '-'.join(display_id)
        else:
            display_id = station.get('brandSlug') or station.get('legacyStationPrefix')

        return {
            'id': station['id'],
            'display_id': display_id,
            'url': url,
            'ext': self._request_ext(url, video_id),
            'vcodec': 'none',
            'is_live': True,
            **traverse_obj(station, {
                'title': (['name', 'brandName'], {str_or_none}),
                'description': 'tagline',
                'thumbnail': 'brandLogo',
            }, get_all=False),
        }


class GlobalPlayerLivePlaylistIE(GlobalPlayerBaseIE):
    _VALID_URL = r'https?://www\.globalplayer\.com/playlists/(?P<id>\w+)/$'
    _TESTS = [{
        # "live playlist"
        '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',

Review comment (suggestion):
```suggestion
class GlobalPlayerLivePlaylistIE(GlobalPlayerBaseIE):
    _VALID_URL = r'https?://www\.globalplayer\.com/playlists/(?P<id>\w+)'
```

Code after:
        stream_url = station['streamUrl']

        return {
            'id': station['id'],
            'display_id': join_nonempty('brandSlug', 'slug', from_dict=station) or station.get('legacyStationPrefix'),
            'url': stream_url,
            'ext': self._request_ext(stream_url, video_id),
            'vcodec': 'none',
            'is_live': True,
            **traverse_obj(station, {
                'title': (('name', 'brandName'), {str_or_none}),
                'description': 'tagline',
                'thumbnail': 'brandLogo',
            }, get_all=False),
        }


class GlobalPlayerLivePlaylistIE(GlobalPlayerBaseIE):
    _VALID_URL = r'https?://www\.globalplayer\.com/playlists/(?P<id>\w+)'
    _TESTS = [{
        # "live playlist"
        'url': 'https://www.globalplayer.com/playlists/8bLk/',
        'info_dict': {
            'id': '8bLk',
            'ext': 'aac',
            'live_status': 'is_live',
            'description': 'md5:e10f5e10b01a7f2c14ba815509fbb38d',
            'thumbnail': 'https://images.globalplayer.com/images/551379?width=450&signature=oMLPZIoi5_dBSHnTMREW0Xg76mA=',
            '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',
            }),
        }