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

Code before:
        formats, subtitles = self._extract_theplatform_smil(smil_url, video_id)

        note = 'Downloading m3u8 information'
        errnote = 'Failed to download m3u8 information'
        # on at least one site reading just the SMIL data misses some formats as well as subtitles.
        # Therefore also read the m3u8 file and add those formats and subtitles
        m3u8_url = url.split("&")[0]
        ext = urlhandle_detect_ext(self._request_webpage(
            HEADRequest(m3u8_url),
            video_id,
            fatal=False))
        if ext == 'm3u8':
            res = self._download_webpage_handle(
                m3u8_url, video_id,
                note=note,
                errnote=errnote,
                fatal=False)
            if res is not False:
                m3u8_doc, urlh = res
                formats2, subtitles2 = self._parse_m3u8_formats_and_subtitles(
                    m3u8_doc, m3u8_url, entry_protocol='m3u8_native',
                    note=note, errnote=errnote, fatal=False,
                    video_id=video_id)
                formats += formats2
                subtitles.update(subtitles2)

        ret = self._extract_theplatform_metadata(path, video_id)
        combined_subtitles = self._merge_subtitles(ret.get('subtitles', {}), subtitles)
        ret.update({
            'id': video_id,
            'formats': formats,
            'subtitles': combined_subtitles,
        })

        return ret


class ThePlatformFeedIE(ThePlatformBaseIE):
    _URL_TEMPLATE = '%s//feed.theplatform.com/f/%s/%s?form=json&%s'
    _VALID_URL = r'https?://feed\.theplatform\.com/f/(?P<provider_id>[^/]+)/(?P<feed_id>[^?/]+)\?(?:[^&]+&)*(?P<filter>by(?:Gui|I)d=(?P<id>[^&]+))'
    _TESTS = [{
        # From http://player.theplatform.com/p/7wvmTC/MSNBCEmbeddedOffSite?guid=n_hardball_5biden_140207
        'url': 'http://feed.theplatform.com/f/7wvmTC/msnbc_video-p-test?form=json&pretty=true&range=-40&byGuid=n_hardball_5biden_140207',
        'md5': '6e32495b5073ab414471b615c5ded394',
        'info_dict': {
            'id': 'n_hardball_5biden_140207',
            'ext': 'mp4',
            'title': 'The Biden factor: will Joe run in 2016?',
            'description': 'Could Vice President Joe Biden be preparing a 2016 campaign? Mark Halperin and Sam Stein weigh in.',
            'thumbnail': r're:^https?://.*\.jpg$',
            'upload_date': '20140208',

Review comment (refactor):
`update_url` can be imported from utils
```suggestion
        # With some sites, extracting from manifest URL directly yields more formats
        m3u8_url = update_url(url, query='mbr=true&manifest=m3u', fragment=None)
        ext = urlhandle_detect_ext(self._request_webpage(
            HEADRequest(m3u8_url), video_id, 'Checking for additional m3u8 formats', fatal=False))
        if ext == 'm3u8':
            m3u8_fmts, m3u8_subs = self._extract_m3u8_formats_and_subtitles(m3u8_url, video_id, fatal=False)
            formats.extend(m3u8_fmts)
            self._merge_subtitles(m3u8_subs, target=subtitles)

```

Code after:
        formats, subtitles = self._extract_theplatform_smil(smil_url, video_id)

        # With some sites, manifest URL must be forced to extract HLS formats
        if not traverse_obj(formats, lambda _, v: v['format_id'].startswith('hls')):
            m3u8_url = update_url(url, query='mbr=true&manifest=m3u', fragment=None)
            urlh = self._request_webpage(
                HEADRequest(m3u8_url), video_id, 'Checking for HLS formats', 'No HLS formats found', fatal=False)
            if urlh and urlhandle_detect_ext(urlh) == 'm3u8':
                m3u8_fmts, m3u8_subs = self._extract_m3u8_formats_and_subtitles(
                    m3u8_url, video_id, m3u8_id='hls', fatal=False)
                formats.extend(m3u8_fmts)
                self._merge_subtitles(m3u8_subs, target=subtitles)

        ret = self._extract_theplatform_metadata(path, video_id)
        combined_subtitles = self._merge_subtitles(ret.get('subtitles', {}), subtitles)
        ret.update({
            'id': video_id,
            'formats': formats,
            'subtitles': combined_subtitles,
        })

        return ret


class ThePlatformFeedIE(ThePlatformBaseIE):
    _URL_TEMPLATE = '%s//feed.theplatform.com/f/%s/%s?form=json&%s'
    _VALID_URL = r'https?://feed\.theplatform\.com/f/(?P<provider_id>[^/]+)/(?P<feed_id>[^?/]+)\?(?:[^&]+&)*(?P<filter>by(?:Gui|I)d=(?P<id>[^&]+))'
    _TESTS = [{
        # From http://player.theplatform.com/p/7wvmTC/MSNBCEmbeddedOffSite?guid=n_hardball_5biden_140207
        'url': 'http://feed.theplatform.com/f/7wvmTC/msnbc_video-p-test?form=json&pretty=true&range=-40&byGuid=n_hardball_5biden_140207',
        'md5': '6e32495b5073ab414471b615c5ded394',
        'info_dict': {
            'id': 'n_hardball_5biden_140207',
            'ext': 'mp4',
            'title': 'The Biden factor: will Joe run in 2016?',
            'description': 'Could Vice President Joe Biden be preparing a 2016 campaign? Mark Halperin and Sam Stein weigh in.',
            'thumbnail': r're:^https?://.*\.jpg$',
            'upload_date': '20140208',
            'timestamp': 1391824260,
            'duration': 467.0,
            'categories': ['MSNBC/Issues/Democrats', 'MSNBC/Issues/Elections/Election 2016'],
            'uploader': 'NBCU-NEWS',
        },
    }, {
        'url': 'http://feed.theplatform.com/f/2E2eJC/nnd_NBCNews?byGuid=nn_netcast_180306.Copy.01',
        'only_matching': True,
    }]

    def _extract_feed_info(self, provider_id, feed_id, filter_query, video_id, custom_fields=None, asset_types_query={}, account_id=None):
        real_url = self._URL_TEMPLATE % (self.http_scheme(), provider_id, feed_id, filter_query)
        entry = self._download_json(real_url, video_id)['entries'][0]