Repository: yt-dlp/yt-dlp

Issue:
"No video formats found" error on Paramount+
### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

- [X] I understand that I will be **blocked** if I remove or skip any mandatory\* field

### Checklist

- [X] I'm reporting a broken site
- [X] I've verified that I'm running yt-dlp version **2022.09.01** ([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 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

USA

### Provide a description that is worded well enough to be understood

Downloading Twin Peaks from Paramount+ and all of the episodes downloaded except two: episodes 8 and 21 from season 2. 

URLs for those episodes:
https://www.paramountplus.com/shows/video/723621733/
https://www.paramountplus.com/shows/video/723703091/

These are both playable in a browser. Another tool I have for archiving content was able to retrieve the hls-4xxx (4.5 Mbps) format and subtitles streams, so the video is definitely there. 

### 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] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below

### Complete Verbose Output

```shell
$ yt-dlp -vU --embed-subs --check-formats --remux-video mkv -o '%(series)s s%(season_number)02de%(episode_number)02d %(title)s.%(ext)s' --cookies ../../_cookies/paramount+.txt https://www.paramountplus.com/shows/video/723621733/ https://www.paramountplus.com/shows/video/723703091/
[debug] Command-line config: ['-vU', '--embed-subs', '--check-formats', '--remux-video', 'mkv', '-o', '%(series)s s%(season_number)02de%(episode_number)02d %(title)s.%(ext)s', '--cookies', '../../_cookies/paramount+.txt', 'https://www.paramountplus.com/shows/video/723621733/', 'https://www.paramountplus.com/shows/video/723703091/']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version 2022.09.01 [5d7c7d6] (pip)
[debug] Python 3.9.14 (CPython 64bit) - FreeBSD-12.3-RELEASE-p6-amd64-64bit-ELF (libc 7)
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: ffprobe -bsfs
[debug] exe versions: ffmpeg 4.4.2 (setts), ffprobe 4.4.2
[debug] Optional libraries: Cryptodome-3.15.0, brotli-1.0.9, certifi-2022.09.14, mutagen-1.45.1, websockets-10.3
[debug] Proxy map: {}
[debug] Loaded 1670 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest
Latest version: 2022.09.01, Current version: 2022.09.01
yt-dlp is up to date (2022.09.01)
[debug] [ParamountPlus] Extracting URL: https://www.paramountplus.com/shows/video/723621733/
[ParamountPlus] 723621733: Downloading JSON metadata
[ParamountPlus] 723621733: Downloading JSON metadata
[ParamountPlus] 723621733: Downloading DASH_CENC_PRECON SMIL data
[ParamountPlus] 723621733: Downloading m3u8 information
WARNING: [ParamountPlus] Failed to download m3u8 information: HTTP Error 404: Not Found
[info] 723621733: Downloading subtitles: en
ERROR: [ParamountPlus] 723621733: No video formats found!; 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
Traceback (most recent call last):
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1459, in wrapper
    return func(self, *args, **kwargs)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1556, in __extract_info
    return self.process_ie_result(ie_result, download, extra_info)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1614, in process_ie_result
    ie_result = self.process_video_result(ie_result, download=download)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2546, in process_video_result
    self.raise_no_formats(info_dict)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1025, in raise_no_formats
    raise ExtractorError(msg, video_id=info['id'], ie=info['extractor'],
yt_dlp.utils.ExtractorError: [ParamountPlus] 723621733: No video formats found!; 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

[debug] [ParamountPlus] Extracting URL: https://www.paramountplus.com/shows/video/723703091/
[ParamountPlus] 723703091: Downloading JSON metadata
[ParamountPlus] 723703091: Downloading JSON metadata
[ParamountPlus] 723703091: Downloading DASH_CENC_PRECON SMIL data
[ParamountPlus] 723703091: Downloading m3u8 information
WARNING: [ParamountPlus] Failed to download m3u8 information: HTTP Error 404: Not Found
[info] 723703091: Downloading subtitles: en
ERROR: [ParamountPlus] 723703091: No video formats found!; 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
Traceback (most recent call last):
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1459, in wrapper
    return func(self, *args, **kwargs)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1556, in __extract_info
    return self.process_ie_result(ie_result, download, extra_info)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1614, in process_ie_result
    ie_result = self.process_video_result(ie_result, download=download)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 2546, in process_video_result
    self.raise_no_formats(info_dict)
  File "/home/melissa/.local/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1025, in raise_no_formats
    raise ExtractorError(msg, video_id=info['id'], ie=info['extractor'],
yt_dlp.utils.ExtractorError: [ParamountPlus] 723703091: No video formats found!; 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
```



Discussion:

Resolving patch:
diff --git a/yt_dlp/extractor/paramountplus.py b/yt_dlp/extractor/paramountplus.py
--- a/yt_dlp/extractor/paramountplus.py
+++ b/yt_dlp/extractor/paramountplus.py
@@ -3,6 +3,7 @@
 from .common import InfoExtractor
 from .cbs import CBSBaseIE
 from ..utils import (
+    ExtractorError,
     int_or_none,
     url_or_none,
 )
@@ -24,14 +25,22 @@ class ParamountPlusIE(CBSBaseIE):
             'ext': 'mp4',
             'title': 'CatDog - Climb Every CatDog/The Canine Mutiny',
             'description': 'md5:7ac835000645a69933df226940e3c859',
-            'duration': 1418,
+            'duration': 1426,
             'timestamp': 920264400,
             'upload_date': '19990301',
             'uploader': 'CBSI-NEW',
+            'episode_number': 5,
+            'thumbnail': r're:https?://.+\.jpg$',
+            'season': 'Season 2',
+            'chapters': 'count:3',
+            'episode': 'Episode 5',
+            'season_number': 2,
+            'series': 'CatDog',
         },
         'params': {
             'skip_download': 'm3u8',
         },
+        'expected_warnings': ['Ignoring subtitle tracks'],  # TODO: Investigate this
     }, {
         'url': 'https://www.paramountplus.com/shows/video/6hSWYWRrR9EUTz7IEe5fJKBhYvSUfexd/',
         'info_dict': {
@@ -43,10 +52,18 @@ class ParamountPlusIE(CBSBaseIE):
             'timestamp': 1627063200,
             'upload_date': '20210723',
             'uploader': 'CBSI-NEW',
+            'episode_number': 81,
+            'thumbnail': r're:https?://.+\.jpg$',
+            'season': 'Season 2',
+            'chapters': 'count:4',
+            'episode': 'Episode 81',
+            'season_number': 2,
+            'series': 'Tooning Out The News',
         },
         'params': {
             'skip_download': 'm3u8',
         },
+        'expected_warnings': ['Ignoring subtitle tracks'],
     }, {
         'url': 'https://www.paramountplus.com/movies/video/vM2vm0kE6vsS2U41VhMRKTOVHyQAr6pC/',
         'info_dict': {
@@ -54,14 +71,18 @@ class ParamountPlusIE(CBSBaseIE):
             'ext': 'mp4',
             'title': 'Daddy\'s Home',
             'upload_date': '20151225',
-            'description': 'md5:a0beaf24e8d3b0e81b2ee41d47c06f33',
+            'description': 'md5:9a6300c504d5e12000e8707f20c54745',
             'uploader': 'CBSI-NEW',
             'timestamp': 1451030400,
+            'thumbnail': r're:https?://.+\.jpg$',
+            'chapters': 'count:0',
+            'duration': 5761,
+            'series': 'Paramount+ Movies',
         },
         'params': {
             'skip_download': 'm3u8',
         },
-        'expected_warnings': ['Ignoring subtitle tracks'],  # TODO: Investigate this
+        'skip': 'DRM',
     }, {
         'url': 'https://www.paramountplus.com/movies/video/5EKDXPOzdVf9voUqW6oRuocyAEeJGbEc/',
         'info_dict': {
@@ -72,11 +93,15 @@ class ParamountPlusIE(CBSBaseIE):
             'timestamp': 1577865600,
             'title': 'Sonic the Hedgehog',
             'upload_date': '20200101',
+            'thumbnail': r're:https?://.+\.jpg$',
+            'chapters': 'count:0',
+            'duration': 5932,
+            'series': 'Paramount+ Movies',
         },
         'params': {
             'skip_download': 'm3u8',
         },
-        'expected_warnings': ['Ignoring subtitle tracks'],
+        'skip': 'DRM',
     }, {
         'url': 'https://www.paramountplus.com/shows/the-real-world/video/mOVeHeL9ub9yWdyzSZFYz8Uj4ZBkVzQg/the-real-world-reunion/',
         'only_matching': True,
@@ -99,18 +124,42 @@ def _extract_video_info(self, content_id, mpx_acc=2198311517):
         asset_types = {
             item.get('assetType'): {
                 'format': 'SMIL',
-                'formats': 'MPEG4,M3U',
+                'formats': 'M3U+none,MPEG4',  # '+none' specifies ProtectionScheme (no DRM)
             } for item in items_data['itemList']
         }
         item = items_data['itemList'][-1]
-        return self._extract_common_video_info(content_id, asset_types, mpx_acc, extra_info={
+
+        info, error = {}, None
+        metadata = {
             'title': item.get('title'),
             'series': item.get('seriesTitle'),
             'season_number': int_or_none(item.get('seasonNum')),
             'episode_number': int_or_none(item.get('episodeNum')),
             'duration': int_or_none(item.get('duration')),
             'thumbnail': url_or_none(item.get('thumbnail')),
-        })
+        }
+        try:
+            info = self._extract_common_video_info(content_id, asset_types, mpx_acc, extra_info=metadata)
+        except ExtractorError as e:
+            error = e
+
+        # Check for DRM formats to give appropriate error
+        if not info.get('formats'):
+            for query in asset_types.values():
+                query['formats'] = 'MPEG-DASH,M3U,MPEG4'  # allows DRM formats
+
+            try:
+                drm_info = self._extract_common_video_info(content_id, asset_types, mpx_acc, extra_info=metadata)
+            except ExtractorError:
+                if error:
+                    raise error from None
+                raise
+            if drm_info['formats']:
+                self.report_drm(content_id)
+            elif error:
+                raise error
+
+        return info
 
 
 class ParamountPlusSeriesIE(InfoExtractor):


Test patch: