We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Jiosaavn] Extract more metadata
### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

- [X] I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field

### Checklist

- [X] I'm requesting a site-specific feature
- [X] I've verified that I have **updated yt-dlp to nightly or master** ([update instructions](https://github.com/yt-dlp/yt-dlp#update-channels))
- [X] I've checked that all provided URLs are playable in a browser with the same IP and same login details
- [X] I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and 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

India

### Example URLs

https://www.jiosaavn.com/song/love-me-again/OgFZRER2A3c

### Provide a description that is worded well enough to be understood

Please add the option to include metadata when songs are downloaded froom Jiosaavn. I am able to add metadata when downloading from youtube music. Please do something similar for Jiosaavn

### Provide verbose output that clearly demonstrates the problem

- [ ] Run **your** yt-dlp command with **-vU** flag added (`yt-dlp -vU <your command line>`)
- [X] If using API, add `'verbose': True` to `YoutubeDL` params instead
- [X] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below

### Complete Verbose Output

```shell
[debug] Command-line config: ['--verbose', 'https://www.jiosaavn.com/song/love-me-again/OgFZRER2A3c']
[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version stable@2024.03.10 from yt-dlp/yt-dlp [615a84447] (win_exe)
[debug] Python 3.8.10 (CPython AMD64 64bit) - Windows-10-10.0.19045-SP0 (OpenSSL 1.1.1k  25 Mar 2021)
[debug] exe versions: ffmpeg N-112207-g8eb094adb2-20230928 (setts), ffprobe N-112207-g8eb094adb2-20230928
[debug] Optional libraries: Cryptodome-3.20.0, brotli-1.1.0, certifi-2024.02.02, mutagen-1.47.0, requests-2.31.0, sqlite3-3.35.5, urllib3-2.2.1, websockets-12.0
[debug] Proxy map: {}
[debug] Request Handlers: urllib, requests, websockets
[debug] Loaded 1803 extractors
[JioSaavnSong] Extracting URL: https://www.jiosaavn.com/song/love-me-again/OgFZRER2A3c
[JioSaavnSong] OgFZRER2A3c: Downloading webpage
[JioSaavnSong] OgFZRER2A3c: Downloading format info for 128
[JioSaavnSong] OgFZRER2A3c: Downloading format info for 320
[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, hdr:12(7), vcodec:vp9.2(10), channels, acodec, size, br, asr, proto, vext, aext, hasaud, source, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] OgFZRER2A3c: Downloading 1 format(s): 320
[debug] Invoking http downloader on "https://ac.cf.saavncdn.com/593/23d333a3c1c0f706b6c57629f756f059_320.mp4?Expires=1712173385&Signature=fheCPEBOGuUsngOaUjck3xkTBBIyGE9jHg50kaEmIuzpD5DVzGw~7RDZEUO2ZeCk7UUvxsM1N7svIPh3V7cEfi3BCLjkiYqKwxh044TorkWad-GC-1P4oOcovsfAf0GxwCVQg3syVwza3QQJLWeUrcUS36B~rhqJg5~4AzaK8z~sinByrUCG5~BENyvLNsCGUN5gVnLQH3QN9MaavJ742Vn9Ew7DrddQkQuRD25j84hvBtPQsUuD3VAUX9zg5h1~bZ3~fWdrXJbCMPUy4Wq4b6KZexmMPu7tO8IjpwGXDpTdgB94N9R2UrAqc7S7HghmXEwESbNXNiC-iX-VSBUpCw__&Key-Pair-Id=APKAJB334VX63D3WJ5ZQ"
[debug] File locking is not supported. Proceeding without locking
[download] Destination: Love Me Again [OgFZRER2A3c].mp4
[download] 100% of    9.20MiB in 00:00:01 at 5.19MiB/s
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `yt_dlp/extractor/jiosaavn.py`
Content:
```
1 from .common import InfoExtractor
2 from ..utils import (
3     int_or_none,
4     js_to_json,
5     url_or_none,
6     urlencode_postdata,
7     urljoin,
8 )
9 from ..utils.traversal import traverse_obj
10 
11 
12 class JioSaavnBaseIE(InfoExtractor):
13     def _extract_initial_data(self, url, audio_id):
14         webpage = self._download_webpage(url, audio_id)
15         return self._search_json(
16             r'window\.__INITIAL_DATA__\s*=', webpage,
17             'init json', audio_id, transform_source=js_to_json)
18 
19 
20 class JioSaavnSongIE(JioSaavnBaseIE):
21     _VALID_URL = r'https?://(?:www\.)?(?:jiosaavn\.com/song/[^/?#]+/|saavn\.com/s/song/(?:[^/?#]+/){3})(?P<id>[^/?#]+)'
22     _TESTS = [{
23         'url': 'https://www.jiosaavn.com/song/leja-re/OQsEfQFVUXk',
24         'md5': '3b84396d15ed9e083c3106f1fa589c04',
25         'info_dict': {
26             'id': 'OQsEfQFVUXk',
27             'ext': 'mp4',
28             'title': 'Leja Re',
29             'album': 'Leja Re',
30             'thumbnail': 'https://c.saavncdn.com/258/Leja-Re-Hindi-2018-20181124024539-500x500.jpg',
31             'duration': 205,
32             'view_count': int,
33             'release_year': 2018,
34         },
35     }, {
36         'url': 'https://www.saavn.com/s/song/hindi/Saathiya/O-Humdum-Suniyo-Re/KAMiazoCblU',
37         'only_matching': True,
38     }]
39 
40     _VALID_BITRATES = ('16', '32', '64', '128', '320')
41 
42     def _real_extract(self, url):
43         audio_id = self._match_id(url)
44         extract_bitrates = self._configuration_arg('bitrate', ['128', '320'], ie_key='JioSaavn')
45         if invalid_bitrates := [br for br in extract_bitrates if br not in self._VALID_BITRATES]:
46             raise ValueError(
47                 f'Invalid bitrate(s): {", ".join(invalid_bitrates)}. '
48                 + f'Valid bitrates are: {", ".join(self._VALID_BITRATES)}')
49 
50         song_data = self._extract_initial_data(url, audio_id)['song']['song']
51         formats = []
52         for bitrate in extract_bitrates:
53             media_data = self._download_json(
54                 'https://www.jiosaavn.com/api.php', audio_id, f'Downloading format info for {bitrate}',
55                 fatal=False, data=urlencode_postdata({
56                     '__call': 'song.generateAuthToken',
57                     '_format': 'json',
58                     'bitrate': bitrate,
59                     'url': song_data['encrypted_media_url'],
60                 }))
61             if not media_data.get('auth_url'):
62                 self.report_warning(f'Unable to extract format info for {bitrate}')
63                 continue
64             formats.append({
65                 'url': media_data['auth_url'],
66                 'ext': media_data.get('type'),
67                 'format_id': bitrate,
68                 'abr': int(bitrate),
69                 'vcodec': 'none',
70             })
71 
72         return {
73             'id': audio_id,
74             'formats': formats,
75             **traverse_obj(song_data, {
76                 'title': ('title', 'text'),
77                 'album': ('album', 'text'),
78                 'thumbnail': ('image', 0, {url_or_none}),
79                 'duration': ('duration', {int_or_none}),
80                 'view_count': ('play_count', {int_or_none}),
81                 'release_year': ('year', {int_or_none}),
82             }),
83         }
84 
85 
86 class JioSaavnAlbumIE(JioSaavnBaseIE):
87     _VALID_URL = r'https?://(?:www\.)?(?:jio)?saavn\.com/album/[^/?#]+/(?P<id>[^/?#]+)'
88     _TESTS = [{
89         'url': 'https://www.jiosaavn.com/album/96/buIOjYZDrNA_',
90         'info_dict': {
91             'id': 'buIOjYZDrNA_',
92             'title': '96',
93         },
94         'playlist_count': 10,
95     }]
96 
97     def _real_extract(self, url):
98         album_id = self._match_id(url)
99         album_view = self._extract_initial_data(url, album_id)['albumView']
100 
101         return self.playlist_from_matches(
102             traverse_obj(album_view, (
103                 'modules', lambda _, x: x['key'] == 'list', 'data', ..., 'title', 'action', {str})),
104             album_id, traverse_obj(album_view, ('album', 'title', 'text', {str})), ie=JioSaavnSongIE,
105             getter=lambda x: urljoin('https://www.jiosaavn.com/', x))
106
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/yt_dlp/extractor/jiosaavn.py b/yt_dlp/extractor/jiosaavn.py
--- a/yt_dlp/extractor/jiosaavn.py
+++ b/yt_dlp/extractor/jiosaavn.py
@@ -2,6 +2,7 @@
 from ..utils import (
     int_or_none,
     js_to_json,
+    orderedSet,
     url_or_none,
     urlencode_postdata,
     urljoin,
@@ -31,6 +32,7 @@
             'duration': 205,
             'view_count': int,
             'release_year': 2018,
+            'artists': ['Sandesh Shandilya', 'Dhvani Bhanushali', 'Tanishk Bagchi', 'Rashmi Virag', 'Irshad Kamil'],
         },
     }, {
         'url': 'https://www.saavn.com/s/song/hindi/Saathiya/O-Humdum-Suniyo-Re/KAMiazoCblU',
@@ -79,6 +81,7 @@
                 'duration': ('duration', {int_or_none}),
                 'view_count': ('play_count', {int_or_none}),
                 'release_year': ('year', {int_or_none}),
+                'artists': ('artists', ..., 'name', {str}, all, {orderedSet}),
             }),
         }

