]> jfr.im git - yt-dlp.git/blame - yt_dlp/extractor/generic.py
[docs] Improvements
[yt-dlp.git] / yt_dlp / extractor / generic.py
CommitLineData
9b122384
PH
1import os
2import re
f9934b96 3import xml.etree.ElementTree
9b122384 4
f8271158 5from .ant1newsgr import Ant1NewsGrEmbedIE
6from .anvato import AnvatoIE
7from .apa import APAIE
8from .arcpublishing import ArcPublishingIE
9from .arkena import ArkenaIE
10from .arte import ArteTVEmbedIE
11from .bitchute import BitChuteIE
12from .blogger import BloggerIE
13from .brightcove import BrightcoveLegacyIE, BrightcoveNewIE
14from .channel9 import Channel9IE
15from .cloudflarestream import CloudflareStreamIE
9b122384 16from .common import InfoExtractor
f8271158 17from .commonprotocols import RtmpIE
18from .condenast import CondeNastIE
19from .dailymail import DailyMailIE
20from .dailymotion import DailymotionIE
21from .dbtv import DBTVIE
22from .digiteka import DigitekaIE
23from .drtuber import DrTuberIE
24from .eagleplatform import EaglePlatformIE
25from .ertgr import ERTWebtvEmbedIE
26from .expressen import ExpressenIE
27from .facebook import FacebookIE
28from .foxnews import FoxNewsIE
29from .gedidigital import GediDigitalIE
30from .gfycat import GfycatIE
31from .glomex import GlomexEmbedIE
32from .googledrive import GoogleDriveIE
33from .indavideo import IndavideoEmbedIE
34from .instagram import InstagramIE
35from .joj import JojIE
36from .jwplatform import JWPlatformIE
37from .kaltura import KalturaIE
38from .kinja import KinjaEmbedIE
39from .limelight import LimelightBaseIE
40from .mainstreaming import MainStreamingIE
41from .medialaan import MedialaanIE
42from .mediaset import MediasetIE
43from .mediasite import MediasiteIE
44from .megaphone import MegaphoneIE
45from .megatvcom import MegaTVComEmbedIE
46from .mofosex import MofosexEmbedIE
47from .mtv import MTVServicesEmbeddedIE
48from .myvi import MyviIE
49from .nbc import NBCSportsVPlayerIE
50from .nexx import NexxEmbedIE, NexxIE
51from .odnoklassniki import OdnoklassnikiIE
52from .onionstudios import OnionStudiosIE
53from .ooyala import OoyalaIE
54from .panopto import PanoptoBaseIE
55from .peertube import PeerTubeIE
56from .piksel import PikselIE
57from .pladform import PladformIE
58from .pornhub import PornHubIE
59from .rcs import RCSEmbedsIE
60from .redtube import RedTubeIE
61from .rumble import RumbleEmbedIE
62from .rutube import RutubeIE
63from .rutv import RUTVIE
64from .ruutu import RuutuIE
65from .senategov import SenateISVPIE
66from .simplecast import SimplecastIE
67from .soundcloud import SoundcloudEmbedIE
68from .spankwire import SpankwireIE
69from .sportbox import SportBoxIE
a49e777d 70from .spotify import SpotifyBaseIE
f8271158 71from .springboardplatform import SpringboardPlatformIE
612e31f5 72from .substack import SubstackIE
f8271158 73from .svt import SVTIE
74from .teachable import TeachableIE
75from .ted import TedEmbedIE
76from .theplatform import ThePlatformIE
77from .threeqsdn import ThreeQSDNIE
b801cd71 78from .tiktok import TikTokIE
f8271158 79from .tnaflix import TNAFlixNetworkEmbedIE
80from .tube8 import Tube8IE
81from .tunein import TuneInBaseIE
82from .tvc import TVCIE
83from .tvopengr import TVOpenGrEmbedIE
84from .tvp import TVPEmbedIE
85from .twentymin import TwentyMinutenIE
86from .udn import UDNEmbedIE
87from .ustream import UstreamIE
88from .vbox7 import Vbox7IE
89from .vice import ViceIE
90from .videa import VideaIE
91from .videomore import VideomoreIE
92from .videopress import VideoPressIE
93from .viewlift import ViewLiftEmbedIE
94from .vimeo import VHXEmbedIE, VimeoIE
95from .viqeo import ViqeoIE
96from .vk import VKIE
97from .vshare import VShareIE
98from .vzaar import VzaarIE
99from .washingtonpost import WashingtonPostIE
100from .webcaster import WebcasterFeedIE
101from .wimtv import WimTVIE
102from .wistia import WistiaIE
103from .xfileshare import XFileShareIE
104from .xhamster import XHamsterEmbedIE
105from .yapfiles import YapFilesIE
106from .youporn import YouPornIE
fc9713a1 107from .youtube import YoutubeIE
f8271158 108from .zype import ZypeIE
8c25f81b 109from ..compat import (
f7854627 110 compat_etree_fromstring,
4e363703 111 compat_str,
1ddb9456 112 compat_urllib_parse_unquote,
a5caba1e 113 compat_urlparse,
8c25f81b
PH
114)
115from ..utils import (
f8271158 116 KNOWN_EXTENSIONS,
117 ExtractorError,
118 HEADRequest,
119 UnsupportedError,
b759a0d4 120 determine_ext,
c2d2ee40 121 dict_get,
c8e9a235 122 float_or_none,
c76eb41b 123 int_or_none,
61ca9a80 124 is_html,
a4a554a7 125 js_to_json,
6cc62232 126 merge_dicts,
63d990d2 127 mimetype2ext,
ed2d6a19 128 orderedSet,
c76eb41b 129 parse_duration,
11c86170 130 parse_resolution,
5c2266df 131 sanitized_Request,
9d4660ca 132 smuggle_url,
c2d2ee40 133 str_or_none,
d6bf1161 134 try_call,
9d4660ca 135 unescapeHTML,
29f7c58a 136 unified_timestamp,
4d54ef20 137 unsmuggle_url,
29f7c58a 138 url_or_none,
139 xpath_attr,
76c73715 140 xpath_text,
c76eb41b 141 xpath_with_ns,
9b122384
PH
142)
143
0838239e 144
9b122384 145class GenericIE(InfoExtractor):
79649588 146 IE_DESC = 'Generic downloader that works on some sites'
9b122384 147 _VALID_URL = r'.*'
79649588 148 IE_NAME = 'generic'
52efa4b3 149 _NETRC_MACHINE = False # Supress username warning
cfe50f04 150 _TESTS = [
c5fa81fe
S
151 # Direct link to a video
152 {
153 'url': 'http://media.w3.org/2010/05/sintel/trailer.mp4',
154 'md5': '67d406c2bcb6af27fa886f31aa934bbe',
155 'info_dict': {
156 'id': 'trailer',
157 'ext': 'mp4',
158 'title': 'trailer',
159 'upload_date': '20100513',
160 }
161 },
c5138a7c 162 # Direct link to media delivered compressed (until Accept-Encoding is *)
c5fa81fe
S
163 {
164 'url': 'http://calimero.tk/muzik/FictionJunction-Parallel_Hearts.flac',
165 'md5': '128c42e68b13950268b648275386fc74',
166 'info_dict': {
167 'id': 'FictionJunction-Parallel_Hearts',
168 'ext': 'flac',
169 'title': 'FictionJunction-Parallel_Hearts',
170 'upload_date': '20140522',
171 },
172 'expected_warnings': [
173 'URL could be a direct video link, returning it as such.'
39efc6e3
YCH
174 ],
175 'skip': 'URL invalid',
c5fa81fe
S
176 },
177 # Direct download with broken HEAD
178 {
179 'url': 'http://ai-radio.org:8000/radio.opus',
180 'info_dict': {
181 'id': 'radio',
182 'ext': 'opus',
183 'title': 'radio',
184 },
185 'params': {
186 'skip_download': True, # infinite live stream
187 },
188 'expected_warnings': [
ef0e4e7b
YCH
189 r'501.*Not Implemented',
190 r'400.*Bad Request',
c5fa81fe
S
191 ],
192 },
193 # Direct link with incorrect MIME type
194 {
195 'url': 'http://ftp.nluug.nl/video/nluug/2014-11-20_nj14/zaal-2/5_Lennart_Poettering_-_Systemd.webm',
196 'md5': '4ccbebe5f36706d85221f204d7eb5913',
197 'info_dict': {
198 'url': 'http://ftp.nluug.nl/video/nluug/2014-11-20_nj14/zaal-2/5_Lennart_Poettering_-_Systemd.webm',
199 'id': '5_Lennart_Poettering_-_Systemd',
200 'ext': 'webm',
201 'title': '5_Lennart_Poettering_-_Systemd',
202 'upload_date': '20141120',
203 },
204 'expected_warnings': [
205 'URL could be a direct video link, returning it as such.'
206 ]
207 },
208 # RSS feed
209 {
210 'url': 'http://phihag.de/2014/youtube-dl/rss2.xml',
211 'info_dict': {
2068a603 212 'id': 'https://phihag.de/2014/youtube-dl/rss2.xml',
c5fa81fe
S
213 'title': 'Zero Punctuation',
214 'description': 're:.*groundbreaking video review series.*'
215 },
216 'playlist_mincount': 11,
217 },
218 # RSS feed with enclosure
219 {
220 'url': 'http://podcastfeeds.nbcnews.com/audio/podcast/MSNBC-MADDOW-NETCAST-M4V.xml',
221 'info_dict': {
29f7c58a 222 'id': 'http://podcastfeeds.nbcnews.com/nbcnews/video/podcast/MSNBC-MADDOW-NETCAST-M4V.xml',
223 'title': 'MSNBC Rachel Maddow (video)',
224 'description': 're:.*her unique approach to storytelling.*',
225 },
226 'playlist': [{
227 'info_dict': {
228 'ext': 'mov',
229 'id': 'pdv_maddow_netcast_mov-12-03-2020-223726',
230 'title': 'MSNBC Rachel Maddow (video) - 12-03-2020-223726',
231 'description': 're:.*her unique approach to storytelling.*',
232 'upload_date': '20201204',
233 },
234 }],
235 },
236 # RSS feed with item with description and thumbnails
237 {
238 'url': 'https://anchor.fm/s/dd00e14/podcast/rss',
239 'info_dict': {
240 'id': 'https://anchor.fm/s/dd00e14/podcast/rss',
241 'title': 're:.*100% Hydrogen.*',
242 'description': 're:.*In this episode.*',
243 },
244 'playlist': [{
245 'info_dict': {
246 'ext': 'm4a',
247 'id': 'c1c879525ce2cb640b344507e682c36d',
248 'title': 're:Hydrogen!',
249 'description': 're:.*In this episode we are going.*',
250 'timestamp': 1567977776,
251 'upload_date': '20190908',
252 'duration': 459,
253 'thumbnail': r're:^https?://.*\.jpg$',
254 'episode_number': 1,
255 'season_number': 1,
256 'age_limit': 0,
2068a603
B
257 'season': 'Season 1',
258 'direct': True,
259 'episode': 'Episode 1',
29f7c58a 260 },
261 }],
262 'params': {
263 'skip_download': True,
264 },
c5fa81fe 265 },
01aec848
BG
266 # RSS feed with enclosures and unsupported link URLs
267 {
268 'url': 'http://www.hellointernet.fm/podcast?format=rss',
269 'info_dict': {
270 'id': 'http://www.hellointernet.fm/podcast?format=rss',
271 'description': 'CGP Grey and Brady Haran talk about YouTube, life, work, whatever.',
272 'title': 'Hello Internet',
273 },
274 'playlist_mincount': 100,
275 },
2068a603
B
276 # RSS feed with guid
277 {
278 'url': 'https://www.omnycontent.com/d/playlist/a7b4f8fe-59d9-4afc-a79a-a90101378abf/bf2c1d80-3656-4449-9d00-a903004e8f84/efbff746-e7c1-463a-9d80-a903004e8f8f/podcast.rss',
279 'info_dict': {
280 'id': 'https://www.omnycontent.com/d/playlist/a7b4f8fe-59d9-4afc-a79a-a90101378abf/bf2c1d80-3656-4449-9d00-a903004e8f84/efbff746-e7c1-463a-9d80-a903004e8f8f/podcast.rss',
281 'description': 'md5:be809a44b63b0c56fb485caf68685520',
282 'title': 'The Little Red Podcast',
283 },
284 'playlist_mincount': 76,
285 },
8765222d
S
286 # SMIL from http://videolectures.net/promogram_igor_mekjavic_eng
287 {
288 'url': 'http://videolectures.net/promogram_igor_mekjavic_eng/video/1/smil.xml',
289 'info_dict': {
290 'id': 'smil',
291 'ext': 'mp4',
292 'title': 'Automatics, robotics and biocybernetics',
293 'description': 'md5:815fc1deb6b3a2bff99de2d5325be482',
e327b736 294 'upload_date': '20130627',
8765222d
S
295 'formats': 'mincount:16',
296 'subtitles': 'mincount:1',
297 },
298 'params': {
299 'force_generic_extractor': True,
300 'skip_download': True,
301 },
302 },
303 # SMIL from http://www1.wdr.de/mediathek/video/livestream/index.html
304 {
305 'url': 'http://metafilegenerator.de/WDR/WDR_FS/hds/hds.smil',
306 'info_dict': {
307 'id': 'hds',
308 'ext': 'flv',
309 'title': 'hds',
310 'formats': 'mincount:1',
311 },
312 'params': {
313 'skip_download': True,
314 },
315 },
316 # SMIL from https://www.restudy.dk/video/play/id/1637
317 {
318 'url': 'https://www.restudy.dk/awsmedia/SmilDirectory/video_1637.xml',
319 'info_dict': {
320 'id': 'video_1637',
321 'ext': 'flv',
322 'title': 'video_1637',
323 'formats': 'mincount:3',
324 },
325 'params': {
326 'skip_download': True,
327 },
328 },
329 # SMIL from http://adventure.howstuffworks.com/5266-cool-jobs-iditarod-musher-video.htm
330 {
331 'url': 'http://services.media.howstuffworks.com/videos/450221/smil-service.smil',
332 'info_dict': {
333 'id': 'smil-service',
334 'ext': 'flv',
335 'title': 'smil-service',
336 'formats': 'mincount:1',
337 },
338 'params': {
339 'skip_download': True,
340 },
341 },
342 # SMIL from http://new.livestream.com/CoheedandCambria/WebsterHall/videos/4719370
343 {
344 'url': 'http://api.new.livestream.com/accounts/1570303/events/1585861/videos/4719370.smil',
345 'info_dict': {
346 'id': '4719370',
347 'ext': 'mp4',
348 'title': '571de1fd-47bc-48db-abf9-238872a58d1f',
349 'formats': 'mincount:3',
350 },
351 'params': {
352 'skip_download': True,
353 },
354 },
1de5cd3b
S
355 # XSPF playlist from http://www.telegraaf.nl/tv/nieuws/binnenland/24353229/__Tikibad_ontruimd_wegens_brand__.html
356 {
357 'url': 'http://www.telegraaf.nl/xml/playlist/2015/8/7/mZlp2ctYIUEB.xspf',
358 'info_dict': {
359 'id': 'mZlp2ctYIUEB',
360 'ext': 'mp4',
361 'title': 'Tikibad ontruimd wegens brand',
362 'description': 'md5:05ca046ff47b931f9b04855015e163a4',
ec85ded8 363 'thumbnail': r're:^https?://.*\.jpg$',
1de5cd3b
S
364 'duration': 33,
365 },
366 'params': {
367 'skip_download': True,
368 },
369 },
9d939cec
S
370 # MPD from http://dash-mse-test.appspot.com/media.html
371 {
372 'url': 'http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-manifest.mpd',
373 'md5': '4b57baab2e30d6eb3a6a09f0ba57ef53',
374 'info_dict': {
375 'id': 'car-20120827-manifest',
376 'ext': 'mp4',
377 'title': 'car-20120827-manifest',
378 'formats': 'mincount:9',
0738187f 379 'upload_date': '20130904',
9d939cec 380 },
9d939cec 381 },
20938f76
S
382 # m3u8 served with Content-Type: audio/x-mpegURL; charset=utf-8
383 {
384 'url': 'http://once.unicornmedia.com/now/master/playlist/bb0b18ba-64f5-4b1b-a29f-0ac252f06b68/77a785f3-5188-4806-b788-0893a61634ed/93677179-2d99-4ef4-9e17-fe70d49abfbf/content.m3u8',
385 'info_dict': {
386 'id': 'content',
387 'ext': 'mp4',
388 'title': 'content',
389 'formats': 'mincount:8',
390 },
391 'params': {
392 # m3u8 downloads
393 'skip_download': True,
39efc6e3
YCH
394 },
395 'skip': 'video gone',
20938f76 396 },
edd9b71c
S
397 # m3u8 served with Content-Type: text/plain
398 {
399 'url': 'http://www.nacentapps.com/m3u8/index.m3u8',
400 'info_dict': {
401 'id': 'index',
402 'ext': 'mp4',
403 'title': 'index',
404 'upload_date': '20140720',
405 'formats': 'mincount:11',
406 },
407 'params': {
408 # m3u8 downloads
409 'skip_download': True,
39efc6e3
YCH
410 },
411 'skip': 'video gone',
edd9b71c 412 },
c5fa81fe
S
413 # google redirect
414 {
415 'url': 'http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCUQtwIwAA&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DcmQHVoWB5FY&ei=F-sNU-LLCaXk4QT52ICQBQ&usg=AFQjCNEw4hL29zgOohLXvpJ-Bdh2bils1Q&bvm=bv.61965928,d.bGE',
416 'info_dict': {
417 'id': 'cmQHVoWB5FY',
418 'ext': 'mp4',
419 'upload_date': '20130224',
420 'uploader_id': 'TheVerge',
ec85ded8 421 'description': r're:^Chris Ziegler takes a look at the\.*',
c5fa81fe
S
422 'uploader': 'The Verge',
423 'title': 'First Firefox OS phones side-by-side',
424 },
425 'params': {
426 'skip_download': False,
427 }
428 },
6c91a5a7
S
429 {
430 # redirect in Refresh HTTP header
431 'url': 'https://www.facebook.com/l.php?u=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DpO8h3EaFRdo&h=TAQHsoToz&enc=AZN16h-b6o4Zq9pZkCCdOLNKMN96BbGMNtcFwHSaazus4JHT_MFYkAA-WARTX2kvsCIdlAIyHZjl6d33ILIJU7Jzwk_K3mcenAXoAzBNoZDI_Q7EXGDJnIhrGkLXo_LJ_pAa2Jzbx17UHMd3jAs--6j2zaeto5w9RTn8T_1kKg3fdC5WPX9Dbb18vzH7YFX0eSJmoa6SP114rvlkw6pkS1-T&s=1',
432 'info_dict': {
433 'id': 'pO8h3EaFRdo',
434 'ext': 'mp4',
435 'title': 'Tripeo Boiler Room x Dekmantel Festival DJ Set',
436 'description': 'md5:6294cc1af09c4049e0652b51a2df10d5',
437 'upload_date': '20150917',
438 'uploader_id': 'brtvofficial',
439 'uploader': 'Boiler Room',
440 },
441 'params': {
442 'skip_download': False,
443 },
444 },
cfe50f04 445 {
79649588 446 'url': 'http://www.hodiho.fr/2013/02/regis-plante-sa-jeep.html',
d360a146 447 'md5': '85b90ccc9d73b4acd9138d3af4c27f89',
79649588 448 'info_dict': {
d360a146
S
449 'id': '13601338388002',
450 'ext': 'mp4',
79649588
PH
451 'uploader': 'www.hodiho.fr',
452 'title': 'R\u00e9gis plante sa Jeep',
cfe50f04
JMF
453 }
454 },
c19f7764
JMF
455 # bandcamp page with custom domain
456 {
79649588
PH
457 'add_ie': ['Bandcamp'],
458 'url': 'http://bronyrock.com/track/the-pony-mash',
79649588 459 'info_dict': {
fd50bf62
S
460 'id': '3235767654',
461 'ext': 'mp3',
79649588
PH
462 'title': 'The Pony Mash',
463 'uploader': 'M_Pallante',
c19f7764 464 },
79649588 465 'skip': 'There is a limit of 200 free downloads / month for the test song',
c19f7764 466 },
eeb165e6 467 {
53a664ed
S
468 # embedded brightcove video
469 # it also tests brightcove videos that need to set the 'Referer'
470 # in the http requests
3b7d9aa4 471 'add_ie': ['BrightcoveLegacy'],
79649588
PH
472 'url': 'http://www.bfmtv.com/video/bfmbusiness/cours-bourse/cours-bourse-l-analyse-technique-154522/',
473 'info_dict': {
474 'id': '2765128793001',
475 'ext': 'mp4',
476 'title': 'Le cours de bourse : l’analyse technique',
477 'description': 'md5:7e9ad046e968cb2d1114004aba466fd9',
478 'uploader': 'BFM BUSINESS',
eeb165e6 479 },
79649588
PH
480 'params': {
481 'skip_download': True,
eeb165e6
JMF
482 },
483 },
53a664ed
S
484 {
485 # embedded with itemprop embedURL and video id spelled as `idVideo`
486 'add_id': ['BrightcoveLegacy'],
487 'url': 'http://bfmbusiness.bfmtv.com/mediaplayer/chroniques/olivier-delamarche/',
488 'info_dict': {
489 'id': '5255628253001',
490 'ext': 'mp4',
491 'title': 'md5:37c519b1128915607601e75a87995fc0',
492 'description': 'md5:37f7f888b434bb8f8cc8dbd4f7a4cf26',
493 'uploader': 'BFM BUSINESS',
494 'uploader_id': '876450612001',
495 'timestamp': 1482255315,
496 'upload_date': '20161220',
497 },
498 'params': {
499 'skip_download': True,
500 },
501 },
17ab4d3b 502 {
067aa17e 503 # https://github.com/ytdl-org/youtube-dl/issues/2253
17ab4d3b 504 'url': 'http://bcove.me/i6nfkrc3',
17ab4d3b
PH
505 'md5': '0ba9446db037002366bab3b3eb30c88c',
506 'info_dict': {
fd50bf62
S
507 'id': '3101154703001',
508 'ext': 'mp4',
17ab4d3b
PH
509 'title': 'Still no power',
510 'uploader': 'thestar.com',
511 'description': 'Mississauga resident David Farmer is still out of power as a result of the ice storm a month ago. To keep the house warm, Farmer cuts wood from his property for a wood burning stove downstairs.',
512 },
3b7d9aa4 513 'add_ie': ['BrightcoveLegacy'],
39efc6e3 514 'skip': 'video gone',
17ab4d3b 515 },
0479c625
S
516 {
517 'url': 'http://www.championat.com/video/football/v/87/87499.html',
518 'md5': 'fb973ecf6e4a78a67453647444222983',
519 'info_dict': {
520 'id': '3414141473001',
521 'ext': 'mp4',
522 'title': 'Видео. Удаление Дзагоева (ЦСКА)',
523 'description': 'Онлайн-трансляция матча ЦСКА - "Волга"',
524 'uploader': 'Championat',
525 },
526 },
bdf97017 527 {
067aa17e 528 # https://github.com/ytdl-org/youtube-dl/issues/3541
3b7d9aa4 529 'add_ie': ['BrightcoveLegacy'],
bdf97017
NJ
530 'url': 'http://www.kijk.nl/sbs6/leermijvrouwenkennen/videos/jqMiXKAYan2S/aflevering-1',
531 'info_dict': {
532 'id': '3866516442001',
37aab278 533 'ext': 'mp4',
bdf97017
NJ
534 'title': 'Leer mij vrouwen kennen: Aflevering 1',
535 'description': 'Leer mij vrouwen kennen: Aflevering 1',
536 'uploader': 'SBS Broadcasting',
537 },
37aab278 538 'skip': 'Restricted to Netherlands',
bdf97017 539 'params': {
37aab278 540 'skip_download': True, # m3u8 download
bdf97017
NJ
541 },
542 },
06d0ad9a
YCH
543 {
544 # Brightcove video in <iframe>
545 'url': 'http://www.un.org/chinese/News/story.asp?NewsID=27724',
546 'md5': '36d74ef5e37c8b4a2ce92880d208b968',
547 'info_dict': {
548 'id': '5360463607001',
549 'ext': 'mp4',
550 'title': '叙利亚失明儿童在废墟上演唱《心跳》 呼吁获得正常童年生活',
551 'description': '联合国儿童基金会中东和北非区域大使、作曲家扎德·迪拉尼(Zade Dirani)在3月15日叙利亚冲突爆发7周年纪念日之际发布了为叙利亚谱写的歌曲《心跳》(HEARTBEAT),为受到六年冲突影响的叙利亚儿童发出强烈呐喊,呼吁世界做出共同努力,使叙利亚儿童重新获得享有正常童年生活的权利。',
552 'uploader': 'United Nations',
553 'uploader_id': '1362235914001',
554 'timestamp': 1489593889,
555 'upload_date': '20170315',
556 },
557 'add_ie': ['BrightcoveLegacy'],
558 },
16e2c8f7
YCH
559 {
560 # Brightcove with alternative playerID key
561 'url': 'http://www.nature.com/nmeth/journal/v9/n7/fig_tab/nmeth.2062_SV1.html',
562 'info_dict': {
563 'id': 'nmeth.2062_SV1',
564 'title': 'Simultaneous multiview imaging of the Drosophila syncytial blastoderm : Quantitative high-speed imaging of entire developing embryos with simultaneous multiview light-sheet microscopy : Nature Methods : Nature Research',
565 },
566 'playlist': [{
567 'info_dict': {
568 'id': '2228375078001',
569 'ext': 'mp4',
570 'title': 'nmeth.2062-sv1',
571 'description': 'nmeth.2062-sv1',
572 'timestamp': 1363357591,
573 'upload_date': '20130315',
574 'uploader': 'Nature Publishing Group',
575 'uploader_id': '1964492299001',
576 },
577 }],
578 },
40158f55
JH
579 {
580 # Brightcove with UUID in videoPlayer
581 'url': 'http://www8.hp.com/cn/zh/home.html',
582 'info_dict': {
583 'id': '5255815316001',
584 'ext': 'mp4',
585 'title': 'Sprocket Video - China',
586 'description': 'Sprocket Video - China',
587 'uploader': 'HP-Video Gallery',
588 'timestamp': 1482263210,
589 'upload_date': '20161220',
590 'uploader_id': '1107601872001',
591 },
592 'params': {
593 'skip_download': True, # m3u8 download
594 },
595 'skip': 'video rotates...weekly?',
596 },
597 {
598 # Brightcove:new type [2].
599 'url': 'http://www.delawaresportszone.com/video-st-thomas-more-earns-first-trip-to-basketball-semis',
600 'md5': '2b35148fcf48da41c9fb4591650784f3',
601 'info_dict': {
602 'id': '5348741021001',
603 'ext': 'mp4',
604 'upload_date': '20170306',
605 'uploader_id': '4191638492001',
606 'timestamp': 1488769918,
607 'title': 'VIDEO: St. Thomas More earns first trip to basketball semis',
608
609 },
610 },
611 {
612 # Alternative brightcove <video> attributes
613 'url': 'http://www.programme-tv.net/videos/extraits/81095-guillaume-canet-evoque-les-rumeurs-d-infidelite-de-marion-cotillard-avec-brad-pitt-dans-vivement-dimanche/',
614 'info_dict': {
615 'id': '81095-guillaume-canet-evoque-les-rumeurs-d-infidelite-de-marion-cotillard-avec-brad-pitt-dans-vivement-dimanche',
616 'title': "Guillaume Canet évoque les rumeurs d'infidélité de Marion Cotillard avec Brad Pitt dans Vivement Dimanche, Extraits : toutes les vidéos avec Télé-Loisirs",
617 },
618 'playlist': [{
619 'md5': '732d22ba3d33f2f3fc253c39f8f36523',
620 'info_dict': {
621 'id': '5311302538001',
622 'ext': 'mp4',
623 'title': "Guillaume Canet évoque les rumeurs d'infidélité de Marion Cotillard avec Brad Pitt dans Vivement Dimanche",
624 'description': "Guillaume Canet évoque les rumeurs d'infidélité de Marion Cotillard avec Brad Pitt dans Vivement Dimanche (France 2, 5 février 2017)",
625 'timestamp': 1486321708,
626 'upload_date': '20170205',
627 'uploader_id': '800000640001',
628 },
629 'only_matching': True,
630 }],
631 },
b68a812e
S
632 {
633 # Brightcove with UUID in videoPlayer
634 'url': 'http://www8.hp.com/cn/zh/home.html',
635 'info_dict': {
636 'id': '5255815316001',
637 'ext': 'mp4',
638 'title': 'Sprocket Video - China',
639 'description': 'Sprocket Video - China',
640 'uploader': 'HP-Video Gallery',
641 'timestamp': 1482263210,
642 'upload_date': '20161220',
643 'uploader_id': '1107601872001',
644 },
645 'params': {
646 'skip_download': True, # m3u8 download
647 },
648 },
c0d0b01f
JMF
649 # ooyala video
650 {
79649588 651 'url': 'http://www.rollingstone.com/music/videos/norwegian-dj-cashmere-cat-goes-spartan-on-with-me-premiere-20131219',
87830900 652 'md5': '166dd577b433b4d4ebfee10b0824d8ff',
79649588
PH
653 'info_dict': {
654 'id': 'BwY2RxaTrTkslxOfcan0UCf0YqyvWysJ',
655 'ext': 'mp4',
3486df38 656 'title': '2cc213299525360.mov', # that's what we get
53e06b25 657 'duration': 238.231,
c0d0b01f 658 },
87830900 659 'add_ie': ['Ooyala'],
c0d0b01f 660 },
bf94d763
S
661 {
662 # ooyala video embedded with http://player.ooyala.com/iframe.js
663 'url': 'http://www.macrumors.com/2015/07/24/steve-jobs-the-man-in-the-machine-first-trailer/',
664 'info_dict': {
665 'id': 'p0MGJndjoG5SOKqO_hZJuZFPB-Tr5VgB',
666 'ext': 'mp4',
667 'title': '"Steve Jobs: Man in the Machine" trailer',
668 'description': 'The first trailer for the Alex Gibney documentary "Steve Jobs: Man in the Machine."',
53e06b25 669 'duration': 135.427,
bf94d763
S
670 },
671 'params': {
672 'skip_download': True,
673 },
39efc6e3 674 'skip': 'movie expired',
bf94d763 675 },
198d4cb4
GR
676 # ooyala video embedded with http://player.ooyala.com/static/v4/production/latest/core.min.js
677 {
678 'url': 'http://wnep.com/2017/07/22/steampunk-fest-comes-to-honesdale/',
679 'info_dict': {
680 'id': 'lwYWYxYzE6V5uJMjNGyKtwwiw9ZJD7t2',
681 'ext': 'mp4',
682 'title': 'Steampunk Fest Comes to Honesdale',
683 'duration': 43.276,
684 },
685 'params': {
686 'skip_download': True,
687 }
688 },
1b86cc41 689 # embed.ly video
690 {
691 'url': 'http://www.tested.com/science/weird/460206-tested-grinding-coffee-2000-frames-second/',
692 'info_dict': {
693 'id': '9ODmcdjQcHQ',
694 'ext': 'mp4',
0a5bce56
PH
695 'title': 'Tested: Grinding Coffee at 2000 Frames Per Second',
696 'upload_date': '20140225',
697 'description': 'md5:06a40fbf30b220468f1e0957c0f558ff',
698 'uploader': 'Tested',
699 'uploader_id': 'testedcom',
1b86cc41 700 },
701 # No need to test YoutubeIE here
702 'params': {
703 'skip_download': True,
704 },
705 },
60cc4dc4
PH
706 # funnyordie embed
707 {
708 'url': 'http://www.theguardian.com/world/2014/mar/11/obama-zach-galifianakis-between-two-ferns',
60cc4dc4
PH
709 'info_dict': {
710 'id': '18e820ec3f',
711 'ext': 'mp4',
712 'title': 'Between Two Ferns with Zach Galifianakis: President Barack Obama',
713 'description': 'Episode 18: President Barack Obama sits down with Zach Galifianakis for his most memorable interview yet.',
93d020dd 714 },
39efc6e3
YCH
715 # HEAD requests lead to endless 301, while GET is OK
716 'expected_warnings': ['301'],
60cc4dc4 717 },
93d020dd
S
718 # RUTV embed
719 {
720 'url': 'http://www.rg.ru/2014/03/15/reg-dfo/anklav-anons.html',
721 'info_dict': {
722 'id': '776940',
723 'ext': 'mp4',
724 'title': 'Охотское море стало целиком российским',
725 'description': 'md5:5ed62483b14663e2a95ebbe115eb8f43',
726 },
727 'params': {
728 # m3u8 download
729 'skip_download': True,
730 },
aab74fa1 731 },
f37bdbe5
S
732 # TVC embed
733 {
734 'url': 'http://sch1298sz.mskobr.ru/dou_edu/karamel_ki/filial_galleries/video/iframe_src_http_tvc_ru_video_iframe_id_55304_isplay_false_acc_video_id_channel_brand_id_11_show_episodes_episode_id_32307_frameb/',
735 'info_dict': {
736 'id': '55304',
737 'ext': 'mp4',
738 'title': 'Дошкольное воспитание',
739 },
740 },
b827a601
S
741 # SportBox embed
742 {
743 'url': 'http://www.vestifinance.ru/articles/25753',
744 'info_dict': {
745 'id': '25753',
05d1e7aa 746 'title': 'Прямые трансляции с Форума-выставки "Госзаказ-2013"',
b827a601
S
747 },
748 'playlist': [{
749 'info_dict': {
750 'id': '370908',
751 'title': 'Госзаказ. День 3',
752 'ext': 'mp4',
753 }
754 }, {
755 'info_dict': {
756 'id': '370905',
757 'title': 'Госзаказ. День 2',
758 'ext': 'mp4',
759 }
760 }, {
761 'info_dict': {
762 'id': '370902',
763 'title': 'Госзаказ. День 1',
764 'ext': 'mp4',
765 }
766 }],
767 'params': {
768 # m3u8 download
769 'skip_download': True,
770 },
771 },
bf20b9c5
S
772 # Myvi.ru embed
773 {
774 'url': 'http://www.kinomyvi.tv/news/detail/Pervij-dublirovannij-trejler--Uzhastikov-_nOw1',
775 'info_dict': {
776 'id': 'f4dafcad-ff21-423d-89b5-146cfd89fa1e',
777 'ext': 'mp4',
778 'title': 'Ужастики, русский трейлер (2015)',
ec85ded8 779 'thumbnail': r're:^https?://.*\.jpg$',
bf20b9c5
S
780 'duration': 153,
781 }
782 },
c76799c5
S
783 # XHamster embed
784 {
785 'url': 'http://www.numisc.com/forum/showthread.php?11696-FM15-which-pumiscer-was-this-%28-vid-%29-%28-alfa-as-fuck-srx-%29&s=711f5db534502e22260dec8c5e2d66d8',
786 'info_dict': {
787 'id': 'showthread',
788 'title': '[NSFL] [FM15] which pumiscer was this ( vid ) ( alfa as fuck srx )',
789 },
790 'playlist_mincount': 7,
39efc6e3
YCH
791 # This forum does not allow <iframe> syntaxes anymore
792 # Now HTML tags are displayed as-is
793 'skip': 'No videos on this page',
c76799c5 794 },
aab74fa1
PH
795 # Embedded TED video
796 {
797 'url': 'http://en.support.wordpress.com/videos/ted-talks/',
a8eb5a8e 798 'md5': '65fdff94098e4a607385a60c5177c638',
aab74fa1 799 'info_dict': {
a8eb5a8e 800 'id': '1969',
aab74fa1 801 'ext': 'mp4',
a8eb5a8e
PH
802 'title': 'Hidden miracles of the natural world',
803 'uploader': 'Louie Schwartzberg',
804 'description': 'md5:8145d19d320ff3e52f28401f4c4283b9',
aab74fa1 805 }
60cc4dc4 806 },
d95e35d6
S
807 # nowvideo embed hidden behind percent encoding
808 {
809 'url': 'http://www.waoanime.tv/the-super-dimension-fortress-macross-episode-1/',
810 'md5': '2baf4ddd70f697d94b1c18cf796d5107',
811 'info_dict': {
812 'id': '06e53103ca9aa',
813 'ext': 'flv',
814 'title': 'Macross Episode 001 Watch Macross Episode 001 onl',
815 'description': 'No description',
816 },
0f2a2ba1 817 },
893f8832
PH
818 # arte embed
819 {
820 'url': 'http://www.tv-replay.fr/redirection/20-03-14/x-enius-arte-10753389.html',
821 'md5': '7653032cbb25bf6c80d80f217055fa43',
822 'info_dict': {
823 'id': '048195-004_PLUS7-F',
824 'ext': 'flv',
825 'title': 'X:enius',
826 'description': 'md5:d5fdf32ef6613cdbfd516ae658abf168',
827 'upload_date': '20140320',
828 },
829 'params': {
830 'skip_download': 'Requires rtmpdump'
39efc6e3
YCH
831 },
832 'skip': 'video gone',
893f8832 833 },
cbd55ade
S
834 # francetv embed
835 {
836 'url': 'http://www.tsprod.com/replay-du-concert-alcaline-de-calogero',
837 'info_dict': {
838 'id': 'EV_30231',
839 'ext': 'mp4',
840 'title': 'Alcaline, le concert avec Calogero',
841 'description': 'md5:61f08036dcc8f47e9cfc33aed08ffaff',
842 'upload_date': '20150226',
843 'timestamp': 1424989860,
844 'duration': 5400,
845 },
846 'params': {
847 # m3u8 downloads
848 'skip_download': True,
849 },
850 'expected_warnings': [
851 'Forbidden'
852 ]
853 },
fa35cdad
PH
854 # Condé Nast embed
855 {
856 'url': 'http://www.wired.com/2014/04/honda-asimo/',
857 'md5': 'ba0dfe966fa007657bd1443ee672db0f',
858 'info_dict': {
859 'id': '53501be369702d3275860000',
860 'ext': 'mp4',
861 'title': 'Honda’s New Asimo Robot Is More Human Than Ever',
862 }
ebd3c7b3
PH
863 },
864 # Dailymotion embed
865 {
866 'url': 'http://www.spi0n.com/zap-spi0n-com-n216/',
867 'md5': '441aeeb82eb72c422c7f14ec533999cd',
868 'info_dict': {
869 'id': 'k2mm4bCdJ6CQ2i7c8o2',
870 'ext': 'mp4',
871 'title': 'Le Zap de Spi0n n°216 - Zapping du Web',
0738187f 872 'description': 'md5:faf028e48a461b8b7fad38f1e104b119',
ebd3c7b3 873 'uploader': 'Spi0n',
0738187f
YCH
874 'uploader_id': 'xgditw',
875 'upload_date': '20140425',
876 'timestamp': 1398441542,
ebd3c7b3
PH
877 },
878 'add_ie': ['Dailymotion'],
2b88feed 879 },
71a1db89
S
880 # DailyMail embed
881 {
882 'url': 'http://www.bumm.sk/krimi/2017/07/05/biztonsagi-kamera-buktatta-le-az-agg-ferfit-utlegelo-apolot',
883 'info_dict': {
884 'id': '1495629',
885 'ext': 'mp4',
886 'title': 'Care worker punches elderly dementia patient in head 11 times',
887 'description': 'md5:3a743dee84e57e48ec68bf67113199a5',
888 },
889 'add_ie': ['DailyMail'],
890 'params': {
891 'skip_download': True,
892 },
893 },
2b88feed
PH
894 # YouTube embed
895 {
896 'url': 'http://www.badzine.de/ansicht/datum/2014/06/09/so-funktioniert-die-neue-englische-badminton-liga.html',
897 'info_dict': {
898 'id': 'FXRb4ykk4S0',
899 'ext': 'mp4',
900 'title': 'The NBL Auction 2014',
901 'uploader': 'BADMINTON England',
902 'uploader_id': 'BADMINTONEvents',
903 'upload_date': '20140603',
904 'description': 'md5:9ef128a69f1e262a700ed83edb163a73',
905 },
906 'add_ie': ['Youtube'],
907 'params': {
908 'skip_download': True,
909 }
910 },
a0566bbf 911 # MTVServices embed
c5cd249e 912 {
1fa309da
YCH
913 'url': 'http://www.vulture.com/2016/06/new-key-peele-sketches-released.html',
914 'md5': 'ca1aef97695ef2c1d6973256a57e5252',
c5cd249e 915 'info_dict': {
1fa309da 916 'id': '769f7ec0-0692-4d62-9b45-0d88074bffc1',
c5cd249e 917 'ext': 'mp4',
1fa309da
YCH
918 'title': 'Key and Peele|October 10, 2012|2|203|Liam Neesons - Uncensored',
919 'description': 'Two valets share their love for movie star Liam Neesons.',
05d1e7aa
YCH
920 'timestamp': 1349922600,
921 'upload_date': '20121011',
c5cd249e
JMF
922 },
923 },
61013473 924 # YouTube embed via <data-embed-url="">
925 {
926 'url': 'https://play.google.com/store/apps/details?id=com.gameloft.android.ANMP.GloftA8HM',
61013473 927 'info_dict': {
a8eb5a8e 928 'id': '4vAffPZIT44',
61013473 929 'ext': 'mp4',
a8eb5a8e 930 'title': 'Asphalt 8: Airborne - Update - Welcome to Dubai!',
ed2d6a19
PH
931 'uploader': 'Gameloft',
932 'uploader_id': 'gameloft',
a8eb5a8e
PH
933 'upload_date': '20140828',
934 'description': 'md5:c80da9ed3d83ae6d1876c834de03e1c4',
ed2d6a19
PH
935 },
936 'params': {
937 'skip_download': True,
61013473 938 }
c8e9a235 939 },
61568e50
JH
940 # YouTube <object> embed
941 {
942 'url': 'http://www.improbable.com/2017/04/03/untrained-modern-youths-and-ancient-masters-in-selfie-portraits/',
943 'md5': '516718101ec834f74318df76259fb3cc',
944 'info_dict': {
945 'id': 'msN87y-iEx0',
946 'ext': 'webm',
947 'title': 'Feynman: Mirrors FUN TO IMAGINE 6',
948 'upload_date': '20080526',
949 'description': 'md5:0ffc78ea3f01b2e2c247d5f8d1d3c18d',
950 'uploader': 'Christopher Sykes',
951 'uploader_id': 'ChristopherJSykes',
952 },
953 'add_ie': ['Youtube'],
954 },
c8e9a235
PH
955 # Camtasia studio
956 {
957 'url': 'http://www.ll.mit.edu/workshops/education/videocourses/antennas/lecture1/video/',
958 'playlist': [{
959 'md5': '0c5e352edabf715d762b0ad4e6d9ee67',
960 'info_dict': {
961 'id': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final',
962 'title': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final - video1',
963 'ext': 'flv',
964 'duration': 2235.90,
965 }
966 }, {
967 'md5': '10e4bb3aaca9fd630e273ff92d9f3c63',
968 'info_dict': {
969 'id': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final_PIP',
970 'title': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final - pip',
971 'ext': 'flv',
972 'duration': 2235.93,
973 }
974 }],
975 'info_dict': {
976 'title': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final',
977 }
4d805e06
PH
978 },
979 # Flowplayer
980 {
981 'url': 'http://www.handjobhub.com/video/busty-blonde-siri-tit-fuck-while-wank-6313.html',
982 'md5': '9d65602bf31c6e20014319c7d07fba27',
983 'info_dict': {
984 'id': '5123ea6d5e5a7',
985 'ext': 'mp4',
986 'age_limit': 18,
987 'uploader': 'www.handjobhub.com',
d6d9186f 988 'title': 'Busty Blonde Siri Tit Fuck While Wank at HandjobHub.com',
4d805e06 989 }
0990305d 990 },
22a6f150 991 # Multiple brightcove videos
067aa17e 992 # https://github.com/ytdl-org/youtube-dl/issues/2283
22a6f150
PH
993 {
994 'url': 'http://www.newyorker.com/online/blogs/newsdesk/2014/01/always-never-nuclear-command-and-control.html',
995 'info_dict': {
996 'id': 'always-never',
997 'title': 'Always / Never - The New Yorker',
998 },
999 'playlist_count': 3,
1000 'params': {
1001 'extract_flat': False,
1002 'skip_download': True,
1003 }
1a94ff68
S
1004 },
1005 # MLB embed
1006 {
1007 'url': 'http://umpire-empire.com/index.php/topic/58125-laz-decides-no-thats-low/',
1008 'md5': '96f09a37e44da40dd083e12d9a683327',
1009 'info_dict': {
1010 'id': '33322633',
1011 'ext': 'mp4',
1012 'title': 'Ump changes call to ball',
1013 'description': 'md5:71c11215384298a172a6dcb4c2e20685',
1014 'duration': 48,
1015 'timestamp': 1401537900,
1016 'upload_date': '20140531',
ec85ded8 1017 'thumbnail': r're:^https?://.*\.jpg$',
1a94ff68
S
1018 },
1019 },
746c67d7
NJ
1020 # Wistia embed
1021 {
6c114b12
S
1022 'url': 'http://study.com/academy/lesson/north-american-exploration-failed-colonies-of-spain-france-england.html#lesson',
1023 'md5': '1953f3a698ab51cfc948ed3992a0b7ff',
746c67d7 1024 'info_dict': {
6c114b12 1025 'id': '6e2wtrbdaf',
746c67d7 1026 'ext': 'mov',
6c114b12
S
1027 'title': 'paywall_north-american-exploration-failed-colonies-of-spain-france-england',
1028 'description': 'a Paywall Videos video from Remilon',
1029 'duration': 644.072,
1030 'uploader': 'study.com',
1031 'timestamp': 1459678540,
1032 'upload_date': '20160403',
1033 'filesize': 24687186,
746c67d7
NJ
1034 },
1035 },
7ded6545
S
1036 # Wistia standard embed (async)
1037 {
1038 'url': 'https://www.getdrip.com/university/brennan-dunn-drip-workshop/',
1039 'info_dict': {
1040 'id': '807fafadvk',
1041 'ext': 'mp4',
1042 'title': 'Drip Brennan Dunn Workshop',
1043 'description': 'a JV Webinars video from getdrip-1',
1044 'duration': 4986.95,
7ded6545 1045 'timestamp': 1463607249,
6c114b12 1046 'upload_date': '20160518',
7ded6545
S
1047 },
1048 'params': {
1049 'skip_download': True,
1050 }
1051 },
ac645ac7
PH
1052 # Soundcloud embed
1053 {
1054 'url': 'http://nakedsecurity.sophos.com/2014/10/29/sscc-171-are-you-sure-that-1234-is-a-bad-password-podcast/',
1055 'info_dict': {
1056 'id': '174391317',
1057 'ext': 'mp3',
1058 'description': 'md5:ff867d6b555488ad3c52572bb33d432c',
1059 'uploader': 'Sophos Security',
1060 'title': 'Chet Chat 171 - Oct 29, 2014',
1061 'upload_date': '20141029',
1062 }
af63fed7 1063 },
db19df6c
S
1064 # Soundcloud multiple embeds
1065 {
1066 'url': 'http://www.guitarplayer.com/lessons/1014/legato-workout-one-hour-to-more-fluid-performance---tab/52809',
1067 'info_dict': {
1068 'id': '52809',
1069 'title': 'Guitar Essentials: Legato Workout—One-Hour to Fluid Performance | TAB + AUDIO',
1070 },
1071 'playlist_mincount': 7,
1072 },
027e2312
S
1073 # TuneIn station embed
1074 {
1075 'url': 'http://radiocnrv.com/promouvoir-radio-cnrv/',
1076 'info_dict': {
1077 'id': '204146',
1078 'ext': 'mp3',
1079 'title': 'CNRV',
1080 'location': 'Paris, France',
1081 'is_live': True,
1082 },
1083 'params': {
1084 # Live stream
1085 'skip_download': True,
1086 },
1087 },
af63fed7
PH
1088 # Livestream embed
1089 {
1090 'url': 'http://www.esa.int/Our_Activities/Space_Science/Rosetta/Philae_comet_touch-down_webcast',
1091 'info_dict': {
1092 'id': '67864563',
1093 'ext': 'flv',
1094 'upload_date': '20141112',
1095 'title': 'Rosetta #CometLanding webcast HL 10',
1096 }
1097 },
78d3b3e2
YCH
1098 # Another Livestream embed, without 'new.' in URL
1099 {
1100 'url': 'https://www.freespeech.org/',
1101 'info_dict': {
1102 'id': '123537347',
1103 'ext': 'mp4',
1104 'title': 're:^FSTV [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
1105 },
1106 'params': {
1107 # Live stream
1108 'skip_download': True,
1109 },
1110 },
65f3a228
PH
1111 # LazyYT
1112 {
e8e4cc5a 1113 'url': 'https://skiplagged.com/',
65f3a228 1114 'info_dict': {
e8e4cc5a
JH
1115 'id': 'skiplagged',
1116 'title': 'Skiplagged: The smart way to find cheap flights',
65f3a228 1117 },
e8e4cc5a
JH
1118 'playlist_mincount': 1,
1119 'add_ie': ['Youtube'],
4e262a88 1120 },
42bdd9d0
PH
1121 # Cinchcast embed
1122 {
1123 'url': 'http://undergroundwellness.com/podcasts/306-5-steps-to-permanent-gut-healing/',
1124 'info_dict': {
1125 'id': '7141703',
1126 'ext': 'mp3',
1127 'upload_date': '20141126',
1128 'title': 'Jack Tips: 5 Steps to Permanent Gut Healing',
1129 }
1130 },
501f13fb
PH
1131 # Cinerama player
1132 {
1133 'url': 'http://www.abc.net.au/7.30/content/2015/s4164797.htm',
1134 'info_dict': {
1135 'id': '730m_DandD_1901_512k',
1136 'ext': 'mp4',
1137 'uploader': 'www.abc.net.au',
1138 'title': 'Game of Thrones with dice - Dungeons and Dragons fantasy role-playing game gets new life - 19/01/2015',
1139 }
796df3c6
S
1140 },
1141 # embedded viddler video
1142 {
1143 'url': 'http://deadspin.com/i-cant-stop-watching-john-wall-chop-the-nuggets-with-th-1681801597',
1144 'info_dict': {
1145 'id': '4d03aad9',
1146 'ext': 'mp4',
1147 'uploader': 'deadspin',
1148 'title': 'WALL-TO-GORTAT',
1149 'timestamp': 1422285291,
1150 'upload_date': '20150126',
1151 },
1152 'add_ie': ['Viddler'],
a0f71985 1153 },
2051acde
S
1154 # Libsyn embed
1155 {
1156 'url': 'http://thedailyshow.cc.com/podcast/episodetwelve',
1157 'info_dict': {
1158 'id': '3377616',
1159 'ext': 'mp3',
1160 'title': "The Daily Show Podcast without Jon Stewart - Episode 12: Bassem Youssef: Egypt's Jon Stewart",
1161 'description': 'md5:601cb790edd05908957dae8aaa866465',
1162 'upload_date': '20150220',
1163 },
326fa4e6 1164 'skip': 'All The Daily Show URLs now redirect to http://www.cc.com/shows/',
2051acde 1165 },
a0f71985
PH
1166 # jwplayer YouTube
1167 {
1168 'url': 'http://media.nationalarchives.gov.uk/index.php/webinar-using-discovery-national-archives-online-catalogue/',
1169 'info_dict': {
1170 'id': 'Mrj4DVp2zeA',
1171 'ext': 'mp4',
f37e3f99 1172 'upload_date': '20150212',
a0f71985 1173 'uploader': 'The National Archives UK',
2637fadc 1174 'description': 'md5:8078af856dca76edc42910b61273dbbf',
a0f71985
PH
1175 'uploader_id': 'NationalArchives08',
1176 'title': 'Webinar: Using Discovery, The National Archives’ online catalogue',
1177 },
59b8ab58 1178 },
5620f840
S
1179 # jwplayer rtmp
1180 {
6899b1d9 1181 'url': 'http://www.suffolk.edu/sjc/live.php',
5620f840 1182 'info_dict': {
6899b1d9 1183 'id': 'live',
5620f840
S
1184 'ext': 'flv',
1185 'title': 'Massachusetts Supreme Judicial Court Oral Arguments',
1186 'uploader': 'www.suffolk.edu',
1187 },
1188 'params': {
1189 'skip_download': True,
2637fadc 1190 },
6899b1d9 1191 'skip': 'Only has video a few mornings per month, see http://www.suffolk.edu/sjc/',
5620f840 1192 },
5e7bbac3 1193 # jwplayer with only the json URL
1194 {
1195 'url': 'https://www.hollywoodreporter.com/news/general-news/dunkirk-team-reveals-what-christopher-nolan-said-oscar-win-meet-your-oscar-winner-1092454',
1196 'info_dict': {
1197 'id': 'TljWkvWH',
1198 'ext': 'mp4',
1199 'upload_date': '20180306',
1200 'title': 'md5:91eb1862f6526415214f62c00b453936',
1201 'description': 'md5:73048ae50ae953da10549d1d2fe9b3aa',
1202 'timestamp': 1520367225,
1203 },
1204 'params': {
1205 'skip_download': True,
1206 },
1207 },
a4a554a7
YCH
1208 # Complex jwplayer
1209 {
1210 'url': 'http://www.indiedb.com/games/king-machine/videos',
1211 'info_dict': {
1212 'id': 'videos',
1213 'ext': 'mp4',
1214 'title': 'king machine trailer 1',
2637fadc 1215 'description': 'Browse King Machine videos & audio for sweet media. Your eyes will thank you.',
a4a554a7
YCH
1216 'thumbnail': r're:^https?://.*\.jpg$',
1217 },
1218 },
03486dbb
RU
1219 {
1220 # JWPlayer config passed as variable
1221 'url': 'http://www.txxx.com/videos/3326530/ariele/',
1222 'info_dict': {
1223 'id': '3326530_hq',
1224 'ext': 'mp4',
1225 'title': 'ARIELE | Tube Cup',
1226 'uploader': 'www.txxx.com',
1227 'age_limit': 18,
1228 },
1229 'params': {
1230 'skip_download': True,
1231 }
1232 },
939be9ad
JH
1233 {
1234 # JWPlatform iframe
2fac2e91 1235 'url': 'https://www.covermagazine.co.uk/feature/2465255/business-protection-involved',
939be9ad 1236 'info_dict': {
2fac2e91 1237 'id': 'AG26UQXM',
939be9ad 1238 'ext': 'mp4',
2fac2e91
AG
1239 'upload_date': '20160719',
1240 'timestamp': 468923808,
1241 'title': '2016_05_18 Cover L&G Business Protection V1 FINAL.mp4',
939be9ad 1242 },
805f5bf7 1243 'add_ie': [JWPlatformIE.ie_key()],
939be9ad 1244 },
63d990d2 1245 {
c5b7014a 1246 # Video.js embed, multiple formats
63d990d2
S
1247 'url': 'http://ortcam.com/solidworks-урок-6-настройка-чертежа_33f9b7351.html',
1248 'info_dict': {
1249 'id': 'yygqldloqIk',
1250 'ext': 'mp4',
1251 'title': 'SolidWorks. Урок 6 Настройка чертежа',
1252 'description': 'md5:baf95267792646afdbf030e4d06b2ab3',
1253 'upload_date': '20130314',
1254 'uploader': 'PROстое3D',
1255 'uploader_id': 'PROstoe3D',
1256 },
1257 'params': {
1258 'skip_download': True,
1259 },
1260 },
c5b7014a
S
1261 {
1262 # Video.js embed, single format
1263 'url': 'https://www.vooplayer.com/v3/watch/watch.php?v=NzgwNTg=',
1264 'info_dict': {
1265 'id': 'watch',
1266 'ext': 'mp4',
1267 'title': 'Step 1 - Good Foundation',
1268 'description': 'md5:d1e7ff33a29fc3eb1673d6c270d344f4',
1269 },
1270 'params': {
1271 'skip_download': True,
1272 },
1273 },
59b8ab58
PH
1274 # rtl.nl embed
1275 {
1276 'url': 'http://www.rtlnieuws.nl/nieuws/buitenland/aanslagen-kopenhagen',
1277 'playlist_mincount': 5,
1278 'info_dict': {
1279 'id': 'aanslagen-kopenhagen',
2637fadc 1280 'title': 'Aanslagen Kopenhagen',
59b8ab58 1281 }
255fca5e
S
1282 },
1283 # Zapiks embed
1284 {
1285 'url': 'http://www.skipass.com/news/116090-bon-appetit-s5ep3-baqueira-mi-cor.html',
1286 'info_dict': {
1287 'id': '118046',
1288 'ext': 'mp4',
1289 'title': 'EP3S5 - Bon Appétit - Baqueira Mi Corazon !',
1290 }
1291 },
66e568de
S
1292 # Kaltura embed (different embed code)
1293 {
1294 'url': 'http://www.premierchristianradio.com/Shows/Saturday/Unbelievable/Conference-Videos/Os-Guinness-Is-It-Fools-Talk-Unbelievable-Conference-2014',
1295 'info_dict': {
1296 'id': '1_a52wc67y',
1297 'ext': 'flv',
1298 'upload_date': '20150127',
1299 'uploader_id': 'PremierMedia',
1300 'timestamp': int,
1301 'title': 'Os Guinness // Is It Fools Talk? // Unbelievable? Conference 2014',
1302 },
1303 },
87703231
YCH
1304 # Kaltura embed with single quotes
1305 {
1306 'url': 'http://fod.infobase.com/p_ViewPlaylist.aspx?AssignmentID=NUN8ZY',
1307 'info_dict': {
1308 'id': '0_izeg5utt',
1309 'ext': 'mp4',
1310 'title': '35871',
1311 'timestamp': 1355743100,
1312 'upload_date': '20121217',
e30991f9 1313 'uploader_id': 'cplapp@learn360.com',
87703231
YCH
1314 },
1315 'add_ie': ['Kaltura'],
1316 },
427cd050
S
1317 {
1318 # Kaltura embedded via quoted entry_id
1319 'url': 'https://www.oreilly.com/ideas/my-cloud-makes-pretty-pictures',
1320 'info_dict': {
1321 'id': '0_utuok90b',
1322 'ext': 'mp4',
1323 'title': '06_matthew_brender_raj_dutt',
1324 'timestamp': 1466638791,
1325 'upload_date': '20160622',
1326 },
1327 'add_ie': ['Kaltura'],
1328 'expected_warnings': [
1329 'Could not send HEAD request'
1330 ],
1331 'params': {
1332 'skip_download': True,
1333 }
1334 },
8ab7e6c4
YCH
1335 {
1336 # Kaltura embedded, some fileExt broken (#11480)
1337 'url': 'http://www.cornell.edu/video/nima-arkani-hamed-standard-models-of-particle-physics',
1338 'info_dict': {
1339 'id': '1_sgtvehim',
1340 'ext': 'mp4',
1341 'title': 'Our "Standard Models" of particle physics and cosmology',
1342 'description': 'md5:67ea74807b8c4fea92a6f38d6d323861',
1343 'timestamp': 1321158993,
1344 'upload_date': '20111113',
1345 'uploader_id': 'kps1',
1346 },
1347 'add_ie': ['Kaltura'],
1348 },
a01825a5
JH
1349 {
1350 # Kaltura iframe embed
1351 'url': 'http://www.gsd.harvard.edu/event/i-m-pei-a-centennial-celebration/',
1352 'md5': 'ae5ace8eb09dc1a35d03b579a9c2cc44',
1353 'info_dict': {
1354 'id': '0_f2cfbpwy',
1355 'ext': 'mp4',
1356 'title': 'I. M. Pei: A Centennial Celebration',
1357 'description': 'md5:1db8f40c69edc46ca180ba30c567f37c',
1358 'upload_date': '20170403',
1359 'uploader_id': 'batchUser',
1360 'timestamp': 1491232186,
1361 },
1362 'add_ie': ['Kaltura'],
1363 },
c21692fa
S
1364 {
1365 # Kaltura iframe embed, more sophisticated
1366 'url': 'http://www.cns.nyu.edu/~eero/math-tools/Videos/lecture-05sep2017.html',
1367 'info_dict': {
1368 'id': '1_9gzouybz',
1369 'ext': 'mp4',
1370 'title': 'lecture-05sep2017',
1371 'description': 'md5:40f347d91fd4ba047e511c5321064b49',
1372 'upload_date': '20170913',
1373 'uploader_id': 'eps2',
1374 'timestamp': 1505340777,
1375 },
1376 'params': {
1377 'skip_download': True,
1378 },
1379 'add_ie': ['Kaltura'],
1380 },
e30991f9
S
1381 {
1382 # meta twitter:player
1383 'url': 'http://thechive.com/2017/12/08/all-i-want-for-christmas-is-more-twerk/',
1384 'info_dict': {
1385 'id': '0_01b42zps',
1386 'ext': 'mp4',
1387 'title': 'Main Twerk (Video)',
1388 'upload_date': '20171208',
1389 'uploader_id': 'sebastian.salinas@thechive.com',
1390 'timestamp': 1512713057,
1391 },
1392 'params': {
1393 'skip_download': True,
1394 },
1395 'add_ie': ['Kaltura'],
1396 },
250b042c
S
1397 # referrer protected EaglePlatform embed
1398 {
1399 'url': 'https://tvrain.ru/lite/teleshow/kak_vse_nachinalos/namin-418921/',
1400 'info_dict': {
1401 'id': '582306',
1402 'ext': 'mp4',
1403 'title': 'Стас Намин: «Мы нарушили девственность Кремля»',
1404 'thumbnail': r're:^https?://.*\.jpg$',
1405 'duration': 3382,
1406 'view_count': int,
1407 },
1408 'params': {
1409 'skip_download': True,
1410 },
135c9c42 1411 },
665e9452 1412 # ClipYou (EaglePlatform) embed (custom URL)
d47ae7f6
S
1413 {
1414 'url': 'http://muz-tv.ru/play/7129/',
4645432d 1415 # Not checking MD5 as sometimes the direct HTTP link results in 404 and HLS is used
d47ae7f6
S
1416 'info_dict': {
1417 'id': '12820',
1418 'ext': 'mp4',
1419 'title': "'O Sole Mio",
ec85ded8 1420 'thumbnail': r're:^https?://.*\.jpg$',
d47ae7f6
S
1421 'duration': 216,
1422 'view_count': int,
1423 },
250b042c
S
1424 'params': {
1425 'skip_download': True,
1426 },
2637fadc 1427 'skip': 'This video is unavailable.',
d47ae7f6 1428 },
f8388757
S
1429 # Pladform embed
1430 {
1431 'url': 'http://muz-tv.ru/kinozal/view/7400/',
1432 'info_dict': {
1433 'id': '100183293',
1434 'ext': 'mp4',
62259846 1435 'title': 'Тайны перевала Дятлова • 1 серия 2 часть',
f8388757 1436 'description': 'Документальный сериал-расследование одной из самых жутких тайн ХХ века',
ec85ded8 1437 'thumbnail': r're:^https?://.*\.jpg$',
f8388757
S
1438 'duration': 694,
1439 'age_limit': 0,
1440 },
2637fadc 1441 'skip': 'HTTP Error 404: Not Found',
f8388757 1442 },
c798f15b
S
1443 # Playwire embed
1444 {
1445 'url': 'http://www.cinemablend.com/new/First-Joe-Dirt-2-Trailer-Teaser-Stupid-Greatness-70874.html',
1446 'info_dict': {
1447 'id': '3519514',
1448 'ext': 'mp4',
1449 'title': 'Joe Dirt 2 Beautiful Loser Teaser Trailer',
ec85ded8 1450 'thumbnail': r're:^https?://.*\.png$',
c798f15b
S
1451 'duration': 45.115,
1452 },
1453 },
a4257017
S
1454 # Crooks and Liars embed
1455 {
1456 'url': 'http://crooksandliars.com/2015/04/fox-friends-says-protecting-atheists',
1457 'info_dict': {
1458 'id': '8RUoRhRi',
1459 'ext': 'mp4',
1460 'title': "Fox & Friends Says Protecting Atheists From Discrimination Is Anti-Christian!",
1461 'description': 'md5:e1a46ad1650e3a5ec7196d432799127f',
1462 'timestamp': 1428207000,
1463 'upload_date': '20150405',
1464 'uploader': 'Heather',
1465 },
1466 },
1467 # Crooks and Liars external embed
1468 {
1469 'url': 'http://theothermccain.com/2010/02/02/video-proves-that-bill-kristol-has-been-watching-glenn-beck/comment-page-1/',
1470 'info_dict': {
1471 'id': 'MTE3MjUtMzQ2MzA',
1472 'ext': 'mp4',
1473 'title': 'md5:5e3662a81a4014d24c250d76d41a08d5',
1474 'description': 'md5:9b8e9542d6c3c5de42d6451b7d780cec',
1475 'timestamp': 1265032391,
1476 'upload_date': '20100201',
1477 'uploader': 'Heather',
1478 },
1479 },
facecb84 1480 # NBC Sports vplayer embed
a2edf2e7 1481 {
facecb84 1482 'url': 'http://www.riderfans.com/forum/showthread.php?121827-Freeman&s=e98fa1ea6dc08e886b1678d35212494a',
a2edf2e7 1483 'info_dict': {
facecb84
S
1484 'id': 'ln7x1qSThw4k',
1485 'ext': 'flv',
1486 'title': "PFT Live: New leader in the 'new-look' defense",
1487 'description': 'md5:65a19b4bbfb3b0c0c5768bed1dfad74e',
0738187f
YCH
1488 'uploader': 'NBCU-SPORTS',
1489 'upload_date': '20140107',
1490 'timestamp': 1389118457,
a2edf2e7 1491 },
2637fadc 1492 'skip': 'Invalid Page URL',
418c5cc3 1493 },
de3eb07e
YCH
1494 # NBC News embed
1495 {
1496 'url': 'http://www.vulture.com/2016/06/letterman-couldnt-care-less-about-late-night.html',
1497 'md5': '1aa589c675898ae6d37a17913cf68d66',
1498 'info_dict': {
2637fadc 1499 'id': 'x_dtl_oa_LettermanliftPR_160608',
de3eb07e 1500 'ext': 'mp4',
2637fadc 1501 'title': 'David Letterman: A Preview',
de3eb07e 1502 'description': 'A preview of Tom Brokaw\'s interview with David Letterman as part of the On Assignment series powered by Dateline. Airs Sunday June 12 at 7/6c.',
2637fadc
RA
1503 'upload_date': '20160609',
1504 'timestamp': 1465431544,
1505 'uploader': 'NBCU-NEWS',
de3eb07e
YCH
1506 },
1507 },
418c5cc3
YCH
1508 # UDN embed
1509 {
811586eb 1510 'url': 'https://video.udn.com/news/300346',
01c58f84 1511 'md5': 'fd2060e988c326991037b9aff9df21a6',
418c5cc3 1512 'info_dict': {
01c58f84 1513 'id': '300346',
418c5cc3 1514 'ext': 'mp4',
01c58f84 1515 'title': '中一中男師變性 全校師生力挺',
ec85ded8 1516 'thumbnail': r're:^https?://.*\.jpg$',
811586eb
YCH
1517 },
1518 'params': {
1519 # m3u8 download
1520 'skip_download': True,
1521 },
2637fadc 1522 'expected_warnings': ['Failed to parse JSON Expecting value'],
edfcf7ab 1523 },
b26733ba
YCH
1524 # Brightcove URL in single quotes
1525 {
1526 'url': 'http://www.sportsnet.ca/baseball/mlb/sn-presents-russell-martin-world-citizen/',
1527 'md5': '4ae374f1f8b91c889c4b9203c8c752af',
1528 'info_dict': {
1529 'id': '4255764656001',
1530 'ext': 'mp4',
1531 'title': 'SN Presents: Russell Martin, World Citizen',
1532 'description': 'To understand why he was the Toronto Blue Jays’ top off-season priority is to appreciate his background and upbringing in Montreal, where he first developed his baseball skills. Written and narrated by Stephen Brunt.',
1533 'uploader': 'Rogers Sportsnet',
0738187f
YCH
1534 'uploader_id': '1704050871',
1535 'upload_date': '20150525',
1536 'timestamp': 1432570283,
b26733ba 1537 },
756f574e 1538 },
55adb63e 1539 # Kinja embed
8084be78
S
1540 {
1541 'url': 'http://www.clickhole.com/video/dont-understand-bitcoin-man-will-mumble-explanatio-2537',
1542 'info_dict': {
55adb63e 1543 'id': '106351',
8084be78
S
1544 'ext': 'mp4',
1545 'title': 'Don’t Understand Bitcoin? This Man Will Mumble An Explanation At You',
55adb63e 1546 'description': 'Migrated from OnionStudios',
ec85ded8 1547 'thumbnail': r're:^https?://.*\.jpe?g$',
55adb63e
RA
1548 'uploader': 'clickhole',
1549 'upload_date': '20150527',
1550 'timestamp': 1432744860,
8084be78
S
1551 }
1552 },
b8c1cc1a
S
1553 # SnagFilms embed
1554 {
1555 'url': 'http://whilewewatch.blogspot.ru/2012/06/whilewewatch-whilewewatch-gripping.html',
1556 'info_dict': {
1557 'id': '74849a00-85a9-11e1-9660-123139220831',
1558 'ext': 'mp4',
1559 'title': '#whilewewatch',
1560 }
1561 },
a5158f38
YCH
1562 # AdobeTVVideo embed
1563 {
1564 'url': 'https://helpx.adobe.com/acrobat/how-to/new-experience-acrobat-dc.html?set=acrobat--get-started--essential-beginners',
1565 'md5': '43662b577c018ad707a63766462b1e87',
1566 'info_dict': {
1567 'id': '2456',
1568 'ext': 'mp4',
1569 'title': 'New experience with Acrobat DC',
1570 'description': 'New experience with Acrobat DC',
1571 'duration': 248.667,
1572 },
1f812580 1573 },
ed126900 1574 # BrightcoveInPageEmbed embed
1575 {
1576 'url': 'http://www.geekandsundry.com/tabletop-bonus-wils-final-thoughts-on-dread/',
1577 'info_dict': {
1578 'id': '4238694884001',
1579 'ext': 'flv',
1580 'title': 'Tabletop: Dread, Last Thoughts',
1581 'description': 'Tabletop: Dread, Last Thoughts',
1582 'duration': 51690,
1583 },
750b9ff0 1584 },
d10fe835
YCH
1585 # Brightcove embed, with no valid 'renditions' but valid 'IOSRenditions'
1586 # This video can't be played in browsers if Flash disabled and UA set to iPhone, which is actually a false alarm
1587 {
1588 'url': 'https://dl.dropboxusercontent.com/u/29092637/interview.html',
1589 'info_dict': {
1590 'id': '4785848093001',
1591 'ext': 'mp4',
1592 'title': 'The Cardinal Pell Interview',
1593 'description': 'Sky News Contributor Andrew Bolt interviews George Pell in Rome, following the Cardinal\'s evidence before the Royal Commission into Child Abuse. ',
1594 'uploader': 'GlobeCast Australia - GlobeStream',
0738187f
YCH
1595 'uploader_id': '2733773828001',
1596 'upload_date': '20160304',
1597 'timestamp': 1457083087,
d10fe835
YCH
1598 },
1599 'params': {
1600 # m3u8 downloads
1601 'skip_download': True,
1602 },
1603 },
9edf47df
S
1604 {
1605 # Brightcove embed with whitespace around attribute names
1606 'url': 'http://www.stack.com/video/3167554373001/learn-to-hit-open-three-pointers-with-damian-lillard-s-baseline-drift-drill',
1607 'info_dict': {
1608 'id': '3167554373001',
1609 'ext': 'mp4',
1610 'title': "Learn to Hit Open Three-Pointers With Damian Lillard's Baseline Drift Drill",
1611 'description': 'md5:57bacb0e0f29349de4972bfda3191713',
1612 'uploader_id': '1079349493',
1613 'upload_date': '20140207',
1614 'timestamp': 1391810548,
1615 },
1616 'params': {
1617 'skip_download': True,
1618 },
1619 },
134c207e
YCH
1620 # Another form of arte.tv embed
1621 {
1622 'url': 'http://www.tv-replay.fr/redirection/09-04-16/arte-reportage-arte-11508975.html',
1623 'md5': '850bfe45417ddf221288c88a0cffe2e2',
1624 'info_dict': {
1625 'id': '030273-562_PLUS7-F',
1626 'ext': 'mp4',
1627 'title': 'ARTE Reportage - Nulle part, en France',
1628 'description': 'md5:e3a0e8868ed7303ed509b9e3af2b870d',
1629 'upload_date': '20160409',
1630 },
1631 },
4a120778
YCH
1632 # Duplicated embedded video URLs
1633 {
1634 'url': 'http://www.hudl.com/athlete/2538180/highlights/149298443',
1635 'info_dict': {
1636 'id': '149298443_480_16c25b74_2',
1637 'ext': 'mp4',
1638 'title': 'vs. Blue Orange Spring Game',
1639 'uploader': 'www.hudl.com',
1640 },
1641 },
371ddb14
S
1642 # twitter:player:stream embed
1643 {
1644 'url': 'http://www.rtl.be/info/video/589263.aspx?CategoryID=288',
1645 'info_dict': {
1646 'id': 'master',
1647 'ext': 'mp4',
1648 'title': 'Une nouvelle espèce de dinosaure découverte en Argentine',
1649 'uploader': 'www.rtl.be',
1650 },
1651 'params': {
1652 # m3u8 downloads
1653 'skip_download': True,
1654 },
1655 },
32917907
RA
1656 # twitter:player embed
1657 {
1658 'url': 'http://www.theatlantic.com/video/index/484130/what-do-black-holes-sound-like/',
1659 'md5': 'a3e0df96369831de324f0778e126653c',
1660 'info_dict': {
1661 'id': '4909620399001',
1662 'ext': 'mp4',
1663 'title': 'What Do Black Holes Sound Like?',
1664 'description': 'what do black holes sound like',
1665 'upload_date': '20160524',
1666 'uploader_id': '29913724001',
1667 'timestamp': 1464107587,
1668 'uploader': 'TheAtlantic',
1669 },
1670 'add_ie': ['BrightcoveLegacy'],
fd6ca382
YCH
1671 },
1672 # Facebook <iframe> embed
1673 {
1674 'url': 'https://www.hostblogger.de/blog/archives/6181-Auto-jagt-Betonmischer.html',
dbf0157a 1675 'md5': 'fbcde74f534176ecb015849146dd3aee',
fd6ca382
YCH
1676 'info_dict': {
1677 'id': '599637780109885',
1678 'ext': 'mp4',
1679 'title': 'Facebook video #599637780109885',
1680 },
1681 },
fd1c5fba
S
1682 # Facebook <iframe> embed, plugin video
1683 {
1684 'url': 'http://5pillarsuk.com/2017/06/07/tariq-ramadan-disagrees-with-pr-exercise-by-imams-refusing-funeral-prayers-for-london-attackers/',
1685 'info_dict': {
1686 'id': '1754168231264132',
1687 'ext': 'mp4',
1688 'title': 'About the Imams and Religious leaders refusing to perform funeral prayers for...',
1689 'uploader': 'Tariq Ramadan (official)',
1690 'timestamp': 1496758379,
1691 'upload_date': '20170606',
1692 },
1693 'params': {
1694 'skip_download': True,
1695 },
1696 },
fd6ca382
YCH
1697 # Facebook API embed
1698 {
1699 'url': 'http://www.lothype.com/blue-stars-2016-preview-standstill-full-show/',
dbf0157a 1700 'md5': 'a47372ee61b39a7b90287094d447d94e',
fd6ca382
YCH
1701 'info_dict': {
1702 'id': '10153467542406923',
1703 'ext': 'mp4',
1704 'title': 'Facebook video #10153467542406923',
1705 },
7deef1ba
YCH
1706 },
1707 # Wordpress "YouTube Video Importer" plugin
1708 {
1709 'url': 'http://www.lothype.com/blue-devils-drumline-stanford-lot-2016/',
dbf0157a 1710 'md5': 'd16797741b560b485194eddda8121b48',
7deef1ba
YCH
1711 'info_dict': {
1712 'id': 'HNTXWDXV9Is',
1713 'ext': 'mp4',
1714 'title': 'Blue Devils Drumline Stanford lot 2016',
1715 'upload_date': '20160627',
1716 'uploader_id': 'GENOCIDE8GENERAL10',
1717 'uploader': 'cylus cyrus',
1718 },
1719 },
81953d1a
RA
1720 {
1721 # video stored on custom kaltura server
1722 'url': 'http://www.expansion.com/multimedia/videos.html?media=EQcM30NHIPv',
1723 'md5': '537617d06e64dfed891fa1593c4b30cc',
1724 'info_dict': {
1725 'id': '0_1iotm5bh',
1726 'ext': 'mp4',
1727 'title': 'Elecciones británicas: 5 lecciones para Rajoy',
1728 'description': 'md5:435a89d68b9760b92ce67ed227055f16',
1729 'uploader_id': 'videos.expansion@el-mundo.net',
1730 'upload_date': '20150429',
1731 'timestamp': 1430303472,
1732 },
1733 'add_ie': ['Kaltura'],
1734 },
562de77f
S
1735 {
1736 # multiple kaltura embeds, nsfw
1737 'url': 'https://www.quartier-rouge.be/prive/femmes/kamila-avec-video-jaime-sadomie.html',
1738 'info_dict': {
1739 'id': 'kamila-avec-video-jaime-sadomie',
1740 'title': "Kamila avec vídeo “J'aime sadomie”",
1741 },
1742 'playlist_count': 8,
1743 },
c03adf90
YCH
1744 {
1745 # Non-standard Vimeo embed
1746 'url': 'https://openclassrooms.com/courses/understanding-the-web',
1747 'md5': '64d86f1c7d369afd9a78b38cbb88d80a',
1748 'info_dict': {
1749 'id': '148867247',
1750 'ext': 'mp4',
1751 'title': 'Understanding the web - Teaser',
1752 'description': 'This is "Understanding the web - Teaser" by openclassrooms on Vimeo, the home for high quality videos and the people who love them.',
1753 'upload_date': '20151214',
1754 'uploader': 'OpenClassrooms',
1755 'uploader_id': 'openclassrooms',
1756 },
1757 'add_ie': ['Vimeo'],
1758 },
a5ff05df
S
1759 {
1760 # generic vimeo embed that requires original URL passed as Referer
1761 'url': 'http://racing4everyone.eu/2016/07/30/formula-1-2016-round12-germany/',
1762 'only_matching': True,
1763 },
1979969f
S
1764 {
1765 'url': 'https://support.arkena.com/display/PLAY/Ways+to+embed+your+video',
1766 'md5': 'b96f2f71b359a8ecd05ce4e1daa72365',
1767 'info_dict': {
1768 'id': 'b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe',
1769 'ext': 'mp4',
1770 'title': 'Big Buck Bunny',
1771 'description': 'Royalty free test video',
1772 'timestamp': 1432816365,
1773 'upload_date': '20150528',
1774 'is_live': False,
1775 },
1776 'params': {
1777 'skip_download': True,
1778 },
1779 'add_ie': [ArkenaIE.ie_key()],
1780 },
2a1321a2
S
1781 {
1782 'url': 'http://nova.bg/news/view/2016/08/16/156543/%D0%BD%D0%B0-%D0%BA%D0%BE%D1%81%D1%8A%D0%BC-%D0%BE%D1%82-%D0%B2%D0%B7%D1%80%D0%B8%D0%B2-%D0%BE%D1%82%D1%86%D0%B5%D0%BF%D0%B8%D1%85%D0%B0-%D1%86%D1%8F%D0%BB-%D0%BA%D0%B2%D0%B0%D1%80%D1%82%D0%B0%D0%BB-%D0%B7%D0%B0%D1%80%D0%B0%D0%B4%D0%B8-%D0%B8%D0%B7%D1%82%D0%B8%D1%87%D0%B0%D0%BD%D0%B5-%D0%BD%D0%B0-%D0%B3%D0%B0%D0%B7-%D0%B2-%D0%BF%D0%BB%D0%BE%D0%B2%D0%B4%D0%B8%D0%B2/',
1783 'info_dict': {
1784 'id': '1c7141f46c',
1785 'ext': 'mp4',
1786 'title': 'НА КОСЪМ ОТ ВЗРИВ: Изтичане на газ на бензиностанция в Пловдив',
1787 },
1788 'params': {
1789 'skip_download': True,
1790 },
1791 'add_ie': [Vbox7IE.ie_key()],
1792 },
b0c8f2e9
DR
1793 {
1794 # DBTV embeds
1795 'url': 'http://www.dagbladet.no/2016/02/23/nyheter/nordlys/ski/troms/ver/43254897/',
fd3ec986
S
1796 'info_dict': {
1797 'id': '43254897',
1798 'title': 'Etter ett års planlegging, klaffet endelig alt: - Jeg måtte ta en liten dans',
1799 },
b0c8f2e9
DR
1800 'playlist_mincount': 3,
1801 },
e186a9ec
S
1802 {
1803 # Videa embeds
1804 'url': 'http://forum.dvdtalk.com/movie-talk/623756-deleted-magic-star-wars-ot-deleted-alt-scenes-docu-style.html',
1805 'info_dict': {
1806 'id': '623756-deleted-magic-star-wars-ot-deleted-alt-scenes-docu-style',
1807 'title': 'Deleted Magic - Star Wars: OT Deleted / Alt. Scenes Docu. Style - DVD Talk Forum',
1808 },
1809 'playlist_mincount': 2,
1810 },
b687c85e
S
1811 {
1812 # 20 minuten embed
1813 'url': 'http://www.20min.ch/schweiz/news/story/So-kommen-Sie-bei-Eis-und-Schnee-sicher-an-27032552',
1814 'info_dict': {
1815 'id': '523629',
1816 'ext': 'mp4',
1817 'title': 'So kommen Sie bei Eis und Schnee sicher an',
1818 'description': 'md5:117c212f64b25e3d95747e5276863f7d',
1819 },
1820 'params': {
1821 'skip_download': True,
1822 },
1823 'add_ie': [TwentyMinutenIE.ie_key()],
6ef3e65a
S
1824 },
1825 {
1826 # VideoPress embed
1827 'url': 'https://en.support.wordpress.com/videopress/',
1828 'info_dict': {
1829 'id': 'OcobLTqC',
1830 'ext': 'm4v',
1831 'title': 'IMG_5786',
1832 'timestamp': 1435711927,
1833 'upload_date': '20150701',
1834 },
1835 'params': {
1836 'skip_download': True,
1837 },
1838 'add_ie': [VideoPressIE.ie_key()],
fef51645 1839 },
eb3079b6
S
1840 {
1841 # Rutube embed
1842 'url': 'http://magazzino.friday.ru/videos/vipuski/kazan-2',
1843 'info_dict': {
1844 'id': '9b3d5bee0a8740bf70dfd29d3ea43541',
1845 'ext': 'flv',
1846 'title': 'Магаззино: Казань 2',
1847 'description': 'md5:99bccdfac2269f0e8fdbc4bbc9db184a',
1848 'uploader': 'Магаззино',
1849 'upload_date': '20170228',
1850 'uploader_id': '996642',
1851 },
1852 'params': {
1853 'skip_download': True,
1854 },
1855 'add_ie': [RutubeIE.ie_key()],
1856 },
71738b14 1857 {
fdf80059 1858 # glomex:embed
71738b14
ZM
1859 'url': 'https://www.skai.gr/news/world/iatrikos-syllogos-tourkias-to-turkovac-aplo-dialyma-erntogan-eiste-apateones-kai-pseytes',
1860 'info_dict': {
1861 'id': 'v-ch2nkhcirwc9-sf',
1862 'ext': 'mp4',
1863 'title': 'md5:786e1e24e06c55993cee965ef853a0c1',
1864 'description': 'md5:8b517a61d577efe7e36fde72fd535995',
1865 'timestamp': 1641885019,
1866 'upload_date': '20220111',
1867 'duration': 460000,
b143e83e 1868 'thumbnail': 'https://i3thumbs.glomex.com/dC1idjJwdndiMjRzeGwvMjAyMi8wMS8xMS8wNy8xMF8zNV82MWRkMmQ2YmU5ZTgyLmpwZw==/profile:player-960x540',
71738b14
ZM
1869 },
1870 },
b143e83e
ZM
1871 {
1872 # megatvcom:embed
1873 'url': 'https://www.in.gr/2021/12/18/greece/apokalypsi-mega-poios-parelave-tin-ereyna-tsiodra-ek-merous-tis-kyvernisis-o-prothypourgos-telika-gnorize/',
1874 'info_dict': {
1875 'id': 'apokalypsi-mega-poios-parelave-tin-ereyna-tsiodra-ek-merous-tis-kyvernisis-o-prothypourgos-telika-gnorize',
1876 'title': 'md5:5e569cf996ec111057c2764ec272848f',
1877 },
1878 'playlist': [{
1879 'md5': '1afa26064ff00ccb91617957dbc73dc1',
1880 'info_dict': {
1881 'ext': 'mp4',
1882 'id': '564916',
1883 'display_id': 'md5:6cdf22d3a2e7bacb274b7295089a1770',
1884 'title': 'md5:33b9dd39584685b62873043670eb52a6',
1885 'description': 'md5:c1db7310f390518ac36dd69d947ef1a1',
1886 'timestamp': 1639753145,
1887 'upload_date': '20211217',
1888 'thumbnail': 'https://www.megatv.com/wp-content/uploads/2021/12/prezerakos-1024x597.jpg',
1889 },
1890 }, {
1891 'md5': '4a1c220695f1ef865a8b7966a53e2474',
1892 'info_dict': {
1893 'ext': 'mp4',
1894 'id': '564905',
1895 'display_id': 'md5:ead15695e485e649aed2b81ebd699b88',
1896 'title': 'md5:2b71fd54249a3ca34609fe39ae31c47b',
1897 'description': 'md5:c42e12f638d0a97d6de4508e2c4df982',
1898 'timestamp': 1639753047,
1899 'upload_date': '20211217',
1900 'thumbnail': 'https://www.megatv.com/wp-content/uploads/2021/12/tsiodras-mitsotakis-1024x545.jpg',
1901 },
1902 }]
1903 },
2d49720f
ZM
1904 {
1905 'url': 'https://www.ertnews.gr/video/manolis-goyalles-o-anthropos-piso-apo-ti-diadiktyaki-vasilopita/',
1906 'info_dict': {
1907 'id': '2022/tv/news-themata-ianouarios/20220114-apotis6-gouales-pita.mp4',
1908 'ext': 'mp4',
1909 'title': 'md5:df64f5b61c06d0e9556c0cdd5cf14464',
1910 'thumbnail': 'https://www.ert.gr/themata/photos/2021/20220114-apotis6-gouales-pita.jpg',
1911 },
1912 },
fef51645
YCH
1913 {
1914 # ThePlatform embedded with whitespaces in URLs
1915 'url': 'http://www.golfchannel.com/topics/shows/golftalkcentral.htm',
1916 'only_matching': True,
1917 },
97952bdb
JH
1918 {
1919 # Senate ISVP iframe https
1920 'url': 'https://www.hsgac.senate.gov/hearings/canadas-fast-track-refugee-plan-unanswered-questions-and-implications-for-us-national-security',
1921 'md5': 'fb8c70b0b515e5037981a2492099aab8',
1922 'info_dict': {
1923 'id': 'govtaff020316',
1924 'ext': 'mp4',
1925 'title': 'Integrated Senate Video Player',
1926 },
1927 'add_ie': [SenateISVPIE.ie_key()],
1928 },
ab87c260
S
1929 {
1930 # Limelight embeds (1 channel embed + 4 media embeds)
1931 'url': 'http://www.sedona.com/FacilitatorTraining2017',
1932 'info_dict': {
1933 'id': 'FacilitatorTraining2017',
1934 'title': 'Facilitator Training 2017',
1935 },
1936 'playlist_mincount': 5,
1937 },
eb02940c
S
1938 {
1939 # Limelight embed (LimelightPlayerUtil.embed)
1940 'url': 'https://tv5.ca/videos?v=xuu8qowr291ri',
1941 'info_dict': {
1942 'id': '95d035dc5c8a401588e9c0e6bd1e9c92',
1943 'ext': 'mp4',
1944 'title': '07448641',
1945 'timestamp': 1499890639,
1946 'upload_date': '20170712',
1947 },
1948 'params': {
1949 'skip_download': True,
1950 },
1951 'add_ie': ['LimelightMedia'],
1952 },
7986c3ab
S
1953 {
1954 'url': 'http://kron4.com/2017/04/28/standoff-with-walnut-creek-murder-suspect-ends-with-arrest/',
1955 'info_dict': {
1956 'id': 'standoff-with-walnut-creek-murder-suspect-ends-with-arrest',
1957 'title': 'Standoff with Walnut Creek murder suspect ends',
1958 'description': 'md5:3ccc48a60fc9441eeccfc9c469ebf788',
1959 },
1960 'playlist_mincount': 4,
1961 },
55719459
JH
1962 {
1963 # WashingtonPost embed
1964 'url': 'http://www.vanityfair.com/hollywood/2017/04/donald-trump-tv-pitches',
1965 'info_dict': {
1966 'id': '8caf6e88-d0ec-11e5-90d3-34c2c42653ac',
1967 'ext': 'mp4',
1968 'title': "No one has seen the drama series based on Trump's life \u2014 until now",
1969 'description': 'Donald Trump wanted a weekly TV drama based on his life. It never aired. But The Washington Post recently obtained a scene from the pilot script — and enlisted actors.',
1970 'timestamp': 1455216756,
1971 'uploader': 'The Washington Post',
1972 'upload_date': '20160211',
1973 },
1974 'add_ie': [WashingtonPostIE.ie_key()],
1975 },
2b8e6a68
S
1976 {
1977 # Mediaset embed
1978 'url': 'http://www.tgcom24.mediaset.it/politica/serracchiani-voglio-vivere-in-una-societa-aperta-reazioni-sproporzionate-_3071354-201702a.shtml',
1979 'info_dict': {
1980 'id': '720642',
1981 'ext': 'mp4',
1982 'title': 'Serracchiani: "Voglio vivere in una società aperta, con tutela del patto di fiducia"',
1983 },
1984 'params': {
1985 'skip_download': True,
1986 },
1987 'add_ie': [MediasetIE.ie_key()],
1988 },
73cf76a9
S
1989 {
1990 # JOJ.sk embeds
1991 'url': 'https://www.noviny.sk/slovensko/238543-slovenskom-sa-prehnala-vlna-silnych-burok',
1992 'info_dict': {
1993 'id': '238543-slovenskom-sa-prehnala-vlna-silnych-burok',
1994 'title': 'Slovenskom sa prehnala vlna silných búrok',
1995 },
1996 'playlist_mincount': 5,
1997 'add_ie': [JojIE.ie_key()],
1998 },
4328ddf8
S
1999 {
2000 # AMP embed (see https://www.ampproject.org/docs/reference/components/amp-video)
2001 'url': 'https://tvrain.ru/amp/418921/',
2002 'md5': 'cc00413936695987e8de148b67d14f1d',
2003 'info_dict': {
2004 'id': '418921',
2005 'ext': 'mp4',
2006 'title': 'Стас Намин: «Мы нарушили девственность Кремля»',
2007 },
2008 },
41918eaa 2009 {
2010 # vzaar embed
1663bd6e
S
2011 'url': 'http://help.vzaar.com/article/165-embedding-video',
2012 'md5': '7e3919d9d2620b89e3e00bec7fe8c9d4',
41918eaa 2013 'info_dict': {
1663bd6e 2014 'id': '8707641',
41918eaa 2015 'ext': 'mp4',
1663bd6e 2016 'title': 'Building A Business Online: Principal Chairs Q & A',
41918eaa 2017 },
2018 },
9ce1ac40 2019 {
2020 # multiple HTML5 videos on one page
2021 'url': 'https://www.paragon-software.com/home/rk-free/keyscenarios.html',
2022 'info_dict': {
2023 'id': 'keyscenarios',
2024 'title': 'Rescue Kit 14 Free Edition - Getting started',
2025 },
2026 'playlist_count': 4,
0987f2dd
T
2027 },
2028 {
2029 # vshare embed
7a5c1cfe 2030 'url': 'https://youtube-dl-demo.neocities.org/vshare.html',
0987f2dd
T
2031 'md5': '17b39f55b5497ae8b59f5fbce8e35886',
2032 'info_dict': {
2033 'id': '0f64ce6',
2034 'title': 'vl14062007715967',
2035 'ext': 'mp4',
2036 }
2ca7ed41
S
2037 },
2038 {
2039 'url': 'http://www.heidelberg-laureate-forum.org/blog/video/lecture-friday-september-23-2016-sir-c-antony-r-hoare/',
2040 'md5': 'aecd089f55b1cb5a59032cb049d3a356',
2041 'info_dict': {
2042 'id': '90227f51a80c4d8f86c345a7fa62bd9a1d',
2043 'ext': 'mp4',
2044 'title': 'Lecture: Friday, September 23, 2016 - Sir Tony Hoare',
2045 'description': 'md5:5a51db84a62def7b7054df2ade403c6c',
2046 'timestamp': 1474354800,
2047 'upload_date': '20160920',
2048 }
7d540621
S
2049 },
2050 {
2051 'url': 'http://www.kidzworld.com/article/30935-trolls-the-beat-goes-on-interview-skylar-astin-and-amanda-leighton',
2052 'info_dict': {
2053 'id': '1731611',
2054 'ext': 'mp4',
2055 'title': 'Official Trailer | TROLLS: THE BEAT GOES ON!',
2056 'description': 'md5:eb5f23826a027ba95277d105f248b825',
2057 'timestamp': 1516100691,
2058 'upload_date': '20180116',
2059 },
2060 'params': {
2061 'skip_download': True,
2062 },
2063 'add_ie': [SpringboardPlatformIE.ie_key()],
ea696249 2064 },
4c780fbd
S
2065 {
2066 'url': 'https://www.yapfiles.ru/show/1872528/690b05d3054d2dbe1e69523aa21bb3b1.mp4.html',
2067 'info_dict': {
2068 'id': 'vMDE4NzI1Mjgt690b',
2069 'ext': 'mp4',
2070 'title': 'Котята',
2071 },
2072 'add_ie': [YapFilesIE.ie_key()],
2073 'params': {
2074 'skip_download': True,
2075 },
1fc37ca3 2076 },
660a230b
S
2077 {
2078 # CloudflareStream embed
2079 'url': 'https://www.cloudflare.com/products/cloudflare-stream/',
2080 'info_dict': {
2081 'id': '31c9291ab41fac05471db4e73aa11717',
2082 'ext': 'mp4',
2083 'title': '31c9291ab41fac05471db4e73aa11717',
2084 },
2085 'add_ie': [CloudflareStreamIE.ie_key()],
2086 'params': {
2087 'skip_download': True,
2088 },
2089 },
6bd499e8
S
2090 {
2091 # PeerTube embed
2092 'url': 'https://joinpeertube.org/fr/home/',
2093 'info_dict': {
2094 'id': 'home',
2095 'title': 'Reprenez le contrôle de vos vidéos ! #JoinPeertube',
2096 },
2097 'playlist_count': 2,
2098 },
aee36ca8
S
2099 {
2100 # Indavideo embed
2101 'url': 'https://streetkitchen.hu/receptek/igy_kell_otthon_hamburgert_sutni/',
2102 'info_dict': {
2103 'id': '1693903',
2104 'ext': 'mp4',
2105 'title': 'Így kell otthon hamburgert sütni',
2106 'description': 'md5:f5a730ecf900a5c852e1e00540bbb0f7',
2107 'timestamp': 1426330212,
2108 'upload_date': '20150314',
2109 'uploader': 'StreetKitchen',
2110 'uploader_id': '546363',
2111 },
2112 'add_ie': [IndavideoEmbedIE.ie_key()],
2113 'params': {
2114 'skip_download': True,
2115 },
2116 },
cfd7f2a6
S
2117 {
2118 # APA embed via JWPlatform embed
2119 'url': 'http://www.vol.at/blue-man-group/5593454',
2120 'info_dict': {
2121 'id': 'jjv85FdZ',
2122 'ext': 'mp4',
2123 'title': '"Blau ist mysteriös": Die Blue Man Group im Interview',
2124 'description': 'md5:d41d8cd98f00b204e9800998ecf8427e',
2125 'thumbnail': r're:^https?://.*\.jpg$',
2126 'duration': 254,
2127 'timestamp': 1519211149,
2128 'upload_date': '20180221',
2129 },
2130 'params': {
2131 'skip_download': True,
2132 },
2133 },
1fc37ca3
SO
2134 {
2135 'url': 'http://share-videos.se/auto/video/83645793?uid=13',
2136 'md5': 'b68d276de422ab07ee1d49388103f457',
2137 'info_dict': {
2138 'id': '83645793',
2139 'title': 'Lock up and get excited',
1fc37ca3 2140 'ext': 'mp4'
d3431dcb
S
2141 },
2142 'skip': 'TODO: fix nested playlists processing in tests',
2143 },
9d1b2138
S
2144 {
2145 # Viqeo embeds
2146 'url': 'https://viqeo.tv/',
2147 'info_dict': {
2148 'id': 'viqeo',
2149 'title': 'All-new video platform',
2150 },
2151 'playlist_count': 6,
2152 },
d78657fd
BM
2153 {
2154 # Squarespace video embed, 2019-08-28
2155 'url': 'http://ootboxford.com',
2156 'info_dict': {
2157 'id': 'Tc7b_JGdZfw',
2158 'title': 'Out of the Blue, at Childish Things 10',
7cb51b5d
S
2159 'ext': 'mp4',
2160 'description': 'md5:a83d0026666cf5ee970f8bd1cfd69c7f',
2161 'uploader_id': 'helendouglashouse',
2162 'uploader': 'Helen & Douglas House',
2163 'upload_date': '20140328',
d78657fd
BM
2164 },
2165 'params': {
2166 'skip_download': True,
2167 },
2168 },
29f7c58a 2169 # {
2170 # # Zype embed
2171 # 'url': 'https://www.cookscountry.com/episode/554-smoky-barbecue-favorites',
2172 # 'info_dict': {
2173 # 'id': '5b400b834b32992a310622b9',
2174 # 'ext': 'mp4',
2175 # 'title': 'Smoky Barbecue Favorites',
2176 # 'thumbnail': r're:^https?://.*\.jpe?g',
2177 # 'description': 'md5:5ff01e76316bd8d46508af26dc86023b',
2178 # 'upload_date': '20170909',
2179 # 'timestamp': 1504915200,
2180 # },
2181 # 'add_ie': [ZypeIE.ie_key()],
2182 # 'params': {
2183 # 'skip_download': True,
2184 # },
2185 # },
e0b6e988
S
2186 {
2187 # videojs embed
2188 'url': 'https://video.sibnet.ru/shell.php?videoid=3422904',
2189 'info_dict': {
2190 'id': 'shell',
2191 'ext': 'mp4',
2192 'title': 'Доставщик пиццы спросил разрешения сыграть на фортепиано',
2193 'description': 'md5:89209cdc587dab1e4a090453dbaa2cb1',
2194 'thumbnail': r're:^https?://.*\.jpg$',
2195 },
2196 'params': {
2197 'skip_download': True,
2198 },
2199 'expected_warnings': ['Failed to download MPD manifest'],
2200 },
5e3da0d4
RA
2201 {
2202 # DailyMotion embed with DM.player
2203 'url': 'https://www.beinsports.com/us/copa-del-rey/video/the-locker-room-valencia-beat-barca-in-copa/1203804',
2204 'info_dict': {
2205 'id': 'k6aKkGHd9FJs4mtJN39',
2206 'ext': 'mp4',
2207 'title': 'The Locker Room: Valencia Beat Barca In Copa del Rey Final',
2208 'description': 'This video is private.',
2209 'uploader_id': 'x1jf30l',
2210 'uploader': 'beIN SPORTS USA',
2211 'upload_date': '20190528',
2212 'timestamp': 1559062971,
2213 },
2214 'params': {
2215 'skip_download': True,
2216 },
2217 },
1a20d295
ZM
2218 {
2219 # tvopengr:embed
2220 'url': 'https://www.ethnos.gr/World/article/190604/hparosiaxekinoynoisynomiliessthgeneyhmethskiatoypolemoypanoapothnoykrania',
2221 'md5': 'eb0c3995d0a6f18f6538c8e057865d7d',
2222 'info_dict': {
2223 'id': '101119',
2224 'ext': 'mp4',
2225 'display_id': 'oikarpoitondiapragmateyseonhparosias',
2226 'title': 'md5:b979f4d640c568617d6547035528a149',
2227 'description': 'md5:e54fc1977c7159b01cc11cd7d9d85550',
2228 'timestamp': 1641772800,
2229 'upload_date': '20220110',
2230 'thumbnail': 'https://opentv-static.siliconweb.com/imgHandler/1920/70bc39fa-895b-4918-a364-c39d2135fc6d.jpg',
2231
2232 }
2233 },
764f5de2
PW
2234 {
2235 # blogger embed
2236 'url': 'https://blog.tomeuvizoso.net/2019/01/a-panfrost-milestone.html',
2237 'md5': 'f1bc19b6ea1b0fd1d81e84ca9ec467ac',
2238 'info_dict': {
2239 'id': 'BLOGGER-video-3c740e3a49197e16-796',
2240 'ext': 'mp4',
2241 'title': 'Blogger',
2242 'thumbnail': r're:^https?://.*',
2243 },
2244 },
6e6b70d6
S
2245 # {
2246 # # TODO: find another test
2247 # # http://schema.org/VideoObject
2248 # 'url': 'https://flipagram.com/f/nyvTSJMKId',
2249 # 'md5': '888dcf08b7ea671381f00fab74692755',
2250 # 'info_dict': {
2251 # 'id': 'nyvTSJMKId',
2252 # 'ext': 'mp4',
2253 # 'title': 'Flipagram by sjuria101 featuring Midnight Memories by One Direction',
2254 # 'description': '#love for cats.',
2255 # 'timestamp': 1461244995,
2256 # 'upload_date': '20160421',
2257 # },
2258 # 'params': {
2259 # 'force_generic_extractor': True,
2260 # },
29f7c58a 2261 # },
2262 {
2263 # VHX Embed
2264 'url': 'https://demo.vhx.tv/category-c/videos/file-example-mp4-480-1-5mg-copy',
2265 'info_dict': {
2266 'id': '858208',
2267 'ext': 'mp4',
2268 'title': 'Untitled',
2269 'uploader_id': 'user80538407',
2270 'uploader': 'OTT Videos',
2271 },
2272 },
2273 {
2274 # ArcPublishing PoWa video player
2275 'url': 'https://www.adn.com/politics/2020/11/02/video-senate-candidates-campaign-in-anchorage-on-eve-of-election-day/',
2276 'md5': 'b03b2fac8680e1e5a7cc81a5c27e71b3',
2277 'info_dict': {
2278 'id': '8c99cb6e-b29c-4bc9-9173-7bf9979225ab',
2279 'ext': 'mp4',
2280 'title': 'Senate candidates wave to voters on Anchorage streets',
2281 'description': 'md5:91f51a6511f090617353dc720318b20e',
2282 'timestamp': 1604378735,
2283 'upload_date': '20201103',
2284 'duration': 1581,
2285 },
2286 },
2181983a 2287 {
2288 # MyChannels SDK embed
2289 # https://www.24kitchen.nl/populair/deskundige-dit-waarom-sommigen-gevoelig-zijn-voor-voedselallergieen
2290 'url': 'https://www.demorgen.be/nieuws/burgemeester-rotterdam-richt-zich-in-videoboodschap-tot-relschoppers-voelt-het-goed~b0bcfd741/',
2291 'md5': '90c0699c37006ef18e198c032d81739c',
2292 'info_dict': {
2293 'id': '194165',
2294 'ext': 'mp4',
2295 'title': 'Burgemeester Aboutaleb spreekt relschoppers toe',
2296 'timestamp': 1611740340,
2297 'upload_date': '20210127',
2298 'duration': 159,
2299 },
2300 },
bc2ca1bb 2301 {
2302 # Simplecast player embed
2303 'url': 'https://www.bio.org/podcast',
2304 'info_dict': {
2305 'id': 'podcast',
2306 'title': 'I AM BIO Podcast | BIO',
2307 },
2308 'playlist_mincount': 52,
2309 },
e4edeb62 2310 {
b73612a2 2311 # Sibnet embed (https://help.sibnet.ru/?sibnet_video_embed)
2312 'url': 'https://phpbb3.x-tk.ru/bbcode-video-sibnet-t24.html',
2313 'only_matching': True,
2314 }, {
e4edeb62 2315 # WimTv embed player
2316 'url': 'http://www.msmotor.tv/wearefmi-pt-2-2021/',
2317 'info_dict': {
2318 'id': 'wearefmi-pt-2-2021',
2319 'title': '#WEAREFMI – PT.2 – 2021 – MsMotorTV',
2320 },
2321 'playlist_count': 1,
a318f59d 2322 }, {
2323 # KVS Player
2324 'url': 'https://www.kvs-demo.com/videos/105/kelis-4th-of-july/',
2325 'info_dict': {
2326 'id': '105',
2327 'display_id': 'kelis-4th-of-july',
2328 'ext': 'mp4',
2329 'title': 'Kelis - 4th Of July',
2330 'thumbnail': 'https://kvs-demo.com/contents/videos_screenshots/0/105/preview.jpg',
2331 },
2332 'params': {
2333 'skip_download': True,
2334 },
2335 }, {
2336 # KVS Player
2337 'url': 'https://www.kvs-demo.com/embed/105/',
2338 'info_dict': {
2339 'id': '105',
2340 'display_id': 'kelis-4th-of-july',
2341 'ext': 'mp4',
2342 'title': 'Kelis - 4th Of July / Embed Player',
2343 'thumbnail': 'https://kvs-demo.com/contents/videos_screenshots/0/105/preview.jpg',
2344 },
2345 'params': {
2346 'skip_download': True,
2347 },
2348 }, {
2349 # KVS Player
2350 'url': 'https://thisvid.com/videos/french-boy-pantsed/',
2351 'md5': '3397979512c682f6b85b3b04989df224',
2352 'info_dict': {
2353 'id': '2400174',
2354 'display_id': 'french-boy-pantsed',
2355 'ext': 'mp4',
2356 'title': 'French Boy Pantsed - ThisVid.com',
2357 'thumbnail': 'https://media.thisvid.com/contents/videos_screenshots/2400000/2400174/preview.mp4.jpg',
2358 }
2359 }, {
2360 # KVS Player
2361 'url': 'https://thisvid.com/embed/2400174/',
2362 'md5': '3397979512c682f6b85b3b04989df224',
2363 'info_dict': {
2364 'id': '2400174',
2365 'display_id': 'french-boy-pantsed',
2366 'ext': 'mp4',
2367 'title': 'French Boy Pantsed - ThisVid.com',
2368 'thumbnail': 'https://media.thisvid.com/contents/videos_screenshots/2400000/2400174/preview.mp4.jpg',
2369 }
2370 }, {
2371 # KVS Player
2372 'url': 'https://youix.com/video/leningrad-zoj/',
2373 'md5': '94f96ba95706dc3880812b27b7d8a2b8',
2374 'info_dict': {
2375 'id': '18485',
2376 'display_id': 'leningrad-zoj',
2377 'ext': 'mp4',
2378 'title': 'Клип: Ленинград - ЗОЖ скачать, смотреть онлайн | Youix.com',
2379 'thumbnail': 'https://youix.com/contents/videos_screenshots/18000/18485/preview_480x320_youix_com.mp4.jpg',
2380 }
2381 }, {
2382 # KVS Player
2383 'url': 'https://youix.com/embed/18485',
2384 'md5': '94f96ba95706dc3880812b27b7d8a2b8',
2385 'info_dict': {
2386 'id': '18485',
2387 'display_id': 'leningrad-zoj',
2388 'ext': 'mp4',
2389 'title': 'Ленинград - ЗОЖ',
2390 'thumbnail': 'https://youix.com/contents/videos_screenshots/18000/18485/preview_480x320_youix_com.mp4.jpg',
2391 }
2392 }, {
2393 # KVS Player
2394 'url': 'https://bogmedia.org/videos/21217/40-nochey-40-nights-2016/',
2395 'md5': '94166bdb26b4cb1fb9214319a629fc51',
2396 'info_dict': {
2397 'id': '21217',
2398 'display_id': '40-nochey-40-nights-2016',
2399 'ext': 'mp4',
2400 'title': '40 ночей (2016) - BogMedia.org',
2401 'thumbnail': 'https://bogmedia.org/contents/videos_screenshots/21000/21217/preview_480p.mp4.jpg',
2402 }
e4edeb62 2403 },
9980d3d2 2404 {
2405 # KVS Player (for sites that serve kt_player.js via non-https urls)
2406 'url': 'http://www.camhub.world/embed/389508',
2407 'md5': 'fbe89af4cfb59c8fd9f34a202bb03e32',
2408 'info_dict': {
2409 'id': '389508',
2410 'display_id': 'syren-de-mer-onlyfans-05-07-2020have-a-happy-safe-holiday5f014e68a220979bdb8cd-source',
2411 'ext': 'mp4',
2412 'title': 'Syren De Mer onlyfans_05-07-2020Have_a_happy_safe_holiday5f014e68a220979bdb8cd_source / Embed плеер',
2413 'thumbnail': 'http://www.camhub.world/contents/videos_screenshots/389000/389508/preview.mp4.jpg',
2414 }
2415 },
e16fefd8
JL
2416 {
2417 # Reddit-hosted video that will redirect and be processed by RedditIE
2418 # Redirects to https://www.reddit.com/r/videos/comments/6rrwyj/that_small_heart_attack/
2419 'url': 'https://v.redd.it/zv89llsvexdz',
2420 'md5': '87f5f02f6c1582654146f830f21f8662',
2421 'info_dict': {
2422 'id': 'zv89llsvexdz',
2423 'ext': 'mp4',
2424 'timestamp': 1501941939.0,
2425 'title': 'That small heart attack.',
2426 'upload_date': '20170805',
2427 'uploader': 'Antw87'
2428 }
2429 },
2430 {
2431 # 1080p Reddit-hosted video that will redirect and be processed by RedditIE
2432 'url': 'https://v.redd.it/33hgok7dfbz71/',
2433 'md5': '7a1d587940242c9bb3bd6eb320b39258',
2434 'info_dict': {
2435 'id': '33hgok7dfbz71',
2436 'ext': 'mp4',
2437 'title': "The game Didn't want me to Knife that Guy I guess",
2438 'uploader': 'paraf1ve',
2439 'timestamp': 1636788683.0,
2440 'upload_date': '20211113'
2441 }
9f517bb1 2442 },
9c634ef8 2443 {
2444 # MainStreaming player
2445 'url': 'https://www.lactv.it/2021/10/03/lac-news24-la-settimana-03-10-2021/',
2446 'info_dict': {
2447 'id': 'EUlZfGWkGpOd',
2448 'title': 'La Settimana ',
2449 'description': '03 Ottobre ore 02:00',
2450 'ext': 'mp4',
2451 'live_status': 'not_live',
2452 'thumbnail': r're:https?://[A-Za-z0-9-]*\.msvdn.net/image/\w+/poster',
2453 'duration': 1512
2454 }
2455 },
9f517bb1 2456 {
2457 # Multiple gfycat iframe embeds
2458 'url': 'https://www.gezip.net/bbs/board.php?bo_table=entertaine&wr_id=613422',
2459 'info_dict': {
2460 'title': '재이, 윤, 세은 황금 드레스를 입고 빛난다',
2461 'id': 'board'
2462 },
2463 'playlist_count': 8,
2464 },
2465 {
2466 # Multiple gfycat gifs (direct links)
2467 'url': 'https://www.gezip.net/bbs/board.php?bo_table=entertaine&wr_id=612199',
2468 'info_dict': {
2469 'title': '옳게 된 크롭 니트 스테이씨 아이사',
2470 'id': 'board'
2471 },
2472 'playlist_count': 6
2473 },
2474 {
2475 # Multiple gfycat embeds, with uppercase "IFR" in urls
2476 'url': 'https://kkzz.kr/?vid=2295',
2477 'info_dict': {
2478 'title': '지방시 앰버서더 에스파 카리나 움짤',
2479 'id': '?vid=2295'
2480 },
2481 'playlist_count': 9
e248be33 2482 },
2483 {
2484 # Panopto embeds
2485 'url': 'https://www.monash.edu/learning-teaching/teachhq/learning-technologies/panopto/how-to/insert-a-quiz-into-a-panopto-video',
2486 'info_dict': {
2487 'title': 'Insert a quiz into a Panopto video',
2488 'id': 'insert-a-quiz-into-a-panopto-video'
2489 },
2490 'playlist_count': 1
0a8a7e68
TI
2491 },
2492 {
2493 # Ruutu embed
2494 'url': 'https://www.nelonen.fi/ohjelmat/madventures-suomi/2160731-riku-ja-tunna-lahtevat-peurajahtiin-tv-sta-tutun-biologin-kanssa---metsastysreissu-huipentuu-kasvissyojan-painajaiseen',
2495 'md5': 'a2513a98d3496099e6eced40f7e6a14b',
2496 'info_dict': {
2497 'id': '4044426',
2498 'ext': 'mp4',
2499 'title': 'Riku ja Tunna lähtevät peurajahtiin tv:stä tutun biologin kanssa – metsästysreissu huipentuu kasvissyöjän painajaiseen!',
2500 'thumbnail': r're:^https?://.+\.jpg$',
2501 'duration': 108,
a44ca5a4 2502 'series': 'Madventures Suomi',
0a8a7e68
TI
2503 'description': 'md5:aa55b44bd06a1e337a6f1d0b46507381',
2504 'categories': ['Matkailu', 'Elämäntyyli'],
2505 'age_limit': 0,
2506 'upload_date': '20220308',
2507 },
2508 },
a0fe51d5
TI
2509 {
2510 # Multiple Ruutu embeds
2511 'url': 'https://www.hs.fi/kotimaa/art-2000008762560.html',
2512 'info_dict': {
2513 'title': 'Koronavirus | Epidemiahuippu voi olla Suomessa ohi, mutta koronaviruksen poistamista yleisvaarallisten tautien joukosta harkitaan vasta syksyllä',
2514 'id': 'art-2000008762560'
2515 },
2516 'playlist_count': 3
2517 },
2518 {
2519 # Ruutu embed in hs.fi with a single video
2520 'url': 'https://www.hs.fi/kotimaa/art-2000008793421.html',
2521 'md5': 'f8964e65d8fada6e8a562389bf366bb4',
2522 'info_dict': {
2523 'id': '4081841',
2524 'ext': 'mp4',
2525 'title': 'Puolustusvoimat siirsi panssariajoneuvoja harjoituksiin Niinisaloon 2.5.2022',
2526 'thumbnail': r're:^https?://.+\.jpg$',
2527 'duration': 138,
2528 'age_limit': 0,
2529 'upload_date': '20220504',
2530 },
2531 },
80e8493e 2532 {
2533 # Webpage contains double BOM
2534 'url': 'https://www.filmarkivet.se/movies/paris-d-moll/',
2535 'md5': 'df02cadc719dcc63d43288366f037754',
2536 'info_dict': {
2537 'id': 'paris-d-moll',
2538 'ext': 'mp4',
2539 'upload_date': '20220518',
2540 'title': 'Paris d-moll',
2541 'description': 'md5:319e37ea5542293db37e1e13072fe330',
2542 'thumbnail': 'https://www.filmarkivet.se/wp-content/uploads/parisdmoll2.jpg',
2543 'timestamp': 1652833414,
2544 'age_limit': 0,
2545 }
612e31f5
E
2546 },
2547 {
2548 'url': 'https://www.mollymovieclub.com/p/interstellar?s=r#details',
2549 'md5': '198bde8bed23d0b23c70725c83c9b6d9',
2550 'info_dict': {
2551 'id': '53602801',
2552 'ext': 'mpga',
2553 'title': 'Interstellar',
2554 'description': 'Listen now | Episode One',
2555 'thumbnail': 'md5:c30d9c83f738e16d8551d7219d321538',
2556 'uploader': 'Molly Movie Club',
2557 'uploader_id': '839621',
2558 },
2559 },
2560 {
2561 'url': 'https://www.blockedandreported.org/p/episode-117-lets-talk-about-depp?s=r',
2562 'md5': 'c0cc44ee7415daeed13c26e5b56d6aa0',
2563 'info_dict': {
2564 'id': '57962052',
2565 'ext': 'mpga',
2566 'title': 'md5:855b2756f0ee10f6723fa00b16266f8d',
2567 'description': 'md5:fe512a5e94136ad260c80bde00ea4eef',
2568 'thumbnail': 'md5:2218f27dfe517bb5ac16c47d0aebac59',
2569 'uploader': 'Blocked and Reported',
2570 'uploader_id': '500230',
2571 },
2572 },
2573 {
55baa67c 2574 'url': 'https://www.skimag.com/video/ski-people-1980/',
2575 'info_dict': {
2576 'id': 'ski-people-1980',
2577 'title': 'Ski People (1980)',
2578 },
2579 'playlist_count': 1,
2580 'playlist': [{
2581 'md5': '022a7e31c70620ebec18deeab376ee03',
2582 'info_dict': {
2583 'id': 'YTmgRiNU',
2584 'ext': 'mp4',
2585 'title': '1980 Ski People',
2586 'timestamp': 1610407738,
2587 'description': 'md5:cf9c3d101452c91e141f292b19fe4843',
2588 'thumbnail': 'https://cdn.jwplayer.com/v2/media/YTmgRiNU/poster.jpg?width=720',
2589 'duration': 5688.0,
2590 'upload_date': '20210111',
2591 }
2592 }]
2593 },
79e591b5 2594 {
2595 'note': 'Rumble embed',
2596 'url': 'https://rumble.com/vdmum1-moose-the-dog-helps-girls-dig-a-snow-fort.html',
2597 'md5': '53af34098a7f92c4e51cf0bd1c33f009',
2598 'info_dict': {
2599 'id': 'vb0ofn',
2600 'ext': 'mp4',
2601 'timestamp': 1612662578,
2602 'uploader': 'LovingMontana',
2603 'channel': 'LovingMontana',
2604 'upload_date': '20210207',
2605 'title': 'Winter-loving dog helps girls dig a snow fort ',
2606 'channel_url': 'https://rumble.com/c/c-546523',
2607 'thumbnail': 'https://sp.rmbl.ws/s8/1/5/f/x/x/5fxxb.OvCc.1-small-Moose-The-Dog-Helps-Girls-D.jpg',
2608 'duration': 103,
2609 }
2610 },
2611 {
2612 'note': 'Rumble JS embed',
2613 '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',
2614 'md5': '4701209ac99095592e73dbba21889690',
2615 'info_dict': {
2616 'id': 'v15eqxl',
2617 'ext': 'mp4',
2618 'channel': 'Mr Producer Media',
2619 'duration': 92,
2620 'title': '911 Audio From The Man Who Wanted To Kill Supreme Court Justice Kavanaugh',
2621 'channel_url': 'https://rumble.com/c/RichSementa',
2622 'thumbnail': 'https://sp.rmbl.ws/s8/1/P/j/f/A/PjfAe.OvCc-small-911-Audio-From-The-Man-Who-.jpg',
2623 'timestamp': 1654892716,
2624 'uploader': 'Mr Producer Media',
2625 'upload_date': '20220610',
2626 }
f3c0c773 2627 },
2628 {
2629 'note': 'JSON LD with multiple @type',
2630 'url': 'https://www.nu.nl/280161/video/hoe-een-bladvlo-dit-verwoestende-japanse-onkruid-moet-vernietigen.html',
2631 'md5': 'c7949f34f57273013fb7ccb1156393db',
2632 'info_dict': {
2633 'id': 'ipy2AcGL',
2634 'ext': 'mp4',
2635 'description': 'md5:6a9d644bab0dc2dc06849c2505d8383d',
2636 'thumbnail': r're:https://media\.nu\.nl/m/.+\.jpg',
2637 'title': 'Hoe een bladvlo dit verwoestende Japanse onkruid moet vernietigen',
2638 'timestamp': 1586577474,
2639 'upload_date': '20200411',
2640 'age_limit': 0,
2641 'duration': 111.0,
2642 }
2643 },
cfe50f04 2644 ]
9b122384 2645
9b122384
PH
2646 def report_following_redirect(self, new_url):
2647 """Report information extraction."""
79649588 2648 self._downloader.to_screen('[redirect] Following redirect to %s' % new_url)
9b122384 2649
aa9369a2 2650 def report_detected(self, name):
2651 self._downloader.write_debug(f'Identified a {name}')
2652
4fc946b5 2653 def _extract_rss(self, url, video_id, doc):
29f7c58a 2654 NS_MAP = {
2655 'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd',
2656 }
2657
76c73715
PH
2658 entries = []
2659 for it in doc.findall('./channel/item'):
d6bf1161 2660 next_url = next(
2661 (e.attrib.get('url') for e in it.findall('./enclosure')),
2662 xpath_text(it, 'link', fatal=False))
76c73715
PH
2663 if not next_url:
2664 continue
2665
d6bf1161 2666 guid = try_call(lambda: it.find('guid').text)
2667 if guid:
2668 next_url = smuggle_url(next_url, {'force_videoid': guid})
2068a603 2669
29f7c58a 2670 def itunes(key):
d6bf1161 2671 return xpath_text(it, xpath_with_ns(f'./itunes:{key}', NS_MAP), default=None)
29f7c58a 2672
76c73715 2673 entries.append({
413c1f8e 2674 '_type': 'url_transparent',
76c73715 2675 'url': next_url,
d6bf1161 2676 'title': try_call(lambda: it.find('title').text),
29f7c58a 2677 'description': xpath_text(it, 'description', default=None),
d6bf1161 2678 'timestamp': unified_timestamp(xpath_text(it, 'pubDate', default=None)),
2679 'duration': parse_duration(itunes('duration')),
29f7c58a 2680 'thumbnail': url_or_none(xpath_attr(it, xpath_with_ns('./itunes:image', NS_MAP), 'href')),
2681 'episode': itunes('title'),
2682 'episode_number': int_or_none(itunes('episode')),
2683 'season_number': int_or_none(itunes('season')),
d6bf1161 2684 'age_limit': {'true': 18, 'yes': 18, 'false': 0, 'no': 0}.get((itunes('explicit') or '').lower()),
76c73715 2685 })
4fc946b5
PH
2686
2687 return {
2688 '_type': 'playlist',
2689 'id': url,
d6bf1161 2690 'title': try_call(lambda: doc.find('./channel/title').text),
2691 'description': try_call(lambda: doc.find('./channel/description').text),
4fc946b5
PH
2692 'entries': entries,
2693 }
2694
c8e9a235
PH
2695 def _extract_camtasia(self, url, video_id, webpage):
2696 """ Returns None if no camtasia video can be found. """
2697
2698 camtasia_cfg = self._search_regex(
2699 r'fo\.addVariable\(\s*"csConfigFile",\s*"([^"]+)"\s*\);',
2700 webpage, 'camtasia configuration file', default=None)
2701 if camtasia_cfg is None:
2702 return None
2703
2704 title = self._html_search_meta('DC.title', webpage, fatal=True)
2705
2706 camtasia_url = compat_urlparse.urljoin(url, camtasia_cfg)
2707 camtasia_cfg = self._download_xml(
2708 camtasia_url, video_id,
2709 note='Downloading camtasia configuration',
2710 errnote='Failed to download camtasia configuration')
2711 fileset_node = camtasia_cfg.find('./playlist/array/fileset')
2712
2713 entries = []
2714 for n in fileset_node.getchildren():
2715 url_n = n.find('./uri')
2716 if url_n is None:
2717 continue
2718
2719 entries.append({
2720 'id': os.path.splitext(url_n.text.rpartition('/')[2])[0],
86e5f3ed 2721 'title': f'{title} - {n.tag}',
c8e9a235
PH
2722 'url': compat_urlparse.urljoin(url, url_n.text),
2723 'duration': float_or_none(n.find('./duration').text),
2724 })
2725
2726 return {
2727 '_type': 'playlist',
2728 'entries': entries,
2729 'title': title,
2730 }
2731
a318f59d 2732 def _kvs_getrealurl(self, video_url, license_code):
2733 if not video_url.startswith('function/0/'):
2734 return video_url # not obfuscated
2735
2736 url_path, _, url_query = video_url.partition('?')
2737 urlparts = url_path.split('/')[2:]
2738 license = self._kvs_getlicensetoken(license_code)
2739 newmagic = urlparts[5][:32]
2740
2741 for o in range(len(newmagic) - 1, -1, -1):
2742 new = ''
86e5f3ed 2743 l = (o + sum(int(n) for n in license[o:])) % 32
a318f59d 2744
2745 for i in range(0, len(newmagic)):
2746 if i == o:
2747 new += newmagic[l]
2748 elif i == l:
2749 new += newmagic[o]
2750 else:
2751 new += newmagic[i]
2752 newmagic = new
2753
2754 urlparts[5] = newmagic + urlparts[5][32:]
2755 return '/'.join(urlparts) + '?' + url_query
2756
2757 def _kvs_getlicensetoken(self, license):
2758 modlicense = license.replace('$', '').replace('0', '1')
2759 center = int(len(modlicense) / 2)
2760 fronthalf = int(modlicense[:center + 1])
2761 backhalf = int(modlicense[center:])
2762
2763 modlicense = str(4 * abs(fronthalf - backhalf))
2764 retval = ''
2765 for o in range(0, center + 1):
2766 for i in range(1, 5):
2767 retval += str((int(license[o + i]) + int(modlicense[o])) % 10)
2768 return retval
2769
9b122384 2770 def _real_extract(self, url):
ebd3c7b3 2771 if url.startswith('//'):
d226c560 2772 return self.url_result(self.http_scheme() + url)
ebd3c7b3 2773
a7130543
JMF
2774 parsed_url = compat_urlparse.urlparse(url)
2775 if not parsed_url.scheme:
a06916d9 2776 default_search = self.get_param('default_search')
04b4d394 2777 if default_search is None:
1f7ccb90 2778 default_search = 'fixup_error'
04b4d394 2779
1f7ccb90 2780 if default_search in ('auto', 'auto_warning', 'fixup_error'):
9c1da4a9 2781 if re.match(r'^[^\s/]+\.[^\s/]+/', url):
6a39ee13 2782 self.report_warning('The url doesn\'t specify the protocol, trying with http')
04b4d394 2783 return self.url_result('http://' + url)
1f7ccb90 2784 elif default_search != 'fixup_error':
9c1fc022 2785 if default_search == 'auto_warning':
0e67ab0d
PH
2786 if re.match(r'^(?:url|URL)$', url):
2787 raise ExtractorError(
7a5c1cfe 2788 'Invalid URL: %r . Call yt-dlp like this: yt-dlp -v "https://www.youtube.com/watch?v=BaW_jenozKc" ' % url,
0e67ab0d
PH
2789 expected=True)
2790 else:
6a39ee13 2791 self.report_warning(
7571c02c 2792 'Falling back to youtube search for %s . Set --default-search "auto" to suppress this warning.' % url)
04b4d394 2793 return self.url_result('ytsearch:' + url)
1f7ccb90
PH
2794
2795 if default_search in ('error', 'fixup_error'):
7571c02c 2796 raise ExtractorError(
b74e86f4 2797 '%r is not a valid URL. '
7a5c1cfe 2798 'Set --default-search "ytsearch" (or run yt-dlp "ytsearch:%s" ) to search YouTube'
b74e86f4 2799 % (url, url), expected=True)
04b4d394 2800 else:
f2f2c0c2
PH
2801 if ':' not in default_search:
2802 default_search += ':'
04b4d394 2803 return self.url_result(default_search + url)
4d54ef20
PH
2804
2805 url, smuggled_data = unsmuggle_url(url)
2806 force_videoid = None
d6e6a422 2807 is_intentional = smuggled_data and smuggled_data.get('to_generic')
4d54ef20
PH
2808 if smuggled_data and 'force_videoid' in smuggled_data:
2809 force_videoid = smuggled_data['force_videoid']
2810 video_id = force_videoid
2811 else:
9dcd6fd3 2812 video_id = self._generic_id(url)
3d83a1ae 2813
79649588 2814 self.to_screen('%s: Requesting header' % video_id)
c1d1facd 2815
ebab4520 2816 head_req = HEADRequest(url)
23be51d8 2817 head_response = self._request_webpage(
ebab4520
PH
2818 head_req, video_id,
2819 note=False, errnote='Could not send HEAD request to %s' % url,
2820 fatal=False)
42393ce2 2821
23be51d8 2822 if head_response is not False:
42393ce2 2823 # Check for redirect
7947a1f7 2824 new_url = head_response.geturl()
42393ce2
PH
2825 if url != new_url:
2826 self.report_following_redirect(new_url)
4d54ef20
PH
2827 if force_videoid:
2828 new_url = smuggle_url(
2829 new_url, {'force_videoid': force_videoid})
cecaaf3f 2830 return self.url_result(new_url)
42393ce2 2831
23be51d8
PH
2832 full_response = None
2833 if head_response is False:
5c2266df 2834 request = sanitized_Request(url)
58bde34a
S
2835 request.add_header('Accept-Encoding', '*')
2836 full_response = self._request_webpage(request, video_id)
23be51d8
PH
2837 head_response = full_response
2838
f930e0c7
S
2839 info_dict = {
2840 'id': video_id,
9dcd6fd3 2841 'title': self._generic_title(url),
29f7c58a 2842 'timestamp': unified_timestamp(head_response.headers.get('Last-Modified'))
f930e0c7
S
2843 }
2844
23be51d8 2845 # Check for direct link to a video
955737b2 2846 content_type = head_response.headers.get('Content-Type', '').lower()
263eff95 2847 m = re.match(r'^(?P<type>audio|video|application(?=/(?:ogg$|(?:vnd\.apple\.|x-)?mpegurl)))/(?P<format_id>[^;\s]+)', content_type)
23be51d8 2848 if m:
aa9369a2 2849 self.report_detected('direct video link')
4e363703 2850 format_id = compat_str(m.group('format_id'))
c26326c1 2851 subtitles = {}
f930e0c7 2852 if format_id.endswith('mpegurl'):
c26326c1 2853 formats, subtitles = self._extract_m3u8_formats_and_subtitles(url, video_id, 'mp4')
cf1f13b8 2854 elif format_id.endswith('mpd') or format_id.endswith('dash+xml'):
2855 formats, subtitles = self._extract_mpd_formats_and_subtitles(url, video_id)
f930e0c7
S
2856 elif format_id == 'f4m':
2857 formats = self._extract_f4m_formats(url, video_id)
eadc3ccd 2858 else:
2859 formats = [{
4e363703 2860 'format_id': format_id,
eadc3ccd 2861 'url': url,
2862 'vcodec': 'none' if m.group('type') == 'audio' else None
2863 }]
de6c51e8 2864 info_dict['direct'] = True
19dbaeec 2865 self._sort_formats(formats)
de6c51e8 2866 info_dict['formats'] = formats
c26326c1 2867 info_dict['subtitles'] = subtitles
f930e0c7 2868 return info_dict
42393ce2 2869
a06916d9 2870 if not self.get_param('test', False) and not is_intentional:
2871 force = self.get_param('force_generic_extractor', False)
6a39ee13 2872 self.report_warning(
2fece970 2873 '%s on generic information extractor.' % ('Forcing' if force else 'Falling back'))
d6e6a422 2874
4e262a88 2875 if not full_response:
5c2266df 2876 request = sanitized_Request(url)
58bde34a
S
2877 # Some webservers may serve compressed content of rather big size (e.g. gzipped flac)
2878 # making it impossible to download only chunk of the file (yet we need only 512kB to
7a5c1cfe 2879 # test whether it's HTML or not). According to yt-dlp default Accept-Encoding
58bde34a
S
2880 # that will always result in downloading the whole file that is not desirable.
2881 # Therefore for extraction pass we have to override Accept-Encoding to any in order
2882 # to accept raw bytes and being able to download only a chunk.
2883 # It may probably better to solve this by checking Content-Type for application/octet-stream
2884 # after HEAD request finishes, but not sure if we can rely on this.
2885 request.add_header('Accept-Encoding', '*')
2886 full_response = self._request_webpage(request, video_id)
4e262a88 2887
5940862d
S
2888 first_bytes = full_response.read(512)
2889
2890 # Is it an M3U playlist?
0d769bcb 2891 if first_bytes.startswith(b'#EXTM3U'):
aa9369a2 2892 self.report_detected('M3U playlist')
da1c94ee 2893 info_dict['formats'], info_dict['subtitles'] = self._extract_m3u8_formats_and_subtitles(url, video_id, 'mp4')
19dbaeec 2894 self._sort_formats(info_dict['formats'])
5940862d
S
2895 return info_dict
2896
4e262a88
PH
2897 # Maybe it's a direct link to a video?
2898 # Be careful not to download the whole thing!
61ca9a80 2899 if not is_html(first_bytes):
6a39ee13 2900 self.report_warning(
4e262a88 2901 'URL could be a direct video link, returning it as such.')
f930e0c7 2902 info_dict.update({
4e262a88
PH
2903 'direct': True,
2904 'url': url,
f930e0c7
S
2905 })
2906 return info_dict
4e262a88
PH
2907
2908 webpage = self._webpage_read_content(
2909 full_response, url, video_id, prefix=first_bytes)
2910
2181983a 2911 if '<title>DPG Media Privacy Gate</title>' in webpage:
2912 webpage = self._download_webpage(url, video_id)
2913
9b122384 2914 self.report_extraction(video_id)
887c6acd 2915
1b840245 2916 # Is it an RSS feed, a SMIL file, an XSPF playlist or a MPD manifest?
4fc946b5 2917 try:
61241abb 2918 try:
2919 doc = compat_etree_fromstring(webpage)
f9934b96 2920 except xml.etree.ElementTree.ParseError:
61241abb 2921 doc = compat_etree_fromstring(webpage.encode('utf-8'))
4fc946b5 2922 if doc.tag == 'rss':
aa9369a2 2923 self.report_detected('RSS feed')
4fc946b5 2924 return self._extract_rss(url, video_id, doc)
cc99a77a 2925 elif doc.tag == 'SmoothStreamingMedia':
7a450a3b 2926 info_dict['formats'], info_dict['subtitles'] = self._parse_ism_formats_and_subtitles(doc, url)
aa9369a2 2927 self.report_detected('ISM manifest')
cc99a77a
S
2928 self._sort_formats(info_dict['formats'])
2929 return info_dict
e5e8d20a 2930 elif re.match(r'^(?:{[^}]+})?smil$', doc.tag):
19dbaeec 2931 smil = self._parse_smil(doc, url, video_id)
aa9369a2 2932 self.report_detected('SMIL file')
19dbaeec
S
2933 self._sort_formats(smil['formats'])
2934 return smil
729accb4 2935 elif doc.tag == '{http://xspf.org/ns/0/}playlist':
aa9369a2 2936 self.report_detected('XSPF playlist')
96b8b9ab 2937 return self.playlist_result(
47a5cb77
S
2938 self._parse_xspf(
2939 doc, video_id, xspf_url=url,
7947a1f7 2940 xspf_base_url=full_response.geturl()),
96b8b9ab 2941 video_id)
1b840245 2942 elif re.match(r'(?i)^(?:{[^}]+})?MPD$', doc.tag):
7de27caf 2943 info_dict['formats'], info_dict['subtitles'] = self._parse_mpd_formats_and_subtitles(
d3f8b76b 2944 doc,
7947a1f7 2945 mpd_base_url=full_response.geturl().rpartition('/')[0],
86f4d14f 2946 mpd_url=url)
aa9369a2 2947 self.report_detected('DASH manifest')
19dbaeec 2948 self._sort_formats(info_dict['formats'])
f930e0c7
S
2949 return info_dict
2950 elif re.match(r'^{http://ns\.adobe\.com/f4m/[12]\.0}manifest$', doc.tag):
2951 info_dict['formats'] = self._parse_f4m_formats(doc, url, video_id)
aa9369a2 2952 self.report_detected('F4M manifest')
19dbaeec 2953 self._sort_formats(info_dict['formats'])
f930e0c7 2954 return info_dict
f9934b96 2955 except xml.etree.ElementTree.ParseError:
4fc946b5
PH
2956 pass
2957
c8e9a235
PH
2958 # Is it a Camtasia project?
2959 camtasia_res = self._extract_camtasia(url, video_id, webpage)
2960 if camtasia_res is not None:
aa9369a2 2961 self.report_detected('Camtasia video')
c8e9a235
PH
2962 return camtasia_res
2963
14390730 2964 # Sometimes embedded video player is hidden behind percent encoding
067aa17e 2965 # (e.g. https://github.com/ytdl-org/youtube-dl/issues/2448)
14390730 2966 # Unescaping the whole page allows to handle those cases in a generic way
29f7c58a 2967 # FIXME: unescaping the whole page may break URLs, commenting out for now.
2968 # There probably should be a second run of generic extractor on unescaped webpage.
2969 # webpage = compat_urllib_parse_unquote(webpage)
1f7659db 2970
7cb51b5d
S
2971 # Unescape squarespace embeds to be detected by generic extractor,
2972 # see https://github.com/ytdl-org/youtube-dl/issues/21294
2973 webpage = re.sub(
2974 r'<div[^>]+class=[^>]*?\bsqs-video-wrapper\b[^>]*>',
2975 lambda x: unescapeHTML(x.group(0)), webpage)
d78657fd 2976
887c6acd
PH
2977 # it's tempting to parse this further, but you would
2978 # have to take into account all the variations like
2979 # Video Title - Site Name
2980 # Site Name | Video Title
2981 # Video Title - Tagline | Site Name
2982 # and so on and so forth; it's just not practical
04f3fd2c 2983 video_title = (self._og_search_title(webpage, default=None)
2984 or self._html_extract_title(webpage, 'video title', default='video'))
ef4fd848 2985
4d805e06
PH
2986 # Try to detect age limit automatically
2987 age_limit = self._rta_search(webpage)
2988 # And then there are the jokers who advertise that they use RTA,
2989 # but actually don't.
2990 AGE_LIMIT_MARKERS = [
197224b7 2991 r'Proudly Labeled <a href="http://www\.rtalabel\.org/" title="Restricted to Adults">RTA</a>',
4d805e06
PH
2992 ]
2993 if any(re.search(marker, webpage) for marker in AGE_LIMIT_MARKERS):
2994 age_limit = 18
2995
ef4fd848
PH
2996 # video uploader is domain name
2997 video_uploader = self._search_regex(
79649588 2998 r'^(?:https?://)?([^/]*)/.*', url, 'video uploader')
887c6acd 2999
6f41b2bc
S
3000 video_description = self._og_search_description(webpage, default=None)
3001 video_thumbnail = self._og_search_thumbnail(webpage, default=None)
3002
b311b0ea
S
3003 info_dict.update({
3004 'title': video_title,
3005 'description': video_description,
3006 'thumbnail': video_thumbnail,
3007 'age_limit': age_limit,
3008 })
3009
aa9369a2 3010 self._downloader.write_debug('Looking for video embeds')
3011
1f4b722b 3012 # Look for Brightcove Legacy Studio embeds
4fcaa4f4 3013 bc_urls = BrightcoveLegacyIE._extract_brightcove_urls(webpage)
99877772 3014 if bc_urls:
99877772
PH
3015 entries = [{
3016 '_type': 'url',
3017 'url': smuggle_url(bc_url, {'Referer': url}),
3b7d9aa4 3018 'ie_key': 'BrightcoveLegacy'
99877772
PH
3019 } for bc_url in bc_urls]
3020
3021 return {
3022 '_type': 'playlist',
3023 'title': video_title,
3024 'id': video_id,
3025 'entries': entries,
3026 }
cfe50f04 3027
f6519f89 3028 # Look for Brightcove New Studio embeds
0254f93b 3029 bc_urls = BrightcoveNewIE._extract_urls(self, webpage)
f6519f89 3030 if bc_urls:
5399ab3f
S
3031 return self.playlist_from_matches(
3032 bc_urls, video_id, video_title,
3033 getter=lambda x: smuggle_url(x, {'referrer': url}),
3034 ie='BrightcoveNew')
ed126900 3035
4e826cd9
S
3036 # Look for Nexx embeds
3037 nexx_urls = NexxIE._extract_urls(webpage)
3038 if nexx_urls:
3039 return self.playlist_from_matches(nexx_urls, video_id, video_title, ie=NexxIE.ie_key())
3040
3f59b015
S
3041 # Look for Nexx iFrame embeds
3042 nexx_embed_urls = NexxEmbedIE._extract_urls(webpage)
3043 if nexx_embed_urls:
3044 return self.playlist_from_matches(nexx_embed_urls, video_id, video_title, ie=NexxEmbedIE.ie_key())
3045
4d8819d2
S
3046 # Look for ThePlatform embeds
3047 tp_urls = ThePlatformIE._extract_urls(webpage)
3048 if tp_urls:
46b18f23 3049 return self.playlist_from_matches(tp_urls, video_id, video_title, ie='ThePlatform')
4d8819d2 3050
29f7c58a 3051 arc_urls = ArcPublishingIE._extract_urls(webpage)
3052 if arc_urls:
3053 return self.playlist_from_matches(arc_urls, video_id, video_title, ie=ArcPublishingIE.ie_key())
3054
2181983a 3055 mychannels_urls = MedialaanIE._extract_urls(webpage)
3056 if mychannels_urls:
3057 return self.playlist_from_matches(
3058 mychannels_urls, video_id, video_title, ie=MedialaanIE.ie_key())
3059
59b8ab58
PH
3060 # Look for embedded rtl.nl player
3061 matches = re.findall(
2637fadc 3062 r'<iframe[^>]+?src="((?:https?:)?//(?:(?:www|static)\.)?rtl\.nl/(?:system/videoplayer/[^"]+(?:video_)?)?embed[^"]+)"',
59b8ab58
PH
3063 webpage)
3064 if matches:
46b18f23 3065 return self.playlist_from_matches(matches, video_id, video_title, ie='RtlNl')
59b8ab58 3066
09b9c45e
S
3067 vimeo_urls = VimeoIE._extract_urls(url, webpage)
3068 if vimeo_urls:
46b18f23 3069 return self.playlist_from_matches(vimeo_urls, video_id, video_title, ie=VimeoIE.ie_key())
7115ca84 3070
aedaa455 3071 vhx_url = VHXEmbedIE._extract_url(url, webpage)
29f7c58a 3072 if vhx_url:
3073 return self.url_result(vhx_url, VHXEmbedIE.ie_key())
3074
df0c8151 3075 # Invidious Instances
3076 # https://github.com/yt-dlp/yt-dlp/issues/195
3077 # https://github.com/iv-org/invidious/pull/1730
3078 youtube_url = self._search_regex(
3079 r'<link rel="alternate" href="(https://www\.youtube\.com/watch\?v=[0-9A-Za-z_-]{11})"',
3080 webpage, 'youtube link', default=None)
3081 if youtube_url:
3082 return self.url_result(youtube_url, YoutubeIE.ie_key())
3083
66c9fa36
S
3084 # Look for YouTube embeds
3085 youtube_urls = YoutubeIE._extract_urls(webpage)
3086 if youtube_urls:
46b18f23 3087 return self.playlist_from_matches(
66c9fa36 3088 youtube_urls, video_id, video_title, ie=YoutubeIE.ie_key())
7deef1ba 3089
ad213a1d 3090 matches = DailymotionIE._extract_urls(webpage)
355e4fd0 3091 if matches:
46b18f23 3092 return self.playlist_from_matches(matches, video_id, video_title)
355e4fd0 3093
8489578d
NJ
3094 # Look for embedded Dailymotion playlist player (#3822)
3095 m = re.search(
3096 r'<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//(?:www\.)?dailymotion\.[a-z]{2,3}/widget/jukebox\?.+?)\1', webpage)
3097 if m:
3098 playlists = re.findall(
3099 r'list\[\]=/playlist/([^/]+)/', unescapeHTML(m.group('url')))
3100 if playlists:
46b18f23
JH
3101 return self.playlist_from_matches(
3102 playlists, video_id, video_title, lambda p: '//dailymotion.com/playlist/%s' % p)
8489578d 3103
71a1db89
S
3104 # Look for DailyMail embeds
3105 dailymail_urls = DailyMailIE._extract_urls(webpage)
3106 if dailymail_urls:
3107 return self.playlist_from_matches(
3108 dailymail_urls, video_id, video_title, ie=DailyMailIE.ie_key())
3109
be7dacf9
S
3110 # Look for Teachable embeds, must be before Wistia
3111 teachable_url = TeachableIE._extract_url(webpage, url)
3112 if teachable_url:
3113 return self.url_result(teachable_url)
3114
ef4fd848 3115 # Look for embedded Wistia player
fda6d237
S
3116 wistia_urls = WistiaIE._extract_urls(webpage)
3117 if wistia_urls:
3118 playlist = self.playlist_from_matches(wistia_urls, video_id, video_title, ie=WistiaIE.ie_key())
3119 for entry in playlist['entries']:
3120 entry.update({
3121 '_type': 'url_transparent',
3122 'uploader': video_uploader,
3123 })
3124 return playlist
5f6a1245 3125
bab19a8e
S
3126 # Look for SVT player
3127 svt_url = SVTIE._extract_url(webpage)
3128 if svt_url:
3129 return self.url_result(svt_url, 'SVT')
3130
c19f7764
JMF
3131 # Look for Bandcamp pages with custom domain
3132 mobj = re.search(r'<meta property="og:url"[^>]*?content="(.*?bandcamp\.com.*?)"', webpage)
3133 if mobj is not None:
3134 burl = unescapeHTML(mobj.group(1))
09804265
JMF
3135 # Don't set the extractor because it can be a track url or an album
3136 return self.url_result(burl)
c19f7764 3137
612e31f5
E
3138 # Check for Substack custom domains
3139 substack_url = SubstackIE._extract_url(webpage, url)
3140 if substack_url:
3141 return self.url_result(substack_url, SubstackIE)
3142
f25571ff
PH
3143 # Look for embedded Vevo player
3144 mobj = re.search(
3145 r'<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//(?:cache\.)?vevo\.com/.+?)\1', webpage)
3146 if mobj is not None:
3147 return self.url_result(mobj.group('url'))
796df3c6
S
3148
3149 # Look for embedded Viddler player
cb454b33
S
3150 mobj = re.search(
3151 r'<(?:iframe[^>]+?src|param[^>]+?value)=(["\'])(?P<url>(?:https?:)?//(?:www\.)?viddler\.com/(?:embed|player)/.+?)\1',
3152 webpage)
796df3c6
S
3153 if mobj is not None:
3154 return self.url_result(mobj.group('url'))
f25571ff 3155
3378d67a
S
3156 # Look for NYTimes player
3157 mobj = re.search(
3158 r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//graphics8\.nytimes\.com/bcvideo/[^/]+/iframe/embed\.html.+?)\1>',
3159 webpage)
3160 if mobj is not None:
3161 return self.url_result(mobj.group('url'))
3162
cefdf970
S
3163 # Look for Libsyn player
3164 mobj = re.search(
3165 r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//html5-player\.libsyn\.com/embed/.+?)\1', webpage)
3166 if mobj is not None:
3167 return self.url_result(mobj.group('url'))
3168
c0d0b01f 3169 # Look for Ooyala videos
3089bc74
S
3170 mobj = (re.search(r'player\.ooyala\.com/[^"?]+[?#][^"]*?(?:embedCode|ec)=(?P<ec>[^"&]+)', webpage)
3171 or re.search(r'OO\.Player\.create\([\'"].*?[\'"],\s*[\'"](?P<ec>.{32})[\'"]', webpage)
3172 or re.search(r'OO\.Player\.create\.apply\(\s*OO\.Player\s*,\s*op\(\s*\[\s*[\'"][^\'"]*[\'"]\s*,\s*[\'"](?P<ec>.{32})[\'"]', webpage)
3173 or re.search(r'SBN\.VideoLinkset\.ooyala\([\'"](?P<ec>.{32})[\'"]\)', webpage)
3174 or re.search(r'data-ooyala-video-id\s*=\s*[\'"](?P<ec>.{32})[\'"]', webpage))
c0d0b01f 3175 if mobj is not None:
9837cb75
RA
3176 embed_token = self._search_regex(
3177 r'embedToken[\'"]?\s*:\s*[\'"]([^\'"]+)',
3178 webpage, 'ooyala embed token', default=None)
3179 return OoyalaIE._build_url_result(smuggle_url(
3180 mobj.group('ec'), {
3181 'domain': url,
3182 'embed_token': embed_token,
3183 }))
c0d0b01f 3184
f076b638 3185 # Look for multiple Ooyala embeds on SBN network websites
3186 mobj = re.search(r'SBN\.VideoLinkset\.entryGroup\((\[.*?\])', webpage)
3187 if mobj is not None:
3188 embeds = self._parse_json(mobj.group(1), video_id, fatal=False)
3189 if embeds:
46b18f23
JH
3190 return self.playlist_from_matches(
3191 embeds, video_id, video_title,
3192 getter=lambda v: OoyalaIE._url_for_embed_code(smuggle_url(v['provider_video_id'], {'domain': url})), ie='Ooyala')
f076b638 3193
aa94a6d3 3194 # Look for Aparat videos
48099643 3195 mobj = re.search(r'<iframe .*?src="(http://www\.aparat\.com/video/[^"]+)"', webpage)
aa94a6d3
PH
3196 if mobj is not None:
3197 return self.url_result(mobj.group(1), 'Aparat')
3198
c93c2ab1 3199 # Look for MPORA videos
c3f51436 3200 mobj = re.search(r'<iframe .*?src="(http://mpora\.(?:com|de)/videos/[^"]+)"', webpage)
c93c2ab1
PH
3201 if mobj is not None:
3202 return self.url_result(mobj.group(1), 'Mpora')
5f59ee79 3203
9834872b 3204 # Look for embedded Facebook player
0646e34c
S
3205 facebook_urls = FacebookIE._extract_urls(webpage)
3206 if facebook_urls:
3207 return self.playlist_from_matches(facebook_urls, video_id, video_title)
9834872b 3208
ca97a56e
S
3209 # Look for embedded VK player
3210 mobj = re.search(r'<iframe[^>]+?src=(["\'])(?P<url>https?://vk\.com/video_ext\.php.+?)\1', webpage)
3211 if mobj is not None:
3212 return self.url_result(mobj.group('url'), 'VK')
3213
33d4fdab 3214 # Look for embedded Odnoklassniki player
416c3ca7
RA
3215 odnoklassniki_url = OdnoklassnikiIE._extract_url(webpage)
3216 if odnoklassniki_url:
3217 return self.url_result(odnoklassniki_url, OdnoklassnikiIE.ie_key())
33d4fdab 3218
b73612a2 3219 # Look for sibnet embedded player
3220 sibnet_urls = VKIE._extract_sibnet_urls(webpage)
3221 if sibnet_urls:
3222 return self.playlist_from_matches(sibnet_urls, video_id, video_title)
3223
0364fa8b
S
3224 # Look for embedded ivi player
3225 mobj = re.search(r'<embed[^>]+?src=(["\'])(?P<url>https?://(?:www\.)?ivi\.ru/video/player.+?)\1', webpage)
3226 if mobj is not None:
3227 return self.url_result(mobj.group('url'), 'Ivi')
3228
db1f3888
PH
3229 # Look for embedded Huffington Post player
3230 mobj = re.search(
c3f51436 3231 r'<iframe[^>]+?src=(["\'])(?P<url>https?://embed\.live\.huffingtonpost\.com/.+?)\1', webpage)
db1f3888
PH
3232 if mobj is not None:
3233 return self.url_result(mobj.group('url'), 'HuffPost')
3234
1b86cc41 3235 # Look for embed.ly
3236 mobj = re.search(r'class=["\']embedly-card["\'][^>]href=["\'](?P<url>[^"\']+)', webpage)
3237 if mobj is not None:
3238 return self.url_result(mobj.group('url'))
3239 mobj = re.search(r'class=["\']embedly-embed["\'][^>]src=["\'][^"\']*url=(?P<url>[^&]+)', webpage)
3240 if mobj is not None:
f7e6f7fa 3241 return self.url_result(compat_urllib_parse_unquote(mobj.group('url')))
1b86cc41 3242
60cc4dc4
PH
3243 # Look for funnyordie embed
3244 matches = re.findall(r'<iframe[^>]+?src="(https?://(?:www\.)?funnyordie\.com/embed/[^"]+)"', webpage)
3245 if matches:
46b18f23
JH
3246 return self.playlist_from_matches(
3247 matches, video_id, video_title, getter=unescapeHTML, ie='FunnyOrDie')
60cc4dc4 3248
bc2ca1bb 3249 # Look for Simplecast embeds
3250 simplecast_urls = SimplecastIE._extract_urls(webpage)
3251 if simplecast_urls:
3252 return self.playlist_from_matches(
3253 simplecast_urls, video_id, video_title)
3254
db546cf8
S
3255 # Look for BBC iPlayer embed
3256 matches = re.findall(r'setPlaylist\("(https?://www\.bbc\.co\.uk/iplayer/[^/]+/[\da-z]{8})"\)', webpage)
3257 if matches:
46b18f23 3258 return self.playlist_from_matches(matches, video_id, video_title, ie='BBCCoUk')
db546cf8 3259
93d020dd
S
3260 # Look for embedded RUTV player
3261 rutv_url = RUTVIE._extract_url(webpage)
3262 if rutv_url:
3263 return self.url_result(rutv_url, 'RUTV')
3264
494f20cb 3265 # Look for embedded TVC player
b8599718
S
3266 tvc_url = TVCIE._extract_url(webpage)
3267 if tvc_url:
3268 return self.url_result(tvc_url, 'TVC')
494f20cb 3269
d40a3b5b 3270 # Look for embedded SportBox player
476cf548 3271 sportbox_urls = SportBoxIE._extract_urls(webpage)
d40a3b5b 3272 if sportbox_urls:
476cf548 3273 return self.playlist_from_matches(sportbox_urls, video_id, video_title, ie=SportBoxIE.ie_key())
d40a3b5b 3274
a49e777d
F
3275 # Look for embedded Spotify player
3276 spotify_urls = SpotifyBaseIE._extract_embed_urls(webpage)
3277 if spotify_urls:
3278 return self.playlist_from_matches(spotify_urls, video_id, video_title)
3279
2bb5b6d0
S
3280 # Look for embedded XHamster player
3281 xhamster_urls = XHamsterEmbedIE._extract_urls(webpage)
3282 if xhamster_urls:
46b18f23 3283 return self.playlist_from_matches(xhamster_urls, video_id, video_title, ie='XHamsterEmbed')
2bb5b6d0 3284
2c9ca782
S
3285 # Look for embedded TNAFlixNetwork player
3286 tnaflix_urls = TNAFlixNetworkEmbedIE._extract_urls(webpage)
3287 if tnaflix_urls:
46b18f23 3288 return self.playlist_from_matches(tnaflix_urls, video_id, video_title, ie=TNAFlixNetworkEmbedIE.ie_key())
2c9ca782 3289
b52c9ef1
S
3290 # Look for embedded PornHub player
3291 pornhub_urls = PornHubIE._extract_urls(webpage)
3292 if pornhub_urls:
46b18f23 3293 return self.playlist_from_matches(pornhub_urls, video_id, video_title, ie=PornHubIE.ie_key())
b52c9ef1 3294
37e7a71c
S
3295 # Look for embedded DrTuber player
3296 drtuber_urls = DrTuberIE._extract_urls(webpage)
3297 if drtuber_urls:
46b18f23 3298 return self.playlist_from_matches(drtuber_urls, video_id, video_title, ie=DrTuberIE.ie_key())
37e7a71c 3299
e28ed498
S
3300 # Look for embedded RedTube player
3301 redtube_urls = RedTubeIE._extract_urls(webpage)
3302 if redtube_urls:
46b18f23 3303 return self.playlist_from_matches(redtube_urls, video_id, video_title, ie=RedTubeIE.ie_key())
e28ed498 3304
06993715
S
3305 # Look for embedded Tube8 player
3306 tube8_urls = Tube8IE._extract_urls(webpage)
3307 if tube8_urls:
3308 return self.playlist_from_matches(tube8_urls, video_id, video_title, ie=Tube8IE.ie_key())
3309
4e7b5bba
S
3310 # Look for embedded Mofosex player
3311 mofosex_urls = MofosexEmbedIE._extract_urls(webpage)
3312 if mofosex_urls:
3313 return self.playlist_from_matches(mofosex_urls, video_id, video_title, ie=MofosexEmbedIE.ie_key())
3314
8fae1a04
S
3315 # Look for embedded Spankwire player
3316 spankwire_urls = SpankwireIE._extract_urls(webpage)
3317 if spankwire_urls:
3318 return self.playlist_from_matches(spankwire_urls, video_id, video_title, ie=SpankwireIE.ie_key())
3319
52c4c515
S
3320 # Look for embedded YouPorn player
3321 youporn_urls = YouPornIE._extract_urls(webpage)
3322 if youporn_urls:
3323 return self.playlist_from_matches(youporn_urls, video_id, video_title, ie=YouPornIE.ie_key())
3324
9872d311
S
3325 # Look for embedded Tvigle player
3326 mobj = re.search(
3327 r'<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//cloud\.tvigle\.ru/video/.+?)\1', webpage)
3328 if mobj is not None:
3329 return self.url_result(mobj.group('url'), 'Tvigle')
3330
7e2ede98 3331 # Look for embedded TED player
4259402c 3332 ted_urls = TedEmbedIE._extract_urls(webpage)
3333 if ted_urls:
3334 return self.playlist_from_matches(ted_urls, video_id, video_title, ie=TedEmbedIE.ie_key())
7e2ede98 3335
5c386252 3336 # Look for embedded Ustream videos
d77ac737
YCH
3337 ustream_url = UstreamIE._extract_url(webpage)
3338 if ustream_url:
3339 return self.url_result(ustream_url, UstreamIE.ie_key())
5c386252 3340
893f8832 3341 # Look for embedded arte.tv player
8bdd16b4 3342 arte_urls = ArteTVEmbedIE._extract_urls(webpage)
3343 if arte_urls:
3344 return self.playlist_from_matches(arte_urls, video_id, video_title)
893f8832 3345
cbd55ade
S
3346 # Look for embedded francetv player
3347 mobj = re.search(
3348 r'<iframe[^>]+?src=(["\'])(?P<url>(?:https?://)?embed\.francetv\.fr/\?ue=.+?)\1',
3349 webpage)
3350 if mobj is not None:
3351 return self.url_result(mobj.group('url'))
3352
e6c2d9ad 3353 # Look for embedded Myvi.ru player
6dd94d3a 3354 myvi_url = MyviIE._extract_url(webpage)
e6c2d9ad
S
3355 if myvi_url:
3356 return self.url_result(myvi_url)
3357
dfb1b146 3358 # Look for embedded soundcloud player
548c3957 3359 soundcloud_urls = SoundcloudEmbedIE._extract_urls(webpage)
94aae015 3360 if soundcloud_urls:
548c3957 3361 return self.playlist_from_matches(soundcloud_urls, video_id, video_title, getter=unescapeHTML)
20991253 3362
027e2312
S
3363 # Look for tunein player
3364 tunein_urls = TuneInBaseIE._extract_urls(webpage)
3365 if tunein_urls:
46b18f23 3366 return self.playlist_from_matches(tunein_urls, video_id, video_title)
027e2312 3367
c5cd249e 3368 # Look for embedded mtvservices player
46fde8a1
S
3369 mtvservices_url = MTVServicesEmbeddedIE._extract_url(webpage)
3370 if mtvservices_url:
3371 return self.url_result(mtvservices_url, ie='MTVServicesEmbedded')
c5cd249e 3372
49807b4a
S
3373 # Look for embedded yahoo player
3374 mobj = re.search(
3375 r'<iframe[^>]+?src=(["\'])(?P<url>https?://(?:screen|movies)\.yahoo\.com/.+?\.html\?format=embed)\1',
3376 webpage)
3377 if mobj is not None:
3378 return self.url_result(mobj.group('url'), 'Yahoo')
3379
2ef6fcb5
PH
3380 # Look for embedded sbs.com.au player
3381 mobj = re.search(
e98b8e79
PH
3382 r'''(?x)
3383 (?:
3384 <meta\s+property="og:video"\s+content=|
3385 <iframe[^>]+?src=
3386 )
3387 (["\'])(?P<url>https?://(?:www\.)?sbs\.com\.au/ondemand/video/.+?)\1''',
2ef6fcb5
PH
3388 webpage)
3389 if mobj is not None:
3390 return self.url_result(mobj.group('url'), 'SBS')
3391
42bdd9d0
PH
3392 # Look for embedded Cinchcast player
3393 mobj = re.search(
3394 r'<iframe[^>]+?src=(["\'])(?P<url>https?://player\.cinchcast\.com/.+?)\1',
3395 webpage)
3396 if mobj is not None:
3397 return self.url_result(mobj.group('url'), 'Cinchcast')
3398
1a94ff68 3399 mobj = re.search(
5263cdfc 3400 r'<iframe[^>]+?src=(["\'])(?P<url>https?://m(?:lb)?\.mlb\.com/shared/video/embed/embed\.html\?.+?)\1',
1a94ff68 3401 webpage)
8001607e
YCH
3402 if not mobj:
3403 mobj = re.search(
1418a043 3404 r'data-video-link=["\'](?P<url>http://m\.mlb\.com/video/[^"\']+)',
8001607e 3405 webpage)
1a94ff68
S
3406 if mobj is not None:
3407 return self.url_result(mobj.group('url'), 'MLB')
3408
1419fafd 3409 mobj = re.search(
dd467d33 3410 r'<(?:iframe|script)[^>]+?src=(["\'])(?P<url>%s)\1' % CondeNastIE.EMBED_URL,
1419fafd
S
3411 webpage)
3412 if mobj is not None:
3413 return self.url_result(self._proto_relative_url(mobj.group('url'), scheme='http:'), 'CondeNast')
3414
af63fed7 3415 mobj = re.search(
78d3b3e2 3416 r'<iframe[^>]+src="(?P<url>https?://(?:new\.)?livestream\.com/[^"]+/player[^"]+)"',
af63fed7
PH
3417 webpage)
3418 if mobj is not None:
3419 return self.url_result(mobj.group('url'), 'Livestream')
3420
255fca5e
S
3421 # Look for Zapiks embed
3422 mobj = re.search(
3423 r'<iframe[^>]+src="(?P<url>https?://(?:www\.)?zapiks\.fr/index\.php\?.+?)"', webpage)
3424 if mobj is not None:
3425 return self.url_result(mobj.group('url'), 'Zapiks')
3426
e3216b82 3427 # Look for Kaltura embeds
562de77f
S
3428 kaltura_urls = KalturaIE._extract_urls(webpage)
3429 if kaltura_urls:
3430 return self.playlist_from_matches(
3431 kaltura_urls, video_id, video_title,
3432 getter=lambda x: smuggle_url(x, {'source_url': url}),
3433 ie=KalturaIE.ie_key())
e3216b82 3434
665e9452 3435 # Look for EaglePlatform embeds
06a96da1
S
3436 eagleplatform_url = EaglePlatformIE._extract_url(webpage)
3437 if eagleplatform_url:
665e9452 3438 return self.url_result(smuggle_url(eagleplatform_url, {'referrer': url}), EaglePlatformIE.ie_key())
135c9c42 3439
665e9452 3440 # Look for ClipYou (uses EaglePlatform) embeds
d47ae7f6
S
3441 mobj = re.search(
3442 r'<iframe[^>]+src="https?://(?P<host>media\.clipyou\.ru)/index/player\?.*\brecord_id=(?P<id>\d+).*"', webpage)
3443 if mobj is not None:
3444 return self.url_result('eagleplatform:%(host)s:%(id)s' % mobj.groupdict(), 'EaglePlatform')
3445
f8388757 3446 # Look for Pladform embeds
45dad7ba
S
3447 pladform_url = PladformIE._extract_url(webpage)
3448 if pladform_url:
3449 return self.url_result(pladform_url)
f8388757 3450
ff18735c
S
3451 # Look for Videomore embeds
3452 videomore_url = VideomoreIE._extract_url(webpage)
3453 if videomore_url:
3454 return self.url_result(videomore_url)
3455
83f1481b
S
3456 # Look for Webcaster embeds
3457 webcaster_url = WebcasterFeedIE._extract_url(self, webpage)
3458 if webcaster_url:
3459 return self.url_result(webcaster_url, ie=WebcasterFeedIE.ie_key())
3460
2dcc114f
S
3461 # Look for Playwire embeds
3462 mobj = re.search(
3463 r'<script[^>]+data-config=(["\'])(?P<url>(?:https?:)?//config\.playwire\.com/.+?)\1', webpage)
3464 if mobj is not None:
3465 return self.url_result(mobj.group('url'))
3466
18153f1b
S
3467 # Look for Crooks and Liars embeds
3468 mobj = re.search(
3469 r'<(?:iframe[^>]+src|param[^>]+value)=(["\'])(?P<url>(?:https?:)?//embed\.crooksandliars\.com/(?:embed|v)/.+?)\1', webpage)
3470 if mobj is not None:
3471 return self.url_result(mobj.group('url'))
3472
a2edf2e7
YCH
3473 # Look for NBC Sports VPlayer embeds
3474 nbc_sports_url = NBCSportsVPlayerIE._extract_url(webpage)
3475 if nbc_sports_url:
3476 return self.url_result(nbc_sports_url, 'NBCSportsVPlayer')
3477
de3eb07e
YCH
3478 # Look for NBC News embeds
3479 nbc_news_embed_url = re.search(
3480 r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//www\.nbcnews\.com/widget/video-embed/[^"\']+)\1', webpage)
3481 if nbc_news_embed_url:
3482 return self.url_result(nbc_news_embed_url.group('url'), 'NBCNews')
3483
653789af 3484 # Look for Google Drive embeds
5b251628 3485 google_drive_url = GoogleDriveIE._extract_url(webpage)
653789af 3486 if google_drive_url:
3487 return self.url_result(google_drive_url, 'GoogleDrive')
3488
418c5cc3
YCH
3489 # Look for UDN embeds
3490 mobj = re.search(
2637fadc 3491 r'<iframe[^>]+src="(?:https?:)?(?P<url>%s)"' % UDNEmbedIE._PROTOCOL_RELATIVE_VALID_URL, webpage)
418c5cc3
YCH
3492 if mobj is not None:
3493 return self.url_result(
0a160363 3494 compat_urlparse.urljoin(url, mobj.group('url')), 'UDNEmbed')
418c5cc3 3495
2fe1b5bd
YCH
3496 # Look for Senate ISVP iframe
3497 senate_isvp_url = SenateISVPIE._search_iframe_url(webpage)
3498 if senate_isvp_url:
25c3a734 3499 return self.url_result(senate_isvp_url, 'SenateISVP')
2fe1b5bd 3500
55adb63e
RA
3501 # Look for Kinja embeds
3502 kinja_embed_urls = KinjaEmbedIE._extract_urls(webpage, url)
3503 if kinja_embed_urls:
3504 return self.playlist_from_matches(
3505 kinja_embed_urls, video_id, video_title)
3506
1ac1c4c2
S
3507 # Look for OnionStudios embeds
3508 onionstudios_url = OnionStudiosIE._extract_url(webpage)
3509 if onionstudios_url:
3510 return self.url_result(onionstudios_url)
3511
764f5de2
PW
3512 # Look for Blogger embeds
3513 blogger_urls = BloggerIE._extract_urls(webpage)
3514 if blogger_urls:
3515 return self.playlist_from_matches(blogger_urls, video_id, video_title, ie=BloggerIE.ie_key())
3516
67167920 3517 # Look for ViewLift embeds
3518 viewlift_url = ViewLiftEmbedIE._extract_url(webpage)
3519 if viewlift_url:
3520 return self.url_result(viewlift_url)
eedd20ef 3521
7cb09524 3522 # Look for JWPlatform embeds
b0ead0e0
S
3523 jwplatform_urls = JWPlatformIE._extract_urls(webpage)
3524 if jwplatform_urls:
3525 return self.playlist_from_matches(jwplatform_urls, video_id, video_title, ie=JWPlatformIE.ie_key())
7cb09524 3526
aecfcd4e
S
3527 # Look for Digiteka embeds
3528 digiteka_url = DigitekaIE._extract_url(webpage)
3529 if digiteka_url:
3530 return self.url_result(self._proto_relative_url(digiteka_url), DigitekaIE.ie_key())
6aeba407 3531
1979969f
S
3532 # Look for Arkena embeds
3533 arkena_url = ArkenaIE._extract_url(webpage)
3534 if arkena_url:
3535 return self.url_result(arkena_url, ArkenaIE.ie_key())
3536
b1c35797
RA
3537 # Look for Piksel embeds
3538 piksel_url = PikselIE._extract_url(webpage)
3539 if piksel_url:
3540 return self.url_result(piksel_url, PikselIE.ie_key())
3541
1bf996fa 3542 # Look for Limelight embeds
e5d39886
S
3543 limelight_urls = LimelightBaseIE._extract_urls(webpage, url)
3544 if limelight_urls:
3545 return self.playlist_result(
3546 limelight_urls, video_id, video_title, video_description)
3547
7986c3ab
S
3548 # Look for Anvato embeds
3549 anvato_urls = AnvatoIE._extract_urls(self, webpage, video_id)
3550 if anvato_urls:
3551 return self.playlist_result(
3552 anvato_urls, video_id, video_title, video_description)
3553
a5158f38
YCH
3554 # Look for AdobeTVVideo embeds
3555 mobj = re.search(
3556 r'<iframe[^>]+src=[\'"]((?:https?:)?//video\.tv\.adobe\.com/v/\d+[^"]+)[\'"]',
3557 webpage)
3558 if mobj is not None:
3559 return self.url_result(
3560 self._proto_relative_url(unescapeHTML(mobj.group(1))),
3561 'AdobeTVVideo')
3562
088e1aac
YCH
3563 # Look for Vine embeds
3564 mobj = re.search(
3565 r'<iframe[^>]+src=[\'"]((?:https?:)?//(?:www\.)?vine\.co/v/[^/]+/embed/(?:simple|postcard))',
3566 webpage)
3567 if mobj is not None:
3568 return self.url_result(
3569 self._proto_relative_url(unescapeHTML(mobj.group(1))), 'Vine')
3570
217d5ae0
RA
3571 # Look for VODPlatform embeds
3572 mobj = re.search(
bd2c211f 3573 r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//(?:(?:www\.)?vod-platform\.net|embed\.kwikmotion\.com)/[eE]mbed/.+?)\1',
217d5ae0
RA
3574 webpage)
3575 if mobj is not None:
3576 return self.url_result(
93b84045 3577 self._proto_relative_url(unescapeHTML(mobj.group('url'))), 'VODPlatform')
217d5ae0 3578
7d273a38
RA
3579 # Look for Mangomolo embeds
3580 mobj = re.search(
755541a4
RA
3581 r'''(?x)<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//
3582 (?:
3583 admin\.mangomolo\.com/analytics/index\.php/customers/embed|
3584 player\.mangomolo\.com/v1
3585 )/
7d273a38
RA
3586 (?:
3587 video\?.*?\bid=(?P<video_id>\d+)|
755541a4 3588 (?:index|live)\?.*?\bchannelid=(?P<channel_id>(?:[A-Za-z0-9+/=]|%2B|%2F|%3D)+)
7d273a38
RA
3589 ).+?)\1''', webpage)
3590 if mobj is not None:
3591 info = {
3592 '_type': 'url_transparent',
3593 'url': self._proto_relative_url(unescapeHTML(mobj.group('url'))),
3594 'title': video_title,
3595 'description': video_description,
3596 'thumbnail': video_thumbnail,
3597 'uploader': video_uploader,
3598 }
3599 video_id = mobj.group('video_id')
3600 if video_id:
3601 info.update({
3602 'ie_key': 'MangomoloVideo',
3603 'id': video_id,
3604 })
3605 else:
3606 info.update({
3607 'ie_key': 'MangomoloLive',
3608 'id': mobj.group('channel_id'),
3609 })
3610 return info
3611
5a51775a
YCH
3612 # Look for Instagram embeds
3613 instagram_embed_url = InstagramIE._extract_embed_url(webpage)
3614 if instagram_embed_url is not None:
11e60fca
S
3615 return self.url_result(
3616 self._proto_relative_url(instagram_embed_url), InstagramIE.ie_key())
5a51775a 3617
5d39176f
S
3618 # Look for 3Q SDN embeds
3619 threeqsdn_url = ThreeQSDNIE._extract_url(webpage)
3620 if threeqsdn_url:
6f41b2bc
S
3621 return {
3622 '_type': 'url_transparent',
3623 'ie_key': ThreeQSDNIE.ie_key(),
3624 'url': self._proto_relative_url(threeqsdn_url),
3625 'title': video_title,
3626 'description': video_description,
3627 'thumbnail': video_thumbnail,
3628 'uploader': video_uploader,
3629 }
5d39176f 3630
2a1321a2
S
3631 # Look for VBOX7 embeds
3632 vbox7_url = Vbox7IE._extract_url(webpage)
3633 if vbox7_url:
3634 return self.url_result(vbox7_url, Vbox7IE.ie_key())
3635
b0c8f2e9
DR
3636 # Look for DBTV embeds
3637 dbtv_urls = DBTVIE._extract_urls(webpage)
3638 if dbtv_urls:
46b18f23 3639 return self.playlist_from_matches(dbtv_urls, video_id, video_title, ie=DBTVIE.ie_key())
b0c8f2e9 3640
e186a9ec
S
3641 # Look for Videa embeds
3642 videa_urls = VideaIE._extract_urls(webpage)
3643 if videa_urls:
46b18f23 3644 return self.playlist_from_matches(videa_urls, video_id, video_title, ie=VideaIE.ie_key())
e186a9ec 3645
b687c85e
S
3646 # Look for 20 minuten embeds
3647 twentymin_urls = TwentyMinutenIE._extract_urls(webpage)
3648 if twentymin_urls:
46b18f23
JH
3649 return self.playlist_from_matches(
3650 twentymin_urls, video_id, video_title, ie=TwentyMinutenIE.ie_key())
b687c85e 3651
6ef3e65a
S
3652 # Look for VideoPress embeds
3653 videopress_urls = VideoPressIE._extract_urls(webpage)
3654 if videopress_urls:
46b18f23
JH
3655 return self.playlist_from_matches(
3656 videopress_urls, video_id, video_title, ie=VideoPressIE.ie_key())
6ef3e65a 3657
eb3079b6
S
3658 # Look for Rutube embeds
3659 rutube_urls = RutubeIE._extract_urls(webpage)
3660 if rutube_urls:
46b18f23 3661 return self.playlist_from_matches(
2583c0b5 3662 rutube_urls, video_id, video_title, ie=RutubeIE.ie_key())
6ef3e65a 3663
71738b14
ZM
3664 # Look for Glomex embeds
3665 glomex_urls = list(GlomexEmbedIE._extract_urls(webpage, url))
3666 if glomex_urls:
3667 return self.playlist_from_matches(
3668 glomex_urls, video_id, video_title, ie=GlomexEmbedIE.ie_key())
3669
32b95bb6
ZM
3670 # Look for megatv.com embeds
3671 megatvcom_urls = list(MegaTVComEmbedIE._extract_urls(webpage))
3672 if megatvcom_urls:
3673 return self.playlist_from_matches(
3674 megatvcom_urls, video_id, video_title, ie=MegaTVComEmbedIE.ie_key())
3675
27231526
ZM
3676 # Look for ant1news.gr embeds
3677 ant1newsgr_urls = list(Ant1NewsGrEmbedIE._extract_urls(webpage))
3678 if ant1newsgr_urls:
3679 return self.playlist_from_matches(
3680 ant1newsgr_urls, video_id, video_title, ie=Ant1NewsGrEmbedIE.ie_key())
3681
55719459
JH
3682 # Look for WashingtonPost embeds
3683 wapo_urls = WashingtonPostIE._extract_urls(webpage)
3684 if wapo_urls:
3685 return self.playlist_from_matches(
3686 wapo_urls, video_id, video_title, ie=WashingtonPostIE.ie_key())
3687
5d29af3d 3688 # Look for Mediaset embeds
8fd12a08 3689 mediaset_urls = MediasetIE._extract_urls(self, webpage)
5d29af3d
S
3690 if mediaset_urls:
3691 return self.playlist_from_matches(
3692 mediaset_urls, video_id, video_title, ie=MediasetIE.ie_key())
3693
73cf76a9
S
3694 # Look for JOJ.sk embeds
3695 joj_urls = JojIE._extract_urls(webpage)
3696 if joj_urls:
3697 return self.playlist_from_matches(
3698 joj_urls, video_id, video_title, ie=JojIE.ie_key())
3699
24e966e8
PH
3700 # Look for megaphone.fm embeds
3701 mpfn_urls = MegaphoneIE._extract_urls(webpage)
3702 if mpfn_urls:
3703 return self.playlist_from_matches(
3704 mpfn_urls, video_id, video_title, ie=MegaphoneIE.ie_key())
3705
1663bd6e
S
3706 # Look for vzaar embeds
3707 vzaar_urls = VzaarIE._extract_urls(webpage)
3708 if vzaar_urls:
3709 return self.playlist_from_matches(
3710 vzaar_urls, video_id, video_title, ie=VzaarIE.ie_key())
3711
26bae2d9
S
3712 channel9_urls = Channel9IE._extract_urls(webpage)
3713 if channel9_urls:
3714 return self.playlist_from_matches(
3715 channel9_urls, video_id, video_title, ie=Channel9IE.ie_key())
3716
0987f2dd
T
3717 vshare_urls = VShareIE._extract_urls(webpage)
3718 if vshare_urls:
3719 return self.playlist_from_matches(
3720 vshare_urls, video_id, video_title, ie=VShareIE.ie_key())
3721
8056c854 3722 # Look for Mediasite embeds
2ca7ed41
S
3723 mediasite_urls = MediasiteIE._extract_urls(webpage)
3724 if mediasite_urls:
3725 entries = [
3726 self.url_result(smuggle_url(
3727 compat_urlparse.urljoin(url, mediasite_url),
3728 {'UrlReferrer': url}), ie=MediasiteIE.ie_key())
3729 for mediasite_url in mediasite_urls]
3730 return self.playlist_result(entries, video_id, video_title)
8056c854 3731
7d540621
S
3732 springboardplatform_urls = SpringboardPlatformIE._extract_urls(webpage)
3733 if springboardplatform_urls:
3734 return self.playlist_from_matches(
3735 springboardplatform_urls, video_id, video_title,
3736 ie=SpringboardPlatformIE.ie_key())
3737
4c780fbd
S
3738 yapfiles_urls = YapFilesIE._extract_urls(webpage)
3739 if yapfiles_urls:
3740 return self.playlist_from_matches(
3741 yapfiles_urls, video_id, video_title, ie=YapFilesIE.ie_key())
3742
86c8cfc5
S
3743 vice_urls = ViceIE._extract_urls(webpage)
3744 if vice_urls:
3745 return self.playlist_from_matches(
3746 vice_urls, video_id, video_title, ie=ViceIE.ie_key())
3747
178ee883
S
3748 xfileshare_urls = XFileShareIE._extract_urls(webpage)
3749 if xfileshare_urls:
3750 return self.playlist_from_matches(
3751 xfileshare_urls, video_id, video_title, ie=XFileShareIE.ie_key())
3752
660a230b
S
3753 cloudflarestream_urls = CloudflareStreamIE._extract_urls(webpage)
3754 if cloudflarestream_urls:
3755 return self.playlist_from_matches(
3756 cloudflarestream_urls, video_id, video_title, ie=CloudflareStreamIE.ie_key())
3757
8b4b400a 3758 peertube_urls = PeerTubeIE._extract_urls(webpage, url)
6bd499e8
S
3759 if peertube_urls:
3760 return self.playlist_from_matches(
3761 peertube_urls, video_id, video_title, ie=PeerTubeIE.ie_key())
3762
aee36ca8
S
3763 indavideo_urls = IndavideoEmbedIE._extract_urls(webpage)
3764 if indavideo_urls:
3765 return self.playlist_from_matches(
3766 indavideo_urls, video_id, video_title, ie=IndavideoEmbedIE.ie_key())
3767
cfd7f2a6
S
3768 apa_urls = APAIE._extract_urls(webpage)
3769 if apa_urls:
3770 return self.playlist_from_matches(
3771 apa_urls, video_id, video_title, ie=APAIE.ie_key())
3772
f51f526b
S
3773 foxnews_urls = FoxNewsIE._extract_urls(webpage)
3774 if foxnews_urls:
3775 return self.playlist_from_matches(
3776 foxnews_urls, video_id, video_title, ie=FoxNewsIE.ie_key())
3777
2e4350ee 3778 sharevideos_urls = [sharevideos_mobj.group('url') for sharevideos_mobj in re.finditer(
d3431dcb
S
3779 r'<iframe[^>]+?\bsrc\s*=\s*(["\'])(?P<url>(?:https?:)?//embed\.share-videos\.se/auto/embed/\d+\?.*?\buid=\d+.*?)\1',
3780 webpage)]
3781 if sharevideos_urls:
3782 return self.playlist_from_matches(
3783 sharevideos_urls, video_id, video_title)
3784
9d1b2138
S
3785 viqeo_urls = ViqeoIE._extract_urls(webpage)
3786 if viqeo_urls:
3787 return self.playlist_from_matches(
3788 viqeo_urls, video_id, video_title, ie=ViqeoIE.ie_key())
57c68ec4
S
3789
3790 expressen_urls = ExpressenIE._extract_urls(webpage)
3791 if expressen_urls:
3792 return self.playlist_from_matches(
3793 expressen_urls, video_id, video_title, ie=ExpressenIE.ie_key())
9d1b2138 3794
83852e57
S
3795 zype_urls = ZypeIE._extract_urls(webpage)
3796 if zype_urls:
3797 return self.playlist_from_matches(
3798 zype_urls, video_id, video_title, ie=ZypeIE.ie_key())
3799
feee67ae 3800 gedi_urls = GediDigitalIE._extract_urls(webpage)
902784a2 3801 if gedi_urls:
3802 return self.playlist_from_matches(
feee67ae 3803 gedi_urls, video_id, video_title, ie=GediDigitalIE.ie_key())
902784a2 3804
feee67ae 3805 # Look for RCS media group embeds
a85e131b 3806 rcs_urls = RCSEmbedsIE._extract_urls(webpage)
3807 if rcs_urls:
3808 return self.playlist_from_matches(
3809 rcs_urls, video_id, video_title, ie=RCSEmbedsIE.ie_key())
3810
e4edeb62 3811 wimtv_urls = WimTVIE._extract_urls(webpage)
3812 if wimtv_urls:
3813 return self.playlist_from_matches(
3814 wimtv_urls, video_id, video_title, ie=WimTVIE.ie_key())
3815
097f1663 3816 bitchute_urls = BitChuteIE._extract_urls(webpage)
3817 if bitchute_urls:
3818 return self.playlist_from_matches(
3819 bitchute_urls, video_id, video_title, ie=BitChuteIE.ie_key())
3820
62852977 3821 rumble_urls = RumbleEmbedIE._extract_urls(webpage)
3822 if len(rumble_urls) == 1:
3823 return self.url_result(rumble_urls[0], RumbleEmbedIE.ie_key())
3824 if rumble_urls:
3825 return self.playlist_from_matches(
3826 rumble_urls, video_id, video_title, ie=RumbleEmbedIE.ie_key())
3827
1a20d295
ZM
3828 # Look for (tvopen|ethnos).gr embeds
3829 tvopengr_urls = list(TVOpenGrEmbedIE._extract_urls(webpage))
3830 if tvopengr_urls:
3831 return self.playlist_from_matches(tvopengr_urls, video_id, video_title, ie=TVOpenGrEmbedIE.ie_key())
3832
2d49720f
ZM
3833 # Look for ert.gr webtv embeds
3834 ertwebtv_urls = list(ERTWebtvEmbedIE._extract_urls(webpage))
3835 if len(ertwebtv_urls) == 1:
3836 return self.url_result(self._proto_relative_url(ertwebtv_urls[0]), video_title=video_title, url_transparent=True)
3837 elif ertwebtv_urls:
3838 return self.playlist_from_matches(ertwebtv_urls, video_id, video_title, ie=ERTWebtvEmbedIE.ie_key())
3839
56bb56f3
LL
3840 tvp_urls = TVPEmbedIE._extract_urls(webpage)
3841 if tvp_urls:
3842 return self.playlist_from_matches(tvp_urls, video_id, video_title, ie=TVPEmbedIE.ie_key())
3843
9c634ef8 3844 # Look for MainStreaming embeds
3845 mainstreaming_urls = MainStreamingIE._extract_urls(webpage)
3846 if mainstreaming_urls:
3847 return self.playlist_from_matches(mainstreaming_urls, video_id, video_title, ie=MainStreamingIE.ie_key())
3848
9f517bb1 3849 # Look for Gfycat Embeds
3850 gfycat_urls = GfycatIE._extract_urls(webpage)
3851 if gfycat_urls:
3852 return self.playlist_from_matches(gfycat_urls, video_id, video_title, ie=GfycatIE.ie_key())
9c634ef8 3853
e248be33 3854 panopto_urls = PanoptoBaseIE._extract_urls(webpage)
3855 if panopto_urls:
3856 return self.playlist_from_matches(panopto_urls, video_id, video_title)
0a8a7e68
TI
3857
3858 # Look for Ruutu embeds
a0fe51d5
TI
3859 ruutu_urls = RuutuIE._extract_urls(webpage)
3860 if ruutu_urls:
3861 return self.playlist_from_matches(ruutu_urls, video_id, video_title)
0a8a7e68 3862
b801cd71 3863 # Look for Tiktok embeds
3864 tiktok_urls = TikTokIE._extract_urls(webpage)
3865 if tiktok_urls:
3866 return self.playlist_from_matches(tiktok_urls, video_id, video_title)
3867
bd264412
YCH
3868 # Look for HTML5 media
3869 entries = self._parse_html5_media_entries(url, webpage, video_id, m3u8_id='hls')
3870 if entries:
aa9369a2 3871 self.report_detected('HTML5 media')
9ce1ac40 3872 if len(entries) == 1:
3873 entries[0].update({
bd264412
YCH
3874 'id': video_id,
3875 'title': video_title,
3876 })
9ce1ac40 3877 else:
3878 for num, entry in enumerate(entries, start=1):
3879 entry.update({
86e5f3ed 3880 'id': f'{video_id}-{num}',
9ce1ac40 3881 'title': '%s (%d)' % (video_title, num),
3882 })
3883 for entry in entries:
bd264412 3884 self._sort_formats(entry['formats'])
9ce1ac40 3885 return self.playlist_result(entries, video_id, video_title)
bd264412 3886
c73e330e
RU
3887 jwplayer_data = self._find_jwplayer_data(
3888 webpage, video_id, transform_source=js_to_json)
3889 if jwplayer_data:
5e7bbac3 3890 if isinstance(jwplayer_data.get('playlist'), str):
aa9369a2 3891 self.report_detected('JW Player playlist')
5e7bbac3 3892 return {
3893 **info_dict,
3894 '_type': 'url',
3895 'ie_key': JWPlatformIE.ie_key(),
3896 'url': jwplayer_data['playlist'],
3897 }
3d08f63d
MYM
3898 try:
3899 info = self._parse_jwplayer_data(
3900 jwplayer_data, video_id, require_title=False, base_url=url)
aa9369a2 3901 self.report_detected('JW Player data')
3d08f63d
MYM
3902 return merge_dicts(info, info_dict)
3903 except ExtractorError:
067aa17e 3904 # See https://github.com/ytdl-org/youtube-dl/pull/16735
3d08f63d 3905 pass
a4a554a7 3906
63d990d2
S
3907 # Video.js embed
3908 mobj = re.search(
c2d2ee40 3909 r'(?s)\bvideojs\s*\(.+?([a-zA-Z0-9_$]+)\.src\s*\(\s*((?:\[.+?\]|{.+?}))\s*\)\s*;',
63d990d2
S
3910 webpage)
3911 if mobj is not None:
c2d2ee40 3912 varname = mobj.group(1)
63d990d2 3913 sources = self._parse_json(
c2d2ee40 3914 mobj.group(2), video_id, transform_source=js_to_json,
63d990d2 3915 fatal=False) or []
c5b7014a
S
3916 if not isinstance(sources, list):
3917 sources = [sources]
63d990d2 3918 formats = []
da1c94ee 3919 subtitles = {}
63d990d2 3920 for source in sources:
e0b6e988
S
3921 src = source.get('src')
3922 if not src or not isinstance(src, compat_str):
63d990d2
S
3923 continue
3924 src = compat_urlparse.urljoin(url, src)
3925 src_type = source.get('type')
3926 if isinstance(src_type, compat_str):
3927 src_type = src_type.lower()
3928 ext = determine_ext(src).lower()
3929 if src_type == 'video/youtube':
3930 return self.url_result(src, YoutubeIE.ie_key())
3931 if src_type == 'application/dash+xml' or ext == 'mpd':
da1c94ee
F
3932 fmts, subs = self._extract_mpd_formats_and_subtitles(
3933 src, video_id, mpd_id='dash', fatal=False)
3934 formats.extend(fmts)
3935 self._merge_subtitles(subs, target=subtitles)
63d990d2 3936 elif src_type == 'application/x-mpegurl' or ext == 'm3u8':
da1c94ee 3937 fmts, subs = self._extract_m3u8_formats_and_subtitles(
63d990d2 3938 src, video_id, 'mp4', entry_protocol='m3u8_native',
da1c94ee
F
3939 m3u8_id='hls', fatal=False)
3940 formats.extend(fmts)
3941 self._merge_subtitles(subs, target=subtitles)
63d990d2
S
3942 else:
3943 formats.append({
3944 'url': src,
3089bc74
S
3945 'ext': (mimetype2ext(src_type)
3946 or ext if ext in KNOWN_EXTENSIONS else 'mp4'),
b73612a2 3947 'http_headers': {
3948 'Referer': full_response.geturl(),
3949 },
63d990d2 3950 })
c2d2ee40
LNO
3951 # https://docs.videojs.com/player#addRemoteTextTrack
3952 # https://html.spec.whatwg.org/multipage/media.html#htmltrackelement
3953 for sub_match in re.finditer(rf'(?s){re.escape(varname)}' r'\.addRemoteTextTrack\(({.+?})\s*,\s*(?:true|false)\)', webpage):
3954 sub = self._parse_json(
3955 sub_match.group(1), video_id, transform_source=js_to_json, fatal=False) or {}
3956 src = str_or_none(sub.get('src'))
3957 if not src:
3958 continue
3959 subtitles.setdefault(dict_get(sub, ('language', 'srclang')) or 'und', []).append({
3960 'url': compat_urlparse.urljoin(url, src),
3961 'name': sub.get('label'),
3962 'http_headers': {
3963 'Referer': full_response.geturl(),
3964 },
3965 })
da1c94ee 3966 if formats or subtitles:
aa9369a2 3967 self.report_detected('video.js embed')
63d990d2
S
3968 self._sort_formats(formats)
3969 info_dict['formats'] = formats
da1c94ee 3970 info_dict['subtitles'] = subtitles
63d990d2
S
3971 return info_dict
3972
ff17be3a 3973 # Looking for http://schema.org/VideoObject
fa0b816e 3974 json_ld = self._search_json_ld(webpage, video_id, default={})
85553414 3975 if json_ld.get('url') not in (url, None):
aa9369a2 3976 self.report_detected('JSON LD')
21a73e9f 3977 return merge_dicts({
3978 '_type': 'url_transparent',
3979 'url': smuggle_url(json_ld['url'], {'force_videoid': video_id, 'to_generic': True}),
3980 }, json_ld, info_dict)
ff17be3a 3981
ced659bb 3982 def check_video(vurl):
a0f71985
PH
3983 if YoutubeIE.suitable(vurl):
3984 return True
b7a8c1bc
S
3985 if RtmpIE.suitable(vurl):
3986 return True
ced659bb 3987 vpath = compat_urlparse.urlparse(vurl).path
a44ca5a4 3988 vext = determine_ext(vpath, None)
3989 return vext not in (None, 'swf', 'png', 'jpg', 'srt', 'sbv', 'sub', 'vtt', 'ttml', 'js', 'xml')
ced659bb
S
3990
3991 def filter_video(urls):
3992 return list(filter(check_video, urls))
3993
9b122384 3994 # Start with something easy: JW Player in SWFObject
ced659bb 3995 found = filter_video(re.findall(r'flashvars: [\'"](?:.*&)?file=(http[^\'"&]*)', webpage))
aa9369a2 3996 if found:
3997 self.report_detected('JW Player in SFWObject')
3998 else:
d981cef6 3999 # Look for gorilla-vid style embedding
ced659bb 4000 found = filter_video(re.findall(r'''(?sx)
c0292e8a
PH
4001 (?:
4002 jw_plugins|
4003 JWPlayerOptions|
4004 jwplayer\s*\(\s*["'][^'"]+["']\s*\)\s*\.setup
4005 )
a0f71985
PH
4006 .*?
4007 ['"]?file['"]?\s*:\s*["\'](.*?)["\']''', webpage))
aa9369a2 4008 if found:
4009 self.report_detected('JW Player embed')
a318f59d 4010 if not found:
4011 # Look for generic KVS player
9980d3d2 4012 found = re.search(r'<script [^>]*?src="https?://.+?/kt_player\.js\?v=(?P<ver>(?P<maj_ver>\d+)(\.\d+)+)".*?>', webpage)
a318f59d 4013 if found:
aa9369a2 4014 self.report_detected('KWS Player')
a318f59d 4015 if found.group('maj_ver') not in ['4', '5']:
4016 self.report_warning('Untested major version (%s) in player engine--Download may fail.' % found.group('ver'))
4017 flashvars = re.search(r'(?ms)<script.*?>.*?var\s+flashvars\s*=\s*(\{.*?\});.*?</script>', webpage)
4018 flashvars = self._parse_json(flashvars.group(1), video_id, transform_source=js_to_json)
4019
4020 # extract the part after the last / as the display_id from the
4021 # canonical URL.
4022 display_id = self._search_regex(
4023 r'(?:<link href="https?://[^"]+/(.+?)/?" rel="canonical"\s*/?>'
4024 r'|<link rel="canonical" href="https?://[^"]+/(.+?)/?"\s*/?>)',
4025 webpage, 'display_id', fatal=False
4026 )
4027 title = self._html_search_regex(r'<(?:h1|title)>(?:Video: )?(.+?)</(?:h1|title)>', webpage, 'title')
4028
4029 thumbnail = flashvars['preview_url']
4030 if thumbnail.startswith('//'):
4031 protocol, _, _ = url.partition('/')
4032 thumbnail = protocol + thumbnail
4033
6970b600 4034 url_keys = list(filter(re.compile(r'video_url|video_alt_url\d*').fullmatch, flashvars.keys()))
a318f59d 4035 formats = []
11c86170 4036 for key in url_keys:
4037 if '/get_file/' not in flashvars[key]:
4038 continue
4039 format_id = flashvars.get(f'{key}_text', key)
4040 formats.append({
4041 'url': self._kvs_getrealurl(flashvars[key], flashvars['license_code']),
4042 'format_id': format_id,
4043 'ext': 'mp4',
4044 **(parse_resolution(format_id) or parse_resolution(flashvars[key]))
4045 })
4046 if not formats[-1].get('height'):
4047 formats[-1]['quality'] = 1
4048
a318f59d 4049 self._sort_formats(formats)
4050
4051 return {
4052 'id': flashvars['video_id'],
4053 'display_id': display_id,
4054 'title': title,
4055 'thumbnail': thumbnail,
4056 'formats': formats,
4057 }
b30b8698 4058 if not found:
9b122384 4059 # Broaden the search a little bit
ced659bb 4060 found = filter_video(re.findall(r'[^A-Za-z0-9]?(?:file|source)=(http[^\'"&]*)', webpage))
aa9369a2 4061 if found:
4062 self.report_detected('video file')
b30b8698
PH
4063 if not found:
4064 # Broaden the findall a little bit: JWPlayer JS loader
ced659bb 4065 found = filter_video(re.findall(
54a9328b 4066 r'[^A-Za-z0-9]?(?:file|video_url)["\']?:\s*["\'](http(?![^\'"]+\.[0-9]+[\'"])[^\'"]+)["\']', webpage))
aa9369a2 4067 if found:
4068 self.report_detected('JW Player JS loader')
4d805e06
PH
4069 if not found:
4070 # Flow player
ced659bb 4071 found = filter_video(re.findall(r'''(?xs)
4d805e06
PH
4072 flowplayer\("[^"]+",\s*
4073 \{[^}]+?\}\s*,
52585fd6 4074 \s*\{[^}]+? ["']?clip["']?\s*:\s*\{\s*
4d805e06 4075 ["']?url["']?\s*:\s*["']([^"']+)["']
ced659bb 4076 ''', webpage))
aa9369a2 4077 if found:
4078 self.report_detected('Flow Player')
501f13fb
PH
4079 if not found:
4080 # Cinerama player
4081 found = re.findall(
4082 r"cinerama\.embedPlayer\(\s*\'[^']+\',\s*'([^']+)'", webpage)
aa9369a2 4083 if found:
4084 self.report_detected('Cinerama player')
b30b8698 4085 if not found:
9b122384 4086 # Try to find twitter cards info
371ddb14
S
4087 # twitter:player:stream should be checked before twitter:player since
4088 # it is expected to contain a raw stream (see
4089 # https://dev.twitter.com/cards/types/player#On_twitter.com_via_desktop_browser)
ced659bb
S
4090 found = filter_video(re.findall(
4091 r'<meta (?:property|name)="twitter:player:stream" (?:content|value)="(.+?)"', webpage))
aa9369a2 4092 if found:
4093 self.report_detected('Twitter card')
b30b8698 4094 if not found:
9b122384
PH
4095 # We look for Open Graph info:
4096 # We have to match any number spaces between elements, some sites try to align them (eg.: statigr.am)
b30b8698 4097 m_video_type = re.findall(r'<meta.*?property="og:video:type".*?content="video/(.*?)"', webpage)
9b122384
PH
4098 # We only look in og:video if the MIME type is a video, don't try if it's a Flash player:
4099 if m_video_type is not None:
b73612a2 4100 found = filter_video(re.findall(r'<meta.*?property="og:(?:video|audio)".*?content="(.*?)"', webpage))
aa9369a2 4101 if found:
4102 self.report_detected('Open Graph video info')
b30b8698 4103 if not found:
ed9a25dd 4104 REDIRECT_REGEX = r'[0-9]{,2};\s*(?:URL|url)=\'?([^\'"]+)'
a5a45015 4105 found = re.search(
89ef304b 4106 r'(?i)<meta\s+(?=(?:[a-z-]+="[^"]+"\s+)*http-equiv="refresh")'
ed9a25dd 4107 r'(?:[a-z-]+="[^"]+"\s+)*?content="%s' % REDIRECT_REGEX,
89ef304b 4108 webpage)
84f81016
S
4109 if not found:
4110 # Look also in Refresh HTTP header
4111 refresh_header = head_response.headers.get('Refresh')
4112 if refresh_header:
ed9a25dd 4113 found = re.search(REDIRECT_REGEX, refresh_header)
b30b8698 4114 if found:
b37317d8 4115 new_url = compat_urlparse.urljoin(url, unescapeHTML(found.group(1)))
54b960f3
S
4116 if new_url != url:
4117 self.report_following_redirect(new_url)
4118 return {
4119 '_type': 'url',
4120 'url': new_url,
4121 }
4122 else:
4123 found = None
371ddb14
S
4124
4125 if not found:
4126 # twitter:player is a https URL to iframe player that may or may not
7a5c1cfe 4127 # be supported by yt-dlp thus this is checked the very last (see
371ddb14
S
4128 # https://dev.twitter.com/cards/types/player#On_twitter.com_via_desktop_browser)
4129 embed_url = self._html_search_meta('twitter:player', webpage, default=None)
02d01e15 4130 if embed_url and embed_url != url:
aa9369a2 4131 self.report_detected('twitter:player iframe')
371ddb14
S
4132 return self.url_result(embed_url)
4133
b30b8698 4134 if not found:
416c7fcb 4135 raise UnsupportedError(url)
9b122384 4136
b30b8698 4137 entries = []
4a120778 4138 for video_url in orderedSet(found):
949b6497 4139 video_url = unescapeHTML(video_url)
6cc37c69 4140 video_url = video_url.replace('\\/', '/')
b30b8698 4141 video_url = compat_urlparse.urljoin(url, video_url)
f7e6f7fa 4142 video_id = compat_urllib_parse_unquote(os.path.basename(video_url))
9b122384 4143
b30b8698
PH
4144 # Sometimes, jwplayer extraction will result in a YouTube URL
4145 if YoutubeIE.suitable(video_url):
4146 entries.append(self.url_result(video_url, 'Youtube'))
4147 continue
9b122384 4148
b30b8698
PH
4149 # here's a fun little line of code for you:
4150 video_id = os.path.splitext(video_id)[0]
3f4faff7 4151 headers = {
4152 'referer': full_response.geturl()
4153 }
fc9713a1 4154
28602e74
YCH
4155 entry_info_dict = {
4156 'id': video_id,
4157 'uploader': video_uploader,
4158 'title': video_title,
4159 'age_limit': age_limit,
3f4faff7 4160 'http_headers': headers,
28602e74
YCH
4161 }
4162
5620f840
S
4163 if RtmpIE.suitable(video_url):
4164 entry_info_dict.update({
4165 '_type': 'url_transparent',
4166 'ie_key': RtmpIE.ie_key(),
4167 'url': video_url,
4168 })
4169 entries.append(entry_info_dict)
4170 continue
4171
729accb4
S
4172 ext = determine_ext(video_url)
4173 if ext == 'smil':
da1c94ee 4174 entry_info_dict = {**self._extract_smil_info(video_url, video_id), **entry_info_dict}
729accb4
S
4175 elif ext == 'xspf':
4176 return self.playlist_result(self._extract_xspf_playlist(video_url, video_id), video_id)
750b9ff0 4177 elif ext == 'm3u8':
3f4faff7 4178 entry_info_dict['formats'], entry_info_dict['subtitles'] = self._extract_m3u8_formats_and_subtitles(video_url, video_id, ext='mp4', headers=headers)
79a35085 4179 elif ext == 'mpd':
3f4faff7 4180 entry_info_dict['formats'], entry_info_dict['subtitles'] = self._extract_mpd_formats_and_subtitles(video_url, video_id, headers=headers)
3f2f4a94 4181 elif ext == 'f4m':
3f4faff7 4182 entry_info_dict['formats'] = self._extract_f4m_formats(video_url, video_id, headers=headers)
4119a96c 4183 elif re.search(r'(?i)\.(?:ism|smil)/manifest', video_url) and video_url != url:
26aae566
S
4184 # Just matching .ism/manifest is not enough to be reliably sure
4185 # whether it's actually an ISM manifest or some other streaming
4186 # manifest since there are various streaming URL formats
4187 # possible (see [1]) as well as some other shenanigans like
4188 # .smil/manifest URLs that actually serve an ISM (see [2]) and
4189 # so on.
4190 # Thus the most reasonable way to solve this is to delegate
4191 # to generic extractor in order to look into the contents of
4192 # the manifest itself.
4193 # 1. https://azure.microsoft.com/en-us/documentation/articles/media-services-deliver-content-overview/#streaming-url-formats
4194 # 2. https://svs.itworkscdn.net/lbcivod/smil:itwfcdn/lbci/170976.smil/Manifest
4195 entry_info_dict = self.url_result(
4196 smuggle_url(video_url, {'to_generic': True}),
4197 GenericIE.ie_key())
d6fd958c 4198 else:
28602e74
YCH
4199 entry_info_dict['url'] = video_url
4200
19dbaeec
S
4201 if entry_info_dict.get('formats'):
4202 self._sort_formats(entry_info_dict['formats'])
4203
28602e74 4204 entries.append(entry_info_dict)
b30b8698
PH
4205
4206 if len(entries) == 1:
24146491 4207 return merge_dicts(entries[0], info_dict)
b30b8698
PH
4208 else:
4209 for num, e in enumerate(entries, start=1):
13d8fbef
JMF
4210 # 'url' results don't have a title
4211 if e.get('title') is not None:
4212 e['title'] = '%s (%d)' % (e['title'], num)
b30b8698
PH
4213 return {
4214 '_type': 'playlist',
4215 'entries': entries,
4216 }