ronantakizawa/codereview-bench huggingface dataset:
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/bibeltv.py (Python)

Code before:
from .common import InfoExtractor


class BibelTVIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?bibeltv\.de/mediathek/videos/(?:crn/)?(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://www.bibeltv.de/mediathek/videos/329703-sprachkurs-in-malaiisch',
        'md5': '252f908192d611de038b8504b08bf97f',
        'info_dict': {
            'id': 'ref:329703',
            'ext': 'mp4',
            'title': 'Sprachkurs in Malaiisch',
            'description': 'md5:3e9f197d29ee164714e67351cf737dfe',
            'timestamp': 1608316701,
            'uploader_id': '5840105145001',
            'upload_date': '20201218',
        }
    }, {
        'url': 'https://www.bibeltv.de/mediathek/videos/crn/326374',
        'only_matching': True,
    }]
    BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/5840105145001/default_default/index.html?videoId=ref:%s'

    def _real_extract(self, url):
        crn_id = self._match_id(url)
        return self.url_result(
            self.BRIGHTCOVE_URL_TEMPLATE % crn_id, 'BrightcoveNew')


Review comment (suggestion):
```suggestion
```
This is not needed as `traverse_obj` filters the `None` returned by `url_or_none` already.

Code after:
                formats.extend(m3u8_formats)
                subtitles.update(m3u8_subs)
            elif media_ext == 'mpd':
                mpd_formats, mpd_subs = self._extract_mpd_formats_and_subtitles(media_url, crn_id)
                formats.extend(mpd_formats)
                subtitles.update(mpd_subs)
            elif media_ext == 'mp4':
                formats.append({'url': media_url})
            else:
                self.report_warning(f'Unknown format {media_ext!r}')

        return formats, subtitles

    @staticmethod
    def _extract_base_info(data):
        return {
            'id': data['crn'],
            **traverse_obj(data, {
                'title': 'title',
                'description': 'description',
                'duration': ('duration', {partial(int_or_none, scale=1000)}),
                'timestamp': ('schedulingStart', {parse_iso8601}),
                'season_number': 'seasonNumber',
                'episode_number': 'episodeNumber',
                'view_count': 'viewCount',
                'like_count': 'likeCount',
            }),
            'thumbnails': orderedSet(traverse_obj(data, ('images', ..., {
                'url': ('url', {url_or_none}),
            }))),
        }

    def _extract_url_info(self, data):
        return {
            '_type': 'url',
            'url': format_field(data, 'slug', 'https://www.bibeltv.de/mediathek/videos/%s'),
            **self._extract_base_info(data),
        }

    def _extract_video_info(self, data):
        crn_id = data['crn']

        if data.get('drm'):
            self.report_drm(crn_id)

        json_data = self._download_json(
            format_field(data, 'id', f'{self.API_URL}/video/%s'), crn_id,
            headers={'Authorization': self.AUTH_TOKEN}, fatal=False,
            errnote='No formats available') or {}

        formats, subtitles = self._extract_formats_and_subtitles(
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/playsuisse.py (Python)

Code before:
import json

from .common import InfoExtractor
from ..utils import int_or_none, traverse_obj


class PlaySuisseIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/(watch|detail)/(.*\?episodeId=)?(?P<id>[0-9]+)?'
    _TESTS = [
        {
            # episode in a series
            'url': 'https://www.playsuisse.ch/watch/763182?episodeId=763211',
            'md5': '82df2a470b2dfa60c2d33772a8a60cf8',
            'info_dict': {
                'id': '763211',
                'ext': 'mp4',
                'title': 'Knochen',
                'description': 'md5:8ea7a8076ba000cd9e8bc132fd0afdd8',
                'duration': 3344,
                'series': 'Wilder',
                'season': 'Season 1',
                'season_number': 1,
                'episode': 'Knochen',
                'episode_number': 1,
                'thumbnail': 'md5:3cd4006d1f42cecbfdbd1ac35479c3dc'
            }
        }, {
            # film
            'url': 'https://www.playsuisse.ch/watch/808675/0',
            'md5': '818b94c1d2d7c4beef953f12cb8f3e75',
            'info_dict': {
                'id': '808675',
                'ext': 'mp4',

Review comment (suggestion):
* Avoid `.*`
* Use non-capturing groups `(?:...)`
* There can be other query
* Why did you make `id` optional?
```suggestion
    _VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/(?:watch|detail)(?:[^#]*[?&]episodeId=)?(?P<id>[0-9]+)'
```

Code after:
import json

from .common import InfoExtractor
from ..utils import int_or_none, traverse_obj


class PlaySuisseIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/(?:watch|detail)/(?:[^#]*[?&]episodeId=)?(?P<id>[0-9]+)'
    _TESTS = [
        {
            # Old URL
            'url': 'https://www.playsuisse.ch/watch/763211/0',
            'only_matching': True,
        },
        {
            # episode in a series
            'url': 'https://www.playsuisse.ch/watch/763182?episodeId=763211',
            'md5': '82df2a470b2dfa60c2d33772a8a60cf8',
            'info_dict': {
                'id': '763211',
                'ext': 'mp4',
                'title': 'Knochen',
                'description': 'md5:8ea7a8076ba000cd9e8bc132fd0afdd8',
                'duration': 3344,
                'series': 'Wilder',
                'season': 'Season 1',
                'season_number': 1,
                'episode': 'Knochen',
                'episode_number': 1,
                'thumbnail': 're:https://playsuisse-img.akamaized.net/',
            }
        }, {
            # film
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/sharepoint.py (Python)

Code before:
import json

from .common import InfoExtractor
from ..utils import (
    float_or_none,
    traverse_obj,
)


class SharePointIE(InfoExtractor):
    _VALID_URL = r'https?://[^\.]+\.sharepoint\.com/:v:/g/[^/]+/[^/]+/(?P<id>[^/?]+)'

    _TESTS = [
        {
            'url': 'https://lut-my.sharepoint.com/:v:/g/personal/juha_eerola_student_lab_fi/EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw?e=ZpQOOw',
            'info_dict': {
                'id': 'EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw',
                'ext': 'mp4',
                'title': 'CmvpJST.mp4',
                'duration': 54.567,
            },
            'params': {'skip_download': 'm3u8'}
        },
    ]

    def _parse_mediapackage(self, video, video_id):
        formats = []

        base_media_url = video['.transformUrl'].replace('/thumbnail?', '/videomanifest?')
        base_media_url += f"&cTag={video['.ctag']}&action=Access&part=index"

        metadata = json.loads(video.get('MediaServiceFastMetadata'))

        # Normally the player is configured with all possible options added to the format URLs,
        # but we always get all formats back no matter what settings you send
        formats.extend(self._extract_mpd_formats(

Review comment (suggestion):
```suggestion
    _VALID_URL = r'https?://[^.]+\.sharepoint\.com/:v:/g/(?:[^/]+/){2}(?P<id>[^/?#]+)'
```

Code after:
import json
import urllib.parse

from .common import InfoExtractor
from ..utils import determine_ext, int_or_none, url_or_none
from ..utils.traversal import traverse_obj


class SharePointIE(InfoExtractor):
    _BASE_URL_RE = r'https?://[\w-]+\.sharepoint\.com/'
    _VALID_URL = [
        rf'{_BASE_URL_RE}:v:/[a-z]/(?:[^/?#]+/)*(?P<id>[^/?#]{{46}})/?(?:$|[?#])',
        rf'{_BASE_URL_RE}(?!:v:)(?:[^/?#]+/)*stream\.aspx\?(?:[^#]+&)?id=(?P<id>[^&#]+)',
    ]
    _TESTS = [{
        'url': 'https://lut-my.sharepoint.com/:v:/g/personal/juha_eerola_student_lab_fi/EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw?e=ZpQOOw',
        'md5': '2950821d0d4937a0a76373782093b435',
        'info_dict': {
            'id': '01EQRS7EKKYCNLSLLPQZGIKRYY6SOY7KGB',
            'display_id': 'EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw',
            'ext': 'mp4',
            'title': 'CmvpJST',
            'duration': 54.567,
            'thumbnail': r're:https://.+/thumbnail',
            'uploader_id': '8dcec565-a956-4b91-95e5-bacfb8bc015f',
        },
    }, {
        'url': 'https://greaternyace.sharepoint.com/:v:/s/acementornydrive/ETski5eAfNVEoPRZUAyy1wEBpLgVFYWso5bjbZjfBLlPUg?e=PQUfVb',
        'md5': 'c496a01644223273bff12e93e501afd1',
        'info_dict': {
            'id': '01QI4AVTZ3ESFZPAD42VCKB5CZKAGLFVYB',
            'display_id': 'ETski5eAfNVEoPRZUAyy1wEBpLgVFYWso5bjbZjfBLlPUg',
            'ext': 'mp4',
            'title': '930103681233985536',
            'duration': 3797.326,
            'thumbnail': r're:https://.+/thumbnail',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/sharepoint.py (Python)

Code before:
import json

from urllib.parse import (
    parse_qs,
    urlencode,
    urljoin,
    urlparse,
    urlunparse,
)

from .common import InfoExtractor
from ..utils import (
    traverse_obj,
)


class SharePointIE(InfoExtractor):
    _VALID_URL = r'https?://[^.]+\.sharepoint\.com/:v:/g/(?:[^/]+/){2}(?P<id>[^/?#]+)'

    _TESTS = [
        {
            'url': 'https://lut-my.sharepoint.com/:v:/g/personal/juha_eerola_student_lab_fi/EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw?e=ZpQOOw',
            'info_dict': {
                'id': 'EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw',
                'ext': 'unknown_video',
                'title': 'CmvpJST.mp4',
                'duration': 54.567,
            },
            'params': {'skip_download': 'm3u8'},
        },
    ]

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

        video = self._search_json(r'g_fileInfo\s*=', webpage, 'player config', video_id)

        parsed_url = urlparse(video['.transformUrl'])

Review comment (suggestion):
```suggestion
from ..utils.traversal import traverse_obj
```

Code after:
import json
import urllib.parse

from .common import InfoExtractor
from ..utils import determine_ext, int_or_none, url_or_none
from ..utils.traversal import traverse_obj


class SharePointIE(InfoExtractor):
    _BASE_URL_RE = r'https?://[\w-]+\.sharepoint\.com/'
    _VALID_URL = [
        rf'{_BASE_URL_RE}:v:/[a-z]/(?:[^/?#]+/)*(?P<id>[^/?#]{{46}})/?(?:$|[?#])',
        rf'{_BASE_URL_RE}(?!:v:)(?:[^/?#]+/)*stream\.aspx\?(?:[^#]+&)?id=(?P<id>[^&#]+)',
    ]
    _TESTS = [{
        'url': 'https://lut-my.sharepoint.com/:v:/g/personal/juha_eerola_student_lab_fi/EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw?e=ZpQOOw',
        'md5': '2950821d0d4937a0a76373782093b435',
        'info_dict': {
            'id': '01EQRS7EKKYCNLSLLPQZGIKRYY6SOY7KGB',
            'display_id': 'EUrAmrktb4ZMhUcY9J2PqMEBD_9x_l0DyYWVgAvp-TTOMw',
            'ext': 'mp4',
            'title': 'CmvpJST',
            'duration': 54.567,
            'thumbnail': r're:https://.+/thumbnail',
            'uploader_id': '8dcec565-a956-4b91-95e5-bacfb8bc015f',
        },
    }, {
        'url': 'https://greaternyace.sharepoint.com/:v:/s/acementornydrive/ETski5eAfNVEoPRZUAyy1wEBpLgVFYWso5bjbZjfBLlPUg?e=PQUfVb',
        'md5': 'c496a01644223273bff12e93e501afd1',
        'info_dict': {
            'id': '01QI4AVTZ3ESFZPAD42VCKB5CZKAGLFVYB',
            'display_id': 'ETski5eAfNVEoPRZUAyy1wEBpLgVFYWso5bjbZjfBLlPUg',
            'ext': 'mp4',
            'title': '930103681233985536',
            'duration': 3797.326,
            'thumbnail': r're:https://.+/thumbnail',
        },
    }, {
        'url': 'https://lut-my.sharepoint.com/personal/juha_eerola_student_lab_fi/_layouts/15/stream.aspx?id=%2Fpersonal%2Fjuha_eerola_student_lab_fi%2FDocuments%2FM-DL%2FCmvpJST.mp4&ga=1&referrer=StreamWebApp.Web&referrerScenario=AddressBarCopied.view',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/owncloud.py (Python)

Code before:
import urllib.parse

from yt_dlp.extractor.common import InfoExtractor
from yt_dlp.utils import (
    determine_ext,
    ExtractorError,
    url_or_none,
    urlencode_postdata,
)


class OwnCloudIE(InfoExtractor):
    _INSTANCES_RE = r'''(?:
                            sciebo\.de|
                            [^\.]+\.sciebo\.de|
                            cloud\.uni-koblenz-landau\.de|
                        )'''
    _VALID_URL = rf'''(?x)
        (?P<server>https?://{_INSTANCES_RE})/s/
        (?P<id>[\w\-\.]+)'''

    _TESTS = [
        {
            'url': 'https://ruhr-uni-bochum.sciebo.de/s/wWhqZzh9jTumVFN',
            'info_dict': {
                'id': 'wWhqZzh9jTumVFN',
                'ext': 'mp4',
                'title': 'CmvpJST.mp4',
            },
        },
    ]

    def _real_extract(self, url):
        server, video_id = self._match_valid_url(url).group('server', 'id')

        webpage, urlh = self._download_webpage_handle(f'{server}/s/{video_id}', video_id, 'Downloading webpage')

        if self._search_regex(r'<label[^>]+?for="(password)"', webpage, 'password field',
                              fatal=False, default=None):
            # Password protected
            webpage, urlh = self._verify_video_password(webpage, urlh.geturl(), video_id)

        hidden_inputs = self._hidden_inputs(webpage)
        title = hidden_inputs['filename']


Review comment (suggestion):
```suggestion
    _INSTANCES_RE = '|'.join((
        r'(?:[^\.]+\.)?sciebo\.de',
        r'cloud\.uni-koblenz-landau\.de',
    ))
    _VALID_URL = f'https?://(?:{_INSTANCES_RE})/s/(?P<id>[\w.-]+)'
```

Code after:
import re
import urllib.parse

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    determine_ext,
    url_or_none,
    urlencode_postdata,
)


class OwnCloudIE(InfoExtractor):
    _INSTANCES_RE = '|'.join((
        r'(?:[^\.]+\.)?sciebo\.de',
        r'cloud\.uni-koblenz-landau\.de',
    ))
    _VALID_URL = rf'https?://(?:{_INSTANCES_RE})/s/(?P<id>[\w.-]+)'

    _TESTS = [
        {
            'url': 'https://ruhr-uni-bochum.sciebo.de/s/wWhqZzh9jTumVFN',
            'info_dict': {
                'id': 'wWhqZzh9jTumVFN',
                'ext': 'mp4',
                'title': 'CmvpJST.mp4',
            },
        },
        {
            'url': 'https://ruhr-uni-bochum.sciebo.de/s/WNDuFu0XuFtmm3f',
            'info_dict': {
                'id': 'WNDuFu0XuFtmm3f',
                'ext': 'mp4',
                'title': 'CmvpJST.mp4',
            },
            'params': {
                'videopassword': '12345',
            },
        },
    ]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        webpage, urlh = self._download_webpage_handle(url, video_id)
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/owncloud.py (Python)

Code before:
import urllib.parse

from yt_dlp.extractor.common import InfoExtractor
from yt_dlp.utils import (
    determine_ext,
    ExtractorError,
    url_or_none,
    urlencode_postdata,
)


class OwnCloudIE(InfoExtractor):
    _INSTANCES_RE = r'''(?:
                            sciebo\.de|
                            [^\.]+\.sciebo\.de|
                            cloud\.uni-koblenz-landau\.de|
                        )'''
    _VALID_URL = rf'''(?x)
        (?P<server>https?://{_INSTANCES_RE})/s/
        (?P<id>[\w\-\.]+)'''

    _TESTS = [
        {
            'url': 'https://ruhr-uni-bochum.sciebo.de/s/wWhqZzh9jTumVFN',
            'info_dict': {
                'id': 'wWhqZzh9jTumVFN',
                'ext': 'mp4',
                'title': 'CmvpJST.mp4',
            },

Review comment (refactor):
```suggestion
from .common import InfoExtractor
from ..utils import (
```
convention

Code after:
import re
import urllib.parse

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    determine_ext,
    url_or_none,
    urlencode_postdata,
)


class OwnCloudIE(InfoExtractor):
    _INSTANCES_RE = '|'.join((
        r'(?:[^\.]+\.)?sciebo\.de',
        r'cloud\.uni-koblenz-landau\.de',
    ))
    _VALID_URL = rf'https?://(?:{_INSTANCES_RE})/s/(?P<id>[\w.-]+)'

    _TESTS = [
        {
            'url': 'https://ruhr-uni-bochum.sciebo.de/s/wWhqZzh9jTumVFN',
            'info_dict': {
                'id': 'wWhqZzh9jTumVFN',
                'ext': 'mp4',
                'title': 'CmvpJST.mp4',
            },
        },
        {
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ettutv.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import traverse_obj, unified_timestamp


class EttuTvIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?ettu\.tv/[^?#]+/playerpage/(?P<id>[0-9]+)'

    _TESTS = [{
        'url': 'https://www.ettu.tv/en-int/playerpage/1573849',
        'md5': '5874b7639a2aa866d1f6c3a4037c7c09',
        'info_dict': {
            'id': '1573849',
            'title': 'Ni Xia Lian - Shao Jieni',
            'description': 'ITTF Europe Top 16 Cup',
            'timestamp': 1677348600,
            'upload_date': '20230225',
            'thumbnail': r're:^https?://.*\.(?:jpg|png)',
            'ext': 'mp4',
        },
    }, {
        'url': 'https://www.ettu.tv/en-int/playerpage/1573753',
        'md5': '1fc094bf96cf2d5ec0f434d3a6dec9aa',
        'info_dict': {
            'id': '1573753',
            'title': 'Qiu Dang - Jorgic Darko',
            'description': 'ITTF Europe Top 16 Cup',
            'timestamp': 1677423600,

Review comment (suggestion):
if the other suggestions are applied:
```suggestion
from ..utils import bool_or_none, traverse_obj, unified_timestamp, url_or_none
```

Code after:
from .common import InfoExtractor
from ..utils import bool_or_none, traverse_obj, unified_timestamp, url_or_none


class EttuTvIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?ettu\.tv/[^?#]+/playerpage/(?P<id>[0-9]+)'

    _TESTS = [{
        'url': 'https://www.ettu.tv/en-int/playerpage/1573849',
        'md5': '5874b7639a2aa866d1f6c3a4037c7c09',
        'info_dict': {
            'id': '1573849',
            'title': 'Ni Xia Lian - Shao Jieni',
            'description': 'ITTF Europe Top 16 Cup',
            'timestamp': 1677348600,
            'upload_date': '20230225',
            'thumbnail': r're:^https?://.*\.(?:jpg|png)',
            'ext': 'mp4',
        },
    }, {
        'url': 'https://www.ettu.tv/en-int/playerpage/1573753',
        'md5': '1fc094bf96cf2d5ec0f434d3a6dec9aa',
        'info_dict': {
            'id': '1573753',
            'title': 'Qiu Dang - Jorgic Darko',
            'description': 'ITTF Europe Top 16 Cup',
            'timestamp': 1677423600,
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ettutv.py (Python)

Code before:
        },
    }]

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

        player_settings = self._download_json(
            f'https://www.ettu.tv/api/v3/contents/{video_id}/player-settings', video_id, query={
                'language': 'en',
                'showTitle': 'true',
                'device': 'desktop',
            })

        stream_response = self._download_json(player_settings['streamAccess'], video_id, data={})

        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            stream_response['data']['stream'], video_id, 'mp4')

        return {
            'id': video_id,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(player_settings, {
                'title': 'title',
                'description': ('metaInformation', 'competition'),
                'thumbnail': 'image',
                'timestamp': ('date', {unified_timestamp}),
                'is_live': 'isLivestream',
            })
        }


Review comment (suggestion):
```suggestion
                'thumbnail': ('image', {url_or_none}),
```

Code after:
        },
    }]

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

        player_settings = self._download_json(
            f'https://www.ettu.tv/api/v3/contents/{video_id}/player-settings', video_id, query={
                'language': 'en',
                'showTitle': 'true',
                'device': 'desktop',
            })

        stream_response = self._download_json(player_settings['streamAccess'], video_id, data={})

        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            stream_response['data']['stream'], video_id, 'mp4')

        return {
            'id': video_id,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(player_settings, {
                'title': 'title',
                'description': ('metaInformation', 'competition'),
                'thumbnail': ('image', {url_or_none}),
                'timestamp': ('date', {unified_timestamp}),
                'is_live': ('isLivestream', {bool_or_none}),
            })
        }
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/ettutv.py (Python)

Code before:

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

        player_settings = self._download_json(
            f'https://www.ettu.tv/api/v3/contents/{video_id}/player-settings', video_id, query={
                'language': 'en',
                'showTitle': 'true',
                'device': 'desktop',
            })

        stream_response = self._download_json(player_settings['streamAccess'], video_id, data={})

        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            stream_response['data']['stream'], video_id, 'mp4')

        return {
            'id': video_id,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(player_settings, {
                'title': 'title',
                'description': ('metaInformation', 'competition'),
                'thumbnail': 'image',
                'timestamp': ('date', {unified_timestamp}),
                'is_live': 'isLivestream',
            })
        }


Review comment (suggestion):
maybe we wanna do this to prevent false positives in case of strange input? what do you think
```suggestion
                'is_live': ('isLivestream', {bool_or_none}),
```

Code after:

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

        player_settings = self._download_json(
            f'https://www.ettu.tv/api/v3/contents/{video_id}/player-settings', video_id, query={
                'language': 'en',
                'showTitle': 'true',
                'device': 'desktop',
            })

        stream_response = self._download_json(player_settings['streamAccess'], video_id, data={})

        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            stream_response['data']['stream'], video_id, 'mp4')

        return {
            'id': video_id,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(player_settings, {
                'title': 'title',
                'description': ('metaInformation', 'competition'),
                'thumbnail': ('image', {url_or_none}),
                'timestamp': ('date', {unified_timestamp}),
                'is_live': ('isLivestream', {bool_or_none}),
            })
        }