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

Code before:
            'ext': 'm4a',
            'view_count': int,
            'thumbnail': r're:^https?://.*\.jpg',
            'like_count': int,
            'live_status': 'is_live',
        },
        'params': {
            'skip_download': True,
        },
    }]

    def _real_extract(self, url):
        url_type, live_radio_id = self._match_valid_url(url).group('type', 'id')
        info = self._call_api(url_type, {'id': live_radio_id})
        manifest_url = info.get('streaming')
        if not manifest_url:
            raise ExtractorError('This radio is offline.', expected=True)
        fmts, subtitles = self._extract_m3u8_formats_and_subtitles(manifest_url, live_radio_id, fatal=False)
        return {
            'id': live_radio_id,
            'is_live': True,
            'formats': fmts,
            'subtitles': subtitles,
            **traverse_obj(info, {
                'title': 'title',
                'thumbnail': (None, ('thumbnail', 'thumbnailM', 'thumbnailV', 'thumbnailH')),
                'view_count': ('activeUsers', {int_or_none}),
                'like_count': ('totalReaction', {int_or_none}),
                'description': 'description',
            }, get_all=False),
        }


class ZingMp3PodcastEpisodeIE(ZingMp3BaseIE):
    IE_NAME = 'zingmp3:PodcastEpisode'
    _VALID_URL = ZingMp3BaseIE._VALID_URL_TMPL % 'pgr|cgr'
    _TESTS = [{
        'url': 'https://zingmp3.vn/pgr/Nhac-Moi-Moi-Ngay/68Z9W66B.html',
        'info_dict': {
            'id': '68Z9W66B',
            'title': 'Nhạc Mới Mỗi Ngày',
            'description': 'md5:2875dfa951f8e5356742f1610cf20691'
        },
        'playlist_mincount': 20,
    }, {
        'url': 'https://zingmp3.vn/cgr/Am-nhac/IWZ980AO.html',
        'info_dict': {
            'id': 'IWZ980AO',
            'title': 'Âm nhạc'
        },
        'playlist_mincount': 2,

Review comment (suggestion):
```suggestion
                'thumbnail': (('thumbnail', 'thumbnailM', 'thumbnailV', 'thumbnailH'), {url_or_none}),
```
import `utils.url_or_none`

Code after:
            'description': 'md5:d41d8cd98f00b204e9800998ecf8427e',
            'protocol': 'm3u8_native',
            'ext': 'm4a',
            'view_count': int,
            'thumbnail': r're:^https?://.*\.jpg',
            'like_count': int,
            'live_status': 'is_live',
        },
        'params': {
            'skip_download': True,
        },
    }]

    def _real_extract(self, url):
        url_type, live_radio_id = self._match_valid_url(url).group('type', 'id')
        info = self._call_api(url_type, {'id': live_radio_id})
        manifest_url = info.get('streaming')
        if not manifest_url:
            raise ExtractorError('This radio is offline.', expected=True)
        fmts, subtitles = self._extract_m3u8_formats_and_subtitles(manifest_url, live_radio_id, fatal=False)
        return {
            'id': live_radio_id,
            'is_live': True,
            'formats': fmts,
            'subtitles': subtitles,
            **traverse_obj(info, {
                'title': 'title',
                'thumbnail': (('thumbnail', 'thumbnailM', 'thumbnailV', 'thumbnailH'), {url_or_none}),
                'view_count': ('activeUsers', {int_or_none}),
                'like_count': ('totalReaction', {int_or_none}),
                'description': 'description',
            }, get_all=False),
        }


class ZingMp3PodcastEpisodeIE(ZingMp3BaseIE):
    IE_NAME = 'zingmp3:podcast-episode'
    _VALID_URL = ZingMp3BaseIE._VALID_URL_TMPL % 'pgr|cgr'
    _TESTS = [{
        'url': 'https://zingmp3.vn/pgr/Nhac-Moi-Moi-Ngay/68Z9W66B.html',
        'info_dict': {
            'id': '68Z9W66B',
            'title': 'Nhạc Mới Mỗi Ngày',
            'description': 'md5:2875dfa951f8e5356742f1610cf20691'
        },
        'playlist_mincount': 20,
    }, {
        'url': 'https://zingmp3.vn/cgr/Am-nhac/IWZ980AO.html',
        'info_dict': {
            'id': 'IWZ980AO',
            'title': 'Âm nhạc'