mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-21 20:46:36 -05:00
parent
3975b4d2e8
commit
471d0367c7
2 changed files with 35 additions and 5 deletions
|
@ -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]`
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue