Repository: yt-dlp/yt-dlp

Issue:
[Broken] [cda.pl] Video quality defaults to 480p
## Checklist
- [x] I'm reporting a broken site support
- [x] I've verified that I'm running yt-dlp version **2021.08.10**
- [x] I've checked that all provided URLs are alive and playable in a browser
- [x] I've checked that all URLs and arguments with special characters are properly quoted or escaped
- [x] I've searched the bugtracker for similar issues including closed ones

## Verbose log
```
$ yt-dlp -v https://www.cda.pl/video/8224343bf
[debug] Command-line config: ['-v', 'https://www.cda.pl/video/8224343bf']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, pref UTF-8
[debug] yt-dlp version 2021.08.10 (zip)
[debug] Python version 3.9.6 (CPython 64bit) - Linux-5.13.8-1-MANJARO-x86_64-with-glibc2.33
[debug] exe versions: ffmpeg 4.4, ffprobe 4.4, rtmpdump 2.4
[debug] Optional libraries: mutagen, pycryptodome, sqlite
[debug] Proxy map: {}
[debug] [CDA] Extracting URL: https://www.cda.pl/video/8224343bf
[CDA] 8224343bf: Downloading webpage
[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, vcodec:vp9.2(10), acodec, filesize, fs_approx, tbr, vbr, abr, asr, proto, vext, aext, hasaud, source, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] 8224343bf: Downloading 1 format(s): 0
[debug] Invoking downloader on "https://vwaw703.cda.pl/FlzIt5ykOPSw_rUsDa2iYw/1629935629/lq3cf931b58c394e14eab41366108035f8.mp4"
[download] Destination: Given Movie napisy pl 1080p [8224343bf].mp4
[download] 100% of 557.32MiB in 02:18
```

## Description

Some videos on cda.pl are downloaded with default 480p quality despite using bestvideo*+bestaudio/best preference. Example video from log is 1080p, yet yt-dlp downloads it as 480p. Some videos, such as https://www.cda.pl/video/81741716d are unaffected.

Example affected videos:
https://www.cda.pl/video/8224343bf
https://www.cda.pl/video/8222894ff
https://www.cda.pl/video/5739761ed


Discussion:

Resolving patch:
diff --git a/yt_dlp/extractor/cda.py b/yt_dlp/extractor/cda.py
--- a/yt_dlp/extractor/cda.py
+++ b/yt_dlp/extractor/cda.py
@@ -3,6 +3,7 @@
 
 import codecs
 import re
+import json
 
 from .common import InfoExtractor
 from ..compat import (
@@ -19,6 +20,7 @@
     parse_duration,
     random_birthday,
     urljoin,
+    try_get,
 )
 
 
@@ -38,6 +40,8 @@ class CDAIE(InfoExtractor):
             'average_rating': float,
             'duration': 39,
             'age_limit': 0,
+            'upload_date': '20160221',
+            'timestamp': 1456078244,
         }
     }, {
         'url': 'http://www.cda.pl/video/57413289',
@@ -143,7 +147,7 @@ def decrypt_file(a):
             b = []
             for c in a:
                 f = compat_ord(c)
-                b.append(compat_chr(33 + (f + 14) % 94) if 33 <= f and 126 >= f else compat_chr(f))
+                b.append(compat_chr(33 + (f + 14) % 94) if 33 <= f <= 126 else compat_chr(f))
             a = ''.join(b)
             a = a.replace('.cda.mp4', '')
             for p in ('.2cda.pl', '.3cda.pl'):
@@ -173,18 +177,34 @@ def extract_format(page, version):
                     video['file'] = video['file'].replace('adc.mp4', '.mp4')
             elif not video['file'].startswith('http'):
                 video['file'] = decrypt_file(video['file'])
-            f = {
+            video_quality = video.get('quality')
+            qualities = video.get('qualities', {})
+            video_quality = next((k for k, v in qualities.items() if v == video_quality), video_quality)
+            info_dict['formats'].append({
                 'url': video['file'],
-            }
-            m = re.search(
-                r'<a[^>]+data-quality="(?P<format_id>[^"]+)"[^>]+href="[^"]+"[^>]+class="[^"]*quality-btn-active[^"]*">(?P<height>[0-9]+)p',
-                page)
-            if m:
-                f.update({
-                    'format_id': m.group('format_id'),
-                    'height': int(m.group('height')),
-                })
-            info_dict['formats'].append(f)
+                'format_id': video_quality,
+                'height': int_or_none(video_quality[:-1]),
+            })
+            for quality, cda_quality in qualities.items():
+                if quality == video_quality:
+                    continue
+                data = {'jsonrpc': '2.0', 'method': 'videoGetLink', 'id': 2,
+                        'params': [video_id, cda_quality, video.get('ts'), video.get('hash2'), {}]}
+                data = json.dumps(data).encode('utf-8')
+                video_url = self._download_json(
+                    f'https://www.cda.pl/video/{video_id}', video_id, headers={
+                        'Content-Type': 'application/json',
+                        'X-Requested-With': 'XMLHttpRequest'
+                    }, data=data, note=f'Fetching {quality} url',
+                    errnote=f'Failed to fetch {quality} url', fatal=False)
+                if try_get(video_url, lambda x: x['result']['status']) == 'ok':
+                    video_url = try_get(video_url, lambda x: x['result']['resp'])
+                    info_dict['formats'].append({
+                        'url': video_url,
+                        'format_id': quality,
+                        'height': int_or_none(quality[:-1])
+                    })
+
             if not info_dict['duration']:
                 info_dict['duration'] = parse_duration(video.get('duration'))
 


Test patch: