[youtube:clips] Support downloading clips

Closes #2543
This commit is contained in:
pukkandan 2022-06-22 02:45:05 +05:30
parent 3975b4d2e8
commit 471d0367c7
No known key found for this signature in database
GPG key ID: 7EEE9E1E817D0A39
2 changed files with 35 additions and 5 deletions

View file

@ -90,6 +90,7 @@ # NEW FEATURES
* Youtube music Albums, channels etc can be downloaded ([except self-uploaded music](https://github.com/yt-dlp/yt-dlp/issues/723)) * Youtube music Albums, channels etc can be downloaded ([except self-uploaded music](https://github.com/yt-dlp/yt-dlp/issues/723))
* Download livestreams from the start using `--live-from-start` (experimental) * Download livestreams from the start using `--live-from-start` (experimental)
* Support for downloading stories (`ytstories:<channel UCID>`) * Support for downloading stories (`ytstories:<channel UCID>`)
* Support for downloading clips
* **Cookies from browser**: Cookies can be automatically extracted from all major web browsers using `--cookies-from-browser BROWSER[+KEYRING][:PROFILE]` * **Cookies from browser**: Cookies can be automatically extracted from all major web browsers using `--cookies-from-browser BROWSER[+KEYRING][:PROFILE]`

View file

@ -5978,14 +5978,43 @@ def _real_extract(self, url):
expected=True) expected=True)
class YoutubeClipIE(InfoExtractor): class YoutubeClipIE(YoutubeTabBaseInfoExtractor):
IE_NAME = 'youtube:clip' IE_NAME = 'youtube:clip'
IE_DESC = False # Do not list _VALID_URL = r'https?://(?:www\.)?youtube\.com/clip/(?P<id>[^/?#]+)'
_VALID_URL = r'https?://(?:www\.)?youtube\.com/clip/' _TESTS = [{
# FIXME: Other metadata should be extracted from the clip, not from the base video
'url': 'https://www.youtube.com/clip/UgytZKpehg-hEMBSn3F4AaABCQ',
'info_dict': {
'id': 'UgytZKpehg-hEMBSn3F4AaABCQ',
'ext': 'mp4',
'section_start': 29.0,
'section_end': 39.7,
'duration': 10.7,
}
}]
def _real_extract(self, url): def _real_extract(self, url):
self.report_warning('YouTube clips are not currently supported. The entire video will be downloaded instead') clip_id = self._match_id(url)
return self.url_result(url, 'Generic') _, data = self._extract_webpage(url, clip_id)
video_id = traverse_obj(data, ('currentVideoEndpoint', 'watchEndpoint', 'videoId'))
if not video_id:
raise ExtractorError('Unable to find video ID')
clip_data = traverse_obj(data, (
'engagementPanels', ..., 'engagementPanelSectionListRenderer', 'content', 'clipSectionRenderer',
'contents', ..., 'clipAttributionRenderer', 'onScrubExit', 'commandExecutorCommand', 'commands', ...,
'openPopupAction', 'popup', 'notificationActionRenderer', 'actionButton', 'buttonRenderer', 'command',
'commandExecutorCommand', 'commands', ..., 'loopCommand'), get_all=False)
return {
'_type': 'url_transparent',
'url': f'https://www.youtube.com/watch?v={video_id}',
'ie_key': YoutubeIE.ie_key(),
'id': clip_id,
'section_start': int(clip_data['startTimeMs']) / 1000,
'section_end': int(clip_data['endTimeMs']) / 1000,
}
class YoutubeTruncatedIDIE(InfoExtractor): class YoutubeTruncatedIDIE(InfoExtractor):