Repository: yt-dlp/yt-dlp

Issue:
Cellebrite
### Checklist

- [X] I'm reporting a new site support request
- [X] I've verified that I'm running yt-dlp version **2022.05.18** ([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 none of provided URLs [violate any copyrights](https://github.com/ytdl-org/youtube-dl#can-you-add-support-for-this-anime-video-site-or-site-which-shows-current-movies-for-free) or contain any [DRM](https://en.wikipedia.org/wiki/Digital_rights_management) to the best of my knowledge
- [X] I've searched 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 am willing to share it if required

### Region

Southern California, USA

### Example URLs

https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/

### Description

Blog website

### Verbose log

```shell
Not yet
```



Discussion:
@upintheairsheep2 Please provide the verbose log
Verbose log:
```
C:\Users\USER\Downloads>yt-dlp -v "https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/"
[debug] Command-line config: ['-v', 'https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/']
[debug] Portable config "C:\Users\USER\Downloads\yt-dlp\yt-dlp.conf": ['-v', '--netrc-location', 'C:UsersUSERDownloadsyt-dlp.netrc', '-f', 'bv+ba/b', '--compat-options', 'format-sort', '--embed-metadata', '--embed-subs', '--sub-langs', 'all', '--console-title', '--downloader', 'aria2c']
[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version 2022.05.18 [b14d523] (win_exe)
[debug] Compatibility options: format-sort
[debug] Python version 3.8.10 (CPython 64bit) - Windows-10-10.0.19044-SP0
[debug] Checking exe version: ffprobe -bsfs
[debug] Checking exe version: ffmpeg -bsfs
[debug] exe versions: ffmpeg 5.0.1-full_build-www.gyan.dev (setts), ffprobe 5.0.1-full_build-www.gyan.dev
[debug] Optional libraries: Cryptodome-3.14.1, brotli-1.0.9, certifi-2021.10.08, mutagen-1.45.1, sqlite3-2.6.0, websockets-10.3
[debug] Proxy map: {}
[debug] [generic] Extracting URL: https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/
[generic] collect-data-from-android-devices-with-cellebrite-ufed: Requesting header
WARNING: [generic] Falling back on generic information extractor.
[generic] collect-data-from-android-devices-with-cellebrite-ufed: Downloading webpage
[generic] collect-data-from-android-devices-with-cellebrite-ufed: Extracting information
[debug] Looking for video embeds
ERROR: Unsupported URL: https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/
Traceback (most recent call last):
  File "yt_dlp\YoutubeDL.py", line 1395, in wrapper
  File "yt_dlp\YoutubeDL.py", line 1465, in __extract_info
  File "yt_dlp\extractor\common.py", line 642, in extract
  File "yt_dlp\extractor\generic.py", line 4031, in _real_extract
yt_dlp.utils.UnsupportedError: Unsupported URL: https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/
```
From this url (https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/), we can get `video_id` from `div class="vidyard-player-container"`. The tag have an attribute `uuid=<video_id>` which we can use in the api url (`https://play.vidyard.com/player/<video_id>.json??disable_popouts=1&v=4.3.6&type=inline`) (actually i not checked if the query is required or not) and we can get the video data from `['payload']['chapters']`

Resolving patch:
diff --git a/yt_dlp/extractor/_extractors.py b/yt_dlp/extractor/_extractors.py
--- a/yt_dlp/extractor/_extractors.py
+++ b/yt_dlp/extractor/_extractors.py
@@ -262,6 +262,7 @@
 from .ccma import CCMAIE
 from .cctv import CCTVIE
 from .cda import CDAIE
+from .cellebrite import CellebriteIE
 from .ceskatelevize import CeskaTelevizeIE
 from .cgtn import CGTNIE
 from .channel9 import Channel9IE
diff --git a/yt_dlp/extractor/cellebrite.py b/yt_dlp/extractor/cellebrite.py
new file mode 100644
--- /dev/null
+++ b/yt_dlp/extractor/cellebrite.py
@@ -0,0 +1,64 @@
+from .common import InfoExtractor
+from ..utils import traverse_obj
+
+
+class CellebriteIE(InfoExtractor):
+    _VALID_URL = r'https?://cellebrite\.com/(?:\w+)?/(?P<id>[\w-]+)'
+    _TESTS = [{
+        'url': 'https://cellebrite.com/en/collect-data-from-android-devices-with-cellebrite-ufed/',
+        'info_dict': {
+            'id': '16025876',
+            'ext': 'mp4',
+            'description': 'md5:174571cb97083fd1d457d75c684f4e2b',
+            'thumbnail': 'https://cellebrite.com/wp-content/uploads/2021/05/Chat-Capture-1024x559.png',
+            'title': 'Ask the Expert: Chat Capture - Collect Data from Android Devices in Cellebrite UFED',
+            'duration': 455,
+            'tags': [],
+        }
+    }, {
+        'url': 'https://cellebrite.com/en/how-to-lawfully-collect-the-maximum-amount-of-data-from-android-devices/',
+        'info_dict': {
+            'id': '29018255',
+            'ext': 'mp4',
+            'duration': 134,
+            'tags': [],
+            'description': 'md5:e9a3d124c7287b0b07bad2547061cacf',
+            'thumbnail': 'https://cellebrite.com/wp-content/uploads/2022/07/How-to-Lawfully-Collect-the-Maximum-Amount-of-Data-From-Android-Devices.png',
+            'title': 'Android Extractions Explained',
+        }
+    }]
+
+    def _get_formats_and_subtitles(self, json_data, display_id):
+        formats = [{'url': url} for url in traverse_obj(json_data, ('mp4', ..., 'url')) or []]
+        subtitles = {}
+
+        for url in traverse_obj(json_data, ('hls', ..., 'url')) or []:
+            fmt, sub = self._extract_m3u8_formats_and_subtitles(
+                url, display_id, ext='mp4', headers={'Referer': 'https://play.vidyard.com/'})
+            formats.extend(fmt)
+            self._merge_subtitles(sub, target=subtitles)
+
+        return formats, subtitles
+
+    def _real_extract(self, url):
+        display_id = self._match_id(url)
+        webpage = self._download_webpage(url, display_id)
+
+        player_uuid = self._search_regex(
+            r'<img\s[^>]*\bdata-uuid\s*=\s*"([^"\?]+)', webpage, 'player UUID')
+        json_data = self._download_json(
+            f'https://play.vidyard.com/player/{player_uuid}.json', display_id)['payload']['chapters'][0]
+
+        formats, subtitles = self._get_formats_and_subtitles(json_data['sources'], display_id)
+        self._sort_formats(formats)
+        return {
+            'id': str(json_data['videoId']),
+            'title': json_data.get('name') or self._og_search_title(webpage),
+            'formats': formats,
+            'subtitles': subtitles,
+            'description': json_data.get('description') or self._og_search_description(webpage),
+            'duration': json_data.get('seconds'),
+            'tags': json_data.get('tags'),
+            'thumbnail': self._og_search_thumbnail(webpage),
+            'http_headers': {'Referer': 'https://play.vidyard.com/'},
+        }


Test patch: