4 from .common
import InfoExtractor
5 from ..compat
import compat_HTTPError
15 class RumbleEmbedIE(InfoExtractor
):
16 _VALID_URL
= r
'https?://(?:www\.)?rumble\.com/embed/(?:[0-9a-z]+\.)?(?P<id>[0-9a-z]+)'
17 _EMBED_REGEX
= [fr
'(?:<(?:script|iframe)[^>]+\bsrc=|["\']embedUrl
["\']\s*:\s*)["\'](?P
<url
>{_VALID_URL}
)']
19 'url
': 'https
://rumble
.com
/embed
/v5pv5f
',
20 'md5
': '36a18a049856720189f30977ccbb2c34
',
24 'title
': 'WMAR
2 News Latest Headlines | October
20, 6pm
',
25 'timestamp
': 1571611968,
26 'upload_date
': '20191020',
27 'channel_url
': 'https
://rumble
.com
/c
/WMAR
',
29 'thumbnail
': 'https
://sp
.rmbl
.ws
/s8
/1/5/M
/z
/1/5Mz1a
.OvCc
-small
-WMAR
-2-News
-Latest
-Headline
.jpg
',
32 'live_status
': 'not_live
',
35 'url
': 'https
://rumble
.com
/embed
/vslb7v
',
36 'md5
': '7418035de1a30a178b8af34dc2b6a52b
',
40 'title
': 'Defense Sec
. says US Commitment to NATO Defense
\'Ironclad
\'',
41 'timestamp
': 1645142135,
42 'upload_date
': '20220217',
43 'channel_url
': 'https
://rumble
.com
/c
/CyberTechNews
',
45 'thumbnail
': 'https
://sp
.rmbl
.ws
/s8
/6/7/i
/9/h
/7i9hd
.OvCc
.jpg
',
48 'live_status
': 'not_live
',
51 'url
': 'https
://rumble
.com
/embed
/vunh1h
',
55 'title
': '‘Gideon
, op zoek naar de waarheid’ including ENG SUBS
',
56 'timestamp
': 1647197663,
57 'upload_date
': '20220313',
58 'channel_url
': 'https
://rumble
.com
/user
/BLCKBX
',
60 'thumbnail
': r're
:https
://.+\
.jpg
',
63 'live_status
': 'not_live
',
67 'url
': r're
:https
://.+\
.vtt
',
74 'params
': {'skip_download': True}
76 'url
': 'https
://rumble
.com
/embed
/v1essrt
',
80 'title
': 'startswith
:lofi hip hop radio
- beats to relax
/study
',
81 'timestamp
': 1661519399,
82 'upload_date
': '20220826',
83 'channel_url
': 'https
://rumble
.com
/c
/LofiGirl
',
84 'channel
': 'Lofi Girl
',
85 'thumbnail
': r're
:https
://.+\
.jpg
',
87 'uploader
': 'Lofi Girl
',
88 'live_status
': 'is_live
',
90 'params
': {'skip_download': True}
92 'url
': 'https
://rumble
.com
/embed
/v1amumr
',
97 'title
': 'Turning Point USA
2022 Student Action Summit DAY
1 - Rumble Exclusive Live
',
98 'timestamp
': 1658518457,
99 'upload_date
': '20220722',
100 'channel_url
': 'https
://rumble
.com
/c
/RumbleEvents
',
101 'channel
': 'Rumble Events
',
102 'thumbnail
': r're
:https
://.+\
.jpg
',
104 'uploader
': 'Rumble Events
',
105 'live_status
': 'was_live
',
107 'params
': {'skip_download': True}
109 'url
': 'https
://rumble
.com
/embed
/ufe9n
.v5pv5f
',
110 'only_matching
': True,
115 'note
': 'Rumble embed
',
116 'url
': 'https
://rumble
.com
/vdmum1
-moose
-the
-dog
-helps
-girls
-dig
-a
-snow
-fort
.html
',
117 'md5
': '53af34098a7f92c4e51cf0bd1c33f009
',
121 'timestamp
': 1612662578,
122 'uploader
': 'LovingMontana
',
123 'channel
': 'LovingMontana
',
124 'upload_date
': '20210207',
125 'title
': 'Winter
-loving dog helps girls dig a snow fort
',
126 'channel_url
': 'https
://rumble
.com
/c
/c
-546523',
127 'thumbnail
': 'https
://sp
.rmbl
.ws
/s8
/1/5/f
/x
/x
/5fxxb
.OvCc
.1-small
-Moose
-The
-Dog
-Helps
-Girls
-D
.jpg
',
129 'live_status
': 'not_live
',
133 'note
': 'Rumble JS embed
',
134 'url
': 'https
://therightscoop
.com
/what
-does
-9-plus
-1-plus
-1-equal
-listen
-to
-this
-audio
-of
-attempted
-kavanaugh
-assassins
-call
-and-youll
-get
-it
',
135 'md5
': '4701209ac99095592e73dbba21889690
',
139 'channel
': 'Mr Producer Media
',
141 'title
': '911 Audio From The Man Who Wanted To Kill Supreme Court Justice Kavanaugh
',
142 'channel_url
': 'https
://rumble
.com
/c
/RichSementa
',
143 'thumbnail
': 'https
://sp
.rmbl
.ws
/s8
/1/P
/j
/f
/A
/PjfAe
.OvCc
-small
-911-Audio
-From
-The
-Man
-Who
-.jpg
',
144 'timestamp
': 1654892716,
145 'uploader
': 'Mr Producer Media
',
146 'upload_date
': '20220610',
147 'live_status
': 'not_live
',
153 def _extract_embed_urls(cls, url, webpage):
154 embeds = tuple(super()._extract_embed_urls(url, webpage))
157 return [f'https
://rumble
.com
/embed
/{mobj.group("id")}
' for mobj in re.finditer(
158 r'<script
>\s
*Rumble\
(\s
*"play"\s
*,\s
*{\s
*[\'"]video[\'"]\s
*:\s
*[\'"](?P<id>[0-9a-z]+)[\'"]', webpage)]
160 def _real_extract(self, url):
161 video_id = self._match_id(url)
162 video = self._download_json(
163 'https
://rumble
.com
/embedJS
/u3
/', video_id,
164 query={'request': 'video', 'ver': 2, 'v': video_id})
166 sys_msg = traverse_obj(video, ('sys
', 'msg
'))
168 self.report_warning(sys_msg, video_id=video_id)
170 if video.get('live
') == 0:
171 live_status = 'not_live
' if video.get('livestream_has_dvr
') is None else 'was_live
'
172 elif video.get('live
') == 1:
173 live_status = 'is_upcoming
' if video.get('livestream_has_dvr
') else 'was_live
'
174 elif video.get('live
') == 2:
175 live_status = 'is_live
'
180 for ext, ext_info in (video.get('ua
') or {}).items():
181 for height, video_info in (ext_info or {}).items():
182 meta = video_info.get('meta
') or {}
183 if not video_info.get('url
'):
186 if meta.get('live
') is True and video.get('live
') == 1:
187 live_status = 'post_live
'
188 formats.extend(self._extract_m3u8_formats(
189 video_info['url
'], video_id,
190 ext='mp4
', m3u8_id='hls
', fatal=False, live=live_status == 'is_live
'))
194 'url
': video_info['url
'],
195 'format_id
': '%s-%sp
' % (ext, height),
196 'height
': int_or_none(height),
197 'fps
': video.get('fps
'),
198 **traverse_obj(meta, {
208 'url
': sub_info['path
'],
209 'name
': sub_info.get('language
') or '',
210 }] for lang, sub_info in (video.get('cc
') or {}).items() if sub_info.get('path
')
213 author = video.get('author
') or {}
214 thumbnails = traverse_obj(video, ('t
', ..., {'url': 'i', 'width': 'w', 'height': 'h'}))
215 if not thumbnails and video.get('i
'):
216 thumbnails = [{'url': video['i']}]
218 if live_status in {'is_live', 'post_live'}:
221 duration = int_or_none(video.get('duration
'))
225 'title
': unescapeHTML(video.get('title
')),
227 'subtitles
': subtitles,
228 'thumbnails
': thumbnails,
229 'timestamp
': parse_iso8601(video.get('pubDate
')),
230 'channel
': author.get('name
'),
231 'channel_url
': author.get('url
'),
232 'duration
': duration,
233 'uploader
': author.get('name
'),
234 'live_status
': live_status,
238 class RumbleChannelIE(InfoExtractor):
239 _VALID_URL = r'(?P
<url
>https?
://(?
:www\
.)?rumble\
.com
/(?
:c|user
)/(?P
<id>[^
&?
#$/]+))'
242 'url': 'https://rumble.com/c/Styxhexenhammer666',
243 'playlist_mincount': 1160,
245 'id': 'Styxhexenhammer666',
248 'url': 'https://rumble.com/user/goldenpoodleharleyeuna',
249 'playlist_mincount': 4,
251 'id': 'goldenpoodleharleyeuna',
255 def entries(self
, url
, playlist_id
):
256 for page
in itertools
.count(1):
258 webpage
= self
._download
_webpage
(f
'{url}?page={page}', playlist_id
, note
='Downloading page %d' % page
)
259 except ExtractorError
as e
:
260 if isinstance(e
.cause
, compat_HTTPError
) and e
.cause
.code
== 404:
263 for video_url
in re
.findall(r
'class=video-item--a\s?href=([^>]+\.html)', webpage
):
264 yield self
.url_result('https://rumble.com' + video_url
)
266 def _real_extract(self
, url
):
267 url
, playlist_id
= self
._match
_valid
_url
(url
).groups()
268 return self
.playlist_result(self
.entries(url
, playlist_id
), playlist_id
=playlist_id
)