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

Code before:
    }, {
        # full video
        'url': 'https://www.manyvids.com/Video/935718/MY-FACE-REVEAL/',
        'md5': 'bb47bab0e0802c2a60c24ef079dfe60f',
        'info_dict': {
            'id': '935718',
            'ext': 'mp4',
            'title': 'MY FACE REVEAL',
            'description': 'md5:ec5901d41808b3746fed90face161612',
            'thumbnail': 'https://ods.manyvids.com/1001061960/3aa5397f2a723ec4597e344df66ab845/screenshots/thumbs/custom_1_180_5be09c1dcce03.jpg',
            'uploader': 'Sarah Calanthe',
            'view_count': int,
            'like_count': int,
            'release_date': '20181110',
            'tags': ['EyeContact', 'Interviews', 'MaskFetish', 'MouthFetish', 'Redhead'],
            'release_timestamp': 1541851200,
            'duration': 224.0,
        },
    }]

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

        info = traverse_obj(
            self._download_json(f'https://www.manyvids.com/bff/store/video/{video_id}', video_id),
            ('data', {dict})) or {}

        video_urls = self._download_json(f'https://www.manyvids.com/bff/store/video/{video_id}/private', video_id)[
            'data']

        video_urls_and_ids = (
            (traverse_obj(video_urls, ('teaser', 'filepath')), 'preview'),
            (video_urls.get('transcodedFilepath'), 'transcoded'),
            (video_urls.get('filepath'), 'filepath'),
        )

        title = traverse_obj(info, 'title')

        # If the video formats JSON only contains a teaser object, then it is a preview
        if video_urls.get('teaser') and not video_urls.get('filepath'):
            title += ' (Preview)'
            video_id += '-preview'
            self.report_warning(
                f'Only extracting preview. Video may be paid or subscription only. {self._login_hint()}')

        formats = []
        for v_url, fmt in video_urls_and_ids:
            v_url = url_or_none(v_url)
            if not v_url:
                continue
            if determine_ext(v_url) == 'm3u8':

Review comment (bug):
This `_download_json` call can/should be non-fatal, and let's do it after the `video_urls`/formats extraction so that we don't waste time before aborting if something is wrong

Code after:
            'uploader': 'Sarah Calanthe',
            'view_count': int,
            'like_count': int,
            'release_date': '20181110',
            'tags': ['EyeContact', 'Interviews', 'MaskFetish', 'MouthFetish', 'Redhead'],
            'release_timestamp': 1541851200,
            'duration': 224.0,
        },
    }]
    _API_BASE = 'https://www.manyvids.com/bff/store/video'

    def _real_extract(self, url):
        video_id = self._match_id(url)
        video_data = self._download_json(f'{self._API_BASE}/{video_id}/private', video_id)['data']
        formats, preview_only = [], True

        for format_id, path in [
            ('preview', ['teaser', 'filepath']),
            ('transcoded', ['transcodedFilepath']),
            ('filepath', ['filepath']),
        ]:
            format_url = traverse_obj(video_data, (*path, {url_or_none}))
            if not format_url:
                continue
            if determine_ext(format_url) == 'm3u8':
                formats.extend(self._extract_m3u8_formats(format_url, video_id, 'mp4', m3u8_id=format_id))
            else:
                formats.append({
                    'url': format_url,
                    'format_id': format_id,
                    'preference': -10 if format_id == 'preview' else None,
                    'quality': 10 if format_id == 'filepath' else None,
                    'height': int_or_none(
                        self._search_regex(r'_(\d{2,3}[02468])_', format_url, 'height', default=None)),
                })
            if format_id != 'preview':
                preview_only = False

        metadata = traverse_obj(
            self._download_json(f'{self._API_BASE}/{video_id}', video_id, fatal=False), 'data')
        title = traverse_obj(metadata, ('title', {clean_html}))

        if preview_only:
            title = join_nonempty(title, '(Preview)', delim=' ')
            video_id += '-preview'
            self.report_warning(
                f'Only extracting preview. Video may be paid or subscription only. {self._login_hint()}')

        return {
            'id': video_id,
            'title': title,