Repository: yt-dlp/yt-dlp

Issue:
[YouTube] YouTube audios
### 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 requesting a site-specific feature
- [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 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)
- [ ] 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

California, USA

### Example URLs

https://youtu.be/2GtVksBMYFM
https://youtu.be/Lyj-MZSAA9o
https://youtube.com/shorts/OgEdGWmlRh8?feature=share

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

YouTube on mobile provides a feature to make shorts with “sounds” and view existing shorts with sounds on them. Please add support for downloading a list of shorts using a videos sounds. As YouTube does not provide a way to view sounds in HTML5, even on mobile HTML5 and grab their URL, we need to put it like ytsound:https://youtu.be/2GtVksBMYFM




### 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
[Documents]$ yt-dlp -vU ytsound:https://youtu.b
e/2GtVksBMYFMG -s 
[debug] Command-line config: ['-vU', 'ytsound:h
ttps://youtu.be/2GtVksBMYFMG', '-s']
[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] (pi
p)
[debug] Python 3.9.10+ (CPython 64bit) - macOS-
15.4.1-iPhone14,5-arm-64bit 
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: ffprobe -bsfs
[debug] exe versions: ffmpeg n5.0.1-4-ga5ebb3d2
5e (setts), ffprobe n5.0.1-4-ga5ebb3d25e, phant
omjs present, rtmpdump present
[debug] Optional libraries: Crypto-3.15.0, cert
ifi-2022.06.15, mutagen-1.45.1, sqlite3-2.6.0, 
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] [generic] Extracting URL: ytsound:https://youtu.be/2GtVksBMYFMG
[generic] 2GtVksBMYFMG: Downloading webpage
ERROR: [generic] Unable to download webpage: <urlopen error unknown url type: ytsound> (caused by URLError('unknown url type: ytsound'))
  File "/var/mobile/Containers/Data/Application/87BE3170-A2E1-4D77-98F2-3C7FE2FA6E42/Library/lib/python3.9/site-packages/yt_dlp/extractor/common.py", line 670, in extract
    ie_result = self._real_extract(url)
  File "/var/mobile/Containers/Data/Application/87BE3170-A2E1-4D77-98F2-3C7FE2FA6E42/Library/lib/python3.9/site-packages/yt_dlp/extractor/generic.py", line 2641, in _real_extract
    full_response = self._request_webpage(url, video_id, headers={'Accept-Encoding': '*'})
  File "/var/mobile/Containers/Data/Application/87BE3170-A2E1-4D77-98F2-3C7FE2FA6E42/Library/lib/python3.9/site-packages/yt_dlp/extractor/common.py", line 821, in _request_webpage
    raise ExtractorError(errmsg, cause=err)

  File "/var/mobile/Containers/Data/Application/87BE3170-A2E1-4D77-98F2-3C7FE2FA6E42/Library/lib/python3.9/site-packages/yt_dlp/extractor/common.py", line 803, in _request_webpage
    return self._downloader.urlopen(self._create_request(url_or_request, data, headers, query))
  File "/var/mobile/Containers/Data/Application/87BE3170-A2E1-4D77-98F2-3C7FE2FA6E42/Library/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3656, in urlopen
    return self._opener.open(req, timeout=self._socket_timeout)
  File "/private/var/containers/Bundle/Application/4A7D25F8-7CF3-49FE-B87D-003CD121D26C/a-Shell-mini.app/Library/lib/python3.9/urllib/request.py", line 517, in open
    response = self._open(req, data)
  File "/private/var/containers/Bundle/Application/4A7D25F8-7CF3-49FE-B87D-003CD121D26C/a-Shell-mini.app/Library/lib/python3.9/urllib/request.py", line 539, in _open
    return self._call_chain(self.handle_open, 'unknown',
  File "/private/var/containers/Bundle/Application/4A7D25F8-7CF3-49FE-B87D-003CD121D26C/a-Shell-mini.app/Library/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/private/var/containers/Bundle/Application/4A7D25F8-7CF3-49FE-B87D-003CD121D26C/a-Shell-mini.app/Library/lib/python3.9/urllib/request.py", line 1417, in unknown_open
    raise URLError('unknown url type: %s' % type)
urllib.error.URLError: <urlopen error unknown url type: ytsound>
[
```



Discussion:

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
@@ -21,6 +21,7 @@
     YoutubeYtBeIE,
     YoutubeYtUserIE,
     YoutubeWatchLaterIE,
+    YoutubeShortsAudioPivotIE
 )
 
 from .abc import (
diff --git a/yt_dlp/extractor/youtube.py b/yt_dlp/extractor/youtube.py
--- a/yt_dlp/extractor/youtube.py
+++ b/yt_dlp/extractor/youtube.py
@@ -4327,8 +4327,8 @@ def _playlist_entries(self, video_list_renderer):
             yield self._extract_video(renderer)
 
     def _rich_entries(self, rich_grid_renderer):
-        renderer = try_get(
-            rich_grid_renderer, lambda x: x['content']['videoRenderer'], dict) or {}
+        renderer = traverse_obj(
+            rich_grid_renderer, ('content', ('videoRenderer', 'reelItemRenderer')), get_all=False) or {}
         video_id = renderer.get('videoId')
         if not video_id:
             return
@@ -5640,6 +5640,16 @@ class YoutubeTabIE(YoutubeTabBaseInfoExtractor):
         'playlist_mincount': 1,
         'params': {'extractor_args': {'youtube': {'lang': ['ja']}}},
         'expected_warnings': ['Preferring "ja"'],
+    }, {
+        # shorts audio pivot for 2GtVksBMYFM.
+        'url': 'https://www.youtube.com/feed/sfv_audio_pivot?bp=8gUrCikSJwoLMkd0VmtzQk1ZRk0SCzJHdFZrc0JNWUZNGgsyR3RWa3NCTVlGTQ==',
+        'info_dict': {
+            'id': 'sfv_audio_pivot',
+            'title': 'sfv_audio_pivot',
+            'tags': [],
+        },
+        'playlist_mincount': 50,
+
     }]
 
     @classmethod
@@ -6307,6 +6317,33 @@ def _real_extract(self, url):
             ie=YoutubeTabIE, video_id=playlist_id)
 
 
+class YoutubeShortsAudioPivotIE(InfoExtractor):
+    IE_DESC = 'YouTube Shorts audio pivot (Shorts using audio of a given video); "ytshortsap:" prefix'
+    IE_NAME = 'youtube:shorts:pivot:audio'
+    _VALID_URL = f'(?x)^ytshortsap:{YoutubeIE._VALID_URL[5:]}'
+    _TESTS = [{
+        'url': 'ytshortsap:https://www.youtube.com/shorts/Lyj-MZSAA9o?feature=share',
+        'only_matching': True,
+    }, {
+        'url': 'ytshortsap:Lyj-MZSAA9o',
+        'only_matching': True,
+    }]
+
+    @staticmethod
+    def _generate_audio_pivot_params(video_id):
+        """
+        Generates sfv_audio_pivot browse params for this video id
+        """
+        pb_params = b'\xf2\x05+\n)\x12\'\n\x0b%b\x12\x0b%b\x1a\x0b%b' % ((video_id.encode(),) * 3)
+        return urllib.parse.quote(base64.b64encode(pb_params).decode())
+
+    def _real_extract(self, url):
+        video_id = self._match_id(url)
+        return self.url_result(
+            f'https://www.youtube.com/feed/sfv_audio_pivot?bp={self._generate_audio_pivot_params(video_id)}',
+            ie=YoutubeTabIE)
+
+
 class YoutubeTruncatedURLIE(InfoExtractor):
     IE_NAME = 'youtube:truncated_url'
     IE_DESC = False  # Do not list


Test patch: