Repository: yt-dlp/yt-dlp

Issue:
DailyWire Support Request
### Checklist

- [X] I'm reporting a new site support request
- [X] I've verified that I'm running yt-dlp version **2022.03.08.1**. ([update instructions](https://github.com/yt-dlp/yt-dlp#update))
- [X] I've checked that all provided URLs are alive and playable in a browser
- [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

USA

### Example URLs

https://www.dailywire.com/episode/1-fauci
https://www.dailywire.com/videos/the-hyperions
https://www.dailywire.com/episode/ep-124-bill-maher

### Description

It seems that the site does not utilize any DRM, as I am able to use my personal DW account, grab the m3u8 from my browser's network tools, and stream/download directly with the m3u8 file (with the appropriate auth/cookie (not sure exactly what's included in the m3u8 file address).

### Verbose log

```shell
kevin@linuxserver:~/youtube-dl/temp-downloads$ yt-dlp --version
2022.03.08.2
kevin@linuxserver:~/youtube-dl/temp-downloads$ yt-dlp -vU https://www.dailywire.com/episode/ep-124-bill-maher
[debug] Command-line config: ['-vU', 'https://www.dailywire.com/episode/ep-124-bill-maher']
[debug] Encodings: locale UTF-8, fs utf-8, out UTF-8, err UTF-8, pref UTF-8
[debug] yt-dlp version 2022.03.08.2 [e491d06d3]
[debug] Python version 3.6.9 (CPython 64bit) - Linux-4.15.0-171-generic-x86_64-with-Ubuntu-18.04-bionic
[debug] exe versions: ffmpeg 4.3.2-0york0, ffprobe 4.3.2-0york0
[debug] Optional libraries: brotli, Cryptodome, secretstorage, mutagen, sqlite, websockets
[debug] Proxy map: {}
Latest version: 2022.03.08.1, Current version: 2022.03.08.2
yt-dlp is up to date (2022.03.08.2)
[debug] [generic] Extracting URL: https://www.dailywire.com/episode/ep-124-bill-maher
[generic] ep-124-bill-maher: Requesting header
WARNING: [generic] Falling back on generic information extractor.
[generic] ep-124-bill-maher: Downloading webpage
[generic] ep-124-bill-maher: Extracting information
[debug] Looking for video embeds
ERROR: Unsupported URL: https://www.dailywire.com/episode/ep-124-bill-maher
Traceback (most recent call last):
  File "/home/kevin/.local/lib/python3.6/site-packages/yt_dlp/YoutubeDL.py", line 1389, in wrapper
    return func(self, *args, **kwargs)
  File "/home/kevin/.local/lib/python3.6/site-packages/yt_dlp/YoutubeDL.py", line 1459, in __extract_info
    ie_result = ie.extract(url)
  File "/home/kevin/.local/lib/python3.6/site-packages/yt_dlp/extractor/common.py", line 617, in extract
    ie_result = self._real_extract(url)
  File "/home/kevin/.local/lib/python3.6/site-packages/yt_dlp/extractor/generic.py", line 3998, in _real_extract
    raise UnsupportedError(url)
yt_dlp.utils.UnsupportedError: Unsupported URL: https://www.dailywire.com/episode/ep-124-bill-maher
```



Discussion:
I would also like to see this added.
From this url ( https://www.dailywire.com/episode/1-fauci ), the video is in `script id='__NEXT_DATA__'`. We can parse it and process it as json. In the json, we can get the stream from `['props']['pageProps']['episodeData']['episode']['segment']`. In there, we can get the audio stream in `[audio]` and video stream at `[video]`

Here's the sample json of `['segment']` :
```
"segments": [{
  "id": "ckzsl50xwqpy508502drqpb12",
 "image": "https://daily-wire-production.imgix.net/episodes/ckzsl50xnqpy30850in3v4bu7/ckzsl50xwqpy508502drqpb12-1645199223218.jpg",
  "title": "Play",
  "liveChatAccess": ["INSIDER", "INSIDER_PLUS", "ALL_ACCESS"],
  "audio": null,
  "video": "https://stream.media.dailywire.com/AlpsMDbjhU2NA11WP00HrXa9Q017NvCXCv.m3u8?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IldhN3M2dVNsQ2VLazAwbWZGTHVDV08wMVhvaGZHY2U5VEcifQ.eyJleHAiOjE2NTQ3Mzc1NjIsImF1ZCI6InYiLCJzdWIiOiJBbHBzTURiamhVMk5BMTFXUDAwSHJYYTlRMDE3TnZDWEN2In0.gt8stgeGdQ98LwNkARFKG0HEqtJLFzyG19k3C9xon61gwfgX-LxL-hvcqiV9lABpEomukPEvwFJMK543RcqKjus_4U-mFltFlxh21kNzPsd5qhQisCNA8IQUQbgKroNyWdFnDNcLEXwEWOygDLTOmZnkaMPOaydULXMYKroG-HL7Rl4RwP6SrSO9n8-uSWgcEraSQ46y1NLTFPHxIQMgKhHd5PGNiQCPp1T3xO1zwPOuXc0oPy4xe4uWYTzuC-l7eVSPZA3A1_b00V386RcSeR_Ptd01VnzmUxOWg81TxC94PeBlH21Up_tdN9F2Q43f3HgSKZKNpyDl4Ls_G39xKw",
  "duration": 1391.681967,
  "watchTime": null,
  "description": null,
  "videoAccess": [],
  "muxAssetId": "wSiuai1fjHyn7XbXkdmSHmGgx02PtfHsZ",
  "muxPlaybackId": "AlpsMDbjhU2NA11WP00HrXa9Q017NvCXCv",
  "captions": [{
    "id": "cl0b3v9ru8kzh0c265nahw1sv"
   }]
}],
```

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
@@ -354,6 +354,10 @@
     DailymotionPlaylistIE,
     DailymotionUserIE,
 )
+from .dailywire import (
+    DailyWireIE,
+    DailyWirePodcastIE,
+)
 from .damtomo import (
     DamtomoRecordIE,
     DamtomoVideoIE,
diff --git a/yt_dlp/extractor/dailywire.py b/yt_dlp/extractor/dailywire.py
new file mode 100644
--- /dev/null
+++ b/yt_dlp/extractor/dailywire.py
@@ -0,0 +1,116 @@
+from .common import InfoExtractor
+from ..utils import (
+    determine_ext,
+    float_or_none,
+    join_nonempty,
+    traverse_obj,
+    url_or_none,
+)
+
+
+class DailyWireBaseIE(InfoExtractor):
+    _JSON_PATH = {
+        'episode': ('props', 'pageProps', 'episodeData', 'episode'),
+        'videos': ('props', 'pageProps', 'videoData', 'video'),
+        'podcasts': ('props', 'pageProps', 'episode'),
+    }
+
+    def _get_json(self, url):
+        sites_type, slug = self._match_valid_url(url).group('sites_type', 'id')
+        json_data = self._search_nextjs_data(self._download_webpage(url, slug), slug)
+        return slug, traverse_obj(json_data, self._JSON_PATH[sites_type])
+
+
+class DailyWireIE(DailyWireBaseIE):
+    _VALID_URL = r'https?://(?:www\.)dailywire(?:\.com)/(?P<sites_type>episode|videos)/(?P<id>[\w-]+)'
+    _TESTS = [{
+        'url': 'https://www.dailywire.com/episode/1-fauci',
+        'info_dict': {
+            'id': 'ckzsl50xnqpy30850in3v4bu7',
+            'ext': 'mp4',
+            'display_id': '1-fauci',
+            'title': '1. Fauci',
+            'description': 'md5:9df630347ef85081b7e97dd30bc22853',
+            'thumbnail': 'https://daily-wire-production.imgix.net/episodes/ckzsl50xnqpy30850in3v4bu7/ckzsl50xnqpy30850in3v4bu7-1648237399554.jpg',
+            'creator': 'Caroline Roberts',
+            'series_id': 'ckzplm0a097fn0826r2vc3j7h',
+            'series': 'China: The Enemy Within',
+        }
+    }, {
+        'url': 'https://www.dailywire.com/episode/ep-124-bill-maher',
+        'info_dict': {
+            'id': 'cl0ngbaalplc80894sfdo9edf',
+            'ext': 'mp3',
+            'display_id': 'ep-124-bill-maher',
+            'title': 'Ep. 124 - Bill Maher',
+            'thumbnail': 'https://daily-wire-production.imgix.net/episodes/cl0ngbaalplc80894sfdo9edf/cl0ngbaalplc80894sfdo9edf-1647065568518.jpg',
+            'creator': 'Caroline Roberts',
+            'description': 'md5:adb0de584bcfa9c41374999d9e324e98',
+            'series_id': 'cjzvep7270hp00786l9hwccob',
+            'series': 'The Sunday Special',
+        }
+    }, {
+        'url': 'https://www.dailywire.com/videos/the-hyperions',
+        'only_matching': True,
+    }]
+
+    def _real_extract(self, url):
+        slug, episode_info = self._get_json(url)
+        urls = traverse_obj(
+            episode_info, (('segments', 'videoUrl'), ..., ('video', 'audio')), expected_type=url_or_none)
+
+        formats, subtitles = [], {}
+        for url in urls:
+            if determine_ext(url) != 'm3u8':
+                formats.append({'url': url})
+                continue
+            format_, subs_ = self._extract_m3u8_formats_and_subtitles(url, slug)
+            formats.extend(format_)
+            self._merge_subtitles(subs_, target=subtitles)
+        self._sort_formats(formats)
+        return {
+            'id': episode_info['id'],
+            'display_id': slug,
+            'title': traverse_obj(episode_info, 'title', 'name'),
+            'description': episode_info.get('description'),
+            'creator': join_nonempty(
+                traverse_obj(episode_info, ('createdBy','firstName')), traverse_obj(episode_info, ('createdBy','lastName')), 
+                delim=' '),
+            'duration': float_or_none(episode_info.get('duration')),
+            'is_live': episode_info.get('isLive'),
+            'thumbnail': traverse_obj(episode_info, 'thumbnail', 'image', expected_type=url_or_none),
+            'formats': formats,
+            'subtitles': subtitles,
+            'series_id': traverse_obj(episode_info, ('show', 'id')),
+            'series': traverse_obj(episode_info, ('show', 'name')),
+        }
+
+
+class DailyWirePodcastIE(DailyWireBaseIE):
+    _VALID_URL = r'https?://(?:www\.)dailywire(?:\.com)/(?P<sites_type>podcasts)/(?P<podcaster>[\w-]+/(?P<id>[\w-]+))'
+    _TESTS = [{
+        'url': 'https://www.dailywire.com/podcasts/morning-wire/get-ready-for-recession-6-15-22',
+        'info_dict': {
+            'id': 'cl4f01d0w8pbe0a98ydd0cfn1',
+            'ext': 'm4a',
+            'display_id': 'get-ready-for-recession-6-15-22',
+            'title': 'Get Ready for Recession | 6.15.22',
+            'description': 'md5:c4afbadda4e1c38a4496f6d62be55634',
+            'thumbnail': 'https://daily-wire-production.imgix.net/podcasts/ckx4otgd71jm508699tzb6hf4-1639506575562.jpg',
+            'duration': 900.117667,
+        }
+    }]
+
+    def _real_extract(self, url):
+        slug, episode_info = self._get_json(url)
+        audio_id = traverse_obj(episode_info, 'audioMuxPlaybackId', 'VUsAipTrBVSgzw73SpC2DAJD401TYYwEp')
+
+        return {
+            'id': episode_info['id'],
+            'url': f'https://stream.media.dailywire.com/{audio_id}/audio.m4a',
+            'display_id': slug,
+            'title': episode_info.get('title'),
+            'duration': float_or_none(episode_info.get('duration')),
+            'thumbnail': episode_info.get('thumbnail'),
+            'description': episode_info.get('description'),
+        }


Test patch: