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

Code before:

            for cc in media_obj.get('closedcaptions', []):
                cc_url = cc.get('url')
                if not cc_url or cc_url in urls:
                    continue
                urls.append(cc_url)
                subtitles.setdefault(cc.get('lang') or 'en-US', []).append({
                    'url': cc_url,
                    'ext': mimetype2ext(cc.get('content_type')),
                })

        if not formats and msg == 'geo restricted':
            self.raise_geo_restricted(metadata_available=True)

        return {
            'id': video_id,
            'title': video.get('title') or '',
            'formats': formats,
            'description': clean_html(video.get('description')),
            'thumbnail': video.get('thumbnail'),
            'timestamp': parse_iso8601(video.get('publish_time')),
            'subtitles': subtitles,
            'duration': int_or_none(video.get('duration')),
            'view_count': int_or_none(video.get('view_count')),
            'is_live': is_live,
            'series': video.get('show_name'),
        }

    def _real_extract(self, url):
        url, country, display_id = self._match_valid_url(url).groups()
        if not country:
            country = 'us'
        else:
            country = country.split('-')[0]

        items = self._download_json(
            f'https://{country}.yahoo.com/caas/content/article', display_id,
            'Downloading content JSON metadata', query={
                'url': url,
            })['items'][0]

        item = items['data']['partnerData']
        if item.get('type') != 'video':
            entries = []

            cover = item.get('cover') or {}
            if cover.get('type') == 'yvideo':
                cover_url = cover.get('url')
                if cover_url:
                    entries.append(self.url_result(
                        cover_url, 'Yahoo', cover.get('uuid')))

Review comment (suggestion):
```suggestion
            'series': traverse_obj(video, ('show_name', {str}, filter)),
```

Code after:
            'Downloading content JSON metadata', query={
                'url': url,
            })['items'][0]

        item = items['data']['partnerData']
        if item.get('type') != 'video':
            entries = []

            cover = item.get('cover') or {}
            if cover.get('type') == 'yvideo':
                cover_url = cover.get('url')
                if cover_url:
                    entries.append(self.url_result(
                        cover_url, 'Yahoo', cover.get('uuid')))

            for e in (item.get('body') or []):
                if e.get('type') == 'videoIframe':
                    iframe_url = e.get('url')
                    if iframe_url:
                        entries.append(self.url_result(iframe_url))

            if item.get('type') == 'storywithleadvideo':
                iframe_url = try_get(item, lambda x: x['meta']['player']['url'])
                if iframe_url:
                    entries.append(self.url_result(iframe_url))
                else:
                    self.report_warning("Yahoo didn't provide an iframe url for this storywithleadvideo")

            if items.get('markup'):
                entries.extend(
                    self.url_result(yt_url) for yt_url in YoutubeIE._extract_embed_urls(url, items['markup']))

            return self.playlist_result(
                entries, item.get('uuid'),
                item.get('title'), item.get('summary'))

        info = self._extract_yahoo_video(item['uuid'], country)
        info['display_id'] = display_id
        return info


class YahooSearchIE(SearchInfoExtractor):
    _MAX_RESULTS = 1000
    IE_NAME = 'yahoo:search'
    _SEARCH_KEY = 'yvsearch'

    def _search_results(self, query):
        for pagenum in itertools.count(0):
            result_url = f'https://video.search.yahoo.com/search/?p={urllib.parse.quote_plus(query)}&fr=screen&o=js&gs=0&b={pagenum * 30}'
            info = self._download_json(result_url, query,
                                       note='Downloading results page ' + str(pagenum + 1))