Upgrade yt_dlp and download script
This commit is contained in:
@@ -7,15 +7,17 @@ from ..utils import (
|
||||
ExtractorError,
|
||||
UnsupportedError,
|
||||
clean_html,
|
||||
determine_ext,
|
||||
extract_attributes,
|
||||
format_field,
|
||||
get_element_by_class,
|
||||
get_elements_html_by_class,
|
||||
int_or_none,
|
||||
join_nonempty,
|
||||
parse_count,
|
||||
parse_iso8601,
|
||||
traverse_obj,
|
||||
unescapeHTML,
|
||||
urljoin,
|
||||
)
|
||||
|
||||
|
||||
@@ -33,11 +35,11 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
'upload_date': '20191020',
|
||||
'channel_url': 'https://rumble.com/c/WMAR',
|
||||
'channel': 'WMAR',
|
||||
'thumbnail': 'https://sp.rmbl.ws/s8/1/5/M/z/1/5Mz1a.OvCc-small-WMAR-2-News-Latest-Headline.jpg',
|
||||
'thumbnail': r're:https://.+\.jpg',
|
||||
'duration': 234,
|
||||
'uploader': 'WMAR',
|
||||
'live_status': 'not_live',
|
||||
}
|
||||
},
|
||||
}, {
|
||||
'url': 'https://rumble.com/embed/vslb7v',
|
||||
'md5': '7418035de1a30a178b8af34dc2b6a52b',
|
||||
@@ -49,11 +51,11 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
'upload_date': '20220217',
|
||||
'channel_url': 'https://rumble.com/c/CyberTechNews',
|
||||
'channel': 'CTNews',
|
||||
'thumbnail': 'https://sp.rmbl.ws/s8/6/7/i/9/h/7i9hd.OvCc.jpg',
|
||||
'thumbnail': r're:https://.+\.jpg',
|
||||
'duration': 901,
|
||||
'uploader': 'CTNews',
|
||||
'live_status': 'not_live',
|
||||
}
|
||||
},
|
||||
}, {
|
||||
'url': 'https://rumble.com/embed/vunh1h',
|
||||
'info_dict': {
|
||||
@@ -73,33 +75,32 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
{
|
||||
'url': r're:https://.+\.vtt',
|
||||
'name': 'English',
|
||||
'ext': 'vtt'
|
||||
}
|
||||
]
|
||||
'ext': 'vtt',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'params': {'skip_download': True}
|
||||
'params': {'skip_download': True},
|
||||
}, {
|
||||
'url': 'https://rumble.com/embed/v1essrt',
|
||||
'info_dict': {
|
||||
'id': 'v1essrt',
|
||||
'ext': 'mp4',
|
||||
'title': 'startswith:lofi hip hop radio - beats to relax/study',
|
||||
'title': 'startswith:lofi hip hop radio 📚 - beats to relax/study to',
|
||||
'timestamp': 1661519399,
|
||||
'upload_date': '20220826',
|
||||
'channel_url': 'https://rumble.com/c/LofiGirl',
|
||||
'channel': 'Lofi Girl',
|
||||
'thumbnail': r're:https://.+\.jpg',
|
||||
'duration': None,
|
||||
'uploader': 'Lofi Girl',
|
||||
'live_status': 'is_live',
|
||||
},
|
||||
'params': {'skip_download': True}
|
||||
'params': {'skip_download': True},
|
||||
}, {
|
||||
'url': 'https://rumble.com/embed/v1amumr',
|
||||
'info_dict': {
|
||||
'id': 'v1amumr',
|
||||
'ext': 'webm',
|
||||
'ext': 'mp4',
|
||||
'fps': 60,
|
||||
'title': 'Turning Point USA 2022 Student Action Summit DAY 1 - Rumble Exclusive Live',
|
||||
'timestamp': 1658518457,
|
||||
@@ -111,7 +112,23 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
'uploader': 'Rumble Events',
|
||||
'live_status': 'was_live',
|
||||
},
|
||||
'params': {'skip_download': True}
|
||||
'params': {'skip_download': True},
|
||||
}, {
|
||||
'url': 'https://rumble.com/embed/v6pezdb',
|
||||
'info_dict': {
|
||||
'id': 'v6pezdb',
|
||||
'ext': 'mp4',
|
||||
'title': '"Es war einmal ein Mädchen" – Ein filmisches Zeitzeugnis aus Leningrad 1944',
|
||||
'uploader': 'RT DE',
|
||||
'channel': 'RT DE',
|
||||
'channel_url': 'https://rumble.com/c/RTDE',
|
||||
'duration': 309,
|
||||
'thumbnail': 'https://1a-1791.com/video/fww1/dc/s8/1/n/z/2/y/nz2yy.qR4e-small-Es-war-einmal-ein-Mdchen-Ei.jpg',
|
||||
'timestamp': 1743703500,
|
||||
'upload_date': '20250403',
|
||||
'live_status': 'not_live',
|
||||
},
|
||||
'params': {'skip_download': True},
|
||||
}, {
|
||||
'url': 'https://rumble.com/embed/ufe9n.v5pv5f',
|
||||
'only_matching': True,
|
||||
@@ -129,12 +146,12 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
'duration': 92,
|
||||
'title': '911 Audio From The Man Who Wanted To Kill Supreme Court Justice Kavanaugh',
|
||||
'channel_url': 'https://rumble.com/c/RichSementa',
|
||||
'thumbnail': 'https://sp.rmbl.ws/s8/1/P/j/f/A/PjfAe.OvCc-small-911-Audio-From-The-Man-Who-.jpg',
|
||||
'thumbnail': 'https://sp.rmbl.ws/s8/1/P/j/f/A/PjfAe.qR4e-small-911-Audio-From-The-Man-Who-.jpg',
|
||||
'timestamp': 1654892716,
|
||||
'uploader': 'Mr Producer Media',
|
||||
'upload_date': '20220610',
|
||||
'live_status': 'not_live',
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -144,7 +161,7 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
if embeds:
|
||||
return embeds
|
||||
return [f'https://rumble.com/embed/{mobj.group("id")}' for mobj in re.finditer(
|
||||
r'<script>[^<]*\bRumble\(\s*"play"\s*,\s*{\s*[\'"]?video[\'"]?\s*:\s*[\'"](?P<id>[0-9a-z]+)[\'"]', webpage)]
|
||||
r'<script>[^<]*\bRumble\(\s*"play"\s*,\s*{[^}]*[\'"]?video[\'"]?\s*:\s*[\'"](?P<id>[0-9a-z]+)[\'"]', webpage)]
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
@@ -166,40 +183,42 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
live_status = None
|
||||
|
||||
formats = []
|
||||
for ext, ext_info in (video.get('ua') or {}).items():
|
||||
if isinstance(ext_info, dict):
|
||||
for height, video_info in ext_info.items():
|
||||
for format_type, format_info in (video.get('ua') or {}).items():
|
||||
if isinstance(format_info, dict):
|
||||
for height, video_info in format_info.items():
|
||||
if not traverse_obj(video_info, ('meta', 'h', {int_or_none})):
|
||||
video_info.setdefault('meta', {})['h'] = height
|
||||
ext_info = ext_info.values()
|
||||
format_info = format_info.values()
|
||||
|
||||
for video_info in ext_info:
|
||||
for video_info in format_info:
|
||||
meta = video_info.get('meta') or {}
|
||||
if not video_info.get('url'):
|
||||
continue
|
||||
if ext == 'hls':
|
||||
# With default query params returns m3u8 variants which are duplicates, without returns tar files
|
||||
if format_type == 'tar':
|
||||
continue
|
||||
if format_type == 'hls':
|
||||
if meta.get('live') is True and video.get('live') == 1:
|
||||
live_status = 'post_live'
|
||||
formats.extend(self._extract_m3u8_formats(
|
||||
video_info['url'], video_id,
|
||||
ext='mp4', m3u8_id='hls', fatal=False, live=live_status == 'is_live'))
|
||||
continue
|
||||
timeline = ext == 'timeline'
|
||||
if timeline:
|
||||
ext = determine_ext(video_info['url'])
|
||||
is_timeline = format_type == 'timeline'
|
||||
is_audio = format_type == 'audio'
|
||||
formats.append({
|
||||
'ext': ext,
|
||||
'acodec': 'none' if timeline else None,
|
||||
'acodec': 'none' if is_timeline else None,
|
||||
'vcodec': 'none' if is_audio else None,
|
||||
'url': video_info['url'],
|
||||
'format_id': join_nonempty(ext, format_field(meta, 'h', '%sp')),
|
||||
'format_note': 'Timeline' if timeline else None,
|
||||
'fps': None if timeline else video.get('fps'),
|
||||
'format_id': join_nonempty(format_type, format_field(meta, 'h', '%sp')),
|
||||
'format_note': 'Timeline' if is_timeline else None,
|
||||
'fps': None if is_timeline or is_audio else video.get('fps'),
|
||||
**traverse_obj(meta, {
|
||||
'tbr': 'bitrate',
|
||||
'filesize': 'size',
|
||||
'width': 'w',
|
||||
'height': 'h',
|
||||
}, expected_type=lambda x: int(x) or None)
|
||||
'tbr': ('bitrate', {int_or_none}),
|
||||
'filesize': ('size', {int_or_none}),
|
||||
'width': ('w', {int_or_none}),
|
||||
'height': ('h', {int_or_none}),
|
||||
}),
|
||||
})
|
||||
|
||||
subtitles = {
|
||||
@@ -236,7 +255,9 @@ class RumbleEmbedIE(InfoExtractor):
|
||||
|
||||
class RumbleIE(InfoExtractor):
|
||||
_VALID_URL = r'https?://(?:www\.)?rumble\.com/(?P<id>v(?!ideos)[\w.-]+)[^/]*$'
|
||||
_EMBED_REGEX = [r'<a class=video-item--a href=(?P<url>/v[\w.-]+\.html)>']
|
||||
_EMBED_REGEX = [
|
||||
r'<a class=video-item--a href=(?P<url>/v[\w.-]+\.html)>',
|
||||
r'<a[^>]+class="videostream__link link"[^>]+href=(?P<url>/v[\w.-]+\.html)[^>]*>']
|
||||
_TESTS = [{
|
||||
'add_ie': ['RumbleEmbed'],
|
||||
'url': 'https://rumble.com/vdmum1-moose-the-dog-helps-girls-dig-a-snow-fort.html',
|
||||
@@ -254,9 +275,10 @@ class RumbleIE(InfoExtractor):
|
||||
'thumbnail': r're:https://.+\.jpg',
|
||||
'duration': 103,
|
||||
'like_count': int,
|
||||
'dislike_count': int,
|
||||
'view_count': int,
|
||||
'live_status': 'not_live',
|
||||
}
|
||||
},
|
||||
}, {
|
||||
'url': 'http://www.rumble.com/vDMUM1?key=value',
|
||||
'only_matching': True,
|
||||
@@ -278,6 +300,9 @@ class RumbleIE(InfoExtractor):
|
||||
'channel_url': 'https://rumble.com/c/Redacted',
|
||||
'live_status': 'not_live',
|
||||
'thumbnail': 'https://sp.rmbl.ws/s8/1/d/x/2/O/dx2Oi.qR4e-small-The-U.S.-CANNOT-hide-this-i.jpg',
|
||||
'like_count': int,
|
||||
'dislike_count': int,
|
||||
'view_count': int,
|
||||
},
|
||||
}, {
|
||||
'url': 'https://rumble.com/v2e7fju-the-covid-twitter-files-drop-protecting-fauci-while-censoring-the-truth-wma.html',
|
||||
@@ -296,12 +321,15 @@ class RumbleIE(InfoExtractor):
|
||||
'channel_url': 'https://rumble.com/c/KimIversen',
|
||||
'channel': 'Kim Iversen',
|
||||
'thumbnail': 'https://sp.rmbl.ws/s8/1/6/b/w/O/6bwOi.qR4e-small-The-Covid-Twitter-Files-Dro.jpg',
|
||||
'like_count': int,
|
||||
'dislike_count': int,
|
||||
'view_count': int,
|
||||
},
|
||||
}]
|
||||
|
||||
_WEBPAGE_TESTS = [{
|
||||
'url': 'https://rumble.com/videos?page=2',
|
||||
'playlist_count': 25,
|
||||
'playlist_mincount': 24,
|
||||
'info_dict': {
|
||||
'id': 'videos?page=2',
|
||||
'title': 'All videos',
|
||||
@@ -309,17 +337,16 @@ class RumbleIE(InfoExtractor):
|
||||
'age_limit': 0,
|
||||
},
|
||||
}, {
|
||||
'url': 'https://rumble.com/live-videos',
|
||||
'playlist_mincount': 19,
|
||||
'url': 'https://rumble.com/browse/live',
|
||||
'playlist_mincount': 25,
|
||||
'info_dict': {
|
||||
'id': 'live-videos',
|
||||
'title': 'Live Videos',
|
||||
'description': 'Live videos on Rumble.com',
|
||||
'id': 'live',
|
||||
'title': 'Browse',
|
||||
'age_limit': 0,
|
||||
},
|
||||
}, {
|
||||
'url': 'https://rumble.com/search/video?q=rumble&sort=views',
|
||||
'playlist_count': 24,
|
||||
'playlist_mincount': 24,
|
||||
'info_dict': {
|
||||
'id': 'video?q=rumble&sort=views',
|
||||
'title': 'Search results for: rumble',
|
||||
@@ -334,19 +361,20 @@ class RumbleIE(InfoExtractor):
|
||||
if not url_info:
|
||||
raise UnsupportedError(url)
|
||||
|
||||
release_ts_str = self._search_regex(
|
||||
r'(?:Livestream begins|Streamed on):\s+<time datetime="([^"]+)',
|
||||
webpage, 'release date', fatal=False, default=None)
|
||||
view_count_str = self._search_regex(r'<span class="media-heading-info">([\d,]+) Views',
|
||||
webpage, 'view count', fatal=False, default=None)
|
||||
|
||||
return self.url_result(
|
||||
url_info['url'], ie_key=url_info['ie_key'], url_transparent=True,
|
||||
view_count=parse_count(view_count_str),
|
||||
release_timestamp=parse_iso8601(release_ts_str),
|
||||
like_count=parse_count(get_element_by_class('rumbles-count', webpage)),
|
||||
description=clean_html(get_element_by_class('media-description', webpage)),
|
||||
)
|
||||
return {
|
||||
'_type': 'url_transparent',
|
||||
'ie_key': url_info['ie_key'],
|
||||
'url': url_info['url'],
|
||||
'release_timestamp': parse_iso8601(self._search_regex(
|
||||
r'(?:Livestream begins|Streamed on):\s+<time datetime="([^"]+)', webpage, 'release date', default=None)),
|
||||
'view_count': int_or_none(self._search_regex(
|
||||
r'"userInteractionCount"\s*:\s*(\d+)', webpage, 'view count', default=None)),
|
||||
'like_count': parse_count(self._search_regex(
|
||||
r'<span data-js="rumbles_up_votes">\s*([\d,.KM]+)', webpage, 'like count', default=None)),
|
||||
'dislike_count': parse_count(self._search_regex(
|
||||
r'<span data-js="rumbles_down_votes">\s*([\d,.KM]+)', webpage, 'dislike count', default=None)),
|
||||
'description': clean_html(get_element_by_class('media-description', webpage)),
|
||||
}
|
||||
|
||||
|
||||
class RumbleChannelIE(InfoExtractor):
|
||||
@@ -369,13 +397,15 @@ class RumbleChannelIE(InfoExtractor):
|
||||
def entries(self, url, playlist_id):
|
||||
for page in itertools.count(1):
|
||||
try:
|
||||
webpage = self._download_webpage(f'{url}?page={page}', playlist_id, note='Downloading page %d' % page)
|
||||
webpage = self._download_webpage(f'{url}?page={page}', playlist_id, note=f'Downloading page {page}')
|
||||
except ExtractorError as e:
|
||||
if isinstance(e.cause, HTTPError) and e.cause.status == 404:
|
||||
break
|
||||
raise
|
||||
for video_url in re.findall(r'class=video-item--a\s?href=([^>]+\.html)', webpage):
|
||||
yield self.url_result('https://rumble.com' + video_url)
|
||||
for video_url in traverse_obj(
|
||||
get_elements_html_by_class('videostream__link', webpage), (..., {extract_attributes}, 'href'),
|
||||
):
|
||||
yield self.url_result(urljoin('https://rumble.com', video_url))
|
||||
|
||||
def _real_extract(self, url):
|
||||
url, playlist_id = self._match_valid_url(url).groups()
|
||||
|
Reference in New Issue
Block a user