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

Code before:
    orderedSet,
    parse_duration,
    remove_end,
    traverse_obj,
    try_call,
    unescapeHTML,
    unified_timestamp,
    url_or_none,
    urljoin,
    variadic,
)


class NhkBaseIE(InfoExtractor):
    _API_URL_TEMPLATE = 'https://api.nhkworld.jp/showsapi/v1/{lang}/{content_format}_{page_type}/{m_id}{extra_page}'
    _BASE_URL_REGEX = r'https?://www3\.nhk\.or\.jp/nhkworld/(?P<lang>[a-z]{2})/'

    def _call_api(self, m_id, lang, is_video, is_episode, is_clip):
        content_format = 'video' if is_video else 'audio'

        if not is_episode:
            page_type = 'programs'

        if is_clip:
            content_type = 'clips'
        else:
            content_type = 'episodes'

        if not is_episode:
            extra_page = f'/{content_format}_{content_type}'
        else:
            extra_page = ''
            page_type = content_type

        return self._download_json(self._API_URL_TEMPLATE.format(
            lang=lang,
            content_format=content_format,
            page_type=page_type,
            m_id=m_id,
            extra_page=extra_page,
        ), video_id=join_nonempty(m_id, lang),
        )

        # FOR EXAMPLE:
        # https://api.nhkworld.jp/showsapi/v1/en/video_episodes/2024117
        # https://api.nhkworld.jp/showsapi/v1/en/audio_episodes/r_l_japannews-20250203-1
        # https://api.nhkworld.jp/showsapi/v1/en/video_clips/9999011
        # https://api.nhkworld.jp/showsapi/v1/en/video_programs/dwc/video_episodes
        # https://api.nhkworld.jp/showsapi/v1/en/audio_programs/livinginjapan/audio_episodes
        # no such thing as an audio_clips afaict


Review comment (suggestion):
```suggestion
        content_format = 'video' if is_video else 'audio'
        content_type = 'clips' if is_clip else 'episodes'

        if not is_episode:
            extra_page = f'/{content_format}_{content_type}'
            page_type = 'programs'
        else:
            extra_page = ''
            page_type = content_type
```

Code after:
    orderedSet,
    parse_duration,
    remove_end,
    traverse_obj,
    try_call,
    unescapeHTML,
    unified_timestamp,
    url_or_none,
    urljoin,
    variadic,
)


class NhkBaseIE(InfoExtractor):
    _API_URL_TEMPLATE = 'https://api.nhkworld.jp/showsapi/v1/{lang}/{content_format}_{page_type}/{m_id}{extra_page}'
    _BASE_URL_REGEX = r'https?://www3\.nhk\.or\.jp/nhkworld/(?P<lang>[a-z]{2})/'

    def _call_api(self, m_id, lang, is_video, is_episode, is_clip):
        content_format = 'video' if is_video else 'audio'
        content_type = 'clips' if is_clip else 'episodes'
        if not is_episode:
            extra_page = f'/{content_format}_{content_type}'
            page_type = 'programs'
        else:
            extra_page = ''
            page_type = content_type

        return self._download_json(
            self._API_URL_TEMPLATE.format(
                lang=lang, content_format=content_format, page_type=page_type,
                m_id=m_id, extra_page=extra_page),
            join_nonempty(m_id, lang))

    def _extract_episode_info(self, url, episode=None):
        fetch_episode = episode is None
        lang, m_type, episode_id = NhkVodIE._match_valid_url(url).group('lang', 'type', 'id')
        is_video = m_type != 'audio'

        if fetch_episode:
            episode = self._call_api(
                episode_id, lang, is_video, is_episode=True, is_clip=episode_id[:4] == '9999')

        video_id = join_nonempty('id', 'lang', from_dict=episode)

        title = episode.get('title')
        series = traverse_obj(episode, (('video_program', 'audio_program'), any, 'title'))

        episode_name = title
        if series and title:
            title = f'{series} - {title}'
        elif series and not title: