Repository: yt-dlp/yt-dlp

Issue:
medal.tv broken for `clips` URL
### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

- [X] I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field

### Checklist

- [X] I'm reporting that a **supported** site is broken
- [X] I've verified that I'm running yt-dlp version **2023.03.04** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit)
- [X] I've checked that all provided URLs are playable in a browser with the same IP and same login details
- [X] I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command)
- [X] I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates
- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)
- [X] I've read about [sharing account credentials](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#are-you-willing-to-share-account-details-if-needed) and I'm willing to share it if required

### Region

Germany

### Provide a description that is worded well enough to be understood

When you try to extract a video from`medal.tv` that contains the `clips` URL it throws this error:

```
[extract] error for url=https://medal.tv/games/valorant/clips/XEXRelR8Soa7l/d1337ronmzqC?invite=cr-MSxxYlksMzc1MDE5OTAs ERROR: [MedalTV] XEXRelR8Soa7l: Could not find build ID.; please report this issue on  https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using  yt-dlp -U Error: ERROR: [MedalTV] XEXRelR8Soa7l: Could not find build ID.; please report this issue on  https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using  yt-dlp -U
    at parse (/Users/janhesters/dev/streamable-api/node_modules/youtube-dl-exec/src/index.js:15:23)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
```

However, when you change it to `/clip/` it works.

This functionality works with the Python package [`youtube-dl`](https://github.com/ytdl-org/youtube-dl).

### Provide verbose output that clearly demonstrates the problem

- [X] Run **your** yt-dlp command with **-vU** flag added (`yt-dlp -vU <your command line>`)
- [X] If using API, add `'verbose': True` to `YoutubeDL` params instead
- [X] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below

### Complete Verbose Output

```shell
[debug] Command-line config: ['-vU', 'https://medal.tv/games/valorant/clips/XEXRelR8Soa7l/d1337ronmzqC?invite=cr-MSxxYlksMzc1MDE5OTAs', '--add-header', 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15', '--add-header', 'Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7', '--add-header', 'Accept-Encoding:gzip, deflate', '--no-call-home', '--dump-single-json', '--format', 'best[protocol^=http][protocol!=http_dash_segments][container!=?mp4_dash][ext=mp4]/best[protocol^=http]/best/bestvideo[protocol^=http]/bestvideo', '--no-mark-watched', '--max-sleep-interval', '3', '--no-check-certificates', '--no-playlist', '--no-warnings', '--referer', 'https://medal.tv', '--simulate', '--skip-download', '--sleep-interval', '1', '--socket-timeout', '5', '--youtube-skip-dash-manifest']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8 (No ANSI), error utf-8 (No ANSI), screen utf-8 (No ANSI)
[debug] yt-dlp version 2023.02.17 [a0a7c01] (zip)
[debug] Python 3.8.9 (CPython x86_64 64bit) - macOS-11.6.2-x86_64-i386-64bit (LibreSSL 2.8.3)
[debug] exe versions: ffmpeg 5.1.2 (setts), ffprobe 5.1.2
[debug] Optional libraries: sqlite3-2.6.0
[debug] Proxy map: {}
[debug] Loaded 1782 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest
Latest version: 2023.03.04, Current version: 2023.02.17
[debug] Downloading _update_spec from https://github.com/yt-dlp/yt-dlp/releases/download/2023.03.04/_update_spec
Current Build Hash a666e88e7f313bf79bf5df1f7379cf80c2780211c41950f75fba1ddff5b5e6c0
Updating to version 2023.03.04 ...
[debug] Downloading yt-dlp from https://github.com/yt-dlp/yt-dlp/releases/download/2023.03.04/yt-dlp
[debug] Downloading SHA2-256SUMS from https://github.com/yt-dlp/yt-dlp/releases/download/2023.03.04/SHA2-256SUMS
Updated yt-dlp to version 2023.03.04
Traceback (most recent call last):
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/__main__.py", line 17, in <module>
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/__init__.py", line 967, in main
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/__init__.py", line 957, in _real_main
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 3353, in download
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 3328, in wrapper
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 1491, in extract_info
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 792, in get_info_extractor
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/extractor/lazy_extractors.py", line 36, in __new__
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/utils.py", line 6030, in __get__
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/extractor/lazy_extractors.py", line 32, in real_class
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 241, in load_module
  File "<frozen zipimport>", line 709, in _get_module_code
  File "<frozen zipimport>", line 548, in _get_data
zipimport.ZipImportError: bad local file header: '/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp' Error: [debug] Command-line config: ['-vU', 'https://medal.tv/games/valorant/clips/XEXRelR8Soa7l/d1337ronmzqC?invite=cr-MSxxYlksMzc1MDE5OTAs', '--add-header', 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15', '--add-header', 'Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7', '--add-header', 'Accept-Encoding:gzip, deflate', '--no-call-home', '--dump-single-json', '--format', 'best[protocol^=http][protocol!=http_dash_segments][container!=?mp4_dash][ext=mp4]/best[protocol^=http]/best/bestvideo[protocol^=http]/bestvideo', '--no-mark-watched', '--max-sleep-interval', '3', '--no-check-certificates', '--no-playlist', '--no-warnings', '--referer', 'https://medal.tv', '--simulate', '--skip-download', '--sleep-interval', '1', '--socket-timeout', '5', '--youtube-skip-dash-manifest']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8 (No ANSI), error utf-8 (No ANSI), screen utf-8 (No ANSI)
[debug] yt-dlp version 2023.02.17 [a0a7c01] (zip)
[debug] Python 3.8.9 (CPython x86_64 64bit) - macOS-11.6.2-x86_64-i386-64bit (LibreSSL 2.8.3)
[debug] exe versions: ffmpeg 5.1.2 (setts), ffprobe 5.1.2
[debug] Optional libraries: sqlite3-2.6.0
[debug] Proxy map: {}
[debug] Loaded 1782 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest
Latest version: 2023.03.04, Current version: 2023.02.17
[debug] Downloading _update_spec from https://github.com/yt-dlp/yt-dlp/releases/download/2023.03.04/_update_spec
Current Build Hash a666e88e7f313bf79bf5df1f7379cf80c2780211c41950f75fba1ddff5b5e6c0
Updating to version 2023.03.04 ...
[debug] Downloading yt-dlp from https://github.com/yt-dlp/yt-dlp/releases/download/2023.03.04/yt-dlp
[debug] Downloading SHA2-256SUMS from https://github.com/yt-dlp/yt-dlp/releases/download/2023.03.04/SHA2-256SUMS
Updated yt-dlp to version 2023.03.04
Traceback (most recent call last):
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/__main__.py", line 17, in <module>
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/__init__.py", line 967, in main
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/__init__.py", line 957, in _real_main
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 3353, in download
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 3328, in wrapper
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 1491, in extract_info
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/YoutubeDL.py", line 792, in get_info_extractor
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/extractor/lazy_extractors.py", line 36, in __new__
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/utils.py", line 6030, in __get__
  File "/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp/yt_dlp/extractor/lazy_extractors.py", line 32, in real_class
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 618, in _load_backward_compatible
  File "<frozen zipimport>", line 241, in load_module
  File "<frozen zipimport>", line 709, in _get_module_code
  File "<frozen zipimport>", line 548, in _get_data
zipimport.ZipImportError: bad local file header: '/Users/my-project-api/node_modules/youtube-dl-exec/bin/yt-dlp'
    at /Users/my-project-api/src/services/extractClips/youtubeDlWrapper.ts:56:30
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
```



Discussion:

Resolving patch:
diff --git a/yt_dlp/extractor/medaltv.py b/yt_dlp/extractor/medaltv.py
--- a/yt_dlp/extractor/medaltv.py
+++ b/yt_dlp/extractor/medaltv.py
@@ -8,12 +8,12 @@
     float_or_none,
     int_or_none,
     str_or_none,
-    traverse_obj,
+    traverse_obj
 )
 
 
 class MedalTVIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?medal\.tv/(?P<path>games/[^/?#&]+/clips)/(?P<id>[^/?#&]+)'
+    _VALID_URL = r'https?://(?:www\.)?medal\.tv/games/[^/?#&]+/clips/(?P<id>[^/?#&]+)'
     _TESTS = [{
         'url': 'https://medal.tv/games/valorant/clips/jTBFnLKdLy15K',
         'md5': '6930f8972914b6b9fdc2bb3918098ba0',
@@ -80,25 +80,14 @@ class MedalTVIE(InfoExtractor):
 
     def _real_extract(self, url):
         video_id = self._match_id(url)
-        path = self._match_valid_url(url).group('path')
 
         webpage = self._download_webpage(url, video_id)
 
-        next_data = self._search_json(
-            '<script[^>]*__NEXT_DATA__[^>]*>', webpage,
+        hydration_data = self._search_json(
+            r'<script[^>]*>[^<]*\bhydrationData\s*=', webpage,
             'next data', video_id, end_pattern='</script>', fatal=False)
 
-        build_id = next_data.get('buildId')
-        if not build_id:
-            raise ExtractorError(
-                'Could not find build ID.', video_id=video_id)
-
-        locale = next_data.get('locale', 'en')
-
-        api_response = self._download_json(
-            f'https://medal.tv/_next/data/{build_id}/{locale}/{path}/{video_id}.json', video_id)
-
-        clip = traverse_obj(api_response, ('pageProps', 'clip')) or {}
+        clip = traverse_obj(hydration_data, ('clips', ...), get_all=False)
         if not clip:
             raise ExtractorError(
                 'Could not find video information.', video_id=video_id)
@@ -152,7 +141,7 @@ def add_item(container, item_url, height, id_key='format_id', item_id=None):
 
         # Necessary because the id of the author is not known in advance.
         # Won't raise an issue if no profile can be found as this is optional.
-        author = traverse_obj(api_response, ('pageProps', 'profile')) or {}
+        author = traverse_obj(hydration_data, ('profiles', ...), get_all=False) or {}
         author_id = str_or_none(author.get('userId'))
         author_url = format_field(author_id, None, 'https://medal.tv/users/%s')
 


Test patch: