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

Code before:
            self.raise_no_formats('Live event has not yet started', expected=True)
            live_status = 'is_upcoming'
            formats = []
        elif player_type == 'player':
            live_status = 'is_live'
            formats = self._extract_m3u8_formats(
                event_data['data']['Channel']['Custom_live_url'], video_id, live=True)
        else:
            raise ExtractorError('Unexpected player type')

        return {
            'release_timestamp': traverse_obj(metadata, ('period', 'start', {parse_iso8601})),
            'live_status': live_status,
            'formats': formats,
        }

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

        metadata = self._download_json(
            f'https://channel.microcms.io/api/v1/media/{video_id}', video_id,
            headers=self._MICROCMS_HEADER)

        info = self._extract_info(metadata)

        video_type = traverse_obj(metadata, ('contents', 'video_type', 0))
        if video_type == 'VOD':
            return merge_dicts(info, self._process_vod(video_id, metadata))
        if video_type == 'LIVE':
            return merge_dicts(info, self._process_live(video_id, metadata))

        raise ExtractorError(f'Unexpected video type {video_type}', expected=False)


class AsobiChannelTagURLIE(AsobiChannelBaseIE):
    IE_NAME = 'asobichannel:tag'
    IE_DESC = 'ASOBI CHANNEL'

    _VALID_URL = r'https?://asobichannel\.asobistore\.jp/tag/(?P<id>[a-z0-9-_]+)'
    _TESTS = [{
        'url': 'https://asobichannel.asobistore.jp/tag/bjhh-nbcja',
        'info_dict': {
            'id': 'bjhh-nbcja',
            'title': 'アイドルマスター ミリオンライブ！ 765プロch 原っぱ通信',
        },
        'playlist_mincount': 16,
    }, {
        'url': 'https://asobichannel.asobistore.jp/tag/hvm5qw3c6od',
        'info_dict': {
            'id': 'hvm5qw3c6od',
            'title': 'アイマスMOIW2023ラジオ',

Review comment (suggestion):
```suggestion
        video_type = traverse_obj(metadata, ('contents', 'video_type', 0, {str}))
```

Code after:
        event_data = self._download_json(
            f'https://survapi.channel.or.jp/ex/events/{content_id}?embed=channel', video_id,
            headers=self._survapi_header, note='Downloading event data')

        player_type = traverse_obj(event_data, ('data', 'Player_type', {str}))
        if player_type == 'poster':
            self.raise_no_formats('Live event has not yet started', expected=True)
            live_status = 'is_upcoming'
            formats = []
        elif player_type == 'player':
            live_status = 'is_live'
            formats = self._extract_m3u8_formats(
                event_data['data']['Channel']['Custom_live_url'], video_id, live=True)
        else:
            raise ExtractorError('Unsupported player type {player_type!r}')

        return {
            'release_timestamp': traverse_obj(metadata, ('period', 'start', {parse_iso8601})),
            'live_status': live_status,
            'formats': formats,
        }

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

        metadata = self._download_json(
            f'https://channel.microcms.io/api/v1/media/{video_id}', video_id,
            headers=self._MICROCMS_HEADER)

        info = self._extract_info(metadata)

        video_type = traverse_obj(metadata, ('contents', 'video_type', 0, {str}))
        if video_type == 'VOD':
            return merge_dicts(info, self._process_vod(video_id, metadata))
        if video_type == 'LIVE':
            return merge_dicts(info, self._process_live(video_id, metadata))

        raise ExtractorError(f'Unexpected video type {video_type!r}')


class AsobiChannelTagURLIE(AsobiChannelBaseIE):
    IE_NAME = 'asobichannel:tag'
    IE_DESC = 'ASOBI CHANNEL'

    _VALID_URL = r'https?://asobichannel\.asobistore\.jp/tag/(?P<id>[a-z0-9-_]+)'
    _TESTS = [{
        'url': 'https://asobichannel.asobistore.jp/tag/bjhh-nbcja',
        'info_dict': {
            'id': 'bjhh-nbcja',
            'title': 'アイドルマスター ミリオンライブ！ 765プロch 原っぱ通信',
        },