{"golden_diff": "diff --git a/yt_dlp/extractor/jiosaavn.py b/yt_dlp/extractor/jiosaavn.py\n--- a/yt_dlp/extractor/jiosaavn.py\n+++ b/yt_dlp/extractor/jiosaavn.py\n@@ -2,6 +2,7 @@\n from ..utils import (\n     int_or_none,\n     js_to_json,\n+    orderedSet,\n     url_or_none,\n     urlencode_postdata,\n     urljoin,\n@@ -31,6 +32,7 @@\n             'duration': 205,\n             'view_count': int,\n             'release_year': 2018,\n+            'artists': ['Sandesh Shandilya', 'Dhvani Bhanushali', 'Tanishk Bagchi', 'Rashmi Virag', 'Irshad Kamil'],\n         },\n     }, {\n         'url': 'https://www.saavn.com/s/song/hindi/Saathiya/O-Humdum-Suniyo-Re/KAMiazoCblU',\n@@ -79,6 +81,7 @@\n                 'duration': ('duration', {int_or_none}),\n                 'view_count': ('play_count', {int_or_none}),\n                 'release_year': ('year', {int_or_none}),\n+                'artists': ('artists', ..., 'name', {str}, all, {orderedSet}),\n             }),\n         }\n", "issue": "[Jiosaavn] Extract more metadata\n### DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE\n\n- [X] I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\\* field\n\n### Checklist\n\n- [X] I'm requesting a site-specific feature\n- [X] I've verified that I have **updated yt-dlp to nightly or master** ([update instructions](https://github.com/yt-dlp/yt-dlp#update-channels))\n- [X] I've checked that all provided URLs are playable in a browser with the same IP and same login details\n- [X] I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates\n- [X] I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue)\n- [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\n\n### Region\n\nIndia\n\n### Example URLs\n\nhttps://www.jiosaavn.com/song/love-me-again/OgFZRER2A3c\n\n### Provide a description that is worded well enough to be understood\n\nPlease add the option to include metadata when songs are downloaded froom Jiosaavn. I am able to add metadata when downloading from youtube music. Please do something similar for Jiosaavn\n\n### Provide verbose output that clearly demonstrates the problem\n\n- [ ] Run **your** yt-dlp command with **-vU** flag added (`yt-dlp -vU <your command line>`)\n- [X] If using API, add `'verbose': True` to `YoutubeDL` params instead\n- [X] Copy the WHOLE output (starting with `[debug] Command-line config`) and insert it below\n\n### Complete Verbose Output\n\n```shell\n[debug] Command-line config: ['--verbose', 'https://www.jiosaavn.com/song/love-me-again/OgFZRER2A3c']\r\n[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8\r\n[debug] yt-dlp version stable@2024.03.10 from yt-dlp/yt-dlp [615a84447] (win_exe)\r\n[debug] Python 3.8.10 (CPython AMD64 64bit) - Windows-10-10.0.19045-SP0 (OpenSSL 1.1.1k  25 Mar 2021)\r\n[debug] exe versions: ffmpeg N-112207-g8eb094adb2-20230928 (setts), ffprobe N-112207-g8eb094adb2-20230928\r\n[debug] Optional libraries: Cryptodome-3.20.0, brotli-1.1.0, certifi-2024.02.02, mutagen-1.47.0, requests-2.31.0, sqlite3-3.35.5, urllib3-2.2.1, websockets-12.0\r\n[debug] Proxy map: {}\r\n[debug] Request Handlers: urllib, requests, websockets\r\n[debug] Loaded 1803 extractors\r\n[JioSaavnSong] Extracting URL: https://www.jiosaavn.com/song/love-me-again/OgFZRER2A3c\r\n[JioSaavnSong] OgFZRER2A3c: Downloading webpage\r\n[JioSaavnSong] OgFZRER2A3c: Downloading format info for 128\r\n[JioSaavnSong] OgFZRER2A3c: Downloading format info for 320\r\n[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, hdr:12(7), vcodec:vp9.2(10), channels, acodec, size, br, asr, proto, vext, aext, hasaud, source, id\r\n[debug] Default format spec: bestvideo*+bestaudio/best\r\n[info] OgFZRER2A3c: Downloading 1 format(s): 320\r\n[debug] Invoking http downloader on \"https://ac.cf.saavncdn.com/593/23d333a3c1c0f706b6c57629f756f059_320.mp4?Expires=1712173385&Signature=fheCPEBOGuUsngOaUjck3xkTBBIyGE9jHg50kaEmIuzpD5DVzGw~7RDZEUO2ZeCk7UUvxsM1N7svIPh3V7cEfi3BCLjkiYqKwxh044TorkWad-GC-1P4oOcovsfAf0GxwCVQg3syVwza3QQJLWeUrcUS36B~rhqJg5~4AzaK8z~sinByrUCG5~BENyvLNsCGUN5gVnLQH3QN9MaavJ742Vn9Ew7DrddQkQuRD25j84hvBtPQsUuD3VAUX9zg5h1~bZ3~fWdrXJbCMPUy4Wq4b6KZexmMPu7tO8IjpwGXDpTdgB94N9R2UrAqc7S7HghmXEwESbNXNiC-iX-VSBUpCw__&Key-Pair-Id=APKAJB334VX63D3WJ5ZQ\"\r\n[debug] File locking is not supported. Proceeding without locking\r\n[download] Destination: Love Me Again [OgFZRER2A3c].mp4\r\n[download] 100% of    9.20MiB in 00:00:01 at 5.19MiB/s\n```\n\n", "before_files": [{"content": "from .common import InfoExtractor\nfrom ..utils import (\n    int_or_none,\n    js_to_json,\n    url_or_none,\n    urlencode_postdata,\n    urljoin,\n)\nfrom ..utils.traversal import traverse_obj\n\n\nclass JioSaavnBaseIE(InfoExtractor):\n    def _extract_initial_data(self, url, audio_id):\n        webpage = self._download_webpage(url, audio_id)\n        return self._search_json(\n            r'window\\.__INITIAL_DATA__\\s*=', webpage,\n            'init json', audio_id, transform_source=js_to_json)\n\n\nclass JioSaavnSongIE(JioSaavnBaseIE):\n    _VALID_URL = r'https?://(?:www\\.)?(?:jiosaavn\\.com/song/[^/?#]+/|saavn\\.com/s/song/(?:[^/?#]+/){3})(?P<id>[^/?#]+)'\n    _TESTS = [{\n        'url': 'https://www.jiosaavn.com/song/leja-re/OQsEfQFVUXk',\n        'md5': '3b84396d15ed9e083c3106f1fa589c04',\n        'info_dict': {\n            'id': 'OQsEfQFVUXk',\n            'ext': 'mp4',\n            'title': 'Leja Re',\n            'album': 'Leja Re',\n            'thumbnail': 'https://c.saavncdn.com/258/Leja-Re-Hindi-2018-20181124024539-500x500.jpg',\n            'duration': 205,\n            'view_count': int,\n            'release_year': 2018,\n        },\n    }, {\n        'url': 'https://www.saavn.com/s/song/hindi/Saathiya/O-Humdum-Suniyo-Re/KAMiazoCblU',\n        'only_matching': True,\n    }]\n\n    _VALID_BITRATES = ('16', '32', '64', '128', '320')\n\n    def _real_extract(self, url):\n        audio_id = self._match_id(url)\n        extract_bitrates = self._configuration_arg('bitrate', ['128', '320'], ie_key='JioSaavn')\n        if invalid_bitrates := [br for br in extract_bitrates if br not in self._VALID_BITRATES]:\n            raise ValueError(\n                f'Invalid bitrate(s): {\", \".join(invalid_bitrates)}. '\n                + f'Valid bitrates are: {\", \".join(self._VALID_BITRATES)}')\n\n        song_data = self._extract_initial_data(url, audio_id)['song']['song']\n        formats = []\n        for bitrate in extract_bitrates:\n            media_data = self._download_json(\n                'https://www.jiosaavn.com/api.php', audio_id, f'Downloading format info for {bitrate}',\n                fatal=False, data=urlencode_postdata({\n                    '__call': 'song.generateAuthToken',\n                    '_format': 'json',\n                    'bitrate': bitrate,\n                    'url': song_data['encrypted_media_url'],\n                }))\n            if not media_data.get('auth_url'):\n                self.report_warning(f'Unable to extract format info for {bitrate}')\n                continue\n            formats.append({\n                'url': media_data['auth_url'],\n                'ext': media_data.get('type'),\n                'format_id': bitrate,\n                'abr': int(bitrate),\n                'vcodec': 'none',\n            })\n\n        return {\n            'id': audio_id,\n            'formats': formats,\n            **traverse_obj(song_data, {\n                'title': ('title', 'text'),\n                'album': ('album', 'text'),\n                'thumbnail': ('image', 0, {url_or_none}),\n                'duration': ('duration', {int_or_none}),\n                'view_count': ('play_count', {int_or_none}),\n                'release_year': ('year', {int_or_none}),\n            }),\n        }\n\n\nclass JioSaavnAlbumIE(JioSaavnBaseIE):\n    _VALID_URL = r'https?://(?:www\\.)?(?:jio)?saavn\\.com/album/[^/?#]+/(?P<id>[^/?#]+)'\n    _TESTS = [{\n        'url': 'https://www.jiosaavn.com/album/96/buIOjYZDrNA_',\n        'info_dict': {\n            'id': 'buIOjYZDrNA_',\n            'title': '96',\n        },\n        'playlist_count': 10,\n    }]\n\n    def _real_extract(self, url):\n        album_id = self._match_id(url)\n        album_view = self._extract_initial_data(url, album_id)['albumView']\n\n        return self.playlist_from_matches(\n            traverse_obj(album_view, (\n                'modules', lambda _, x: x['key'] == 'list', 'data', ..., 'title', 'action', {str})),\n            album_id, traverse_obj(album_view, ('album', 'title', 'text', {str})), ie=JioSaavnSongIE,\n            getter=lambda x: urljoin('https://www.jiosaavn.com/', x))\n", "path": "yt_dlp/extractor/jiosaavn.py"}], "after_files": [{"content": "from .common import InfoExtractor\nfrom ..utils import (\n    int_or_none,\n    js_to_json,\n    orderedSet,\n    url_or_none,\n    urlencode_postdata,\n    urljoin,\n)\nfrom ..utils.traversal import traverse_obj\n\n\nclass JioSaavnBaseIE(InfoExtractor):\n    def _extract_initial_data(self, url, audio_id):\n        webpage = self._download_webpage(url, audio_id)\n        return self._search_json(\n            r'window\\.__INITIAL_DATA__\\s*=', webpage,\n            'init json', audio_id, transform_source=js_to_json)\n\n\nclass JioSaavnSongIE(JioSaavnBaseIE):\n    _VALID_URL = r'https?://(?:www\\.)?(?:jiosaavn\\.com/song/[^/?#]+/|saavn\\.com/s/song/(?:[^/?#]+/){3})(?P<id>[^/?#]+)'\n    _TESTS = [{\n        'url': 'https://www.jiosaavn.com/song/leja-re/OQsEfQFVUXk',\n        'md5': '3b84396d15ed9e083c3106f1fa589c04',\n        'info_dict': {\n            'id': 'OQsEfQFVUXk',\n            'ext': 'mp4',\n            'title': 'Leja Re',\n            'album': 'Leja Re',\n            'thumbnail': 'https://c.saavncdn.com/258/Leja-Re-Hindi-2018-20181124024539-500x500.jpg',\n            'duration': 205,\n            'view_count': int,\n            'release_year': 2018,\n            'artists': ['Sandesh Shandilya', 'Dhvani Bhanushali', 'Tanishk Bagchi', 'Rashmi Virag', 'Irshad Kamil'],\n        },\n    }, {\n        'url': 'https://www.saavn.com/s/song/hindi/Saathiya/O-Humdum-Suniyo-Re/KAMiazoCblU',\n        'only_matching': True,\n    }]\n\n    _VALID_BITRATES = ('16', '32', '64', '128', '320')\n\n    def _real_extract(self, url):\n        audio_id = self._match_id(url)\n        extract_bitrates = self._configuration_arg('bitrate', ['128', '320'], ie_key='JioSaavn')\n        if invalid_bitrates := [br for br in extract_bitrates if br not in self._VALID_BITRATES]:\n            raise ValueError(\n                f'Invalid bitrate(s): {\", \".join(invalid_bitrates)}. '\n                + f'Valid bitrates are: {\", \".join(self._VALID_BITRATES)}')\n\n        song_data = self._extract_initial_data(url, audio_id)['song']['song']\n        formats = []\n        for bitrate in extract_bitrates:\n            media_data = self._download_json(\n                'https://www.jiosaavn.com/api.php', audio_id, f'Downloading format info for {bitrate}',\n                fatal=False, data=urlencode_postdata({\n                    '__call': 'song.generateAuthToken',\n                    '_format': 'json',\n                    'bitrate': bitrate,\n                    'url': song_data['encrypted_media_url'],\n                }))\n            if not media_data.get('auth_url'):\n                self.report_warning(f'Unable to extract format info for {bitrate}')\n                continue\n            formats.append({\n                'url': media_data['auth_url'],\n                'ext': media_data.get('type'),\n                'format_id': bitrate,\n                'abr': int(bitrate),\n                'vcodec': 'none',\n            })\n\n        return {\n            'id': audio_id,\n            'formats': formats,\n            **traverse_obj(song_data, {\n                'title': ('title', 'text'),\n                'album': ('album', 'text'),\n                'thumbnail': ('image', 0, {url_or_none}),\n                'duration': ('duration', {int_or_none}),\n                'view_count': ('play_count', {int_or_none}),\n                'release_year': ('year', {int_or_none}),\n                'artists': ('artists', ..., 'name', {str}, all, {orderedSet}),\n            }),\n        }\n\n\nclass JioSaavnAlbumIE(JioSaavnBaseIE):\n    _VALID_URL = r'https?://(?:www\\.)?(?:jio)?saavn\\.com/album/[^/?#]+/(?P<id>[^/?#]+)'\n    _TESTS = [{\n        'url': 'https://www.jiosaavn.com/album/96/buIOjYZDrNA_',\n        'info_dict': {\n            'id': 'buIOjYZDrNA_',\n            'title': '96',\n        },\n        'playlist_count': 10,\n    }]\n\n    def _real_extract(self, url):\n        album_id = self._match_id(url)\n        album_view = self._extract_initial_data(url, album_id)['albumView']\n\n        return self.playlist_from_matches(\n            traverse_obj(album_view, (\n                'modules', lambda _, x: x['key'] == 'list', 'data', ..., 'title', 'action', {str})),\n            album_id, traverse_obj(album_view, ('album', 'title', 'text', {str})), ie=JioSaavnSongIE,\n            getter=lambda x: urljoin('https://www.jiosaavn.com/', x))\n", "path": "yt_dlp/extractor/jiosaavn.py"}]}