Repository: yt-dlp/yt-dlp

Issue:
An extractor error has occurred. (caused by KeyError('quality'));
### Checklist

- [X] I'm reporting a bug unrelated to a specific site
- [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 all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/ytdl-org/youtube-dl#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)

### Description

The vevo URLs are not playable in the browser, so I was not able to check this. But this error appears, and I don't know how to handle it. Can you help out?



### Verbose log

```shell
./yt-dlp --verbose -F http://www.vevo.com/watch/ES1022200025
[debug] Command-line config: ['--verbose', '-F', 'http://www.vevo.com/watch/ES1022200025']
[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.05.18 [b14d52355] (zip)
[debug] Python version 3.9.12 (CPython 64bit) - macOS-12.4-x86_64-i386-64bit
[debug] Checking exe version: ffprobe -bsfs
[debug] Checking exe version: avprobe -bsfs
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: avconv -bsfs
[debug] exe versions: rtmpdump 2.4
[debug] Optional libraries: sqlite3-2.6.0
[debug] Proxy map: {}
[debug] [Vevo] Extracting URL: http://www.vevo.com/watch/ES1022200025
[Vevo] Retrieving oauth token
[Vevo] ES1022200025: Downloading api video info
[Vevo] ES1022200025: Downloading video versions info
ERROR: ES1022200025: An extractor error has occurred. (caused by KeyError('quality')); 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
  File "/Users/michaelhornke/Development/youtube-song-downloader/youtube-dl/bin/./yt-dlp/yt_dlp/extractor/common.py", line 642, in extract
    ie_result = self._real_extract(url)
  File "/Users/michaelhornke/Development/youtube-song-downloader/youtube-dl/bin/./yt-dlp/yt_dlp/extractor/vevo.py", line 152, in _real_extract
    'format_id': 'http-%s-%s' % (version, video_version['quality']),
KeyError: 'quality'
```



Discussion:
I have the same experience.

Resolving patch:
diff --git a/yt_dlp/extractor/vevo.py b/yt_dlp/extractor/vevo.py
--- a/yt_dlp/extractor/vevo.py
+++ b/yt_dlp/extractor/vevo.py
@@ -33,10 +33,124 @@ class VevoIE(VevoBaseIE):
            https?://cache\.vevo\.com/m/html/embed\.html\?video=|
            https?://videoplayer\.vevo\.com/embed/embedded\?videoId=|
            https?://embed\.vevo\.com/.*?[?&]isrc=|
+           https?://tv\.vevo\.com/watch/artist/(?:[^/]+)/|
            vevo:)
         (?P<id>[^&?#]+)'''
 
-    _TESTS = []
+    _TESTS = [{
+        'url': 'http://www.vevo.com/watch/hurts/somebody-to-die-for/GB1101300280',
+        'md5': '95ee28ee45e70130e3ab02b0f579ae23',
+        'info_dict': {
+            'id': 'GB1101300280',
+            'ext': 'mp4',
+            'title': 'Hurts - Somebody to Die For',
+            'timestamp': 1372057200,
+            'upload_date': '20130624',
+            'uploader': 'Hurts',
+            'track': 'Somebody to Die For',
+            'artist': 'Hurts',
+            'genre': 'Pop',
+        },
+        'expected_warnings': ['Unable to download SMIL file', 'Unable to download info'],
+    }, {
+        'note': 'v3 SMIL format',
+        'url': 'http://www.vevo.com/watch/cassadee-pope/i-wish-i-could-break-your-heart/USUV71302923',
+        'md5': 'f6ab09b034f8c22969020b042e5ac7fc',
+        'info_dict': {
+            'id': 'USUV71302923',
+            'ext': 'mp4',
+            'title': 'Cassadee Pope - I Wish I Could Break Your Heart',
+            'timestamp': 1392796919,
+            'upload_date': '20140219',
+            'uploader': 'Cassadee Pope',
+            'track': 'I Wish I Could Break Your Heart',
+            'artist': 'Cassadee Pope',
+            'genre': 'Country',
+        },
+        'expected_warnings': ['Unable to download SMIL file', 'Unable to download info'],
+    }, {
+        'note': 'Age-limited video',
+        'url': 'https://www.vevo.com/watch/justin-timberlake/tunnel-vision-explicit/USRV81300282',
+        'info_dict': {
+            'id': 'USRV81300282',
+            'ext': 'mp4',
+            'title': 'Justin Timberlake - Tunnel Vision (Explicit)',
+            'age_limit': 18,
+            'timestamp': 1372888800,
+            'upload_date': '20130703',
+            'uploader': 'Justin Timberlake',
+            'track': 'Tunnel Vision (Explicit)',
+            'artist': 'Justin Timberlake',
+            'genre': 'Pop',
+        },
+        'expected_warnings': ['Unable to download SMIL file', 'Unable to download info'],
+    }, {
+        'note': 'No video_info',
+        'url': 'http://www.vevo.com/watch/k-camp-1/Till-I-Die/USUV71503000',
+        'md5': '8b83cc492d72fc9cf74a02acee7dc1b0',
+        'info_dict': {
+            'id': 'USUV71503000',
+            'ext': 'mp4',
+            'title': 'K Camp ft. T.I. - Till I Die',
+            'age_limit': 18,
+            'timestamp': 1449468000,
+            'upload_date': '20151207',
+            'uploader': 'K Camp',
+            'track': 'Till I Die',
+            'artist': 'K Camp',
+            'genre': 'Hip-Hop',
+        },
+        'expected_warnings': ['Unable to download SMIL file', 'Unable to download info'],
+    }, {
+        'note': 'Featured test',
+        'url': 'https://www.vevo.com/watch/lemaitre/Wait/USUV71402190',
+        'md5': 'd28675e5e8805035d949dc5cf161071d',
+        'info_dict': {
+            'id': 'USUV71402190',
+            'ext': 'mp4',
+            'title': 'Lemaitre ft. LoLo - Wait',
+            'age_limit': 0,
+            'timestamp': 1413432000,
+            'upload_date': '20141016',
+            'uploader': 'Lemaitre',
+            'track': 'Wait',
+            'artist': 'Lemaitre',
+            'genre': 'Electronic',
+        },
+        'expected_warnings': ['Unable to download SMIL file', 'Unable to download info'],
+    }, {
+        'note': 'Only available via webpage',
+        'url': 'http://www.vevo.com/watch/GBUV71600656',
+        'md5': '67e79210613865b66a47c33baa5e37fe',
+        'info_dict': {
+            'id': 'GBUV71600656',
+            'ext': 'mp4',
+            'title': 'ABC - Viva Love',
+            'age_limit': 0,
+            'timestamp': 1461830400,
+            'upload_date': '20160428',
+            'uploader': 'ABC',
+            'track': 'Viva Love',
+            'artist': 'ABC',
+            'genre': 'Pop',
+        },
+        'expected_warnings': ['Failed to download video versions info'],
+    }, {
+        # no genres available
+        'url': 'http://www.vevo.com/watch/INS171400764',
+        'only_matching': True,
+    }, {
+        # Another case available only via the webpage; using streams/streamsV3 formats
+        # Geo-restricted to Netherlands/Germany
+        'url': 'http://www.vevo.com/watch/boostee/pop-corn-clip-officiel/FR1A91600909',
+        'only_matching': True,
+    }, {
+        'url': 'https://embed.vevo.com/?isrc=USH5V1923499&partnerId=4d61b777-8023-4191-9ede-497ed6c24647&partnerAdCode=',
+        'only_matching': True,
+    }, {
+        'url': 'https://tv.vevo.com/watch/artist/janet-jackson/US0450100550',
+        'only_matching': True,
+    }]
     _VERSIONS = {
         0: 'youtube',  # only in AuthenticateVideo videoVersions
         1: 'level3',
@@ -138,6 +252,7 @@ def _real_extract(self, url):
                     fatal=False))
             else:
                 m = re.search(r'''(?xi)
+                    _(?P<quality>[a-z0-9]+)
                     _(?P<width>[0-9]+)x(?P<height>[0-9]+)
                     _(?P<vcodec>[a-z0-9]+)
                     _(?P<vbr>[0-9]+)
@@ -149,7 +264,7 @@ def _real_extract(self, url):
 
                 formats.append({
                     'url': version_url,
-                    'format_id': 'http-%s-%s' % (version, video_version['quality']),
+                    'format_id': f'http-{version}-{video_version.get("quality") or m.group("quality")}',
                     'vcodec': m.group('vcodec'),
                     'acodec': m.group('acodec'),
                     'vbr': int(m.group('vbr')),


Test patch: