From 474aa0db26d02763aedd55afc30b4897534576e8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rog=C3=A9rio=20Brito?= Date: Fri, 10 Apr 2020 09:32:01 -0300 Subject: [PATCH 1/1] Import Upstream version 2020.01.24 --- ChangeLog | 364 +++++++++- README.md | 4 +- README.txt | 4 +- devscripts/create-github-release.py | 18 +- docs/supportedsites.md | 62 +- test/test_all_urls.py | 6 - test/test_utils.py | 30 + youtube-dl | Bin 1768611 -> 1747838 bytes youtube-dl.1 | 4 +- youtube_dl/YoutubeDL.py | 2 +- youtube_dl/downloader/hls.py | 4 +- youtube_dl/extractor/abcotvs.py | 79 ++- youtube_dl/extractor/addanime.py | 95 --- youtube_dl/extractor/adobetv.py | 241 ++++--- youtube_dl/extractor/americastestkitchen.py | 42 +- youtube_dl/extractor/ard.py | 258 ++++---- youtube_dl/extractor/atresplayer.py | 214 ++---- youtube_dl/extractor/audioboom.py | 34 +- youtube_dl/extractor/azmedien.py | 36 +- youtube_dl/extractor/bambuser.py | 142 ---- youtube_dl/extractor/bellmedia.py | 4 +- youtube_dl/extractor/bitchute.py | 7 + youtube_dl/extractor/bokecc.py | 8 +- youtube_dl/extractor/brightcove.py | 72 +- youtube_dl/extractor/businessinsider.py | 28 +- youtube_dl/extractor/canvas.py | 83 ++- youtube_dl/extractor/ceskatelevize.py | 2 + youtube_dl/extractor/channel9.py | 20 +- youtube_dl/extractor/chaturbate.py | 50 +- youtube_dl/extractor/cloudflarestream.py | 29 +- youtube_dl/extractor/comcarcoff.py | 74 --- youtube_dl/extractor/common.py | 42 +- youtube_dl/extractor/contv.py | 118 ++++ youtube_dl/extractor/corus.py | 169 +++-- youtube_dl/extractor/dailymotion.py | 561 +++++++--------- youtube_dl/extractor/daisuki.py | 154 ----- youtube_dl/extractor/daum.py | 106 +-- youtube_dl/extractor/dctp.py | 54 +- youtube_dl/extractor/discovery.py | 9 +- youtube_dl/extractor/discoverynetworks.py | 63 +- youtube_dl/extractor/dplay.py | 403 ++++-------- youtube_dl/extractor/drtv.py | 57 +- youtube_dl/extractor/dumpert.py | 83 ++- youtube_dl/extractor/extractors.py | 80 +-- youtube_dl/extractor/facebook.py | 12 +- youtube_dl/extractor/flipagram.py | 115 ---- youtube_dl/extractor/fox9.py | 43 +- youtube_dl/extractor/gameone.py | 134 ---- youtube_dl/extractor/generic.py | 65 +- youtube_dl/extractor/gfycat.py | 8 +- youtube_dl/extractor/globo.py | 42 +- youtube_dl/extractor/go.py | 53 +- youtube_dl/extractor/go90.py | 149 ----- youtube_dl/extractor/hark.py | 33 - youtube_dl/extractor/hotstar.py | 9 +- youtube_dl/extractor/iconosquare.py | 85 --- youtube_dl/extractor/imggaming.py | 133 ++++ youtube_dl/extractor/internetvideoarchive.py | 92 +-- youtube_dl/extractor/ivi.py | 111 +++- youtube_dl/extractor/jamendo.py | 169 +++-- youtube_dl/extractor/kakao.py | 60 +- youtube_dl/extractor/kaltura.py | 11 +- youtube_dl/extractor/keek.py | 39 -- youtube_dl/extractor/kinja.py | 221 +++++++ youtube_dl/extractor/kontrtube.py | 73 -- youtube_dl/extractor/la7.py | 4 +- youtube_dl/extractor/learnr.py | 33 - youtube_dl/extractor/lego.py | 183 +++--- youtube_dl/extractor/lnkgo.py | 100 +-- youtube_dl/extractor/macgamestore.py | 42 -- youtube_dl/extractor/mailru.py | 16 +- youtube_dl/extractor/makertv.py | 32 - youtube_dl/extractor/mangomolo.py | 17 +- youtube_dl/extractor/mediaset.py | 25 +- youtube_dl/extractor/minhateca.py | 70 -- youtube_dl/extractor/mit.py | 24 - youtube_dl/extractor/mitele.py | 99 +-- youtube_dl/extractor/mixcloud.py | 509 +++++++------- youtube_dl/extractor/msn.py | 196 ++++-- youtube_dl/extractor/mtv.py | 88 +-- youtube_dl/extractor/musicplayon.py | 66 -- youtube_dl/extractor/myspass.py | 77 +-- youtube_dl/extractor/naver.py | 158 +++-- youtube_dl/extractor/nbc.py | 146 ++-- youtube_dl/extractor/ndr.py | 18 +- youtube_dl/extractor/nexx.py | 31 +- youtube_dl/extractor/nintendo.py | 28 +- youtube_dl/extractor/nonktube.py | 13 +- youtube_dl/extractor/nrk.py | 50 +- youtube_dl/extractor/nrl.py | 4 +- youtube_dl/extractor/ntvru.py | 49 +- youtube_dl/extractor/odnoklassniki.py | 9 + youtube_dl/extractor/onet.py | 54 +- youtube_dl/extractor/onionstudios.py | 62 +- youtube_dl/extractor/ooyala.py | 103 +-- youtube_dl/extractor/openload.py | 260 -------- youtube_dl/extractor/orf.py | 69 +- youtube_dl/extractor/pandatv.py | 99 --- youtube_dl/extractor/patreon.py | 52 +- youtube_dl/extractor/peertube.py | 397 +++++++++-- youtube_dl/extractor/periscope.py | 80 ++- youtube_dl/extractor/pornhub.py | 85 ++- youtube_dl/extractor/promptfile.py | 70 -- youtube_dl/extractor/prosiebensat1.py | 10 +- youtube_dl/extractor/puhutv.py | 90 +-- youtube_dl/extractor/redtube.py | 39 +- youtube_dl/extractor/revision3.py | 170 ----- youtube_dl/extractor/roosterteeth.py | 55 +- youtube_dl/extractor/safari.py | 3 +- youtube_dl/extractor/scrippsnetworks.py | 48 ++ youtube_dl/extractor/scte.py | 144 ++++ youtube_dl/extractor/seeker.py | 45 +- youtube_dl/extractor/servingsys.py | 72 -- youtube_dl/extractor/shared.py | 27 +- youtube_dl/extractor/slideslive.py | 42 +- youtube_dl/extractor/soundcloud.py | 555 ++++++++-------- youtube_dl/extractor/spankbang.py | 38 +- youtube_dl/extractor/srmediathek.py | 4 +- youtube_dl/extractor/streamango.py | 128 ---- youtube_dl/extractor/stretchinternet.py | 38 +- youtube_dl/extractor/stv.py | 89 +-- youtube_dl/extractor/teachable.py | 21 +- youtube_dl/extractor/teachingchannel.py | 26 +- youtube_dl/extractor/teamcoco.py | 68 +- youtube_dl/extractor/telegraaf.py | 75 ++- youtube_dl/extractor/telequebec.py | 58 +- youtube_dl/extractor/tenplay.py | 55 ++ youtube_dl/extractor/thesun.py | 14 +- youtube_dl/extractor/trunews.py | 49 +- youtube_dl/extractor/tutv.py | 36 - youtube_dl/extractor/tv2.py | 105 ++- youtube_dl/extractor/tv2dk.py | 154 +++++ youtube_dl/extractor/twentyfourvideo.py | 5 +- youtube_dl/extractor/twitch.py | 127 ++-- youtube_dl/extractor/twitter.py | 583 ++++++++-------- youtube_dl/extractor/ufctv.py | 73 +- youtube_dl/extractor/vessel.py | 157 ----- youtube_dl/extractor/vice.py | 212 +++--- youtube_dl/extractor/videodetective.py | 11 +- youtube_dl/extractor/videopremium.py | 46 -- youtube_dl/extractor/viewlift.py | 50 +- youtube_dl/extractor/viewster.py | 217 ------ youtube_dl/extractor/vimeo.py | 278 +++----- youtube_dl/extractor/vk.py | 362 +++++----- youtube_dl/extractor/vlive.py | 56 +- youtube_dl/extractor/vodplatform.py | 9 +- youtube_dl/extractor/voicerepublic.py | 76 +-- youtube_dl/extractor/vzaar.py | 31 +- youtube_dl/extractor/wimp.py | 54 -- youtube_dl/extractor/wistia.py | 83 ++- youtube_dl/extractor/xfileshare.py | 192 +++--- youtube_dl/extractor/xvideos.py | 39 +- youtube_dl/extractor/yahoo.py | 658 ++++++++----------- youtube_dl/extractor/yourporn.py | 18 +- youtube_dl/extractor/youtube.py | 23 +- youtube_dl/extractor/zype.py | 111 +++- youtube_dl/postprocessor/ffmpeg.py | 8 +- youtube_dl/utils.py | 101 +-- youtube_dl/version.py | 2 +- 159 files changed, 7028 insertions(+), 7802 deletions(-) delete mode 100644 youtube_dl/extractor/addanime.py delete mode 100644 youtube_dl/extractor/bambuser.py delete mode 100644 youtube_dl/extractor/comcarcoff.py create mode 100644 youtube_dl/extractor/contv.py delete mode 100644 youtube_dl/extractor/daisuki.py delete mode 100644 youtube_dl/extractor/flipagram.py delete mode 100644 youtube_dl/extractor/gameone.py delete mode 100644 youtube_dl/extractor/go90.py delete mode 100644 youtube_dl/extractor/hark.py delete mode 100644 youtube_dl/extractor/iconosquare.py create mode 100644 youtube_dl/extractor/imggaming.py delete mode 100644 youtube_dl/extractor/keek.py create mode 100644 youtube_dl/extractor/kinja.py delete mode 100644 youtube_dl/extractor/kontrtube.py delete mode 100644 youtube_dl/extractor/learnr.py delete mode 100644 youtube_dl/extractor/macgamestore.py delete mode 100644 youtube_dl/extractor/makertv.py delete mode 100644 youtube_dl/extractor/minhateca.py delete mode 100644 youtube_dl/extractor/musicplayon.py delete mode 100644 youtube_dl/extractor/pandatv.py delete mode 100644 youtube_dl/extractor/promptfile.py delete mode 100644 youtube_dl/extractor/revision3.py create mode 100644 youtube_dl/extractor/scte.py delete mode 100644 youtube_dl/extractor/servingsys.py delete mode 100644 youtube_dl/extractor/streamango.py create mode 100644 youtube_dl/extractor/tenplay.py delete mode 100644 youtube_dl/extractor/tutv.py create mode 100644 youtube_dl/extractor/tv2dk.py delete mode 100644 youtube_dl/extractor/vessel.py delete mode 100644 youtube_dl/extractor/videopremium.py delete mode 100644 youtube_dl/extractor/viewster.py delete mode 100644 youtube_dl/extractor/wimp.py diff --git a/ChangeLog b/ChangeLog index 80681a9..94aa9f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,363 @@ +version 2020.01.24 + +Extractors +* [youtube] Fix sigfunc name extraction (#23819) +* [stretchinternet] Fix extraction (#4319) +* [voicerepublic] Fix extraction +* [azmedien] Fix extraction (#23783) +* [businessinsider] Fix jwplatform id extraction (#22929, #22954) ++ [24video] Add support for 24video.vip (#23753) +* [ivi:compilation] Fix entries extraction (#23770) +* [ard] Improve extraction (#23761) + * Simplify extraction + + Extract age limit and series + * Bypass geo-restriction ++ [nbc] Add support for nbc multi network URLs (#23049) +* [americastestkitchen] Fix extraction +* [zype] Improve extraction + + Extract subtitles (#21258) + + Support URLs with alternative keys/tokens (#21258) + + Extract more metadata +* [orf:tvthek] Improve geo restricted videos detection (#23741) +* [soundcloud] Restore previews extraction (#23739) + + +version 2020.01.15 + +Extractors +* [yourporn] Fix extraction (#21645, #22255, #23459) ++ [canvas] Add support for new API endpoint (#17680, #18629) +* [ndr:base:embed] Improve thumbnails extraction (#23731) ++ [vodplatform] Add support for embed.kwikmotion.com domain ++ [twitter] Add support for promo_video_website cards (#23711) +* [orf:radio] Clean description and improve extraction +* [orf:fm4] Fix extraction (#23599) +* [safari] Fix kaltura session extraction (#23679, #23670) +* [lego] Fix extraction and extract subtitle (#23687) +* [cloudflarestream] Improve extraction + + Add support for bytehighway.net domain + + Add support for signed URLs + + Extract thumbnail +* [naver] Improve extraction + * Improve geo-restriction handling + + Extract automatic captions + + Extract uploader metadata + + Extract VLive HLS formats + * Improve metadata extraction +- [pandatv] Remove extractor (#23630) +* [dctp] Fix format extraction (#23656) ++ [scrippsnetworks] Add support for www.discovery.com videos +* [discovery] Fix anonymous token extraction (#23650) +* [nrktv:seriebase] Fix extraction (#23625, #23537) +* [wistia] Improve format extraction and extract subtitles (#22590) +* [vice] Improve extraction (#23631) +* [redtube] Detect private videos (#23518) + + +version 2020.01.01 + +Extractors +* [brightcove] Invalidate policy key cache on failing requests +* [pornhub] Improve locked videos detection (#22449, #22780) ++ [pornhub] Add support for m3u8 formats +* [pornhub] Fix extraction (#22749, #23082) +* [brightcove] Update policy key on failing requests +* [spankbang] Improve removed video detection (#23423) +* [spankbang] Fix extraction (#23307, #23423, #23444) +* [soundcloud] Automatically update client id on failing requests +* [prosiebensat1] Improve geo restriction handling (#23571) +* [brightcove] Cache brightcove player policy keys +* [teachable] Fail with error message if no video URL found +* [teachable] Improve locked lessons detection (#23528) ++ [scrippsnetworks] Add support for Scripps Networks sites (#19857, #22981) +* [mitele] Fix extraction (#21354, #23456) +* [soundcloud] Update client id (#23516) +* [mailru] Relax URL regular expressions (#23509) + + +version 2019.12.25 + +Core +* [utils] Improve str_to_int ++ [downloader/hls] Add ability to override AES decryption key URL (#17521) + +Extractors +* [mediaset] Fix parse formats (#23508) ++ [tv2dk:bornholm:play] Add support for play.tv2bornholm.dk (#23291) ++ [slideslive] Add support for url and vimeo service names (#23414) +* [slideslive] Fix extraction (#23413) +* [twitch:clips] Fix extraction (#23375) ++ [soundcloud] Add support for token protected embeds (#18954) +* [vk] Improve extraction + * Fix User Videos extraction (#23356) + * Extract all videos for lists with more than 1000 videos (#23356) + + Add support for video albums (#14327, #14492) +- [kontrtube] Remove extractor +- [videopremium] Remove extractor +- [musicplayon] Remove extractor (#9225) ++ [ufctv] Add support for ufcfightpass.imgdge.com and + ufcfightpass.imggaming.com (#23343) ++ [twitch] Extract m3u8 formats frame rate (#23333) ++ [imggaming] Add support for playlists and extract subtitles ++ [ufcarabia] Add support for UFC Arabia (#23312) +* [ufctv] Fix extraction +* [yahoo] Fix gyao brightcove player id (#23303) +* [vzaar] Override AES decryption key URL (#17521) ++ [vzaar] Add support for AES HLS manifests (#17521, #23299) +* [nrl] Fix extraction +* [teachingchannel] Fix extraction +* [nintendo] Fix extraction and partially add support for Nintendo Direct + videos (#4592) ++ [ooyala] Add better fallback values for domain and streams variables ++ [youtube] Add support youtubekids.com (#23272) +* [tv2] Detect DRM protection ++ [tv2] Add support for katsomo.fi and mtv.fi (#10543) +* [tv2] Fix tv2.no article extraction +* [msn] Improve extraction + + Add support for YouTube and NBCSports embeds + + Add support for articles with multiple videos + * Improve AOL embed support + * Improve format extraction +* [abcotvs] Relax URL regular expression and improve metadata extraction + (#18014) +* [channel9] Reduce response size +* [adobetv] Improve extaction + * Use OnDemandPagedList for list extractors + * Reduce show extraction requests + * Extract original video format and subtitles + + Add support for adobe tv embeds + + +version 2019.11.28 + +Core ++ [utils] Add generic caesar cipher and rot47 +* [utils] Handle rd-suffixed day parts in unified_strdate (#23199) + +Extractors +* [vimeo] Improve extraction + * Fix review extraction + * Fix ondemand extraction + * Make password protected player case as an expected error (#22896) + * Simplify channel based extractors code +- [openload] Remove extractor (#11999) +- [verystream] Remove extractor +- [streamango] Remove extractor (#15406) +* [dailymotion] Improve extraction + * Extract http formats included in m3u8 manifest + * Fix user extraction (#3553, #21415) + + Add suport for User Authentication (#11491) + * Fix password protected videos extraction (#23176) + * Respect age limit option and family filter cookie value (#18437) + * Handle video url playlist query param + * Report allowed countries for geo-restricted videos +* [corus] Improve extraction + + Add support for Series Plus, W Network, YTV, ABC Spark, disneychannel.com + and disneylachaine.ca (#20861) + + Add support for self hosted videos (#22075) + * Detect DRM protection (#14910, #9164) +* [vivo] Fix extraction (#22328, #22279) ++ [bitchute] Extract upload date (#22990, #23193) +* [soundcloud] Update client id (#23214) + + +version 2019.11.22 + +Core ++ [extractor/common] Clean jwplayer description HTML tags ++ [extractor/common] Add data, headers and query to all major extract formats + methods + +Extractors +* [chaturbate] Fix extraction (#23010, #23012) ++ [ntvru] Add support for non relative file URLs (#23140) +* [vk] Fix wall audio thumbnails extraction (#23135) +* [ivi] Fix format extraction (#21991) +- [comcarcoff] Remove extractor ++ [drtv] Add support for new URL schema (#23059) ++ [nexx] Add support for Multi Player JS Setup (#23052) ++ [teamcoco] Add support for new videos (#23054) +* [soundcloud] Check if the soundtrack has downloads left (#23045) +* [facebook] Fix posts video data extraction (#22473) +- [addanime] Remove extractor +- [minhateca] Remove extractor +- [daisuki] Remove extractor +* [seeker] Fix extraction +- [revision3] Remove extractors +* [twitch] Fix video comments URL (#18593, #15828) +* [twitter] Improve extraction + + Add support for generic embeds (#22168) + * Always extract http formats for native videos (#14934) + + Add support for Twitter Broadcasts (#21369) + + Extract more metadata + * Improve VMap format extraction + * Unify extraction code for both twitter statuses and cards ++ [twitch] Add support for Clip embed URLs +* [lnkgo] Fix extraction (#16834) +* [mixcloud] Improve extraction + * Improve metadata extraction (#11721) + * Fix playlist extraction (#22378) + * Fix user mixes extraction (#15197, #17865) ++ [kinja] Add support for Kinja embeds (#5756, #11282, #22237, #22384) +* [onionstudios] Fix extraction ++ [hotstar] Pass Referer header to format requests (#22836) +* [dplay] Minimize response size ++ [patreon] Extract uploader_id and filesize +* [patreon] Minimize response size +* [roosterteeth] Fix login request (#16094, #22689) + + +version 2019.11.05 + +Extractors ++ [scte] Add support for learning.scte.org (#22975) ++ [msn] Add support for Vidible and AOL embeds (#22195, #22227) +* [myspass] Fix video URL extraction and improve metadata extraction (#22448) +* [jamendo] Improve extraction + * Fix album extraction (#18564) + * Improve metadata extraction (#18565, #21379) +* [mediaset] Relax URL guid matching (#18352) ++ [mediaset] Extract unprotected M3U and MPD manifests (#17204) +* [telegraaf] Fix extraction ++ [bellmedia] Add support for marilyn.ca videos (#22193) +* [stv] Fix extraction (#22928) +- [iconosquare] Remove extractor +- [keek] Remove extractor +- [gameone] Remove extractor (#21778) +- [flipagram] Remove extractor +- [bambuser] Remove extractor +* [wistia] Reduce embed extraction false positives ++ [wistia] Add support for inline embeds (#22931) +- [go90] Remove extractor +* [kakao] Remove raw request ++ [kakao] Extract format total bitrate +* [daum] Fix VOD and Clip extracton (#15015) +* [kakao] Improve extraction + + Add support for embed URLs + + Add support for Kakao Legacy vid based embed URLs + * Only extract fields used for extraction + * Strip description and extract tags +* [mixcloud] Fix cloudcast data extraction (#22821) +* [yahoo] Improve extraction + + Add support for live streams (#3597, #3779, #22178) + * Bypass cookie consent page for european domains (#16948, #22576) + + Add generic support for embeds (#20332) +* [tv2] Fix and improve extraction (#22787) ++ [tv2dk] Add support for TV2 DK sites +* [onet] Improve extraction … + + Add support for onet100.vod.pl + + Extract m3u8 formats + * Correct audio only format info +* [fox9] Fix extraction + + +version 2019.10.29 + +Core +* [utils] Actualize major IPv4 address blocks per country + +Extractors ++ [go] Add support for abc.com and freeform.com (#22823, #22864) ++ [mtv] Add support for mtvjapan.com +* [mtv] Fix extraction for mtv.de (#22113) +* [videodetective] Fix extraction +* [internetvideoarchive] Fix extraction +* [nbcnews] Fix extraction (#12569, #12576, #21703, #21923) +- [hark] Remove extractor +- [tutv] Remove extractor +- [learnr] Remove extractor +- [macgamestore] Remove extractor +* [la7] Update Kaltura service URL (#22358) +* [thesun] Fix extraction (#16966) +- [makertv] Remove extractor ++ [tenplay] Add support for 10play.com.au (#21446) +* [soundcloud] Improve extraction + * Improve format extraction (#22123) + + Extract uploader_id and uploader_url (#21916) + + Extract all known thumbnails (#19071, #20659) + * Fix extration for private playlists (#20976) + + Add support for playlist embeds (#20976) + * Skip preview formats (#22806) +* [dplay] Improve extraction + + Add support for dplay.fi, dplay.jp and es.dplay.com (#16969) + * Fix it.dplay.com extraction (#22826) + + Extract creator, tags and thumbnails + * Handle playback API call errors ++ [discoverynetworks] Add support for dplay.co.uk +* [vk] Improve extraction + + Add support for Odnoklassniki embeds + + Extract more videos from user lists (#4470) + + Fix wall post audio extraction (#18332) + * Improve error detection (#22568) ++ [odnoklassniki] Add support for embeds +* [puhutv] Improve extraction + * Fix subtitles extraction + * Transform HLS URLs to HTTP URLs + * Improve metadata extraction +* [ceskatelevize] Skip DRM media ++ [facebook] Extract subtitles (#22777) +* [globo] Handle alternative hash signing method + + +version 2019.10.22 + +Core +* [utils] Improve subtitles_filename (#22753) + +Extractors +* [facebook] Bypass download rate limits (#21018) ++ [contv] Add support for contv.com +- [viewster] Remove extractor +* [xfileshare] Improve extractor (#17032, #17906, #18237, #18239) + * Update the list of domains + + Add support for aa-encoded video data + * Improve jwplayer format extraction + + Add support for Clappr sources +* [mangomolo] Fix video format extraction and add support for player URLs +* [audioboom] Improve metadata extraction +* [twitch] Update VOD URL matching (#22395, #22727) +- [mit] Remove support for video.mit.edu (#22403) +- [servingsys] Remove extractor (#22639) +* [dumpert] Fix extraction (#22428, #22564) +* [atresplayer] Fix extraction (#16277, #16716) + + +version 2019.10.16 + +Core +* [extractor/common] Make _is_valid_url more relaxed + +Extractors +* [vimeo] Improve album videos id extraction (#22599) ++ [globo] Extract subtitles (#22713) +* [bokecc] Improve player params extraction (#22638) +* [nexx] Handle result list (#22666) +* [vimeo] Fix VHX embed extraction +* [nbc] Switch to graphql API (#18581, #22693, #22701) +- [vessel] Remove extractor +- [promptfile] Remove extractor (#6239) +* [kaltura] Fix service URL extraction (#22658) +* [kaltura] Fix embed info strip (#22658) +* [globo] Fix format extraction (#20319) +* [redtube] Improve metadata extraction (#22492, #22615) +* [pornhub:uservideos:upload] Fix extraction (#22619) ++ [telequebec:squat] Add support for squat.telequebec.tv (#18503) +- [wimp] Remove extractor (#22088, #22091) ++ [gfycat] Extend URL regular expression (#22225) ++ [chaturbate] Extend URL regular expression (#22309) +* [peertube] Update instances (#22414) ++ [telequebec] Add support for coucou.telequebec.tv (#22482) ++ [xvideos] Extend URL regular expression (#22471) +- [youtube] Remove support for invidious.enkirton.net (#22543) ++ [openload] Add support for oload.monster (#22592) +* [nrktv:seriebase] Fix extraction (#22596) ++ [youtube] Add support for yt.lelux.fi (#22597) +* [orf:tvthek] Make manifest requests non fatal (#22578) +* [teachable] Skip login when already logged in (#22572) +* [viewlift] Improve extraction (#22545) +* [nonktube] Fix extraction (#22544) + + version 2019.09.28 Core @@ -353,7 +713,7 @@ Extractors version 2019.04.17 Extractors -* [openload] Randomize User-Agent (closes #20688) +* [openload] Randomize User-Agent (#20688) + [openload] Add support for oladblock domains (#20471) * [adn] Fix subtitle extraction (#12724) + [aol] Add support for localized websites @@ -918,7 +1278,7 @@ Extractors + [youtube] Extract channel meta fields (#9676, #12939) * [porntube] Fix extraction (#17541) * [asiancrush] Fix extraction (#15630) -+ [twitch:clips] Extend URL regular expression (closes #17559) ++ [twitch:clips] Extend URL regular expression (#17559) + [vzaar] Add support for HLS * [tube8] Fix metadata extraction (#17520) * [eporner] Extract JSON-LD (#17519) diff --git a/README.md b/README.md index c39b136..01f9759 100644 --- a/README.md +++ b/README.md @@ -752,8 +752,8 @@ As a last resort, you can also uninstall the version installed by your package m Afterwards, simply follow [our manual installation instructions](https://ytdl-org.github.io/youtube-dl/download.html): ``` -sudo wget https://yt-dl.org/latest/youtube-dl -O /usr/local/bin/youtube-dl -sudo chmod a+x /usr/local/bin/youtube-dl +sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl +sudo chmod a+rx /usr/local/bin/youtube-dl hash -r ``` diff --git a/README.txt b/README.txt index 045e0b1..cc86a1b 100644 --- a/README.txt +++ b/README.txt @@ -960,8 +960,8 @@ that, remove the distribution's package, with a line like Afterwards, simply follow our manual installation instructions: - sudo wget https://yt-dl.org/latest/youtube-dl -O /usr/local/bin/youtube-dl - sudo chmod a+x /usr/local/bin/youtube-dl + sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl + sudo chmod a+rx /usr/local/bin/youtube-dl hash -r Again, from then on you'll be able to update with sudo youtube-dl -U. diff --git a/devscripts/create-github-release.py b/devscripts/create-github-release.py index 428111b..2ddfa10 100644 --- a/devscripts/create-github-release.py +++ b/devscripts/create-github-release.py @@ -1,7 +1,6 @@ #!/usr/bin/env python from __future__ import unicode_literals -import base64 import io import json import mimetypes @@ -15,7 +14,6 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from youtube_dl.compat import ( compat_basestring, - compat_input, compat_getpass, compat_print, compat_urllib_request, @@ -40,28 +38,20 @@ class GitHubReleaser(object): try: info = netrc.netrc().authenticators(self._NETRC_MACHINE) if info is not None: - self._username = info[0] - self._password = info[2] + self._token = info[2] compat_print('Using GitHub credentials found in .netrc...') return else: compat_print('No GitHub credentials found in .netrc') except (IOError, netrc.NetrcParseError): compat_print('Unable to parse .netrc') - self._username = compat_input( - 'Type your GitHub username or email address and press [Return]: ') - self._password = compat_getpass( - 'Type your GitHub password and press [Return]: ') + self._token = compat_getpass( + 'Type your GitHub PAT (personal access token) and press [Return]: ') def _call(self, req): if isinstance(req, compat_basestring): req = sanitized_Request(req) - # Authorizing manually since GitHub does not response with 401 with - # WWW-Authenticate header set (see - # https://developer.github.com/v3/#basic-authentication) - b64 = base64.b64encode( - ('%s:%s' % (self._username, self._password)).encode('utf-8')).decode('ascii') - req.add_header('Authorization', 'Basic %s' % b64) + req.add_header('Authorization', 'token %s' % self._token) response = self._opener.open(req).read().decode('utf-8') return json.loads(response) diff --git a/docs/supportedsites.md b/docs/supportedsites.md index 3527527..e9a8cc2 100644 --- a/docs/supportedsites.md +++ b/docs/supportedsites.md @@ -26,13 +26,13 @@ - **AcademicEarth:Course** - **acast** - **acast:channel** - - **AddAnime** - **ADN**: Anime Digital Network - **AdobeConnect** - - **AdobeTV** - - **AdobeTVChannel** - - **AdobeTVShow** - - **AdobeTVVideo** + - **adobetv** + - **adobetv:channel** + - **adobetv:embed** + - **adobetv:show** + - **adobetv:video** - **AdultSwim** - **aenetworks**: A+E Networks: A&E, Lifetime, History.com, FYI Network and History Vault - **afreecatv**: afreecatv.com @@ -76,8 +76,6 @@ - **awaan:video** - **AZMedien**: AZ Medien videos - **BaiduVideo**: 百度视频 - - **bambuser** - - **bambuser:channel** - **Bandcamp** - **Bandcamp:album** - **Bandcamp:weekly** @@ -177,12 +175,12 @@ - **CNN** - **CNNArticle** - **CNNBlogs** - - **ComCarCoff** - **ComedyCentral** - **ComedyCentralFullEpisodes** - **ComedyCentralShortname** - **ComedyCentralTV** - **CondeNast**: Condé Nast media group: Allure, Architectural Digest, Ars Technica, Bon Appétit, Brides, Condé Nast, Condé Nast Traveler, Details, Epicurious, GQ, Glamour, Golf Digest, SELF, Teen Vogue, The New Yorker, Vanity Fair, Vogue, W Magazine, WIRED + - **CONtv** - **Corus** - **Coub** - **Cracked** @@ -204,8 +202,6 @@ - **dailymotion** - **dailymotion:playlist** - **dailymotion:user** - - **DaisukiMotto** - - **DaisukiMottoPlaylist** - **daum.net** - **daum.net:clip** - **daum.net:playlist** @@ -231,7 +227,6 @@ - **DouyuShow** - **DouyuTV**: 斗鱼 - **DPlay** - - **DPlayIt** - **DRBonanza** - **Dropbox** - **DrTuber** @@ -284,12 +279,12 @@ - **FiveThirtyEight** - **FiveTV** - **Flickr** - - **Flipagram** - **Folketinget**: Folketinget (ft.dk; Danish parliament) - **FootyRoom** - **Formula1** - **FOX** - **FOX9** + - **FOX9News** - **Foxgay** - **foxnews**: Fox News and Fox Business Video - **foxnews:article** @@ -315,8 +310,6 @@ - **FXNetworks** - **Gaia** - **GameInformer** - - **GameOne** - - **gameone:playlist** - **GameSpot** - **GameStar** - **Gaskrank** @@ -331,14 +324,12 @@ - **Globo** - **GloboArticle** - **Go** - - **Go90** - **GodTube** - **Golem** - **GoogleDrive** - **Goshgay** - **GPUTechConf** - **Groupon** - - **Hark** - **hbo** - **HearThisAt** - **Heise** @@ -367,7 +358,6 @@ - **Hungama** - **HungamaSong** - **Hypem** - - **Iconosquare** - **ign.com** - **imdb**: Internet Movie Database trailers - **imdb:list**: Internet Movie Database lists @@ -407,14 +397,14 @@ - **Kankan** - **Karaoketv** - **KarriereVideos** - - **keek** + - **Katsomo** - **KeezMovies** - **Ketnet** - **KhanAcademy** - **KickStarter** + - **KinjaEmbed** - **KinoPoisk** - **KonserthusetPlay** - - **kontrtube**: KontrTube.ru - Труба зовёт - **KrasView**: Красвью - **Ku6** - **KUSI** @@ -431,7 +421,6 @@ - **Lcp** - **LcpPlay** - **Le**: 乐视网 - - **Learnr** - **Lecture2Go** - **Lecturio** - **LecturioCourse** @@ -465,11 +454,9 @@ - **lynda**: lynda.com videos - **lynda:course**: lynda.com online courses - **m6** - - **macgamestore**: MacGameStore trailers - **mailru**: Видео@Mail.Ru - **mailru:music**: Музыка@Mail.Ru - **mailru:music:search**: Музыка@Mail.Ru - - **MakerTV** - **MallTV** - **mangomolo:live** - **mangomolo:video** @@ -496,14 +483,12 @@ - **Mgoon** - **MGTV**: 芒果TV - **MiaoPai** - - **Minhateca** - **MinistryGrid** - **Minoto** - **miomio.tv** - **MiTele**: mitele.es - **mixcloud** - **mixcloud:playlist** - - **mixcloud:stream** - **mixcloud:user** - **Mixer:live** - **Mixer:vod** @@ -525,11 +510,10 @@ - **mtg**: MTG services - **mtv** - **mtv.de** - - **mtv81** - **mtv:video** + - **mtvjapan** - **mtvservices:embedded** - **MuenchenTV**: münchen.tv - - **MusicPlayOn** - **mva**: Microsoft Virtual Academy videos - **mva:course**: Microsoft Virtual Academy courses - **Mwave** @@ -634,7 +618,6 @@ - **OnionStudios** - **Ooyala** - **OoyalaExternal** - - **Openload** - **OraTV** - **orf:fm4**: radio FM4 - **orf:fm4:story**: fm4.orf.at stories @@ -645,7 +628,6 @@ - **OutsideTV** - **PacktPub** - **PacktPubCourse** - - **PandaTV**: 熊猫TV - **pandora.tv**: 판도라TV - **ParamountNetwork** - **parliamentlive.tv**: UK parliament videos @@ -694,7 +676,6 @@ - **PornoXO** - **PornTube** - **PressTV** - - **PromptFile** - **prosiebensat1**: ProSiebenSat.1 Digital - **puhutv** - **puhutv:serie** @@ -735,8 +716,6 @@ - **Restudy** - **Reuters** - **ReverbNation** - - **revision** - - **revision3:embed** - **RICE** - **RMCDecouverte** - **RockstarGames** @@ -781,11 +760,13 @@ - **screen.yahoo:search**: Yahoo screen search - **Screencast** - **ScreencastOMatic** + - **ScrippsNetworks** - **scrippsnetworks:watch** + - **SCTE** + - **SCTECourse** - **Seeker** - **SenateISVP** - **SendtoNews** - - **ServingSys** - **Servus** - **Sexu** - **SeznamZpravy** @@ -816,6 +797,7 @@ - **soundcloud:set** - **soundcloud:trackstation** - **soundcloud:user** + - **SoundcloudEmbed** - **soundgasm** - **soundgasm:profile** - **southpark.cc.com** @@ -842,7 +824,6 @@ - **Steam** - **Stitcher** - **Streamable** - - **Streamango** - **streamcloud.eu** - **StreamCZ** - **StreetVoice** @@ -884,9 +865,11 @@ - **TeleQuebec** - **TeleQuebecEmission** - **TeleQuebecLive** + - **TeleQuebecSquat** - **TeleTask** - **Telewebion** - **TennisTV** + - **TenPlay** - **TF1** - **TFO** - **TheIntercept** @@ -925,11 +908,12 @@ - **tunein:topic** - **TunePk** - **Turbo** - - **Tutv** - **tv.dfb.de** - **TV2** - **tv2.hu** - **TV2Article** + - **TV2DK** + - **TV2DKBornholmPlay** - **TV4**: tv4.se and tv4play.se - **TV5MondePlus**: TV5MONDE+ - **TVA** @@ -966,10 +950,12 @@ - **twitch:vod** - **twitter** - **twitter:amplify** + - **twitter:broadcast** - **twitter:card** - **udemy** - **udemy:course** - **UDNEmbed**: 聯合影音 + - **UFCArabia** - **UFCTV** - **UKTVPlay** - **umg:de**: Universal Music Deutschland @@ -990,8 +976,6 @@ - **Vbox7** - **VeeHD** - **Veoh** - - **verystream** - - **Vessel** - **Vesti**: Вести.Ru - **Vevo** - **VevoPlaylist** @@ -1006,13 +990,11 @@ - **Viddler** - **Videa** - **video.google:search**: Google Video search - - **video.mit.edu** - **VideoDetective** - **videofy.me** - **videomore** - **videomore:season** - **videomore:video** - - **VideoPremium** - **VideoPress** - **Vidio** - **VidLii** @@ -1024,7 +1006,6 @@ - **vier:videos** - **ViewLift** - **ViewLiftEmbed** - - **Viewster** - **Viidea** - **viki** - **viki:channel** @@ -1090,7 +1071,6 @@ - **Weibo** - **WeiboMobile** - **WeiqiTV**: WQTV - - **Wimp** - **Wistia** - **wnl**: npo.nl, ntr.nl, omroepwnl.nl, zapp.nl and npo3.nl - **WorldStarHipHop** @@ -1099,7 +1079,7 @@ - **WWE** - **XBef** - **XboxClips** - - **XFileShare**: XFileShare based sites: DaClips, FileHoot, GorillaVid, MovPod, PowerWatch, Rapidvideo.ws, TheVideoBee, Vidto, Streamin.To, XVIDSTAGE, Vid ABC, VidBom, vidlo, RapidVideo.TV, FastVideo.me + - **XFileShare**: XFileShare based sites: ClipWatching, GoUnlimited, GoVid, HolaVid, Streamty, TheVideoBee, Uqload, VidBom, vidlo, VidLocker, VidShare, VUp, XVideoSharing - **XHamster** - **XHamsterEmbed** - **XHamsterUser** diff --git a/test/test_all_urls.py b/test/test_all_urls.py index 465ce00..81056a9 100644 --- a/test/test_all_urls.py +++ b/test/test_all_urls.py @@ -123,12 +123,6 @@ class TestAllURLsMatching(unittest.TestCase): self.assertMatch('http://video.pbs.org/viralplayer/2365173446/', ['pbs']) self.assertMatch('http://video.pbs.org/widget/partnerplayer/980042464/', ['pbs']) - def test_yahoo_https(self): - # https://github.com/ytdl-org/youtube-dl/issues/2701 - self.assertMatch( - 'https://screen.yahoo.com/smartwatches-latest-wearable-gadgets-163745379-cbs.html', - ['Yahoo']) - def test_no_duplicated_ie_names(self): name_accu = collections.defaultdict(list) for ie in self.ies: diff --git a/test/test_utils.py b/test/test_utils.py index 659c6ec..0896f41 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -19,6 +19,7 @@ from youtube_dl.utils import ( age_restricted, args_to_str, encode_base_n, + caesar, clean_html, date_from_str, DateRange, @@ -69,11 +70,13 @@ from youtube_dl.utils import ( remove_start, remove_end, remove_quotes, + rot47, shell_quote, smuggle_url, str_to_int, strip_jsonp, strip_or_none, + subtitles_filename, timeconvert, unescapeHTML, unified_strdate, @@ -261,6 +264,11 @@ class TestUtil(unittest.TestCase): self.assertEqual(replace_extension('.abc', 'temp'), '.abc.temp') self.assertEqual(replace_extension('.abc.ext', 'temp'), '.abc.temp') + def test_subtitles_filename(self): + self.assertEqual(subtitles_filename('abc.ext', 'en', 'vtt'), 'abc.en.vtt') + self.assertEqual(subtitles_filename('abc.ext', 'en', 'vtt', 'ext'), 'abc.en.vtt') + self.assertEqual(subtitles_filename('abc.unexpected_ext', 'en', 'vtt', 'ext'), 'abc.unexpected_ext.en.vtt') + def test_remove_start(self): self.assertEqual(remove_start(None, 'A - '), None) self.assertEqual(remove_start('A - B', 'A - '), 'B') @@ -334,6 +342,8 @@ class TestUtil(unittest.TestCase): self.assertEqual(unified_strdate('July 15th, 2013'), '20130715') self.assertEqual(unified_strdate('September 1st, 2013'), '20130901') self.assertEqual(unified_strdate('Sep 2nd, 2013'), '20130902') + self.assertEqual(unified_strdate('November 3rd, 2019'), '20191103') + self.assertEqual(unified_strdate('October 23rd, 2005'), '20051023') def test_unified_timestamps(self): self.assertEqual(unified_timestamp('December 21, 2010'), 1292889600) @@ -489,6 +499,12 @@ class TestUtil(unittest.TestCase): def test_str_to_int(self): self.assertEqual(str_to_int('123,456'), 123456) self.assertEqual(str_to_int('123.456'), 123456) + self.assertEqual(str_to_int(523), 523) + # Python 3 has no long + if sys.version_info < (3, 0): + eval('self.assertEqual(str_to_int(123456L), 123456)') + self.assertEqual(str_to_int('noninteger'), None) + self.assertEqual(str_to_int([]), None) def test_url_basename(self): self.assertEqual(url_basename('http://foo.de/'), '') @@ -1361,6 +1377,20 @@ Line 1 self.assertRaises(ValueError, encode_base_n, 0, 70) self.assertRaises(ValueError, encode_base_n, 0, 60, custom_table) + def test_caesar(self): + self.assertEqual(caesar('ace', 'abcdef', 2), 'cea') + self.assertEqual(caesar('cea', 'abcdef', -2), 'ace') + self.assertEqual(caesar('ace', 'abcdef', -2), 'eac') + self.assertEqual(caesar('eac', 'abcdef', 2), 'ace') + self.assertEqual(caesar('ace', 'abcdef', 0), 'ace') + self.assertEqual(caesar('xyz', 'abcdef', 2), 'xyz') + self.assertEqual(caesar('abc', 'acegik', 2), 'ebg') + self.assertEqual(caesar('ebg', 'acegik', -2), 'abc') + + def test_rot47(self): + self.assertEqual(rot47('youtube-dl'), r'J@FEF36\5=') + self.assertEqual(rot47('YOUTUBE-DL'), r'*~&%&qt\s{') + def test_urshift(self): self.assertEqual(urshift(3, 1), 1) self.assertEqual(urshift(-3, 1), 2147483646) diff --git a/youtube-dl b/youtube-dl index c2e66c3ac5f06b4ee41061572c563b83ea233075..748d6a0deb8f348b9d682f478fb36db4c0515ebc 100755 GIT binary patch delta 480338 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¤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�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

?^vV~2Yt8=53 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 I*h;bfAJE-Js{jB1 delta 498363 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%0Ak*IZ_4apfVmJ!Er;Gmx^&vPvR{6 zoH?&xwRd<69Q%xa2%;cBCO5$yyOj=Wyvu9neEN`LVA0eznAClQ*fVFd6^Zr8o}cKJ zg$<~jSbL3FolKnpDSAYmuQCKm#xO%G81N`6nvOkmuVm{(s*bhdYiz3e19pMluy|{4 zx2k$-%W@o}`rXp*R)TH2LLX6+Xn7Z2ivKMn=!H%}ArU8kC;MZc<>9lu!3%4Qze#q; zzD$jC2v{TGzr+;@f}yB3f(c0p zVWtqGqG6(Pn3a<3nnwku$0h+)9kU_~K>#{t-gAC9G63om^l6==s~Uv|;jEFPa2Abz z_iP)kI-IC^3LU4tFv~+~oOEcrb3bA4dKIm5OAon!&TXzGAZXvs+S$&HNGvVXZ&6Hw zfiP-7a{nXd4wqhFLNHyKBJLeaeC^NAQU}Rd06Vy>al^?(cV+T}e8{8UhIK6Ip_6Y8 zyM&USN-8Wy_(hJOfIDqcL`En<3Ah+nDW7W+6HXySSV$K?w&ZH~P)FGzbVnr)Ph1^| z_lRbHilQful4UpAW@4vtW=(fjST1MF^cd#H9MjxF3mgr2k9rScGRyB>6d}^+;pu;W ze@jp0u1Yi;`AM0hmDCivXDn^K9bCV6O?t)t*d_MhmbE>JDSFT>vM>i|3Y7u-5Q-A^ zeFY6Fn~I#J-1!i1M|!}tHu@`@UAiCe>I)@*EZT0EfbHzt4Rkvz$Ego#7Udrv>9q~D zz-|$|O2ER$@;ghwmfwfCkvj;Wr{AnJ=#AU%D6fhdb|8nCzEXgy9mS`u>M^$rTuADU zpj!i&sGa(KOsQ$|y|l{aj~*6bob3^0jzj5to@e%)Q!apxba|~pg$w9H1V5a&QD2jP z-rFk95%^&ps|#atFK}dbgn&EGKzYvoKtFC>v-G;%t|3qf(u+z2)Rg5&1#TQ!Ui4O* zPwB2@X~4v?0AGk%x^z4##fAR1FZaC1Nd_(Z3{l4(&{>zDgKn)}A*1xhocMYm&?&9* zdS38|>Jc0T$6OQ{PA7~*J?ijT&H8YtpUsx2t^-T9pjs_ziYMd=RJTaACMya*Mapzh&zu}+73B{eqq0Ey zaxP%cu#INJLYEzcs`^r~lcwls<*MnH#Os)WNHgn%+fwgFYR?(xLQ)6NnMxh7Ds3MI6~ey`C#TS;`0J0yH8(qR)3kmLXHA)fDbw-7#xmMcXYK|Gf#4@S614o*8 z!D|+ID~lxxr{v~v`MFy++w5z9q%xYP6Q7|&g5K#sF>7MK$=CRpyCK3q?7)zoa}+2) z#3+BIw>NGTA9C+H4&L5`3x0`_7-`r7Hwd;usq%^cRa*&8|7>k%v3V~~_rj&ZVj&d9 zncxnw1;snzq*0g83)F+5FKY8qq9Y7_5vHOfBEi4exl+9N-q32Q z4k5c3CcG_*U)l)jyCQtge1=3rdeowS+k6uOH%3yQ9ycOJs;^Hlra>yFYm)B%!{I(& zM;R`U&Q9ek+CSRc?FQ_B)}1b>WkgExYXc%h`AP}B-vwrK7Djus<0=?Mt6KRLjSg18 z6!DvWty#hQxH`q}`VgW;ZkaE9N}EBy#f?`IwS4|fhDlWZp0AqrQ`BJw%kakZXa%-J zxBzyHkNEW|+Fo^O%FqXeBR4ZTuwqrj7~?jKR~wW(wUw(PQe}C6zc+h>We{XX4g)kN z@o$x%ROt1vu%67(``7AL^l zcdjUV+iLyUdvW!-ecS%73I=tY;ypYQa{dzAQY57)qPh08KJZS)9bul=)i=wuM76f; zJgG&%*R^d-k0@1t2qt{PDJr^lQq|I~?2xIQk~6TYnz_xNU%*chB}R28;Dr=x8qhhETuna&m|9JN`U2lM=)e=c|}XV%0YS7$-{UaDqaN@-E| z!m9+YKSS*i&U@%T33$3V^SkX*gn6pT)Zt(>a{>xq;pSz3IZ*=T6%H((s*5H%S#Qde zIW!j~1Qd_e)uuvx3!6FDKW zWV5Am72qv@!@5w^dMRolEAKYvfXzsetN`>F|M=$LuissV|9bt4#c_-u8XFlRbXMZ` z?(8zO5nA{8;!^a?lD%OwT|{Za&M+!|nZYH>R<;&qtksVE`uEr2tKY7F(#EYAu4<4- zwQ1EE-=oU9S*Gif9ZEm>!xmJw!`^bol(OS*+{#{mMO)0SDjQwAapR=?3bt|fKdF=Sr(5eOuU>C65a*1koCbVbs_7+Q61 zSbHcFq9%{kRn05ID12-N?7Y`_7W@Ubke~$Q4GQ168Cw$r003YHm(bw|8<&}`1TL2^ z{S^j(5PkPo5GlHnQ`1%*Tegh#8odOli#`Ntb{A;k3bZ&%xTZvbqhi~MmwN}JMtE!8R`ah#U6)DXu+WQEd}l(|40#8Oz$Oq$vn*i2NG zseFqX=c&40TFnxx^akw3^!VC8 zN>(4#2(I{_H=oAuI3QI~SUQTA6`j+F z6;=YqENIfBi38px)9J7N_PIoWncTz3~INjaEAi^8$1vb;NpSinPQ zC+%Job^45P#=6k&@Q_E-D4Oz9U1cE^<1uH}sq=7ry`UFF=khZ!mSqKkUU#A>48l$j z>_N{5(<_)}nK>VwnTaCiYLUB&7{1dboMm`!ke~a+pivf!#hFub+3Hf02*|B}NJYY= zT+u?SIpown;W0EcV>58hp%Q77+3Em@dF7QJ?X?d7yvpS&&X`Rc^+@9{h5bU8b1*Cu zkmykkOIjtRbE(v>el<5+L+)S#f!7-NtnrClx!J+q1pY0E2|hYnefcllZ@1&kRU_kYhX9s?!G> zX1aTNdip(hX&g$HD~cm5hP)sKf|VgZsttrVong!M9ZJMNf>MGlpTwhq zrnh%mJ3Bj0fC!O}QM5qhbgERg+S=z>*6&BZot{`9-v1^|q*R_$nvlc&e{MI#u8%&$ zYFC{_O0POL?xMu+F7&Q)`0jv!q%Gfl<#5tpF^<08Vj5xk6@Zn){e|!1_-o|jY)M*Q z2}s~GYIT7bObI6dxR-x+4`2NAdaor5MlPo37w5pl6pX5++MF0x_!3RSkrrBduR@j zhQ_u#wCzDpH%2{gfDJS-aT&!2f$}2LDq%4Ni!#|kIl`XmX^o%P*>@F&Ke>;;SZ z4E1S%+1wd&=5)#a>`NzD`ZdLOgvRmh22Yqcpsdu7Bf(UEUw7@Ef7f>%(;4d8*clnR zG0^d_uN&iG-^Rm@HRoAqN62UAn#w8O|8u2sotIagn`HLW#;RG0@+Eb1FzRT%HNbu8 zH1MYcI~2Rt5~YzJ%?Kb|%07{zm`X?@S;8z4yApF2j@*{y57BKDFC*#A>6@uU?-DFu z3wrl$>FHW1jA5mPf1mk@^>N=DYxY1j+@Ybu0cq;Ua10geJ<}VFOg!#YR4R^wJ1a!g znZpiX)r&OC4gUUG*vaeP&aLU$#rr?3ckka`yghyk?{ALYf#sA~1|WVyy=-JfAiYIp z5k}%@x`N23?sxb<7kiSGViZ_d_zH#Kz-vn&h1_SbUl`jrf6Qax4ri9bbk@#9fUlr) zf6V}K_>WfVHIG|m!5&gbP;yE4p1c2-1OL=oVLm0UPC@RF{@JiAg=m~S1_&#OcF znaCB?pCx63)mG_o%?!64;D#}EnOoBJn$@+ToH(L>l;Jw5GB>ahaeP~pc#~=_nhxk9j@(?$a>cZ`dglg2}%i4Z*FdSaDF3f5v12rg#Eo__SSnX84>YBlpm~{p!iuXmsg$EVRN0-;-wTo zLHTpN*KNIgUNrHYG!y1;%w)kPeqDhxxe ze;k5X)g{Ka4b>2K2ZQl&Ff>Q5ZuI(^t?MJR-yaXhj)RPG?`hT0vr^(s<(8kk9ZusB zg%A`!1!0L3mKb3$2I-?9EPZSs+)x%7rei}L?(_`JbquJ3di@dBa37(bKD5!`$CgFr zxT6_Aq$p~te_lvSpU&4d^%R9nP!y*qe?(nS!$CLkF<7t)kHcpvj$vw^XXv0fJxw)r zO;>G@r8+k3K6VB}XJCAzjBaM2tQ|Zv+@c-tIJVS;-Jk+vv*!Sxo;gB&*BIMKGn^jM zH4}LoFq~Z`Qs9!QpQ%e=d_- zKUtM~ed;;dsq3ge8hRtu9)pUS#$W($4I8RvJGh5OnyU@Hhqd!j{FKk;A!U7C5R=Xs zG2zG>i8bi%$hM7<)_1*;J}_|~f7|1}J3vG5_^zY5ZtutHZf`gmb+p0XtwPhpC*b73 z^GQJ*&A^h;0$4_NfFG+#Yxm~Nv2&{?u^-V=q#dwGo5X=neXM3nb&>jz>^-`_^Y`~( z)(ZEW4$KnU31nZJO_+Q_;U&>}jfQ?nrQ4lzO)yHGIqZ3cKUFKPR6dyNf0uv0y58fd z+hkYdwU!;bca}BB$i=B;aoW2K?By$^vv=4!=+5<5HHFJrY!@cdmh#+uat55VSc^k& z6VD2UIH1x@rGi}AXQ{y@$jxaOJh(%a;Hn&LqFnA?$=9tsC4?kVIsC_!-s-gWT30%7 zyxs$cmwdOjNq%aR+Nm{{e-gZKWcm$fW`UkX1S}0lb!Y$B=4Yj+wxy3&bDr3`#dkov zxS!~V5oH7Lu|?1N<=JIVT?Ib^tS(RmHME%s&*Uu`^k=}h$R7`B5CYh~5e+YC(jxkhS&lsp? z-x;eAL?CI?oZ(3C_cYUVe}dCx1LK}y>nb*MS2aC*q>jh%>e@rw96R37bT@LQ$EEb2 zA@_yUeTm&{xmj6kMn4x=0UjLe4qeFN$7s}t|6?>TdgJlP-H5rB3yS`*qnY0y9zp+z z;7D(tvLc{~Q?_PZe<&i(H3Brn#fv$V1Gz&X5(`l4z{oo<;I@2LdP9|v5uD~d^Wr|@ zY>+I$Y^*{b)CAUX6v*_G-;~G;) zob;pRe{cTqf0yP_GZK#==T#uiA1aTMz{$~+rO3_o8c@RTRskBOHVx$Jl_8g%Q+-?Gn&7PPHxuX(SjZ54I%DE zk;>UTJ%Rbve}1X}#pVE_c&tG%9^Zgwu{E4HzV*w-bYI&G6UbUl%q`~9UG20KqFz9f z8e-~)m~d=}L%zdpO7al9Mfdm(gfxp|7evSOzs*FL-mOT8V?dPRFrl!pzRp_aJ}7c^ z{$L{Yss{qJHv4%mq>sQ0tn^og35AReN@g10Vptuxe}UXALxC7zr!3ACL(H=?D#0!q z=tbDUgdj-Bg#=;0DF!Lg&Sn>ri!NV#m0~p)YlTbayyQ;3p=@J6ri+YyiYM~>jg3K; zfzwpX9>-bW@gjxYKQWd!vnKT!ZoX6uhqHwV4MV@$|Bnk3U?y_6FEtEO#d+dS# zNgs?}e_QbHn}?YOPS~;?HwzQ8rQ^;Q&v-;zY4xT20qkhYolt>5{MiQ1xj%~#`*h_& zWZqgWA(8^?f|&?PQApC*^V$96Wj?zF|Gw415$gjfaz;IMB-d{)J~eQK1^@5KRm~Son zf2=tiV(?J)R|y7rYRzoV3S4DfQmxbXReAO0z7i$!3n0i+c)|wGcaE9+^g+oapGqOR z1HnuA<{@9P?~0c=Ez_B^&$kFH6W|$Qfc%>+M(j})>oTd@alf7|&hr_MDlOILe)fIW!XhR23(?+id_CLosx{~re@xdmPe7kZzkfic~&^Kv; zf(%b~bBdC3<$lrIz5CWK4=3t8#olE1^3UDty~AC$VcvRwRrj}R3FcY;H-wjGfAS#1 z(pP|rm@5HS^ZpI!M`=f+@K+j=uke7tk!`0}!gMCP$P4fSr(E6P`Jl^Y8Ll`NkltQ# z9FIMVwdiV9&UPzF;TWJGXDKH$=gMc2Pc!Exqp?$PgbpH`RrV6oteDFjbwC%atj zcDHV%%-;jscp;s7ET@F*0dhv^e~>k-5RCc}8sw!DHB5g_UyUe zb{9Ly_8sC~4p0=%)ZW&N`U_;5vnY%xHcdnpflosec?96F>5>pr%Vk?z$pFP$@tmgZ zFBZO+PB`&q{_#ynEj#pS0>ME7D@;M;Ed;;#of%QrB~vr7D8pvteT@7NH#P%MSKKtV zloWRq5|QNVaGhfA0y1d_;uuAW?KP%dGX_E z@+NSsP!Kl(jxLk8)Wx1qPT;c;AguWPoAcu{^XSF#tBZ5a=GK<&T8yD*n0>G=u#2yN zYaP zu|pu7aS{(Xf1H`F-Z$Fqe!F*YV6?kNThGlFVEBg5l@>v}JQ9-7#eD1~Foj+NQ|Q^6 zsR8=!7jor?=nB1{pa1Kz4^er(1LmhB2#N0r3QlLRKf`u!)}2n<{evm)*v?e5`?z<| z)3t+c*XUMQm`97LXA!PfDp5Rmw>D*Sciem*Tvmuif7D7S?(cWBY;={=8YtLWu!_od z&|*L8A;-V=z{#B=V)lUqW;z5@FKC1-*jEkoP=ELxUeHOsKUvBNZKcU+|1$@6sh~j?SYgUV z@JGbqX3Rfe!B5@sv>vv@= zgqd8{O=|gLmA;1LBEG;rg-S$0JJ>;?kDh(P_8gtzAey?wmcBY(@nVXd7Wn~$!LMCw ziD@&K2ZwWu&4*6c+Q<6-f#w*vJ+ltFM!!4lHfvMMX*)Ap?{^ROrx3RI@yYY!XG23j zK%K6E42W>8rDh_1t5RU!=|(*MP^8P#GbT*rxJQpPndYAFoS}pQHwBK>U-om z3=M>D0?eIj$Q7RxG+YMQ1j$}Of3$vy1HyQRBXlfAD*9h*HSW;fGvAX7yv3soTNG?V z@g=?~jtl;!OB}vVFutMgSRRk$+veWkN*Pb2Mk;gz!Y~0Ug>d3GR^)$%L+N%UDJ6U6 zbez5~YA_W)9c=g?Q_uJ#uc+#j*P^QI_TnVe0XoJlneLQ?9+tdc|C@6$PBjVLCD)AE$8H3 zWuif9p#(GDu1~VJGoPY}VQPX_c<%9#%pN+Jcca1+<(PEipsB%s`WI&WtR}j`j`}we&iUM*e>{B& zYDxx52q363GYzWYQNsTQVAUfI3z)NscQbW{XP9CxN3r7ZUuuc^(kJpXpey9b2AY8_ z+~E(f(#IuqNsfQWW339s3nK9%T+a!QkX+K_C`O`tnUpCNXF$2dyrS_;BYNYiGQYn5 zCF-q>jyv`$=VXkzC zC*9YJDrI+_a%#yCMm!c;o}HPhf%sLqxBEhF0pf67V=8~?h^J;RS~L*!cnhAHF+5>d z(Pgx2s3xlqK+UJ+8xP_7rzdZZrOG6p?yNAW4K;%afUrcogcGp@JY_`U_fXJa;fiio zN|O&UxrW6=pF-7`UI25$nF~t>i6hL=*H7fX1SaD;_MxP~H~AVW9jw-(8bsxey^*XA z;SWdUL1lk{^<1?E<$nT_I74afGW8MTO?OUd8{IekVHkP1z=891^4={OVCRB4V4?>| zwu84vWNcf%dNlbKJWc;ZOaT$0wK7%tv#nN&%n8&?2X*lL$EitD{CrON+$r>wvu z80vqD;OmnGsFe5JHA-h<^UW1q^6je5CbdcR?N84)_!l5#1t!)MqWro2_8%eibMb!} zZ$MU}G-KbV@&XTZGgji)YCE45f3-se5u@^X;`%b3vBJ&x~nU=S= zx6w1-yTUX?3j&KV2F-@&s8fq!CzpR`Lm!==U2yQ+J`pFefC-@=k_G0Q1Tudtb-SFz zOY8=iB7U+=!X?LMSBVNLDJDTGkA|-pA-=u34xI;qL#_y{33(`tbWPJ5sGIzQr%Bz) zB*mBJH_khx#{^L|*NX90YnVcmR;I%G((V30GggCJBmSfFKaE>$pzW`uW*mQb@@__3 zDXBAWv9-ZU3gyze#1m1Uf;3qGn&oe6R~rj{`i+}nH(#dGyD{69N1EE7>?wcF-H+K` zcDwtX)DU#4nt&9%sINLpf?Wqeou_^j$a;N!2WO=rUqtx<@Fkahhduk7PXUcFas^bfq%@{uPinsRi6_^aj42zwQ+VxD z%UOQIuN4A;@S&e7>>%#SKDve_3DSFe$hIO;Wq~o`=6wA3oQWl@=vv2s|9gF{t$vI! zru@XZ(=`lT>qB5_2kO+n^tn;)b%-f#!m{x|`mdZgKY^}?D;+)`xgme1VwvlG{x=Hf zZ~wXS9RP+vdA}PYSmONp4~u!9e_0?Q4q{io{uBBgX~VH*x_MH``*(<#6Ei!C@Alg5 zUfZav4;#;K@6-U2-&)ka`us00Ay`|fEj?NLqifC5!SO0DbHz;e6YoIl_B7+0iYH#w zN_FoK2P(Sgbb9&E2g=%*{2xAlCm=I^=#0b(^ur>xtGE08zP7Kc9t=9r#=9PYcr`jY zT(owt^+%jEi=6Y#j+s+zr6a6lZ@m1enVkO`P5#nRDiq5nEU>)MyQh=g@s#7`MISDFfx&hn>K;BZf3Q*ktV<0+$d4Ti)amBZg_`*~XR%Y!lh z^q{$W$azqTOk}5iiPywCkK8g)=S6`X3fEDT1`?VY*2FMW2mf3oQ}D15%%4w!8c)vfUouT6OS2f8rsVoj7^hMexK?Om({ocCBQNQ6_&|(1 z9f$A?tkCzvAZIuYoN)0qjgggxF{c=0sp};1B z-u!f-lr-$_Qnu5Dd9qj@OZ$?{DW$obkGwxRUyu=t%U}cM=cBXJ6Z6x@GZ>5IO`1l@ z;eYOMs2uJ-JUm%c6D-2Q`q!CIt2ZNo%F8LNG z$-(gBa@jo`5;0eYKmK#|*H2x!!=}DmEH9TZ?bV<3ojh_Dd-ASC^#CpMiRrv#+Tr3J zCP{{u*xD@Y;Zc@=1w0oGN2;a|-~F~!)qj!P+luq;F%hSa)R}G@7&+S9nAq!yZHx_F z(;dSYYpR7r78eX_+OCxX<5n>?WD{W%%g}Uvr1$lij{3&jw)(S~Gw-9(Xr_X&wK_5c zfs_+}CF0}<|Gqksx~YfB*a^PJUKrt6dgofV{ofo%TH+*e!(dlhrWw5cj-|8k9)DLQ z*npMTjZ&Z_a$w23>zTTC=K6Sy#;R^iN7;%1MJe^ck++_Yb zKrZo2EXR1aK*`|e>%kwK5?Kr8_lY+ z5@rLF#4n+%`M5+ChoMiXj$#}jNq;+Pqe~);ZgHFd?Uj5K*fD;Pjzdr-k$aN-Hb(ZN z^ly|vwjl54$WEkpu?z1(f&=ntVM}j46x_mxjT@0K7buOvand_4yOCGhdB3rr-+Iz_ zz&r{QK=~4TPCvo%y=&qA+tdDon{N6S;RBAzTac0L6Zb*s)D3PLU~gN_e1E26JVBNX z5irA3Z8o!X%bCvC#$;`M7wjE8!-hU~`s?*v?;BXv`ZGMA0_FudR z)+o_6lDEFZS1Hw3$&gzI|H#&+4z}i_sbkGGJjdE}I@8xWwk(L#aZO19{My*4!t`%~ ze>Tx)+I+4(4}NW=POGv|mVa(Sj?#1Y7E8aoo*$;q!RtrK3m^EN@+kR{A-RdP2CW(a zm^_tek1sBU$5C_~27OR+Jp71)8=Ul=5OBA_{bh;*8^w12%w5MQe*7*(={m9}b9>aE zAOrUeZ93{hM%DUgJkr4+Hnygd7DU0CS`o!mlt4uZRFrZRrMil32!EQ-=3}g)xns{D zC5`NnqiPoH80(p1AbncPJ_3Tq6XS2E&pJ59>ReZ!1e#&!6GNTq;~Fw3EtDL{PwI|H zZr#YV!-s&(2*a0ghF_k#nvwI~4Ir})myw49+qFld;fD-ocsPYL1l!Pjg29ZMrp=7C zs?OBW46C*=AFWBH@PA$SdF@24$k`T6EmriAQgyW&zPmQ`J{liO1K;;xp8T zuncSw1XbTj&`qj_2?OuZ^igVUNJ12y_BtJwd@~#-R+y%JAWN|4qkznN_$l_5$ieTC zkM}F%FVtzp%RP|B>&*6j?@dA%%Q*f8=uTbB$B+bV`o+eMWPf5-^_sA}M0vpL2;E>_ z0Fx)iQ2Ph)XW+OH_@1YfydBGXt^>hT&~0zrG%k%BPIM|aDrvyWgv zB5Y6?^i3hQBY%(u{A4wP}VppxyAS!Zq%N8l)IUjLtm_+2dlKIf7Ew4%}Zenuilk7L-eO;o+ zBnrwRP~=va^Z8ilKatKuYC37>S&3l9twy^wONbNhz>J4K;ja-CQTzEuA(zeWCHOmp z9PygAag8O{6}Y9|69o1IAC!GV0~iE|@~-4dntvKrof7GXPY{xqrweidQAYz*n0h6{ z)6cY(X{tZ-(LR*koPzyqrt+bL;Z*czGu6hu+2myGcZsfBUJ)<&&0G8kYbuVElwze7 zdXn5YkCO9}EC`tzQkPlIarwhjk^(iCAecZ(HkV-*TX;ZGy%o~58PJCSM^su+qFYgw zNq?go(W;ug*iM%!6_(}c<-!!5{Ab<9=NCHbCK`Qxeql8C8g%pwTC5Me#rpmHGw*ZT zd@fRN<+f3uLvCr1-GUU6T9DmB{VU+8Nq7Uk>hyy62KsM}PJ=|_K{fk=eS$o(tQ;oY zJ;p<8w1AYJv`AwD>Bj?w95U_=8J)b{NPp@J$gxw9Hg7HD0Th>&uH&DSF@CuIgVrys z#w3Tz^@VH~v=`Fu@_J1*zh2)XFT?u^T@pPf1rQ%ViK!g^<67$upvJt`2*ZAC~mPw7dwT2W2*y+zY)8Ue0y8W`L_q9}y+w(_5v9#oAYXfc&~2FV}ZYi*a) z?jO0B6BvZF+s?p=w&ZQu`Ux5LmPq0`HoG??uSxsK09md>QO5G!6Lf zF`*5Ju0oLSDPf$NTxV{=q)O<4f0HJY%S$>`$tM4GBhztf)g!CF) zf;7jZN7^*_sy6#7cjDt3e%lC$f(b#MLcw%m&H*$@SHh^J$qxUpBncZ zZcBmhJ0V`IW&qV8-}9By#D8ZfxXDOsOWMys?o!oX1bIQL7Etqp>iaZp$Td|E^ULSP z1WH3^+wU|auKfIx{%sg9pKx!ltd+VKPXy8~K~kOMZD>Er-G<049dy_EE{o9?!8HF~ z(9^Yx7~i}2;nb(+4oyqip12Fw>kSJcy97GJ!A-h34VDlqft|EyFMk}Tmu~1Aq+Voe z&rLSiJ|SoHjpES#jY)K*r=d^l_>qw{ieVzm{IvNcf{rO|qcmdF7s~n!q%D>rXeGoi z6Lid|pU|oZRFGBtu5P^I+cW1E`Q>iCTOk~82 zUlmu#E21&`UEO=ACAh(=amH$jy1q6oizv9PFnUz#3fKke%1#@Uv?IxVUUBvE{gh4f zt!WudyL`=dz2a&wr~amr|6%{w!8FWgd7X~DBK&`<*egypipKMW1{8;%x**9}h5Mjd z#J%i>qTBf&P)h>@moJ?e7?&k*3m2Dcof#0fS#bpt0|}T(X!j=s006s}Ve1SWmymP? zDVLxj3I%^Q5dQ98L98nzC63&z{m>eI!LTJjfV3&nbYEVn2rc6`q%H* zSAWv)x7TD&w70dkFw5y=;xDJG`^n~X9R|y&1zBTUAp1HK@dD(_H=EPItAOqo0^XYwKPFC;EK5c${csZ*+e%pVL=40A?{CWtsMx4}fE)?C``xeco_hl?7nMU+Vg)` zzpTAYfGq?l3uGfaU9LmK4NsQA`rI2gId!Vhx=xs})MerRO4aT_KzW#IRTjSEIvBVA z2XRyiq2@)#BJO(*1RQ%_(9?BU)fr=Q{{O^q5HT*1>=C50h|<<@sNE}Z$clo?*l#vE zGyp1sy@JGX2DT@{aHiqpXrA(?VJUxB+MAhz$<_U0bLxiXyyht8CZZ@>pQG?(fuuQT z7=1Gse6tBk7YB2pCVCc&M~5lmJz#<@*TAjK$*fq+jMYk}LvU|1#H|ko5am>XF-P#c z{R=Kwnc4XlC3&C9x?)c8C`(K}`vua|bQF^BHikuOR#o8c0D#cyZl_ih1rC3WF;3rt zHbWpda!7`xbuka~cqIqTgy9Dlq3?9Zgg+HLvOJ#S{OT9xsG0X&vWJWls|a>80g^b& z30#w2&}({_O7$q{Z1#HQl{4zL-FWj{^I>9jA9k$>&mcO_WNPOfwkG-xVTNLlR8^}7 zDy`bI(ipPWV0R}WSk8~!o49}8kR-_qo)Wxm4DgfYFxHJr6ytSx1FJ&wgv0!g`26hr zT{{La<2GfN8y?l6(^`36|Bk_vW!d}^UQ2NN@oKH8+;dqsJ3NNk%$(GLy{wq^bxndsfN8tz1qr(t!D!mUWR&}KQ01#>QUuNITHCj7fd zJ@WRoNV@NhDjIEBJ>C4~%J|7=h!fW30b%{sd1Q?K1yD-^1eTr|7`GLA1sN|5cewr! zBLe^c-3R~xD3>vD1sRvAq8SvIXsHDoe^uX4+b|G*&tG9}LP-XsqzUwgDBZL%35kbk zu)Q=Ta$=i$OXA3OCe-!$f ziHficOM0Ot#rfH(v*PIXEd(q6{pI}ZTm0+iIT|2o+qN^jb&X|xO|&l6u-|HJwARZR z_P5#^`xNVR5_#?r-qQs_We`SnT@N>$P$)m+H&ot5UO~0ndU!D`%@ax@?@bZSnbzp4 zHQtT9KPnn}pN3IlJO^8oZRTZGf7y>?PEJMM+j#7V_OHpKZ zabCxQ8D9bNV)l)B|Hn})#|39_qGj&f%S-YOP-acHGA{MBG#w|y+iG*ib$!x3=(Ia5 zIB2)SZuhX)Wk+2Sw1d>gf8>z9657}@&(BI@&C{Ifi6CZ&P=;bU6RsFAD`!fR5?@pI zNpBBLu8NLdhj9g35ZXlkM6J`@*Ndvt}FGP8~JOaRj)ZA4Tpv?f5?~3X>%0K*d79? zOPrbDF()8Jwb`593v4*GpSADmtpG+913G^ZDV0_V{c|=myy>5A%AUe+cpsXu3tf5C@6KZ zW2Zrqdh3EA4X_LyP|Rt+*apE!l+9HlHIj;x2LA6oQg4*qxSIf5BJa6-j(4X!{e%*k za-%$B8ToDO%L6$mGqVQ8Y19 zH3$nSsc9kgihpR+$t%Ni-HO8i!Nr9kQV}5qi`_;^m1ZQZ6g6B5e~)W^ie^reeE$8z?R)a+?+@r5Qg~xbsjp@yC*jp>yWK9w(G_^f zQci{DA_1B;GX`RmfJw%d_C$dF_$yC;ThP(h$>{BJw10XX;oA7!&HQc-h8NFnZ7*D@ z9M6zr0-j^mo$-PzDpEQEz*>(sv@D-SW<$jnz2*IuymM1kcg0u8j`8tIZH zoaSgkD+Q==`u|S$pm28mAP@Rz2m26JAu+CV!w3NAA^RI55 zOZYb%hPL!+?D@F!G6R)L3w@Xt{e_n#1zsCwdw&SU{;jxT8f95gvbAr{J?&P3yQeHe zL@}BZR+o0DS)RoR%B(4IhvFLiej+@DYP5hcDX2*{un}5h2jm$N(s=mUz|Vml{G;N< zo$i+1mvqfK^7f>p5m+Z;&w3Pes#%riw(e-BT)*xAXeq*hbG5Wi8iZuc9*1&!DZJ$Z z*ngK}sIH}c{SJQN^Z4hhUG&RR;JEcPM%WS~M{KEZ6u%IOXn`Mi%H(^1;#Khdn0KdG zV8{`FV4tlDUNyR)*Q&X7d*DuO48aX+tOhTicahuiyg*XI=lZo}l5w>Q}ZuLVqR|RG01&)>I}b-c*;Q5e`#xK>7)~tvVJJ(Lu?12~RcdIw|fr2r0;L9wsLrtSWKwuQ}EB1NhP)PJq) zICt0IBQF<R%?lkI>yw}ycngvY1cwt<)`_Z{@;HD>yj?A&{`Q(4hYi0qRgxv!ltYu@LzE!Cpeuz&G1}GSYw#tu(!n{LfFAR~n;N z=zs>S%<~E++d*cu-Hv?vUGNQ1OSiMh1@sLH6%2zbkbnRH&motw*9AgWIwEDyT#AEf01dKDpd0RPkfLox+{cIg1N%cZV&g_^ zY{b3$7iRv^=A+(S-DpytIeTIc!WMzG%oY8{E-#%TOOs8Y_5JONJTcjh)ebBT2(Ncn@8pO7d(W)V4TetQ7H$| z`67T1KO2s->>`POjPhRfX<48gwDi2ewu&+b1X?eD&*E|s6*j0OE#tE| zAC}h(r;+orTnxvv#BCxghG{g9t!L1f^?RAm0KvmJ&ol3fMU)ruaGCzJ%*wc-Kt798 zoMB&)JpO4J7p41(YFZCJ&SwIi=ucNp#w5E+XIV6f^TBjyZchpzYlvioFd1AP&$CMa zl8*E1MHx?q^LUbfLQ)Z0OGF!N)R>#$}ct=n0Ma*)S?$Fr#HDsb`veB#cLY^F^E&ux{jYKr|3fK1{Pz zboARed#7+=fQIMq5taN4DAca@V}X6dRm;Es<><}p;mha4cL)4?4r>pwv8{%mnUUp}g!f?vUOXS1b-@eZf! zbymK}mZ>>^YQR-eCO^Z3zB4IXJ|0eCvh~6PwAoleJTB}<%QP;=(IWot_|;4KB$+1A z0u-L8q05KJvx*YtO*~#;5xXi zAC+px`1e%;|D**ju`j+D&wzIYhv_s^PgD80a?qyGw7Bs1$M5An3Qsv8J5@$gNTBL79 zm!3jpU>#Ff3_+O*oJSc5K;au)Z3Xjz^^Be1rZx}iW` zAmrG823i17WI*@u6b6B79Ue#db#Qf_jL-2s)Jz4b!muaML2B*KFrwuse*Thys-FRH zk8vyzf%Iw;Pa~)jB-4P{ zC}L)wKtIy6ZXkxaMnhQZN!+D?PFM;+IRTcNi7|@azQF0>Cp>=&`LLA-^CfgeOgUpD zo6WK-L>7&%*kvfmWH&HB-xC($pR~jkoAVfnD0baaf>b06n23(;PbLXR3C%$i@RSw-v;^crgMn2XzzP;!69rVW`@t*$KrjW?NTFB|M}RLbA4Hc? zGK)soGr^O;2s|I!Pp@EImPj)rU_Zf6%Lt^rYcUM>^A^MiKnkoIi9lbeyEF*#L4ukC z1w^n!uEio<0PP?gLAA8M`$4%KhH)-`W{5%}ZmJmcgYS-y-x6pdO`s}#+iMH(-SMlp z0EGS^BWPRiyO&2$O*I<_ukOEpB>DuMyvCVo5A3-E?8VM2#9K0rZvf@_{?T`B$_6IV zVCpM4?ZD45>@LuocJOd}o959OZZ*K*2uinYS4@M+UmZD=ad@ODV^FgI<$Dw%RyTAkwolQ3!aotjO@`_Y zvh|{_SxXUYUirV}VyY+3)?jWme;@?OA3r3s8SrM9gxPpGi%Ln12ocCyY@ju8#D0LE z{os5F&Gtd;nc&s{+i@`lS(YS!3ehz#zItSxwfSO4Zf7t-vXf zeV#eP(ajH&32gt#q&)8h=W%j&UV|m;gEEGwp28+2_9p{Db(mIdB8G}{(qnukVupx` zAz=bp*xJ_PHW)dM$LA>sJ0LLx*@A_K9vo9kWI7lBVgoL>g z03DU-$7?w0Nu)3keg`0bmPK4wztA0^It3g&XSj#S=D&;c^5>e`m(}j`xZ8Grx+vt2 z7diGHYt=R8A1XK4VyK!OS@ref2CBbHdtCwN|A4o{bU7bE6@W3iMn!|7KRV=1E~9i@ z*AEG47%ku&_YqJB5`O`wenc4V2xS$14Jh3C;v6^e;OK`J!CU%&Nu0m4B&h_T<>h=a zSL;GPVO8+%qQDV#jd203W)JfC*$d!U73Y1F6I$@lcIIfDU1Q;&+JBV|l(Bnm8u|i3#DgtL7z-XEZ2~(pSTwvk&xY)j$jLAgLcB zf2)XaE#}i2v^dLp&%0^R3b}L+M$8R@!>Oo6qBtW5kJGSGFJ}`#&}wMVi6WshFf26y z%&PW5@CN&ImB2iXGT0cfJ*Dbt{8Y$=2Rn*o2M5SgW2w=9X#C)6lM?|uf3RqEz_vbj zgEi>G8pxOi-L*O~K}{UBQ4t&&nvPykUZc#S$)L-H!n>=6_oY}ROI ztPhZ_ZodbAb8{Bu6BueCsfJa0#6^l0>$Sf{Y)h)+I;0}PR)lIW&lVsPByrJg!GZhR zI7`JG`oUXlKs|%aC6z6-=+f8Fsm;wz)J2>pN?S)~7i5druXYP6z@q?<18}Z2ux$PS z8G00#aHgyyiCL7MEm6z~f|v3u8ODNma5ex+6}wA+oc7-z)ov&f%Fv*&;E4amh52a8Dm_$#cJwE+?LS=OxrmeoM>1{mc!E)Z2A8y2qJOtJVqNd zNk4{_2AQZnDU(`M6l}2^Gps8uF2Yn^J4t08m*aCZCF6D%;Km|MUt*uw>KPV~Qmon* z@*_?vZr#bpc*aIHgjT@h0fwd_YPlGHRTa+l+erB#TnN7B}euVWBXGciEsKf1!P;&qaB335kUCn*bm z^?9)02ic;}<#>VWQzS!dbCguZK-XqQ)Fs6$VWo;@<Oq}x>&al3zQ>jn{A#tTKnn$BNnO%D)aG55s5?OnuY+m{(7u@wauG&27`C?rw5RhlZhoKvt^?T zXMtncu9UzIpEtq5!$;G5y(d-Va%jxjyJ6brAQCk}BUaT;z!x=`sokiGRwjCXP!z2F zLY?^Z@fQaDsg0sSd?sj~LiRps>_GELMiGWsZZDQ_1`w9KNcsS%NhFktHK#SAyQ(6W zH(qhs<$`&fWI|Lnt?1=sF|IUA#=yq3mHZ|D=6bpk$RVQS1eU6*JED@HMTwg+>IkxF<30%sH(J|e8CT(y zPKl`AM8)Z<-EkMTZX||9mI%KDJ}%hc{K&&GC}nU96L7RFGxQRF8xO}33%R?%g+X)) zRcm37wf&@4QeJ0=2S^cqsYSx1i9d_eIHx|y7I<$FIy_0wFXQygu>m6Gv0w;N3sNN- zQ^+k^Df*bQFO&FcIL?--5P`qTuFztBjs1q>+j#^6;#EXPDFb@ObPd8)iS#CSq>I=D z^;+o<7Fm&ysEPf5PR|Oft5QU@s_VLGd=@p=Mc3k@)Gh0}{KiuyVhh`lVeTr68~>)0 zBF-7%fR%{_%!n}E82k+12v)<)iEPHDXBgs*s-^oP-^kh2vZs6_Rw1o6T1CK&QMy(J zb0Le?EM|G^4?3v8L^++8Vt~G>2n-#t)j6ZvxI)=a6V=#%j)#M_|8T#BQ|D@MLzIvE zgl!OjZw`g4KNIDfMQ9wWSsK;``Vu!)DTy)k@f?TzoRDU9v9Yq09}q%SsBxlou?Pi#4Z&0O?gF+7_EQ7b1Hy>we(% zHM8LU1f+F8+J(ICp=g*obyEmRe%zipvZD zFn*TNA(FA88Gw4DG*nVI0o_CWc8~p0Kcc6Be_K0$Sv#Ve7ihWtCeCL`x^~L)cyv~n zdJ^3%z5(PH$yur$sKuO+ZvJGgxQZuniZB=10*!LXSb$9mnBq%)E;-IoJMbc!kzzV0 z`%KW;Tc%{CStt_rko)K`5pk{B9VL8i-@ z;qD%cmjxVrQ2>oU;vHX>Gae3-B&o4h))F%+mp1qF+lo0OUAMAwEiAMh-_I1 z^rCnvW)%g}0{iRVqEQtz)}tu8%0@Ldh|r-ze2c9LOSaVC;lilFdp*%O#42^$c)Gxr z{|tXwd2Hyk8CAAUn`#3$M6j1fQ}-OsFUdk)?h`&t$0UPF-?}Kch_6v5BS}zS5R?kV z9w8Cq6NqbX@cb>Dv?fS(1dlJVI@&{Y4A+2QD9OZBCQ8>UA=QrMfM^YWTX+2AunJ%w zDXXYZ2hfv(Uk{y!l#K;{N@cY$AFUZ`eDn2?y!-T>XDuJo;jf5c*DI4T>3JD_1g=xW zF*^EO#$9Iu2-!pS<@dN70L~-AyEP^BTG^)cZA>7dE9<;xOeSof?4p(isP2hyQjWh@ zyEZ{P6jvh&VJLI){L*B9)1I#H(uq~dE~Usr5C>4M5K9I~F&BnxX$6anQ!+~K4kie* zRSbyAlJbN}KwSc3_cBX~-_uue$;Wh(Oi5W?8ukPjYQcM{>M9O05vLmI#EI>vsLm0p z0|7uS30?+CJcPe%L~DG`mq%j0zD=61&OAw%h2%sDdHt^)9te7WW8N;*0BhZV-RyLS z1tcJT*YADcA%A9wYTck+Moj6osqNEuhqD>Fe<5!v*@o}7Vo{YkK8aphQW;qW5T8~OR#;If2%#DKEwx=_mieRE)w3RNg@Xu3tuI`CuOks%XPfjy~}mePbfg4`EfMOVQ>99FPhm_K%h$dHr8{ z+Tv~^wxc}mPvU8kGX95nNq?ANXa-=-KgXS}>My?%0PjUt!O^)JaDMj`;LRh(x*c~E`GRfeLJIrwL9-oHM6cX;5AU-4*#yajoI zA;zgk%T&i^F}fgcvJ*)djPp$@mwFK!MXjqVqw7{E4RZ2ui>{(;Yg)LR4@8eO;!BKn zBe{*69=F#m^63o&tRZS4!i5GL2b9z*9xhR@#~39bD2;}F^g_(16RZ3s}! z*T%|!-XmSHkLKM9dcMs!5*Y#xA1mT%FeIin9D2+cJx=Fy!-<(bmqWnh{ZA~aaDB2 zv!aJylJ=CNMEnWqJz3fG#1pvnAy@L-_k8$av9n?r6!Kq?q^Y~u{JFCafU zRi#o&0qN=r4aa;~LHPi8&C>KZSjQ5y`;Q}KUgn*HI&l|!ahFA-9&5=Xy39eXU8!xv z060fOwXpYt7(`XoYZzpx_o(5!gOG-SN{Cr87!E0L)X>&@(;Kr6Oj#ZeM4YOQ{aU+! znK5#!wFlI}4$hBcXG8$?6Fa0Da7^*d>_2ftb12p{990m74Ga)h!G(&y)tL{@@@%>2 zgvliAHc|CemS2D%jh(XT`CGbJBE%3P7P6FNMOOC{a!h zI%teWDwk&w(!f;tfCfI)`+DaWYbHW}wY`SBqMF6^Yz;=3EQY+hSfv#w)TKXlO#&hR zaLt=+Vo)z^xzAsQ7@Nac{o`alYY8+dn$2w-tM3}wD>q3aRt_;EK>;k9PuPTQ0jun? zQXC7W(S_+U@u&U^$(`|=c{gDY?2BlLN`9l$sgmF1(^+DKJ3&oGJd5ctiwrk^k}yzA zAT^b8PlBQnL{ey{A0x09q3NxXDMV;1V22Ie4#d&DSdI$3EMa&VP$_YPqNu@X<+ifG ztRJlk?X)fwz{xU~!C}-IvWv3t>&m!>f16F_MrYwTO+p?WCFW7ezH;a|g+e;bkdoBG zf<`$P;*K@p7skS=OpCd*hE3R!KLlUZQ^ z^e*Ncb>G)83L&#ueG>QA%y?=h=EaIKC}EmlY^f+eTh8fTENXiq?XoXL;hMNyTtx7r zU9CTMg=FJQ&=CTw-`eAfuLe_+jI61ddO6(Noa~EgR}oD23op;HIAc|RGBdD(pLLAi z=pp*TbRU)n6X`f+L9p60L`XPqM)P6-QcWk+3^VKzqxHCA@s{?54|bK`R;yRb08jtr zlRMgPqVWadL+skgD8Y*ZyLfuKM5RBB*3bGKIDj3&01cluK|eiS8u#-F9lFJt7#DO= zBI|L3Ppsprrd4qjUAyCdPYTIiI@KZef(~n~%jIGgcRg73qs2>U)~@Yot5T_gTvRMx zo#X8la#EG#@1w2~9epnFWa+?I!THrDM<|wSDR8{#)-83!!0qQ-yqvzZD>{Z8LxEKg zD~r>CaUhi=s)qJi5zB<^MmV=xUElz*FJX&ggrPj8JyRl(cs5;sbhX{FB-eq7ZMg`C zvP#G{n65iG9n}CwVC?SH4sAdlj?Mm;Gk1{5)E<#gsk%e+EqvL}DqSm93!|>mDi2u8 zmDOu9crH|;rqsW|MyOf1ca0dhW~>ax=V&?XsCwNB2df`M!|7Q@)g5p%@bGd+HPSGg znz_G>^HEmBp>S7!tMP=bfGD$JG0x*S?Rd-MCp?+NqvhFY@SYZuSk%Ft!n2YGVJ(8Ys$8Kqe;d6FH+b5z#7kp>M4C`#@{Swj>nO>oVrN^kuA8A>z4ouKl+}ZZv)H~-2 z(X|=|`AI0SIJ#HwnVJbXT1(Aj)tffR@pZUYjh%!;PsQ+5b)x#x3sfkZ6x>Ro_~STU zl%5FjNHlSO%}y$ZHUzgX2LN&$0;4sC9v$%}kp=G!_OakOI)d}}8Wd-W~IC?)SnS*RRUZUN35aJb0;L>|| zH%%Nb_UN$WcBu2m_?lzU2S;VLI7ELHKApGjh!IbJy}2)4)7nrsRlHn%(*@Jqxxw+U zvYojzO7N|6NS(AeOpOg!@PQ3(p0-QlQ)_GPdHL?|p=6^`4=DFg?yR8!Eo$vzKU74cn2> z!)Z7?+3jziN^_0yGrCs2J3JV^-hXxA&O#M`B>Dq!DL>=_H3?(a3^p7`=`b22V;^FP zWkHnO0j{j~0rAFYURa|H^$=C?r1Tk}{)G6xWj=90<3fH-DFZx<#y0xeS}6yP>VlQ4 zsOtp_-5W4V+;h95x4hYk=9)BMZaWx7vZ)Uq1B$ z$_Yc?oPl_p2h{g>Japkqw#ZU4m8X-LsbxEgW9>8{#{#TwY%FJ~&aZgI`dZ}!WbCI= zbH{QU?MPI0?TMDqaEGTkut7ozS<&BrrfOH8tHL`)h#M7x?m7EUb^iSTb^`&#p5boS z^i?=Q%_n;3!CC!09$&1olqpx3X>zvADOZaDOq^)++5&9%Js8(JHVqI0|SiCr?)NDM3)v#KZ4|r3o4MYwohiBP! zp>aE7R8_`v8zU~l&YY5qh`*AR(7)XVrU#>;GF3Fy^-krks*K%fOn}G!nf@mf1E6kh zDvef>dR1Dr#;;qis0YLjQ8|Qv06dT`QU`AJfalxB-@kh)4t<^jDedu8nVdH`)!~3D z@~JS-D|2x(*}IC}IjwxNob{oK*x1DFUL!!ZsWCU!%(>7qfFp=5}fip023piYh}E zqkbEaj}mc0r^Ks&fCLz^#2s`N9K4BKB$3mIRHme&OPCX5~X-5+s-KuvF6V*M+dN3ddd+cZ@To1b^o2Pnz)KK!=Q2p96e)CkT zSr!xAdLyn*s>_K@yigDQd_o*ma7(2gtUe%0YLFwA6poB{C|=^Q&sWiTb?}O?<(G@!Y zPw#Cwzdsare-HnEkIyk3Sh?33-0PyI)o96@l({_-vY*hTbTr*+61PO(ia5%lbE7=` z8t>zr{N>5%J=uek58>MB)6U6X;BWWzUiT!}fNxJu!=_-A7A{V9w>GzTPAeRG?%6MV z{U6}Hc90dqs2C?n=rUq}WHmRSa2y4yd^)4>!^i0q{*Oa{k5pl_7GhrNt%qR?ChyjI zWb9vZvlT^5#W)?r*f<|glscTI)#w^IvMC1w@&07@!PfSvr7#b_rn^s1_Qzw2Of5Vq z=~fo}70rCT!KFfSi)LV6t#tT9j8|%lm`WO*aIhveW~WujqtQMvf^({D9*=kuFv?|c z@It&5*|fZW!mFRq)OEJZrNzV1>mWJ(ErB&Wa_RzoIO&Xim|mjD@yN<}{2TLao% z1HxU?>!?b)3IUeQ5O#=Ag+Sh`nj2sy>|R!>1u=FHP!@a-`$~y=?Wv4lHbHTAM)Hjf z#b%#AfrX@%8Ve8}LIrim$WZ8KDflPMiaSjfl^An>@0Q<8)lj6IMIf7m zA5v(4D-4_w--cWiH#t83W3am${Oy1L+yDCefBpM^`}=?Y+y4{%?f(w`{$Kv~Kj8O& z|NDQze}ljMufP4D@aX^e+yDIA|MmC(?Qj3%Z~wDBpP_M}I(Cp>q=U2Ua*!|0TCN(^ zH=55P!3o}lH4^T@%4NlBu6%jKH~y?jNyUgXHcKD3CqejnvO+m z+z(R&V^6sYMwGv2zi{-vYCyH(5U>8*N^@0JV2#-rquP^QBd54EWjsVEMU5|xtKNNo z4z(#|o;W}NL5DDM!sHo>7PF3X(8cy(bm+(SaAz=jxI<%$J9hUQC8!2RAd1o7dhAzu zvSPfHN1jji!-^WaVU*DF47x+ryTOxSduP+5M@7KH;Se!~N4;4x8q6mTxYj`6MM!Mj zE|B%dNpgl7yy|&e_LKge>_T%vpL%eA-aSR=4v)GTs{9I~4ipLph&`K?7{#O_QC01j zaC(Nde6Q+#;L^=ebm<`*3Cym$PHHVIE_TgV`+pj~-9P>=px~4&_`rWZBRj$! z7K29*x`U`#e5_2hIAmwVkZ}dmnwDX8!lO}vL!>-ndqGwVD3u#L#lIc@=nZNzsuN8; zcd6eRMj`1~L0a(yfySo;T0PFX)d!1;`dA;J z?Zb~)>5|1k+d^OnD=OrdS$461TzFiZR=^f($O5hEOLebx+L4=k<)9>Gg?gP=r$YF* z*$M4cXzYsQRkOF%qp%$?4|@+9G-DQ&-_lM>HVGk+kmN$~y{y1#_}Q0QFAdPqIQ9D? z#d;|tyBLt%D-cn$b%=H7s)n+5LL21QvmxW!wGMq^>%s$ zq#p*D^mmablo3)WVAbg?I^$q`*ogAUrdm3j zfRWpgwM;h88pH!tRVR%k)v**_fvX-!Qw16rP_T7^1*))DFf&49Y^3L007pQ$zi=FT zl%fq68|m9PF*pT!Nh4Bp5HWnDe+w|BW07JO#|yfXU z>k|v%ir^nk3D?yH$_i69h8rWh70i5sH{7iIqiD=egYAzWZ8pU~*wX_Je;t)klJ8qY zQ7Vv334S~Y9ETJ9AdF%VJY%~QMmcf=pQ~s>)s3ZZhL9$i-fTV|+u!k)iuRTpvyJAd$w`J*%Bg%+@abjWL$o$zOcss(%G9-kV`&CVl zRa2)7p+l!+Z8}CoM0UZTe^~PA)EZO=NT%y735*VhYO!c`6=6^%(Wq_I&>O7)>&Dw) zKgT6)-uRrr9oR5an0A3 zo6iDGYDn-lmP`;De?t|@bRYPrl>Y5{W_(^xM_0fEMMUYMLt=Fe+M1SEVCBe_#zpMJ(^wT{_*iy{ula zpp0&GSPfTgfa+O^Ggn1-8|Nzaq`Hh<`+cn=mDhPHxQE(|&Sh-g3DpbdM@$j$+ej1t za`fi43Qu|ixx%UU??l3&UdzbU{~=ENn~4)dz&Dd8u!@Z*3&=lMqNuk1A4{!P%rI7& zPM7&lUt+aPfAT-Xi#Fl~Q9KiQ+lBTy0*29sPr@)>uNE<|@BnF`@YfS!#P@gw=iqjt z1CjW@BiX?z$@5B$$^p1*JDC6!9DeA#1;(U9sPST9m5;bJp77*OaT?qygt46Jip!=w z?g#bN9FH~&tD)F@=`Gqx$k_-lR8djs9fBl=F}~4+e;J-6F&SV_!=?+$rWsmv*3(s| zk7CH$jv@M*OpyJM)z-OKjO8uYJYBbXf7-b)CoM2II1K@NX|z}AT*VN{T~rD*Uk5eA z=DI7pW^RJ=HiSVm)n1`wG|tj#B1Yl8_)UF@$}*lW$QeLXzzmd)J$lCFNQZu=thz?) znDeb&f0IxWklonY%k1oo=Ok=&!6wGQO%G*83-oB)3y-a&i4=QChpxn}GLO%aq9n5& z#r8IxfLFVg!3+%obVls=u{QYtp!u!e$IFdm&xAJm{S;1YW4?k!F;P)-PkLJzC>cdz zM;YL>B3JS5RHidn6A~~eg?0?_A;AvcNmm`nf5lcM`xcQoog0s#5t_qgcZ{fNK3^YCY)bi6(&_O@jz+uPDbL48SOg!*ty_o*czx_24ov z=uaH7@~p&VH=|74=q%CUW;*jO$JC{Gf84a~&%4;HEv1mZH+m(A!Bpf=YDNu5wC&2} z4i1d(6;#+i8`+B6YAnN(w#2u3Xry3iT#YIzm$Am`mWV7{zfNKmj8uHH)`BsHl}o@V z>jgoBZbSTb4KFMMSM?B$LN;9EMVr-S`?~Y0THr>Vr#*EMkG<5C-};;3^Me=rfA3!& z+gf>al_~Z%VU^*KPvZ7D}*e!hwKGc3d=m&st4RWdU5UeRJK-#RoC%rC7vyQB*$7L>$8QeM|`Vs9h&^TY5D>}S8nY(wJ6v21LuU?8Q_pnTsDeNZ^x@bu^ zvek-2Yf#O@QMYob`=ax%cHD0bo5fK|NbKZzg@JnCX_{(7o33X8gMQHgO`IUk>J8}MPIq9WaLMwbWA)O@y$MR~0lJcI z&TIVlE$SO5{=O z>O)?*0-&6Rp2D=Ve-bKdK-L&?im$y;J_t1o^-ewrSF9bAZ+shbrb=p=sR?k_srFRk z{{`)Tvn;z1VG?7V;Y3H>Hk2zuhIGcF;31oH#)5sojIJ#1;5svsiVlK9ltj?^@7!!g z15^qY>SU6NWU8nJqVO}^AN9~=0}cm}AW0B4WY;NY$PIDfe+jI~MtdrZ0iVI_jolG2 zEAb?oV)$7ARRLXjC{R@!dfbdbwy%|e=mxLy1zD;zQ<26*PbMF81eNBABRX^4t!GgN zYpQ@calqK@$lzAhnhrtfnpFl?rFDHD(YHG}Z0W{}yqreXHb>Ue@+#|3IT+?;oa-#J z=uZ-^Si44De>(-3t?EKe8Tw=w7n1t1tHu=uBXM#uFE$qEXfC1N7^!+Nx^Rk~@;_o) z{Q@=bEKFVts{GZw^}XMZv8o{!~%4y#ZgPuI7^J^uz{kbP+g%(qxxxuY{cdP z%}|=M5O45O4hD+ghfdBXtfo0-!xcppl$zY{;@JYDf7UKjVv>bOnXK$8Z{RTeZ5}Po zHAU3KQ_0R)Zj6f#hEet0J5`5%`BNJ3HC!pWfmA6aaS3ezJz`IE6;t+Q{~I zf?q-`e--ZHNtvZpLXGxzEu@g@x#bdq(kMqou_ZVe-@9PU_gft+t4|{f-^f`SVSt$II=79 z>;^x30Uk>DoFmkrckfzj`W>p;6p9v006m=GUn|-RZC_rNBvlxC{jtc1 zAWR`#uR3f%Ki4`Rs9=NERR*xo<8&g_;pPH19S{kV6aN`e*D;YN&$KWP&)*#HzkI0? ze`$_hLT=5IWSi8kc zF>-6?$?PSvbtz#|-?-K!DbQ3gG`OQnZC5LKB?D~Ym4fk|kb{aPSQ+j6S%y`D^|vOg zTrn*cs1q(_?1pd>L7qw(E2(eJrSS@m9Dg`g?n&V%H1K8mUXIn2FRTm%2)=H*e=Bnr zPR0W`-J()Nvn&bFbp9CTFg&60_qMZ6ev2Y1#MRZ+04jj+9nU!QX*!8N4i@JNwJ)D% zS0xClKdrOP$JPc)+X9Mfi4Y$?6!(ap)-Z`ldbS3?Ys9ZSq(8EywRgw+{Rf*n+x@M_ zk0188b~ZQrTMxeast?cC>g9rx5MN8Z(bf$Qb&eGG-YR;i)4b9+D#|5GiUroe}_lTf19nH;2Qdi zm9}=Ack>83f>z?Kubem9KL+1EHc~^ob7%IOj$b_D!7RI?1R=)MPNR7;yB<#S1Oy@Y z(t37_@p(LtXdO_{gg16j1qW{ZWZ7d(iWgMzg{Y_2uN`{Kol&Q?&z{;X&vcfsBYPfi z;$*lJJjE@+d9iwyoKg6uf2+Jo&?uqyH(<86E`yMGu2nbNA6YvXV>(#@qFc4i zlPm6QVr|~qnOM0mquo~@INV)S0PzdpR)^6;clh%8@ZEu8`}nB;@_DE>AOX$VfMk7X z``Zinjfi~3Pcbc%vS3w`u?w(GM#7-Uy2xHOzkD(lo9H?v&mEzre|Uzj2O?4iNZ>{A zSK3?uYB+FVUJAnLzyP$*%B}*%0=zFB{8e=0uM)P%H%)$H@O3$lC2*E*{%Sy@jB(~1 z41$+&8Dfae`I3&|s02adfBiDa*{0)KpyKjHg{*Cn&=3a|By9k3_Gg#)4M+XvvE7J54Z4%w zN}t^NzHXa>Y>x~LHCbpZb!rU`sCwP#PsCS4{df5K_~70Cv*SZp^v8dGdoX;p|F+7? zpJj8rQ?k$Apu3pqnI1SYQn-JX$FVLoOD{1}_fBFidoq8pxnN_G3QUT(g zE_Rv3S8kaf(4V5Y$oKH9wuF(&+DJpmvHsW*o$i-FPm*!RHPCuXVbFe&hFHHol5d?T zeO2=E!t9anRDJGr^U;*jvkoZ^uNRodrd;g>0Pqr}{M2S&B>El-4E%wd{<`GBbEy0B zjMKGvg1O%VLRspjjF%L}(rfl^z%|E*tYt+v>YNPJ0?+6s0&u~O?kSp2Tx5iv zymiUc1GLuHsIhZYcX)wmefGSpgL>woV*uyb1UkGCc2D|Sr?nW>&~MkR_*w*yq~ECM z)DZnxnP${sRlmWkva%E8vY;TH^0e7l_wxwedHC92e}y%O*!l5^SOcdN@X$CcgkQLw z7;x&F&M%cNYR_>+PO(gmOef;^sEq1X1z4e@+jX?2!s!nE0lc+L<)Xi?S;F72RFeAp ztzJ{l(N0`>@$O|!=a!uF6ace4ARnl{$pSSP0r{?kb2p8QoDPQSnFPW5lIJiRejw-$ zP$WMie`cppvaFewBP`L&WTMu_i zu_V29lPV9hp?q?kZ<_a3y~@Z8iTjsVY;zJAiJeB|3=g{&6BqfRRhovsP$r+J_7VQ+ zml*BDh2zV6RK|0;^VmC_k4;&ku$7yNqy3q0e_?}Ez-#=ZJhG&T5!E$7TPHmJ{$P<5 z=mY@AK>4+1ON;rn)SNc33UBph)+IloXa$}6jrQu#+@UH)0T2BoD9XI%B0efs;69(H z;pbBg4uohSHzvV%nf%Q0`e#6*(Y$eB*78=utTV%Gil z4=R6eL2Wf;qG3`r&&rh1trv4QQY0fk@THiY`_Jx*lTay>fzSh+Z+ylWf9QuN zNI%^klE0)98T!!aT=arVHpJq$KsX)`5ToK+%%y!ThQQSLI-MtzNsO+Ui)C4K9P&A?%fS?mx6y3I zCed!^YkEhnPEWdF#iD_qs4R2Ze>Ma@@pm#>mT}Rc%6{DvzNyZOmsX$(wIPHUo@0^e z7M2f<4TlX_nJ1-h)qBAT$4(Y0p-H~SXH}#}9wnM|J?1Kn+5l^c*wp~9 zH)BPY?yRDw;SeLW*c8Otae9HuXlM55-sEZ<4v|99{Thq2(_1o;{%+_Ve}~WRK0(hn zEb(M;5Azt&SJaxw#x0P-6vP>-=4LTz6r$(;>&wmBm} zb@kW+$au-+eHX@@AP#uvgZY@K1Amw4By`S=Q%ZN`gSsBgQCEy%G2#GD;~cwu zo^X0=%=R(CE1=ORXR?C7f1L!K884kkxa+Drhz*W>K?$wtnrcy@R66?0H8myRQ?aXz z9RFbR<)!{JYn1rgFtIa;;!)mN93~zfGcDufy?&_?9tluRK$*U_&m@uW^zk z;-^}a@68^sgB<+=iA9_>)UzskHOkj2pe>l2mDdUxV!ol1C*gEwirdL_XC9vJBH_IT z{9MNvU46ls5&Y*Uf8A6c+8R7?N0*h^IGdSc<0ri3X!?=QVF^?r4DAsy9t33SJ?fIM z`=nC>%H;X$Lw~HYIEi^#Ead!c4z{YaDwjF>1&xJZh3C+a&=M^tNk*Y?n$Qloc;H2R z<0V7}Fq~3&QsxSE;{2O;&kx?AJu-|UytEk37x(GU4uWr zpsX+^81vx`U|l-BsmNO^AxKk-0YpE#0UTk;F~F!NZJ@YYmoHak+4$ZTN2m4TX>A{T zgkC?3i^85j{(TEN7)A?BA?qavMLf) z13ZOvK&sy}MSSzn#yQ+-PHmnzh}bjVaY{Tq*`)&qrGc*UtXVW4O(Kxz#lDghLpW$B z6S~#l7h{DuUze>wb*qf$dw8rh&xCZmZHrt+sL+LZCW*(_tVQB8(r~iGOi-8?RN__E z-gPEue<*^L6|tG2a+xMSEmh^}Wv==|Ee=g!OdTq9L!M)lemRIH6XW#cmbCjcfc1m7 z#ikXCV*;>C8{}rqxQZcd`t9*d@;sO^n(YX0+6k~4xQzgkK{wtbX?)i>!mI}`@ajf( zC7e40Oznl)zB)%;yunq-%uLixS3iNU&D8UufA9e3lZ5YOL2vz@fL6MpiloBh6JeTF zfKmrr;WJ#ncoYZPM<)pkcnTP-gi`hfv#~lLL>pVr;z?}e8r&&tuQIcXG=mh*VgMcD z5E?bHGjyO(@1myYsXQ*^eMw4l0&{zjEHH(xlUo+Y?Xet*vDzN8^aAxtnl>rB6O)Z6 zfBI=~kWl8oHJb4?obENA-!&&rn7k7o7KV&gIB|A7LY*L07uRhhaF`9chNdFNR89}# zSh{O@rhC?ou_VO`sw(Pm`8D0sg!fKyYgOQSs8AF)RJqxh-ILDP6*X6QIE*1RQuMzG*vzvk)kJm{azr=QuFJ`+k1kTzKncrH+@H)g64*uKV&mcV)`NBWE_}-S zTiaV-ZSHLE?AQzRGtyJo0r=#se>5iDIH`unFz*hSlUTiwxi*VJ@gH@_nH-gbkiZD1CHm7W+ zn_b@YlEEt6pW!B?Rc{fM7%nc6ZHqCGf7Q1W{vyQ4 z6s2&eOREiLW@Brx`Dt<4-yUq*chxm4*FY5ho=hgHzyRGBoe&faBiVCmN~iDNhg~<` zn}~K>14+(5Is1DY0X$RTJ?|(&z69Dz$g?d3tQh+sUC2!-;i`jJG^aP?mMYt*MQj={ zcl`|B=*_m-o6qXewx>tyf5AI8ye(5@1qq(NdqtWZavA0J*yaXpU`AYV?9woD6i+Fb z(=B-WqX%Ez?+$7ZE{?pwQSxg{WXl(%J4T`Q*cCKkof<8yqak+4r$3B=C4VZGU~Cbi zEGvNoqlJt){SjEj`7mZKQOE61n#n~0Jp`DjbZ(qVyR;J|AXIP3e{ChKz1GV%AU6`_ z9K*uyZUUUwP!l=@|z4Md>D@JorE$Fja1AtJ`=)&?x_QR9Rsa>ZISL1tcB6T zC<`s!XjK6kQ98xE*bWS+8%Oj0EWU(U(R7FtPZ>OlxO85!@JiB&o0xnZb<`LRZ-#ez zN%|-ToJI>yMa0#%wgx*K5L!Ig!HD25c3x3e-EGU^4Yh|(f1VcRH(oRSdhmyH=rSuO z$~>Da$1xe)VXCGV%^Xg>YOcNrE9kt9um!(U-F^UIxFOb_*--4g?dEK~OPwy@J=Foc744 znI)?p$Pyl?xJoC<6qo5N<^yes;TWS)f>uBLfs1seT!oNb1*7XgC^9`h9P6@^q^^bm zYh_oZER49~@?*|G&DEQdeP?#&HEYQ@N~vSMPrXrlf0+60j)~^yW=BRp5wntje5(Cy znO0&1$19ngf#pd|wsB2i5Ng0qvbYczKB+#?&~+e;zbap2&>;FJ z5OALl5QcDRH&Kb!z!V%7Rv*#BuCkvXq1Hf^{Y}b2@I%a@OUK#b8ndF26fM>X!lmfI z=(*?beOnVaU^6pZ5x7WKG)e5XxZ+eZ@EvVJhZaQ-A);bLt zYr%I2=g4PB4ip8C-$|V#J|?;Yl*)`zu9mSzxhF%e*oR4zDr$~6iZny)PQx%#BpZ7(j!O)n?*_cZ?HCnn)xh+o`J{ex(rwx70oR;MO7>5CD_AL`z=<1y#~Alj2A=J5B_xA|5N|P{-2Ke&tC14R$q3UynETo@M0Dff9Jve z7_(Zgq5voKrfA{l;OOY^&FlUj5B|J6xcl_|yTiS;;$niwVvVXUH@N^_g~_1vw=+k) zUZu}>o(ftMMx^DgbIf15DjRRm2I$|?v4f9x-!w9JY=1u&-*4Ii;EeCPI-0c?A4L#6xH_V$(u z;QoyPJbJu+-yG!+D!VBjnvA&qa-K*tM+cyJgb8(3I>I72+3E#5gZqOWL-D&FB!hTh z6rzxMd|eg@Q|C|NGa=sa4&JbPOh&FW$cYVTe59+kdH>W3>W5^8f&Yl}f3c1Opk2#T zodJ+?OHg7Nf{ZF3z>@Bcwu%&Hh`<+FUM^EOcg?PQE+)_}h~0>zBEdUj7_1~cThc{j zfjVrU%$Kw&$| z$pmO%6wC3Q-7zKOC?YE;f1=&yVCysxyy1BN-M0tF&);Kw&Nr{IDa87_gMWR0`0n62 zM`i(V*R|6~t$I3F83e{~yuw>@<_uzbuw2~D8<#F<%3w|^ETA}mhH1jT@bOT46je@Y z!&S*dh{U{1t~MrPkZKUSRCW#&u<@qNDo<;>4^ZiUT2aVw|#G@a?-d z@89+hpA(H?3i=?*V?~_R=0#998YxK);vzD=WCa8Q#+X6IBiV}c7~Atl@9XHssAsZ0 zc1*C--ph|Ca34ETYRr+CcLEYE>{_y$18#M9lzkh!C#&=Q2 z(~F7;fJYBPLUr&B3V+jTbyC%MAs?X|{2e9H*|Ss^P+}TfHmKTUqY_t_RprIB5+zf9 zYL21uVU1&p-~(F7>1f4&O$}FXQOiQ8w7j!}CG~u~+<*P;PW%0D4}6~MRIP!p(EA(k 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

y8MGgb)cVo*;$l3Aj%g1M=WIXh~ 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', media_sequence) decrypt_info['KEY'] = decrypt_info.get('KEY') or self.ydl.urlopen( - self._prepare_url(info_dict, decrypt_info['URI'])).read() + self._prepare_url(info_dict, info_dict.get('_decryption_key_url') or decrypt_info['URI'])).read() frag_content = AES.new( decrypt_info['KEY'], AES.MODE_CBC, iv).decrypt(frag_content) self._append_fragment(ctx, frag_content) diff --git a/youtube_dl/extractor/abcotvs.py b/youtube_dl/extractor/abcotvs.py index 03b92a3..0bc69a6 100644 --- a/youtube_dl/extractor/abcotvs.py +++ b/youtube_dl/extractor/abcotvs.py @@ -4,29 +4,30 @@ from __future__ import unicode_literals import re from .common import InfoExtractor +from ..compat import compat_str from ..utils import ( + dict_get, int_or_none, - parse_iso8601, + try_get, ) class ABCOTVSIE(InfoExtractor): IE_NAME = 'abcotvs' IE_DESC = 'ABC Owned Television Stations' - _VALID_URL = r'https?://(?:abc(?:7(?:news|ny|chicago)?|11|13|30)|6abc)\.com(?:/[^/]+/(?P[^/]+))?/(?P\d+)' + _VALID_URL = r'https?://(?Pabc(?:7(?:news|ny|chicago)?|11|13|30)|6abc)\.com(?:(?:/[^/]+)*/(?P[^/]+))?/(?P\d+)' _TESTS = [ { 'url': 'http://abc7news.com/entertainment/east-bay-museum-celebrates-vintage-synthesizers/472581/', 'info_dict': { - 'id': '472581', + 'id': '472548', 'display_id': 'east-bay-museum-celebrates-vintage-synthesizers', 'ext': 'mp4', - 'title': 'East Bay museum celebrates vintage synthesizers', + 'title': 'East Bay museum celebrates synthesized music', 'description': 'md5:24ed2bd527096ec2a5c67b9d5a9005f3', 'thumbnail': r're:^https?://.*\.jpg$', - 'timestamp': 1421123075, + 'timestamp': 1421118520, 'upload_date': '20150113', - 'uploader': 'Jonathan Bloom', }, 'params': { # m3u8 download @@ -37,39 +38,63 @@ class ABCOTVSIE(InfoExtractor): 'url': 'http://abc7news.com/472581', 'only_matching': True, }, + { + 'url': 'https://6abc.com/man-75-killed-after-being-struck-by-vehicle-in-chester/5725182/', + 'only_matching': True, + }, ] + _SITE_MAP = { + '6abc': 'wpvi', + 'abc11': 'wtvd', + 'abc13': 'ktrk', + 'abc30': 'kfsn', + 'abc7': 'kabc', + 'abc7chicago': 'wls', + 'abc7news': 'kgo', + 'abc7ny': 'wabc', + } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') - display_id = mobj.group('display_id') or video_id - - webpage = self._download_webpage(url, display_id) + site, display_id, video_id = re.match(self._VALID_URL, url).groups() + display_id = display_id or video_id + station = self._SITE_MAP[site] - m3u8 = self._html_search_meta( - 'contentURL', webpage, 'm3u8 url', fatal=True).split('?')[0] + data = self._download_json( + 'https://api.abcotvs.com/v2/content', display_id, query={ + 'id': video_id, + 'key': 'otv.web.%s.story' % station, + 'station': station, + })['data'] + video = try_get(data, lambda x: x['featuredMedia']['video'], dict) or data + video_id = compat_str(dict_get(video, ('id', 'publishedKey'), video_id)) + title = video.get('title') or video['linkText'] - formats = self._extract_m3u8_formats(m3u8, display_id, 'mp4') + formats = [] + m3u8_url = video.get('m3u8') + if m3u8_url: + formats = self._extract_m3u8_formats( + video['m3u8'].split('?')[0], display_id, 'mp4', m3u8_id='hls', fatal=False) + mp4_url = video.get('mp4') + if mp4_url: + formats.append({ + 'abr': 128, + 'format_id': 'https', + 'height': 360, + 'url': mp4_url, + 'width': 640, + }) self._sort_formats(formats) - title = self._og_search_title(webpage).strip() - description = self._og_search_description(webpage).strip() - thumbnail = self._og_search_thumbnail(webpage) - timestamp = parse_iso8601(self._search_regex( - r'

\s*', - webpage, 'uploader', default=None) + image = video.get('image') or {} return { 'id': video_id, 'display_id': display_id, 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'timestamp': timestamp, - 'uploader': uploader, + 'description': dict_get(video, ('description', 'caption'), try_get(video, lambda x: x['meta']['description'])), + 'thumbnail': dict_get(image, ('source', 'dynamicSource')), + 'timestamp': int_or_none(video.get('date')), + 'duration': int_or_none(video.get('length')), 'formats': formats, } diff --git a/youtube_dl/extractor/addanime.py b/youtube_dl/extractor/addanime.py deleted file mode 100644 index 5e7c072..0000000 --- a/youtube_dl/extractor/addanime.py +++ /dev/null @@ -1,95 +0,0 @@ -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..compat import ( - compat_HTTPError, - compat_str, - compat_urllib_parse_urlencode, - compat_urllib_parse_urlparse, -) -from ..utils import ( - ExtractorError, - qualities, -) - - -class AddAnimeIE(InfoExtractor): - _VALID_URL = r'https?://(?:\w+\.)?add-anime\.net/(?:watch_video\.php\?(?:.*?)v=|video/)(?P[\w_]+)' - _TESTS = [{ - 'url': 'http://www.add-anime.net/watch_video.php?v=24MR3YO5SAS9', - 'md5': '72954ea10bc979ab5e2eb288b21425a0', - 'info_dict': { - 'id': '24MR3YO5SAS9', - 'ext': 'mp4', - 'description': 'One Piece 606', - 'title': 'One Piece 606', - }, - 'skip': 'Video is gone', - }, { - 'url': 'http://add-anime.net/video/MDUGWYKNGBD8/One-Piece-687', - 'only_matching': True, - }] - - def _real_extract(self, url): - video_id = self._match_id(url) - - try: - webpage = self._download_webpage(url, video_id) - except ExtractorError as ee: - if not isinstance(ee.cause, compat_HTTPError) or \ - ee.cause.code != 503: - raise - - redir_webpage = ee.cause.read().decode('utf-8') - action = self._search_regex( - r'
', - redir_webpage, 'redirect vc value') - av = re.search( - r'a\.value = ([0-9]+)[+]([0-9]+)[*]([0-9]+);', - redir_webpage) - if av is None: - raise ExtractorError('Cannot find redirect math task') - av_res = int(av.group(1)) + int(av.group(2)) * int(av.group(3)) - - parsed_url = compat_urllib_parse_urlparse(url) - av_val = av_res + len(parsed_url.netloc) - confirm_url = ( - parsed_url.scheme + '://' + parsed_url.netloc - + action + '?' - + compat_urllib_parse_urlencode({ - 'jschl_vc': vc, 'jschl_answer': compat_str(av_val)})) - self._download_webpage( - confirm_url, video_id, - note='Confirming after redirect') - webpage = self._download_webpage(url, video_id) - - FORMATS = ('normal', 'hq') - quality = qualities(FORMATS) - formats = [] - for format_id in FORMATS: - rex = r"var %s_video_file = '(.*?)';" % re.escape(format_id) - video_url = self._search_regex(rex, webpage, 'video file URLx', - fatal=False) - if not video_url: - continue - formats.append({ - 'format_id': format_id, - 'url': video_url, - 'quality': quality(format_id), - }) - self._sort_formats(formats) - video_title = self._og_search_title(webpage) - video_description = self._og_search_description(webpage) - - return { - '_type': 'video', - 'id': video_id, - 'formats': formats, - 'title': video_title, - 'description': video_description - } diff --git a/youtube_dl/extractor/adobetv.py b/youtube_dl/extractor/adobetv.py index 008c98e..80060f0 100644 --- a/youtube_dl/extractor/adobetv.py +++ b/youtube_dl/extractor/adobetv.py @@ -1,25 +1,119 @@ from __future__ import unicode_literals +import functools import re from .common import InfoExtractor from ..compat import compat_str from ..utils import ( - parse_duration, - unified_strdate, - str_to_int, - int_or_none, float_or_none, + int_or_none, ISO639Utils, - determine_ext, + OnDemandPagedList, + parse_duration, + str_or_none, + str_to_int, + unified_strdate, ) class AdobeTVBaseIE(InfoExtractor): - _API_BASE_URL = 'http://tv.adobe.com/api/v4/' + def _call_api(self, path, video_id, query, note=None): + return self._download_json( + 'http://tv.adobe.com/api/v4/' + path, + video_id, note, query=query)['data'] + + def _parse_subtitles(self, video_data, url_key): + subtitles = {} + for translation in video_data.get('translations', []): + vtt_path = translation.get(url_key) + if not vtt_path: + continue + lang = translation.get('language_w3c') or ISO639Utils.long2short(translation['language_medium']) + subtitles.setdefault(lang, []).append({ + 'ext': 'vtt', + 'url': vtt_path, + }) + return subtitles + + def _parse_video_data(self, video_data): + video_id = compat_str(video_data['id']) + title = video_data['title'] + + s3_extracted = False + formats = [] + for source in video_data.get('videos', []): + source_url = source.get('url') + if not source_url: + continue + f = { + 'format_id': source.get('quality_level'), + 'fps': int_or_none(source.get('frame_rate')), + 'height': int_or_none(source.get('height')), + 'tbr': int_or_none(source.get('video_data_rate')), + 'width': int_or_none(source.get('width')), + 'url': source_url, + } + original_filename = source.get('original_filename') + if original_filename: + if not (f.get('height') and f.get('width')): + mobj = re.search(r'_(\d+)x(\d+)', original_filename) + if mobj: + f.update({ + 'height': int(mobj.group(2)), + 'width': int(mobj.group(1)), + }) + if original_filename.startswith('s3://') and not s3_extracted: + formats.append({ + 'format_id': 'original', + 'preference': 1, + 'url': original_filename.replace('s3://', 'https://s3.amazonaws.com/'), + }) + s3_extracted = True + formats.append(f) + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'description': video_data.get('description'), + 'thumbnail': video_data.get('thumbnail'), + 'upload_date': unified_strdate(video_data.get('start_date')), + 'duration': parse_duration(video_data.get('duration')), + 'view_count': str_to_int(video_data.get('playcount')), + 'formats': formats, + 'subtitles': self._parse_subtitles(video_data, 'vtt'), + } + + +class AdobeTVEmbedIE(AdobeTVBaseIE): + IE_NAME = 'adobetv:embed' + _VALID_URL = r'https?://tv\.adobe\.com/embed/\d+/(?P\d+)' + _TEST = { + 'url': 'https://tv.adobe.com/embed/22/4153', + 'md5': 'c8c0461bf04d54574fc2b4d07ac6783a', + 'info_dict': { + 'id': '4153', + 'ext': 'flv', + 'title': 'Creating Graphics Optimized for BlackBerry', + 'description': 'md5:eac6e8dced38bdaae51cd94447927459', + 'thumbnail': r're:https?://.*\.jpg$', + 'upload_date': '20091109', + 'duration': 377, + 'view_count': int, + }, + } + + def _real_extract(self, url): + video_id = self._match_id(url) + + video_data = self._call_api( + 'episode/' + video_id, video_id, {'disclosure': 'standard'})[0] + return self._parse_video_data(video_data) class AdobeTVIE(AdobeTVBaseIE): + IE_NAME = 'adobetv' _VALID_URL = r'https?://tv\.adobe\.com/(?:(?Pfr|de|es|jp)/)?watch/(?P[^/]+)/(?P[^/]+)' _TEST = { @@ -42,45 +136,33 @@ class AdobeTVIE(AdobeTVBaseIE): if not language: language = 'en' - video_data = self._download_json( - self._API_BASE_URL + 'episode/get/?language=%s&show_urlname=%s&urlname=%s&disclosure=standard' % (language, show_urlname, urlname), - urlname)['data'][0] - - formats = [{ - 'url': source['url'], - 'format_id': source.get('quality_level') or source['url'].split('-')[-1].split('.')[0] or None, - 'width': int_or_none(source.get('width')), - 'height': int_or_none(source.get('height')), - 'tbr': int_or_none(source.get('video_data_rate')), - } for source in video_data['videos']] - self._sort_formats(formats) - - return { - 'id': compat_str(video_data['id']), - 'title': video_data['title'], - 'description': video_data.get('description'), - 'thumbnail': video_data.get('thumbnail'), - 'upload_date': unified_strdate(video_data.get('start_date')), - 'duration': parse_duration(video_data.get('duration')), - 'view_count': str_to_int(video_data.get('playcount')), - 'formats': formats, - } + video_data = self._call_api( + 'episode/get', urlname, { + 'disclosure': 'standard', + 'language': language, + 'show_urlname': show_urlname, + 'urlname': urlname, + })[0] + return self._parse_video_data(video_data) class AdobeTVPlaylistBaseIE(AdobeTVBaseIE): - def _parse_page_data(self, page_data): - return [self.url_result(self._get_element_url(element_data)) for element_data in page_data] + _PAGE_SIZE = 25 + + def _fetch_page(self, display_id, query, page): + page += 1 + query['page'] = page + for element_data in self._call_api( + self._RESOURCE, display_id, query, 'Download Page %d' % page): + yield self._process_data(element_data) - def _extract_playlist_entries(self, url, display_id): - page = self._download_json(url, display_id) - entries = self._parse_page_data(page['data']) - for page_num in range(2, page['paging']['pages'] + 1): - entries.extend(self._parse_page_data( - self._download_json(url + '&page=%d' % page_num, display_id)['data'])) - return entries + def _extract_playlist_entries(self, display_id, query): + return OnDemandPagedList(functools.partial( + self._fetch_page, display_id, query), self._PAGE_SIZE) class AdobeTVShowIE(AdobeTVPlaylistBaseIE): + IE_NAME = 'adobetv:show' _VALID_URL = r'https?://tv\.adobe\.com/(?:(?Pfr|de|es|jp)/)?show/(?P[^/]+)' _TEST = { @@ -92,26 +174,31 @@ class AdobeTVShowIE(AdobeTVPlaylistBaseIE): }, 'playlist_mincount': 136, } - - def _get_element_url(self, element_data): - return element_data['urls'][0] + _RESOURCE = 'episode' + _process_data = AdobeTVBaseIE._parse_video_data def _real_extract(self, url): language, show_urlname = re.match(self._VALID_URL, url).groups() if not language: language = 'en' - query = 'language=%s&show_urlname=%s' % (language, show_urlname) + query = { + 'disclosure': 'standard', + 'language': language, + 'show_urlname': show_urlname, + } - show_data = self._download_json(self._API_BASE_URL + 'show/get/?%s' % query, show_urlname)['data'][0] + show_data = self._call_api( + 'show/get', show_urlname, query)[0] return self.playlist_result( - self._extract_playlist_entries(self._API_BASE_URL + 'episode/?%s' % query, show_urlname), - compat_str(show_data['id']), - show_data['show_name'], - show_data['show_description']) + self._extract_playlist_entries(show_urlname, query), + str_or_none(show_data.get('id')), + show_data.get('show_name'), + show_data.get('show_description')) class AdobeTVChannelIE(AdobeTVPlaylistBaseIE): + IE_NAME = 'adobetv:channel' _VALID_URL = r'https?://tv\.adobe\.com/(?:(?Pfr|de|es|jp)/)?channel/(?P[^/]+)(?:/(?P[^/]+))?' _TEST = { @@ -121,24 +208,30 @@ class AdobeTVChannelIE(AdobeTVPlaylistBaseIE): }, 'playlist_mincount': 96, } + _RESOURCE = 'show' - def _get_element_url(self, element_data): - return element_data['url'] + def _process_data(self, show_data): + return self.url_result( + show_data['url'], 'AdobeTVShow', str_or_none(show_data.get('id'))) def _real_extract(self, url): language, channel_urlname, category_urlname = re.match(self._VALID_URL, url).groups() if not language: language = 'en' - query = 'language=%s&channel_urlname=%s' % (language, channel_urlname) + query = { + 'channel_urlname': channel_urlname, + 'language': language, + } if category_urlname: - query += '&category_urlname=%s' % category_urlname + query['category_urlname'] = category_urlname return self.playlist_result( - self._extract_playlist_entries(self._API_BASE_URL + 'show/?%s' % query, channel_urlname), + self._extract_playlist_entries(channel_urlname, query), channel_urlname) -class AdobeTVVideoIE(InfoExtractor): +class AdobeTVVideoIE(AdobeTVBaseIE): + IE_NAME = 'adobetv:video' _VALID_URL = r'https?://video\.tv\.adobe\.com/v/(?P\d+)' _TEST = { @@ -160,38 +253,36 @@ class AdobeTVVideoIE(InfoExtractor): video_data = self._parse_json(self._search_regex( r'var\s+bridge\s*=\s*([^;]+);', webpage, 'bridged data'), video_id) - - formats = [{ - 'format_id': '%s-%s' % (determine_ext(source['src']), source.get('height')), - 'url': source['src'], - 'width': int_or_none(source.get('width')), - 'height': int_or_none(source.get('height')), - 'tbr': int_or_none(source.get('bitrate')), - } for source in video_data['sources']] + title = video_data['title'] + + formats = [] + sources = video_data.get('sources') or [] + for source in sources: + source_src = source.get('src') + if not source_src: + continue + formats.append({ + 'filesize': int_or_none(source.get('kilobytes') or None, invscale=1000), + 'format_id': '-'.join(filter(None, [source.get('format'), source.get('label')])), + 'height': int_or_none(source.get('height') or None), + 'tbr': int_or_none(source.get('bitrate') or None), + 'width': int_or_none(source.get('width') or None), + 'url': source_src, + }) self._sort_formats(formats) # For both metadata and downloaded files the duration varies among # formats. I just pick the max one duration = max(filter(None, [ float_or_none(source.get('duration'), scale=1000) - for source in video_data['sources']])) - - subtitles = {} - for translation in video_data.get('translations', []): - lang_id = translation.get('language_w3c') or ISO639Utils.long2short(translation['language_medium']) - if lang_id not in subtitles: - subtitles[lang_id] = [] - subtitles[lang_id].append({ - 'url': translation['vttPath'], - 'ext': 'vtt', - }) + for source in sources])) return { 'id': video_id, 'formats': formats, - 'title': video_data['title'], + 'title': title, 'description': video_data.get('description'), - 'thumbnail': video_data['video'].get('poster'), + 'thumbnail': video_data.get('video', {}).get('poster'), 'duration': duration, - 'subtitles': subtitles, + 'subtitles': self._parse_subtitles(video_data, 'vttPath'), } diff --git a/youtube_dl/extractor/americastestkitchen.py b/youtube_dl/extractor/americastestkitchen.py index 8b32aa8..9c9d77a 100644 --- a/youtube_dl/extractor/americastestkitchen.py +++ b/youtube_dl/extractor/americastestkitchen.py @@ -5,6 +5,7 @@ from .common import InfoExtractor from ..utils import ( clean_html, int_or_none, + js_to_json, try_get, unified_strdate, ) @@ -13,22 +14,21 @@ from ..utils import ( class AmericasTestKitchenIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?americastestkitchen\.com/(?:episode|videos)/(?P\d+)' _TESTS = [{ - 'url': 'https://www.americastestkitchen.com/episode/548-summer-dinner-party', + 'url': 'https://www.americastestkitchen.com/episode/582-weeknight-japanese-suppers', 'md5': 'b861c3e365ac38ad319cfd509c30577f', 'info_dict': { - 'id': '1_5g5zua6e', - 'title': 'Summer Dinner Party', + 'id': '5b400b9ee338f922cb06450c', + 'title': 'Weeknight Japanese Suppers', 'ext': 'mp4', - 'description': 'md5:858d986e73a4826979b6a5d9f8f6a1ec', - 'thumbnail': r're:^https?://.*\.jpg', - 'timestamp': 1497285541, - 'upload_date': '20170612', - 'uploader_id': 'roger.metcalf@americastestkitchen.com', - 'release_date': '20170617', + 'description': 'md5:3d0c1a44bb3b27607ce82652db25b4a8', + 'thumbnail': r're:^https?://', + 'timestamp': 1523664000, + 'upload_date': '20180414', + 'release_date': '20180414', 'series': "America's Test Kitchen", - 'season_number': 17, - 'episode': 'Summer Dinner Party', - 'episode_number': 24, + 'season_number': 18, + 'episode': 'Weeknight Japanese Suppers', + 'episode_number': 15, }, 'params': { 'skip_download': True, @@ -47,7 +47,7 @@ class AmericasTestKitchenIE(InfoExtractor): self._search_regex( r'window\.__INITIAL_STATE__\s*=\s*({.+?})\s*;\s*', webpage, 'initial context'), - video_id) + video_id, js_to_json) ep_data = try_get( video_data, @@ -55,17 +55,7 @@ class AmericasTestKitchenIE(InfoExtractor): lambda x: x['videoDetail']['content']['data']), dict) ep_meta = ep_data.get('full_video', {}) - zype_id = ep_meta.get('zype_id') - if zype_id: - embed_url = 'https://player.zype.com/embed/%s.js?api_key=jZ9GUhRmxcPvX7M3SlfejB6Hle9jyHTdk2jVxG7wOHPLODgncEKVdPYBhuz9iWXQ' % zype_id - ie_key = 'Zype' - else: - partner_id = self._search_regex( - r'src=["\'](?:https?:)?//(?:[^/]+\.)kaltura\.com/(?:[^/]+/)*(?:p|partner_id)/(\d+)', - webpage, 'kaltura partner id') - external_id = ep_data.get('external_id') or ep_meta['external_id'] - embed_url = 'kaltura:%s:%s' % (partner_id, external_id) - ie_key = 'Kaltura' + zype_id = ep_data.get('zype_id') or ep_meta['zype_id'] title = ep_data.get('title') or ep_meta.get('title') description = clean_html(ep_meta.get('episode_description') or ep_data.get( @@ -79,8 +69,8 @@ class AmericasTestKitchenIE(InfoExtractor): return { '_type': 'url_transparent', - 'url': embed_url, - 'ie_key': ie_key, + 'url': 'https://player.zype.com/embed/%s.js?api_key=jZ9GUhRmxcPvX7M3SlfejB6Hle9jyHTdk2jVxG7wOHPLODgncEKVdPYBhuz9iWXQ' % zype_id, + 'ie_key': 'Zype', 'title': title, 'description': description, 'thumbnail': thumbnail, diff --git a/youtube_dl/extractor/ard.py b/youtube_dl/extractor/ard.py index 8adae46..2f47e21 100644 --- a/youtube_dl/extractor/ard.py +++ b/youtube_dl/extractor/ard.py @@ -1,6 +1,7 @@ # coding: utf-8 from __future__ import unicode_literals +import json import re from .common import InfoExtractor @@ -22,66 +23,28 @@ from ..utils import ( from ..compat import compat_etree_fromstring -class ARDMediathekIE(InfoExtractor): - IE_NAME = 'ARD:mediathek' - _VALID_URL = r'^https?://(?:(?:(?:www|classic)\.)?ardmediathek\.de|mediathek\.(?:daserste|rbb-online)\.de|one\.ard\.de)/(?:.*/)(?P[0-9]+|[^0-9][^/\?]+)[^/\?]*(?:\?.*)?' - - _TESTS = [{ - # available till 26.07.2022 - 'url': 'http://www.ardmediathek.de/tv/S%C3%9CDLICHT/Was-ist-die-Kunst-der-Zukunft-liebe-Ann/BR-Fernsehen/Video?bcastId=34633636&documentId=44726822', - 'info_dict': { - 'id': '44726822', - 'ext': 'mp4', - 'title': 'Was ist die Kunst der Zukunft, liebe Anna McCarthy?', - 'description': 'md5:4ada28b3e3b5df01647310e41f3a62f5', - 'duration': 1740, - }, - 'params': { - # m3u8 download - 'skip_download': True, - } - }, { - 'url': 'https://one.ard.de/tv/Mord-mit-Aussicht/Mord-mit-Aussicht-6-39-T%C3%B6dliche-Nach/ONE/Video?bcastId=46384294&documentId=55586872', - 'only_matching': True, - }, { - # audio - 'url': 'http://www.ardmediathek.de/tv/WDR-H%C3%B6rspiel-Speicher/Tod-eines-Fu%C3%9Fballers/WDR-3/Audio-Podcast?documentId=28488308&bcastId=23074086', - 'only_matching': True, - }, { - 'url': 'http://mediathek.daserste.de/sendungen_a-z/328454_anne-will/22429276_vertrauen-ist-gut-spionieren-ist-besser-geht', - 'only_matching': True, - }, { - # audio - 'url': 'http://mediathek.rbb-online.de/radio/Hörspiel/Vor-dem-Fest/kulturradio/Audio?documentId=30796318&topRessort=radio&bcastId=9839158', - 'only_matching': True, - }, { - 'url': 'https://classic.ardmediathek.de/tv/Panda-Gorilla-Co/Panda-Gorilla-Co-Folge-274/Das-Erste/Video?bcastId=16355486&documentId=58234698', - 'only_matching': True, - }] - - @classmethod - def suitable(cls, url): - return False if ARDBetaMediathekIE.suitable(url) else super(ARDMediathekIE, cls).suitable(url) +class ARDMediathekBaseIE(InfoExtractor): + _GEO_COUNTRIES = ['DE'] def _extract_media_info(self, media_info_url, webpage, video_id): media_info = self._download_json( media_info_url, video_id, 'Downloading media JSON') + return self._parse_media_info(media_info, video_id, '"fsk"' in webpage) + def _parse_media_info(self, media_info, video_id, fsk): formats = self._extract_formats(media_info, video_id) if not formats: - if '"fsk"' in webpage: + if fsk: raise ExtractorError( 'This video is only available after 20:00', expected=True) elif media_info.get('_geoblocked'): - raise ExtractorError('This video is not available due to geo restriction', expected=True) + self.raise_geo_restricted( + 'This video is not available due to geoblocking', + countries=self._GEO_COUNTRIES) self._sort_formats(formats) - duration = int_or_none(media_info.get('_duration')) - thumbnail = media_info.get('_previewImage') - is_live = media_info.get('_isLive') is True - subtitles = {} subtitle_url = media_info.get('_subtitleUrl') if subtitle_url: @@ -92,9 +55,9 @@ class ARDMediathekIE(InfoExtractor): return { 'id': video_id, - 'duration': duration, - 'thumbnail': thumbnail, - 'is_live': is_live, + 'duration': int_or_none(media_info.get('_duration')), + 'thumbnail': media_info.get('_previewImage'), + 'is_live': media_info.get('_isLive') is True, 'formats': formats, 'subtitles': subtitles, } @@ -123,11 +86,11 @@ class ARDMediathekIE(InfoExtractor): update_url_query(stream_url, { 'hdcore': '3.1.1', 'plugin': 'aasp-3.1.1.69.124' - }), - video_id, f4m_id='hds', fatal=False)) + }), video_id, f4m_id='hds', fatal=False)) elif ext == 'm3u8': formats.extend(self._extract_m3u8_formats( - stream_url, video_id, 'mp4', m3u8_id='hls', fatal=False)) + stream_url, video_id, 'mp4', 'm3u8_native', + m3u8_id='hls', fatal=False)) else: if server and server.startswith('rtmp'): f = { @@ -140,7 +103,9 @@ class ARDMediathekIE(InfoExtractor): 'url': stream_url, 'format_id': 'a%s-%s-%s' % (num, ext, quality) } - m = re.search(r'_(?P\d+)x(?P\d+)\.mp4$', stream_url) + m = re.search( + r'_(?P\d+)x(?P\d+)\.mp4$', + stream_url) if m: f.update({ 'width': int(m.group('width')), @@ -151,6 +116,48 @@ class ARDMediathekIE(InfoExtractor): formats.append(f) return formats + +class ARDMediathekIE(ARDMediathekBaseIE): + IE_NAME = 'ARD:mediathek' + _VALID_URL = r'^https?://(?:(?:(?:www|classic)\.)?ardmediathek\.de|mediathek\.(?:daserste|rbb-online)\.de|one\.ard\.de)/(?:.*/)(?P[0-9]+|[^0-9][^/\?]+)[^/\?]*(?:\?.*)?' + + _TESTS = [{ + # available till 26.07.2022 + 'url': 'http://www.ardmediathek.de/tv/S%C3%9CDLICHT/Was-ist-die-Kunst-der-Zukunft-liebe-Ann/BR-Fernsehen/Video?bcastId=34633636&documentId=44726822', + 'info_dict': { + 'id': '44726822', + 'ext': 'mp4', + 'title': 'Was ist die Kunst der Zukunft, liebe Anna McCarthy?', + 'description': 'md5:4ada28b3e3b5df01647310e41f3a62f5', + 'duration': 1740, + }, + 'params': { + # m3u8 download + 'skip_download': True, + } + }, { + 'url': 'https://one.ard.de/tv/Mord-mit-Aussicht/Mord-mit-Aussicht-6-39-T%C3%B6dliche-Nach/ONE/Video?bcastId=46384294&documentId=55586872', + 'only_matching': True, + }, { + # audio + 'url': 'http://www.ardmediathek.de/tv/WDR-H%C3%B6rspiel-Speicher/Tod-eines-Fu%C3%9Fballers/WDR-3/Audio-Podcast?documentId=28488308&bcastId=23074086', + 'only_matching': True, + }, { + 'url': 'http://mediathek.daserste.de/sendungen_a-z/328454_anne-will/22429276_vertrauen-ist-gut-spionieren-ist-besser-geht', + 'only_matching': True, + }, { + # audio + 'url': 'http://mediathek.rbb-online.de/radio/Hörspiel/Vor-dem-Fest/kulturradio/Audio?documentId=30796318&topRessort=radio&bcastId=9839158', + 'only_matching': True, + }, { + 'url': 'https://classic.ardmediathek.de/tv/Panda-Gorilla-Co/Panda-Gorilla-Co-Folge-274/Das-Erste/Video?bcastId=16355486&documentId=58234698', + 'only_matching': True, + }] + + @classmethod + def suitable(cls, url): + return False if ARDBetaMediathekIE.suitable(url) else super(ARDMediathekIE, cls).suitable(url) + def _real_extract(self, url): # determine video id from url m = re.match(self._VALID_URL, url) @@ -302,19 +309,20 @@ class ARDIE(InfoExtractor): } -class ARDBetaMediathekIE(InfoExtractor): - _VALID_URL = r'https://(?:beta|www)\.ardmediathek\.de/[^/]+/(?:player|live)/(?P[a-zA-Z0-9]+)(?:/(?P[^/?#]+))?' +class ARDBetaMediathekIE(ARDMediathekBaseIE): + _VALID_URL = r'https://(?:beta|www)\.ardmediathek\.de/(?P[^/]+)/(?:player|live)/(?P[a-zA-Z0-9]+)(?:/(?P[^/?#]+))?' _TESTS = [{ 'url': 'https://beta.ardmediathek.de/ard/player/Y3JpZDovL2Rhc2Vyc3RlLmRlL3RhdG9ydC9mYmM4NGM1NC0xNzU4LTRmZGYtYWFhZS0wYzcyZTIxNGEyMDE/die-robuste-roswita', - 'md5': '2d02d996156ea3c397cfc5036b5d7f8f', + 'md5': 'dfdc87d2e7e09d073d5a80770a9ce88f', 'info_dict': { 'display_id': 'die-robuste-roswita', - 'id': 'Y3JpZDovL2Rhc2Vyc3RlLmRlL3RhdG9ydC9mYmM4NGM1NC0xNzU4LTRmZGYtYWFhZS0wYzcyZTIxNGEyMDE', - 'title': 'Tatort: Die robuste Roswita', + 'id': '70153354', + 'title': 'Die robuste Roswita', 'description': r're:^Der Mord.*trüber ist als die Ilm.', 'duration': 5316, - 'thumbnail': 'https://img.ardmediathek.de/standard/00/55/43/59/34/-1774185891/16x9/960?mandant=ard', - 'upload_date': '20180826', + 'thumbnail': 'https://img.ardmediathek.de/standard/00/70/15/33/90/-1852531467/16x9/960?mandant=ard', + 'timestamp': 1577047500, + 'upload_date': '20191222', 'ext': 'mp4', }, }, { @@ -330,71 +338,69 @@ class ARDBetaMediathekIE(InfoExtractor): video_id = mobj.group('video_id') display_id = mobj.group('display_id') or video_id - webpage = self._download_webpage(url, display_id) - data_json = self._search_regex(r'window\.__APOLLO_STATE__\s*=\s*(\{.*);\n', webpage, 'json') - data = self._parse_json(data_json, display_id) - - res = { - 'id': video_id, - 'display_id': display_id, + player_page = self._download_json( + 'https://api.ardmediathek.de/public-gateway', + display_id, data=json.dumps({ + 'query': '''{ + playerPage(client:"%s", clipId: "%s") { + blockedByFsk + broadcastedOn + maturityContentRating + mediaCollection { + _duration + _geoblocked + _isLive + _mediaArray { + _mediaStreamArray { + _quality + _server + _stream } - formats = [] - subtitles = {} - geoblocked = False - for widget in data.values(): - if widget.get('_geoblocked') is True: - geoblocked = True - if '_duration' in widget: - res['duration'] = int_or_none(widget['_duration']) - if 'clipTitle' in widget: - res['title'] = widget['clipTitle'] - if '_previewImage' in widget: - res['thumbnail'] = widget['_previewImage'] - if 'broadcastedOn' in widget: - res['timestamp'] = unified_timestamp(widget['broadcastedOn']) - if 'synopsis' in widget: - res['description'] = widget['synopsis'] - subtitle_url = url_or_none(widget.get('_subtitleUrl')) - if subtitle_url: - subtitles.setdefault('de', []).append({ - 'ext': 'ttml', - 'url': subtitle_url, - }) - if '_quality' in widget: - format_url = url_or_none(try_get( - widget, lambda x: x['_stream']['json'][0])) - if not format_url: - continue - ext = determine_ext(format_url) - if ext == 'f4m': - formats.extend(self._extract_f4m_formats( - format_url + '?hdcore=3.11.0', - video_id, f4m_id='hds', fatal=False)) - elif ext == 'm3u8': - formats.extend(self._extract_m3u8_formats( - format_url, video_id, 'mp4', m3u8_id='hls', - fatal=False)) - else: - # HTTP formats are not available when geoblocked is True, - # other formats are fine though - if geoblocked: - continue - quality = str_or_none(widget.get('_quality')) - formats.append({ - 'format_id': ('http-' + quality) if quality else 'http', - 'url': format_url, - 'preference': 10, # Plain HTTP, that's nice - }) - - if not formats and geoblocked: - self.raise_geo_restricted( - msg='This video is not available due to geoblocking', - countries=['DE']) - - self._sort_formats(formats) - res.update({ - 'subtitles': subtitles, - 'formats': formats, + } + _previewImage + _subtitleUrl + _type + } + show { + title + } + synopsis + title + tracking { + atiCustomVars { + contentId + } + } + } +}''' % (mobj.group('client'), video_id), + }).encode(), headers={ + 'Content-Type': 'application/json' + })['data']['playerPage'] + title = player_page['title'] + content_id = str_or_none(try_get( + player_page, lambda x: x['tracking']['atiCustomVars']['contentId'])) + media_collection = player_page.get('mediaCollection') or {} + if not media_collection and content_id: + media_collection = self._download_json( + 'https://www.ardmediathek.de/play/media/' + content_id, + content_id, fatal=False) or {} + info = self._parse_media_info( + media_collection, content_id or video_id, + player_page.get('blockedByFsk')) + age_limit = None + description = player_page.get('synopsis') + maturity_content_rating = player_page.get('maturityContentRating') + if maturity_content_rating: + age_limit = int_or_none(maturity_content_rating.lstrip('FSK')) + if not age_limit and description: + age_limit = int_or_none(self._search_regex( + r'\(FSK\s*(\d+)\)\s*$', description, 'age limit', default=None)) + info.update({ + 'age_limit': age_limit, + 'display_id': display_id, + 'title': title, + 'description': description, + 'timestamp': unified_timestamp(player_page.get('broadcastedOn')), + 'series': try_get(player_page, lambda x: x['show']['title']), }) - - return res + return info diff --git a/youtube_dl/extractor/atresplayer.py b/youtube_dl/extractor/atresplayer.py index ae1c094..c2cec98 100644 --- a/youtube_dl/extractor/atresplayer.py +++ b/youtube_dl/extractor/atresplayer.py @@ -1,202 +1,118 @@ +# coding: utf-8 from __future__ import unicode_literals -import time -import hmac -import hashlib import re from .common import InfoExtractor -from ..compat import compat_str +from ..compat import compat_HTTPError from ..utils import ( ExtractorError, - float_or_none, int_or_none, - sanitized_Request, urlencode_postdata, - xpath_text, ) class AtresPlayerIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?atresplayer\.com/television/[^/]+/[^/]+/[^/]+/(?P.+?)_\d+\.html' + _VALID_URL = r'https?://(?:www\.)?atresplayer\.com/[^/]+/[^/]+/[^/]+/[^/]+/(?P.+?)_(?P[0-9a-f]{24})' _NETRC_MACHINE = 'atresplayer' _TESTS = [ { - 'url': 'http://www.atresplayer.com/television/programas/el-club-de-la-comedia/temporada-4/capitulo-10-especial-solidario-nochebuena_2014122100174.html', - 'md5': 'efd56753cda1bb64df52a3074f62e38a', + 'url': 'https://www.atresplayer.com/antena3/series/pequenas-coincidencias/temporada-1/capitulo-7-asuntos-pendientes_5d4aa2c57ed1a88fc715a615/', 'info_dict': { - 'id': 'capitulo-10-especial-solidario-nochebuena', + 'id': '5d4aa2c57ed1a88fc715a615', 'ext': 'mp4', - 'title': 'Especial Solidario de Nochebuena', - 'description': 'md5:e2d52ff12214fa937107d21064075bf1', - 'duration': 5527.6, - 'thumbnail': r're:^https?://.*\.jpg$', + 'title': 'Capítulo 7: Asuntos pendientes', + 'description': 'md5:7634cdcb4d50d5381bedf93efb537fbc', + 'duration': 3413, + }, + 'params': { + 'format': 'bestvideo', }, 'skip': 'This video is only available for registered users' }, { - 'url': 'http://www.atresplayer.com/television/especial/videoencuentros/temporada-1/capitulo-112-david-bustamante_2014121600375.html', - 'md5': '6e52cbb513c405e403dbacb7aacf8747', - 'info_dict': { - 'id': 'capitulo-112-david-bustamante', - 'ext': 'flv', - 'title': 'David Bustamante', - 'description': 'md5:f33f1c0a05be57f6708d4dd83a3b81c6', - 'duration': 1439.0, - 'thumbnail': r're:^https?://.*\.jpg$', - }, + 'url': 'https://www.atresplayer.com/lasexta/programas/el-club-de-la-comedia/temporada-4/capitulo-10-especial-solidario-nochebuena_5ad08edf986b2855ed47adc4/', + 'only_matching': True, }, { - 'url': 'http://www.atresplayer.com/television/series/el-secreto-de-puente-viejo/el-chico-de-los-tres-lunares/capitulo-977-29-12-14_2014122400174.html', + 'url': 'https://www.atresplayer.com/antena3/series/el-secreto-de-puente-viejo/el-chico-de-los-tres-lunares/capitulo-977-29-12-14_5ad51046986b2886722ccdea/', 'only_matching': True, }, ] - - _USER_AGENT = 'Dalvik/1.6.0 (Linux; U; Android 4.3; GT-I9300 Build/JSS15J' - _MAGIC = 'QWtMLXs414Yo+c#_+Q#K@NN)' - _TIMESTAMP_SHIFT = 30000 - - _TIME_API_URL = 'http://servicios.atresplayer.com/api/admin/time.json' - _URL_VIDEO_TEMPLATE = 'https://servicios.atresplayer.com/api/urlVideo/{1}/{0}/{1}|{2}|{3}.json' - _PLAYER_URL_TEMPLATE = 'https://servicios.atresplayer.com/episode/getplayer.json?episodePk=%s' - _EPISODE_URL_TEMPLATE = 'http://www.atresplayer.com/episodexml/%s' - - _LOGIN_URL = 'https://servicios.atresplayer.com/j_spring_security_check' - - _ERRORS = { - 'UNPUBLISHED': 'We\'re sorry, but this video is not yet available.', - 'DELETED': 'This video has expired and is no longer available for online streaming.', - 'GEOUNPUBLISHED': 'We\'re sorry, but this video is not available in your region due to right restrictions.', - # 'PREMIUM': 'PREMIUM', - } + _API_BASE = 'https://api.atresplayer.com/' def _real_initialize(self): self._login() + def _handle_error(self, e, code): + if isinstance(e.cause, compat_HTTPError) and e.cause.code == code: + error = self._parse_json(e.cause.read(), None) + if error.get('error') == 'required_registered': + self.raise_login_required() + raise ExtractorError(error['error_description'], expected=True) + raise + def _login(self): username, password = self._get_login_info() if username is None: return - login_form = { - 'j_username': username, - 'j_password': password, - } + self._request_webpage( + self._API_BASE + 'login', None, 'Downloading login page') - request = sanitized_Request( - self._LOGIN_URL, urlencode_postdata(login_form)) - request.add_header('Content-Type', 'application/x-www-form-urlencoded') - response = self._download_webpage( - request, None, 'Logging in') + try: + target_url = self._download_json( + 'https://account.atresmedia.com/api/login', None, + 'Logging in', headers={ + 'Content-Type': 'application/x-www-form-urlencoded' + }, data=urlencode_postdata({ + 'username': username, + 'password': password, + }))['targetUrl'] + except ExtractorError as e: + self._handle_error(e, 400) - error = self._html_search_regex( - r'(?s)]+class="[^"]*\blist_error\b[^"]*">(.+?)', - response, 'error', default=None) - if error: - raise ExtractorError( - 'Unable to login: %s' % error, expected=True) + self._request_webpage(target_url, None, 'Following Target URL') def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) + display_id, video_id = re.match(self._VALID_URL, url).groups() - episode_id = self._search_regex( - r'episode="([^"]+)"', webpage, 'episode id') + try: + episode = self._download_json( + self._API_BASE + 'client/v1/player/episode/' + video_id, video_id) + except ExtractorError as e: + self._handle_error(e, 403) - request = sanitized_Request( - self._PLAYER_URL_TEMPLATE % episode_id, - headers={'User-Agent': self._USER_AGENT}) - player = self._download_json(request, episode_id, 'Downloading player JSON') - - episode_type = player.get('typeOfEpisode') - error_message = self._ERRORS.get(episode_type) - if error_message: - raise ExtractorError( - '%s returned error: %s' % (self.IE_NAME, error_message), expected=True) + title = episode['titulo'] formats = [] - video_url = player.get('urlVideo') - if video_url: - format_info = { - 'url': video_url, - 'format_id': 'http', - } - mobj = re.search(r'(?P\d+)K_(?P\d+)x(?P\d+)', video_url) - if mobj: - format_info.update({ - 'width': int_or_none(mobj.group('width')), - 'height': int_or_none(mobj.group('height')), - 'tbr': int_or_none(mobj.group('bitrate')), - }) - formats.append(format_info) - - timestamp = int_or_none(self._download_webpage( - self._TIME_API_URL, - video_id, 'Downloading timestamp', fatal=False), 1000, time.time()) - timestamp_shifted = compat_str(timestamp + self._TIMESTAMP_SHIFT) - token = hmac.new( - self._MAGIC.encode('ascii'), - (episode_id + timestamp_shifted).encode('utf-8'), hashlib.md5 - ).hexdigest() - - request = sanitized_Request( - self._URL_VIDEO_TEMPLATE.format('windows', episode_id, timestamp_shifted, token), - headers={'User-Agent': self._USER_AGENT}) - - fmt_json = self._download_json( - request, video_id, 'Downloading windows video JSON') - - result = fmt_json.get('resultDes') - if result.lower() != 'ok': - raise ExtractorError( - '%s returned error: %s' % (self.IE_NAME, result), expected=True) - - for format_id, video_url in fmt_json['resultObject'].items(): - if format_id == 'token' or not video_url.startswith('http'): - continue - if 'geodeswowsmpra3player' in video_url: - # f4m_path = video_url.split('smil:', 1)[-1].split('free_', 1)[0] - # f4m_url = 'http://drg.antena3.com/{0}hds/es/sd.f4m'.format(f4m_path) - # this videos are protected by DRM, the f4m downloader doesn't support them + for source in episode.get('sources', []): + src = source.get('src') + if not src: continue - video_url_hd = video_url.replace('free_es', 'es') - formats.extend(self._extract_f4m_formats( - video_url_hd[:-9] + '/manifest.f4m', video_id, f4m_id='hds', - fatal=False)) - formats.extend(self._extract_mpd_formats( - video_url_hd[:-9] + '/manifest.mpd', video_id, mpd_id='dash', - fatal=False)) + src_type = source.get('type') + if src_type == 'application/vnd.apple.mpegurl': + formats.extend(self._extract_m3u8_formats( + src, video_id, 'mp4', 'm3u8_native', + m3u8_id='hls', fatal=False)) + elif src_type == 'application/dash+xml': + formats.extend(self._extract_mpd_formats( + src, video_id, mpd_id='dash', fatal=False)) self._sort_formats(formats) - path_data = player.get('pathData') - - episode = self._download_xml( - self._EPISODE_URL_TEMPLATE % path_data, video_id, - 'Downloading episode XML') - - duration = float_or_none(xpath_text( - episode, './media/asset/info/technical/contentDuration', 'duration')) - - art = episode.find('./media/asset/info/art') - title = xpath_text(art, './name', 'title') - description = xpath_text(art, './description', 'description') - thumbnail = xpath_text(episode, './media/asset/files/background', 'thumbnail') - - subtitles = {} - subtitle_url = xpath_text(episode, './media/asset/files/subtitle', 'subtitle') - if subtitle_url: - subtitles['es'] = [{ - 'ext': 'srt', - 'url': subtitle_url, - }] + heartbeat = episode.get('heartbeat') or {} + omniture = episode.get('omniture') or {} + get_meta = lambda x: heartbeat.get(x) or omniture.get(x) return { + 'display_id': display_id, 'id': video_id, 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'duration': duration, + 'description': episode.get('descripcion'), + 'thumbnail': episode.get('imgPoster'), + 'duration': int_or_none(episode.get('duration')), 'formats': formats, - 'subtitles': subtitles, + 'channel': get_meta('channel'), + 'season': get_meta('season'), + 'episode_number': int_or_none(get_meta('episodeNumber')), } diff --git a/youtube_dl/extractor/audioboom.py b/youtube_dl/extractor/audioboom.py index 393f381..c51837b 100644 --- a/youtube_dl/extractor/audioboom.py +++ b/youtube_dl/extractor/audioboom.py @@ -2,22 +2,25 @@ from __future__ import unicode_literals from .common import InfoExtractor -from ..utils import float_or_none +from ..utils import ( + clean_html, + float_or_none, +) class AudioBoomIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?audioboom\.com/(?:boos|posts)/(?P[0-9]+)' _TESTS = [{ - 'url': 'https://audioboom.com/boos/4279833-3-09-2016-czaban-hour-3?t=0', - 'md5': '63a8d73a055c6ed0f1e51921a10a5a76', + 'url': 'https://audioboom.com/posts/7398103-asim-chaudhry', + 'md5': '7b00192e593ff227e6a315486979a42d', 'info_dict': { - 'id': '4279833', + 'id': '7398103', 'ext': 'mp3', - 'title': '3/09/2016 Czaban Hour 3', - 'description': 'Guest: Nate Davis - NFL free agency, Guest: Stan Gans', - 'duration': 2245.72, - 'uploader': 'SB Nation A.M.', - 'uploader_url': r're:https?://(?:www\.)?audioboom\.com/channel/steveczabanyahoosportsradio', + 'title': 'Asim Chaudhry', + 'description': 'md5:2f3fef17dacc2595b5362e1d7d3602fc', + 'duration': 4000.99, + 'uploader': 'Sue Perkins: An hour or so with...', + 'uploader_url': r're:https?://(?:www\.)?audioboom\.com/channel/perkins', } }, { 'url': 'https://audioboom.com/posts/4279833-3-09-2016-czaban-hour-3?t=0', @@ -32,8 +35,8 @@ class AudioBoomIE(InfoExtractor): clip = None clip_store = self._parse_json( - self._search_regex( - r'data-new-clip-store=(["\'])(?P{.*?"clipId"\s*:\s*%s.*?})\1' % video_id, + self._html_search_regex( + r'data-new-clip-store=(["\'])(?P{.+?})\1', webpage, 'clip store', default='{}', group='json'), video_id, fatal=False) if clip_store: @@ -47,14 +50,15 @@ class AudioBoomIE(InfoExtractor): audio_url = from_clip('clipURLPriorToLoading') or self._og_search_property( 'audio', webpage, 'audio url') - title = from_clip('title') or self._og_search_title(webpage) - description = from_clip('description') or self._og_search_description(webpage) + title = from_clip('title') or self._html_search_meta( + ['og:title', 'og:audio:title', 'audio_title'], webpage) + description = from_clip('description') or clean_html(from_clip('formattedDescription')) or self._og_search_description(webpage) duration = float_or_none(from_clip('duration') or self._html_search_meta( 'weibo:audio:duration', webpage)) - uploader = from_clip('author') or self._og_search_property( - 'audio:artist', webpage, 'uploader', fatal=False) + uploader = from_clip('author') or self._html_search_meta( + ['og:audio:artist', 'twitter:audio:artist_name', 'audio_artist'], webpage, 'uploader') uploader_url = from_clip('author_url') or self._html_search_meta( 'audioboo:channel', webpage, 'uploader url') diff --git a/youtube_dl/extractor/azmedien.py b/youtube_dl/extractor/azmedien.py index fcbdc71..b1e20de 100644 --- a/youtube_dl/extractor/azmedien.py +++ b/youtube_dl/extractor/azmedien.py @@ -47,39 +47,19 @@ class AZMedienIE(InfoExtractor): 'url': 'https://www.telebaern.tv/telebaern-news/montag-1-oktober-2018-ganze-sendung-133531189#video=0_7xjo9lf1', 'only_matching': True }] - + _API_TEMPL = 'https://www.%s/api/pub/gql/%s/NewsArticleTeaser/cb9f2f81ed22e9b47f4ca64ea3cc5a5d13e88d1d' _PARTNER_ID = '1719221' def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - host = mobj.group('host') - video_id = mobj.group('id') - entry_id = mobj.group('kaltura_id') + host, display_id, article_id, entry_id = re.match(self._VALID_URL, url).groups() if not entry_id: - api_url = 'https://www.%s/api/pub/gql/%s' % (host, host.split('.')[0]) - payload = { - 'query': '''query VideoContext($articleId: ID!) { - article: node(id: $articleId) { - ... on Article { - mainAssetRelation { - asset { - ... on VideoAsset { - kalturaId - } - } - } - } - } - }''', - 'variables': {'articleId': 'Article:%s' % mobj.group('article_id')}, - } - json_data = self._download_json( - api_url, video_id, headers={ - 'Content-Type': 'application/json', - }, - data=json.dumps(payload).encode()) - entry_id = json_data['data']['article']['mainAssetRelation']['asset']['kalturaId'] + entry_id = self._download_json( + self._API_TEMPL % (host, host.split('.')[0]), display_id, query={ + 'variables': json.dumps({ + 'contextId': 'NewsArticle:' + article_id, + }), + })['data']['context']['mainAsset']['video']['kaltura']['kalturaId'] return self.url_result( 'kaltura:%s:%s' % (self._PARTNER_ID, entry_id), diff --git a/youtube_dl/extractor/bambuser.py b/youtube_dl/extractor/bambuser.py deleted file mode 100644 index 4400ff9..0000000 --- a/youtube_dl/extractor/bambuser.py +++ /dev/null @@ -1,142 +0,0 @@ -from __future__ import unicode_literals - -import re -import itertools - -from .common import InfoExtractor -from ..compat import compat_str -from ..utils import ( - ExtractorError, - float_or_none, - int_or_none, - sanitized_Request, - urlencode_postdata, -) - - -class BambuserIE(InfoExtractor): - IE_NAME = 'bambuser' - _VALID_URL = r'https?://bambuser\.com/v/(?P\d+)' - _API_KEY = '005f64509e19a868399060af746a00aa' - _LOGIN_URL = 'https://bambuser.com/user' - _NETRC_MACHINE = 'bambuser' - - _TEST = { - 'url': 'http://bambuser.com/v/4050584', - # MD5 seems to be flaky, see https://travis-ci.org/ytdl-org/youtube-dl/jobs/14051016#L388 - # 'md5': 'fba8f7693e48fd4e8641b3fd5539a641', - 'info_dict': { - 'id': '4050584', - 'ext': 'flv', - 'title': 'Education engineering days - lightning talks', - 'duration': 3741, - 'uploader': 'pixelversity', - 'uploader_id': '344706', - 'timestamp': 1382976692, - 'upload_date': '20131028', - 'view_count': int, - }, - 'params': { - # It doesn't respect the 'Range' header, it would download the whole video - # caused the travis builds to fail: https://travis-ci.org/ytdl-org/youtube-dl/jobs/14493845#L59 - 'skip_download': True, - }, - } - - def _login(self): - username, password = self._get_login_info() - if username is None: - return - - login_form = { - 'form_id': 'user_login', - 'op': 'Log in', - 'name': username, - 'pass': password, - } - - request = sanitized_Request( - self._LOGIN_URL, urlencode_postdata(login_form)) - request.add_header('Referer', self._LOGIN_URL) - response = self._download_webpage( - request, None, 'Logging in') - - login_error = self._html_search_regex( - r'(?s)
(.+?)
', - response, 'login error', default=None) - if login_error: - raise ExtractorError( - 'Unable to login: %s' % login_error, expected=True) - - def _real_initialize(self): - self._login() - - def _real_extract(self, url): - video_id = self._match_id(url) - - info = self._download_json( - 'http://player-c.api.bambuser.com/getVideo.json?api_key=%s&vid=%s' - % (self._API_KEY, video_id), video_id) - - error = info.get('error') - if error: - raise ExtractorError( - '%s returned error: %s' % (self.IE_NAME, error), expected=True) - - result = info['result'] - - return { - 'id': video_id, - 'title': result['title'], - 'url': result['url'], - 'thumbnail': result.get('preview'), - 'duration': int_or_none(result.get('length')), - 'uploader': result.get('username'), - 'uploader_id': compat_str(result.get('owner', {}).get('uid')), - 'timestamp': int_or_none(result.get('created')), - 'fps': float_or_none(result.get('framerate')), - 'view_count': int_or_none(result.get('views_total')), - 'comment_count': int_or_none(result.get('comment_count')), - } - - -class BambuserChannelIE(InfoExtractor): - IE_NAME = 'bambuser:channel' - _VALID_URL = r'https?://bambuser\.com/channel/(?P.*?)(?:/|#|\?|$)' - # The maximum number we can get with each request - _STEP = 50 - _TEST = { - 'url': 'http://bambuser.com/channel/pixelversity', - 'info_dict': { - 'title': 'pixelversity', - }, - 'playlist_mincount': 60, - } - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - user = mobj.group('user') - urls = [] - last_id = '' - for i in itertools.count(1): - req_url = ( - 'http://bambuser.com/xhr-api/index.php?username={user}' - '&sort=created&access_mode=0%2C1%2C2&limit={count}' - '&method=broadcast&format=json&vid_older_than={last}' - ).format(user=user, count=self._STEP, last=last_id) - req = sanitized_Request(req_url) - # Without setting this header, we wouldn't get any result - req.add_header('Referer', 'http://bambuser.com/channel/%s' % user) - data = self._download_json( - req, user, 'Downloading page %d' % i) - results = data['result'] - if not results: - break - last_id = results[-1]['vid'] - urls.extend(self.url_result(v['page'], 'Bambuser') for v in results) - - return { - '_type': 'playlist', - 'title': user, - 'entries': urls, - } diff --git a/youtube_dl/extractor/bellmedia.py b/youtube_dl/extractor/bellmedia.py index f36a245..4851737 100644 --- a/youtube_dl/extractor/bellmedia.py +++ b/youtube_dl/extractor/bellmedia.py @@ -22,7 +22,8 @@ class BellMediaIE(InfoExtractor): bravo| mtv| space| - etalk + etalk| + marilyn )\.ca| much\.com )/.*?(?:\bvid(?:eoid)?=|-vid|~|%7E|/(?:episode)?)(?P[0-9]{6,})''' @@ -70,6 +71,7 @@ class BellMediaIE(InfoExtractor): 'animalplanet': 'aniplan', 'etalk': 'ctv', 'bnnbloomberg': 'bnn', + 'marilyn': 'ctv_marilyn', } def _real_extract(self, url): diff --git a/youtube_dl/extractor/bitchute.py b/youtube_dl/extractor/bitchute.py index 430663f..0c773e6 100644 --- a/youtube_dl/extractor/bitchute.py +++ b/youtube_dl/extractor/bitchute.py @@ -7,6 +7,7 @@ import re from .common import InfoExtractor from ..utils import ( orderedSet, + unified_strdate, urlencode_postdata, ) @@ -23,6 +24,7 @@ class BitChuteIE(InfoExtractor): 'description': 'md5:3f21f6fb5b1d17c3dee9cf6b5fe60b3a', 'thumbnail': r're:^https?://.*\.jpg$', 'uploader': 'Victoria X Rave', + 'upload_date': '20170813', }, }, { 'url': 'https://www.bitchute.com/embed/lbb5G1hjPhw/', @@ -74,12 +76,17 @@ class BitChuteIE(InfoExtractor): r'(?s)]+\bclass=["\']video-author[^>]+>(.+?)

'), webpage, 'uploader', fatal=False) + upload_date = unified_strdate(self._search_regex( + r'class=["\']video-publish-date[^>]+>[^<]+ at \d+:\d+ UTC on (.+?)\.', + webpage, 'upload date', fatal=False)) + return { 'id': video_id, 'title': title, 'description': description, 'thumbnail': thumbnail, 'uploader': uploader, + 'upload_date': upload_date, 'formats': formats, } diff --git a/youtube_dl/extractor/bokecc.py b/youtube_dl/extractor/bokecc.py index 86a7f4d..6017e83 100644 --- a/youtube_dl/extractor/bokecc.py +++ b/youtube_dl/extractor/bokecc.py @@ -11,8 +11,8 @@ from ..utils import ExtractorError class BokeCCBaseIE(InfoExtractor): def _extract_bokecc_formats(self, webpage, video_id, format_id=None): player_params_str = self._html_search_regex( - r'<(?:script|embed)[^>]+src="http://p\.bokecc\.com/player\?([^"]+)', - webpage, 'player params') + r'<(?:script|embed)[^>]+src=(?P["\'])(?:https?:)?//p\.bokecc\.com/(?:player|flash/player\.swf)\?(?P.+?)(?P=q)', + webpage, 'player params', group='query') player_params = compat_parse_qs(player_params_str) @@ -36,9 +36,9 @@ class BokeCCIE(BokeCCBaseIE): _VALID_URL = r'https?://union\.bokecc\.com/playvideo\.bo\?(?P.*)' _TESTS = [{ - 'url': 'http://union.bokecc.com/playvideo.bo?vid=E44D40C15E65EA30&uid=CD0C5D3C8614B28B', + 'url': 'http://union.bokecc.com/playvideo.bo?vid=E0ABAE9D4F509B189C33DC5901307461&uid=FE644790DE9D154A', 'info_dict': { - 'id': 'CD0C5D3C8614B28B_E44D40C15E65EA30', + 'id': 'FE644790DE9D154A_E0ABAE9D4F509B189C33DC5901307461', 'ext': 'flv', 'title': 'BokeCC Video', }, diff --git a/youtube_dl/extractor/brightcove.py b/youtube_dl/extractor/brightcove.py index 8e2f721..85001b3 100644 --- a/youtube_dl/extractor/brightcove.py +++ b/youtube_dl/extractor/brightcove.py @@ -586,45 +586,63 @@ class BrightcoveNewIE(AdobePassIE): account_id, player_id, embed, content_type, video_id = re.match(self._VALID_URL, url).groups() - webpage = self._download_webpage( - 'http://players.brightcove.net/%s/%s_%s/index.min.js' - % (account_id, player_id, embed), video_id) + policy_key_id = '%s_%s' % (account_id, player_id) + policy_key = self._downloader.cache.load('brightcove', policy_key_id) + policy_key_extracted = False + store_pk = lambda x: self._downloader.cache.store('brightcove', policy_key_id, x) - policy_key = None + def extract_policy_key(): + webpage = self._download_webpage( + 'http://players.brightcove.net/%s/%s_%s/index.min.js' + % (account_id, player_id, embed), video_id) - catalog = self._search_regex( - r'catalog\(({.+?})\);', webpage, 'catalog', default=None) - if catalog: - catalog = self._parse_json( - js_to_json(catalog), video_id, fatal=False) + policy_key = None + + catalog = self._search_regex( + r'catalog\(({.+?})\);', webpage, 'catalog', default=None) if catalog: - policy_key = catalog.get('policyKey') + catalog = self._parse_json( + js_to_json(catalog), video_id, fatal=False) + if catalog: + policy_key = catalog.get('policyKey') + + if not policy_key: + policy_key = self._search_regex( + r'policyKey\s*:\s*(["\'])(?P.+?)\1', + webpage, 'policy key', group='pk') - if not policy_key: - policy_key = self._search_regex( - r'policyKey\s*:\s*(["\'])(?P.+?)\1', - webpage, 'policy key', group='pk') + store_pk(policy_key) + return policy_key api_url = 'https://edge.api.brightcove.com/playback/v1/accounts/%s/%ss/%s' % (account_id, content_type, video_id) - headers = { - 'Accept': 'application/json;pk=%s' % policy_key, - } + headers = {} referrer = smuggled_data.get('referrer') if referrer: headers.update({ 'Referer': referrer, 'Origin': re.search(r'https?://[^/]+', referrer).group(0), }) - try: - json_data = self._download_json(api_url, video_id, headers=headers) - except ExtractorError as e: - if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403: - json_data = self._parse_json(e.cause.read().decode(), video_id)[0] - message = json_data.get('message') or json_data['error_code'] - if json_data.get('error_subcode') == 'CLIENT_GEO': - self.raise_geo_restricted(msg=message) - raise ExtractorError(message, expected=True) - raise + + for _ in range(2): + if not policy_key: + policy_key = extract_policy_key() + policy_key_extracted = True + headers['Accept'] = 'application/json;pk=%s' % policy_key + try: + json_data = self._download_json(api_url, video_id, headers=headers) + break + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code in (401, 403): + json_data = self._parse_json(e.cause.read().decode(), video_id)[0] + message = json_data.get('message') or json_data['error_code'] + if json_data.get('error_subcode') == 'CLIENT_GEO': + self.raise_geo_restricted(msg=message) + elif json_data.get('error_code') == 'INVALID_POLICY_KEY' and not policy_key_extracted: + policy_key = None + store_pk(None) + continue + raise ExtractorError(message, expected=True) + raise errors = json_data.get('errors') if errors and errors[0].get('error_subcode') == 'TVE_AUTH': diff --git a/youtube_dl/extractor/businessinsider.py b/youtube_dl/extractor/businessinsider.py index dfcf9bc..73a57b1 100644 --- a/youtube_dl/extractor/businessinsider.py +++ b/youtube_dl/extractor/businessinsider.py @@ -9,21 +9,26 @@ class BusinessInsiderIE(InfoExtractor): _VALID_URL = r'https?://(?:[^/]+\.)?businessinsider\.(?:com|nl)/(?:[^/]+/)*(?P[^/?#&]+)' _TESTS = [{ 'url': 'http://uk.businessinsider.com/how-much-radiation-youre-exposed-to-in-everyday-life-2016-6', - 'md5': 'ca237a53a8eb20b6dc5bd60564d4ab3e', + 'md5': 'ffed3e1e12a6f950aa2f7d83851b497a', 'info_dict': { - 'id': 'hZRllCfw', + 'id': 'cjGDb0X9', 'ext': 'mp4', - 'title': "Here's how much radiation you're exposed to in everyday life", - 'description': 'md5:9a0d6e2c279948aadaa5e84d6d9b99bd', - 'upload_date': '20170709', - 'timestamp': 1499606400, - }, - 'params': { - 'skip_download': True, + 'title': "Bananas give you more radiation exposure than living next to a nuclear power plant", + 'description': 'md5:0175a3baf200dd8fa658f94cade841b3', + 'upload_date': '20160611', + 'timestamp': 1465675620, }, }, { 'url': 'https://www.businessinsider.nl/5-scientifically-proven-things-make-you-less-attractive-2017-7/', - 'only_matching': True, + 'md5': '43f438dbc6da0b89f5ac42f68529d84a', + 'info_dict': { + 'id': '5zJwd4FK', + 'ext': 'mp4', + 'title': 'Deze dingen zorgen ervoor dat je minder snel een date scoort', + 'description': 'md5:2af8975825d38a4fed24717bbe51db49', + 'upload_date': '20170705', + 'timestamp': 1499270528, + }, }, { 'url': 'http://www.businessinsider.com/excel-index-match-vlookup-video-how-to-2015-2?IR=T', 'only_matching': True, @@ -35,7 +40,8 @@ class BusinessInsiderIE(InfoExtractor): jwplatform_id = self._search_regex( (r'data-media-id=["\']([a-zA-Z0-9]{8})', r'id=["\']jwplayer_([a-zA-Z0-9]{8})', - r'id["\']?\s*:\s*["\']?([a-zA-Z0-9]{8})'), + r'id["\']?\s*:\s*["\']?([a-zA-Z0-9]{8})', + r'(?:jwplatform\.com/players/|jwplayer_)([a-zA-Z0-9]{8})'), webpage, 'jwplatform id') return self.url_result( 'jwplatform:%s' % jwplatform_id, ie=JWPlatformIE.ie_key(), diff --git a/youtube_dl/extractor/canvas.py b/youtube_dl/extractor/canvas.py index c506bc5..8667a0d 100644 --- a/youtube_dl/extractor/canvas.py +++ b/youtube_dl/extractor/canvas.py @@ -13,6 +13,8 @@ from ..utils import ( int_or_none, merge_dicts, parse_iso8601, + str_or_none, + url_or_none, ) @@ -20,15 +22,15 @@ class CanvasIE(InfoExtractor): _VALID_URL = r'https?://mediazone\.vrt\.be/api/v1/(?Pcanvas|een|ketnet|vrt(?:video|nieuws)|sporza)/assets/(?P[^/?#&]+)' _TESTS = [{ 'url': 'https://mediazone.vrt.be/api/v1/ketnet/assets/md-ast-4ac54990-ce66-4d00-a8ca-9eac86f4c475', - 'md5': '90139b746a0a9bd7bb631283f6e2a64e', + 'md5': '68993eda72ef62386a15ea2cf3c93107', 'info_dict': { 'id': 'md-ast-4ac54990-ce66-4d00-a8ca-9eac86f4c475', 'display_id': 'md-ast-4ac54990-ce66-4d00-a8ca-9eac86f4c475', - 'ext': 'flv', + 'ext': 'mp4', 'title': 'Nachtwacht: De Greystook', - 'description': 'md5:1db3f5dc4c7109c821261e7512975be7', + 'description': 'Nachtwacht: De Greystook', 'thumbnail': r're:^https?://.*\.jpg$', - 'duration': 1468.03, + 'duration': 1468.04, }, 'expected_warnings': ['is not a supported codec', 'Unknown MIME type'], }, { @@ -39,23 +41,45 @@ class CanvasIE(InfoExtractor): 'HLS': 'm3u8_native', 'HLS_AES': 'm3u8', } + _REST_API_BASE = 'https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1' def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) site_id, video_id = mobj.group('site_id'), mobj.group('id') + # Old API endpoint, serves more formats but may fail for some videos data = self._download_json( 'https://mediazone.vrt.be/api/v1/%s/assets/%s' - % (site_id, video_id), video_id) + % (site_id, video_id), video_id, 'Downloading asset JSON', + 'Unable to download asset JSON', fatal=False) + + # New API endpoint + if not data: + token = self._download_json( + '%s/tokens' % self._REST_API_BASE, video_id, + 'Downloading token', data=b'', + headers={'Content-Type': 'application/json'})['vrtPlayerToken'] + data = self._download_json( + '%s/videos/%s' % (self._REST_API_BASE, video_id), + video_id, 'Downloading video JSON', fatal=False, query={ + 'vrtPlayerToken': token, + 'client': '%s@PROD' % site_id, + }, expected_status=400) + message = data.get('message') + if message and not data.get('title'): + if data.get('code') == 'AUTHENTICATION_REQUIRED': + self.raise_login_required(message) + raise ExtractorError(message, expected=True) title = data['title'] description = data.get('description') formats = [] for target in data['targetUrls']: - format_url, format_type = target.get('url'), target.get('type') + format_url, format_type = url_or_none(target.get('url')), str_or_none(target.get('type')) if not format_url or not format_type: continue + format_type = format_type.upper() if format_type in self._HLS_ENTRY_PROTOCOLS_MAP: formats.extend(self._extract_m3u8_formats( format_url, video_id, 'mp4', self._HLS_ENTRY_PROTOCOLS_MAP[format_type], @@ -134,20 +158,20 @@ class CanvasEenIE(InfoExtractor): }, 'skip': 'Pagina niet gevonden', }, { - 'url': 'https://www.een.be/sorry-voor-alles/herbekijk-sorry-voor-alles', + 'url': 'https://www.een.be/thuis/emma-pakt-thilly-aan', 'info_dict': { - 'id': 'mz-ast-11a587f8-b921-4266-82e2-0bce3e80d07f', - 'display_id': 'herbekijk-sorry-voor-alles', + 'id': 'md-ast-3a24ced2-64d7-44fb-b4ed-ed1aafbf90b8', + 'display_id': 'emma-pakt-thilly-aan', 'ext': 'mp4', - 'title': 'Herbekijk Sorry voor alles', - 'description': 'md5:8bb2805df8164e5eb95d6a7a29dc0dd3', + 'title': 'Emma pakt Thilly aan', + 'description': 'md5:c5c9b572388a99b2690030afa3f3bad7', 'thumbnail': r're:^https?://.*\.jpg$', - 'duration': 3788.06, + 'duration': 118.24, }, 'params': { 'skip_download': True, }, - 'skip': 'Episode no longer available', + 'expected_warnings': ['is not a supported codec'], }, { 'url': 'https://www.canvas.be/check-point/najaar-2016/de-politie-uw-vriend', 'only_matching': True, @@ -183,19 +207,44 @@ class VrtNUIE(GigyaBaseIE): IE_DESC = 'VrtNU.be' _VALID_URL = r'https?://(?:www\.)?vrt\.be/(?Pvrtnu)/(?:[^/]+/)*(?P[^/?#&]+)' _TESTS = [{ + # Available via old API endpoint 'url': 'https://www.vrt.be/vrtnu/a-z/postbus-x/1/postbus-x-s1a1/', 'info_dict': { 'id': 'pbs-pub-2e2d8c27-df26-45c9-9dc6-90c78153044d$vid-90c932b1-e21d-4fb8-99b1-db7b49cf74de', - 'ext': 'flv', + 'ext': 'mp4', 'title': 'De zwarte weduwe', - 'description': 'md5:d90c21dced7db869a85db89a623998d4', + 'description': 'md5:db1227b0f318c849ba5eab1fef895ee4', 'duration': 1457.04, 'thumbnail': r're:^https?://.*\.jpg$', - 'season': '1', + 'season': 'Season 1', 'season_number': 1, 'episode_number': 1, }, - 'skip': 'This video is only available for registered users' + 'skip': 'This video is only available for registered users', + 'params': { + 'username': '', + 'password': '', + }, + 'expected_warnings': ['is not a supported codec'], + }, { + # Only available via new API endpoint + 'url': 'https://www.vrt.be/vrtnu/a-z/kamp-waes/1/kamp-waes-s1a5/', + 'info_dict': { + 'id': 'pbs-pub-0763b56c-64fb-4d38-b95b-af60bf433c71$vid-ad36a73c-4735-4f1f-b2c0-a38e6e6aa7e1', + 'ext': 'mp4', + 'title': 'Aflevering 5', + 'description': 'Wie valt door de mand tijdens een missie?', + 'duration': 2967.06, + 'season': 'Season 1', + 'season_number': 1, + 'episode_number': 5, + }, + 'skip': 'This video is only available for registered users', + 'params': { + 'username': '', + 'password': '', + }, + 'expected_warnings': ['Unable to download asset JSON', 'is not a supported codec', 'Unknown MIME type'], }] _NETRC_MACHINE = 'vrtnu' _APIKEY = '3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy' diff --git a/youtube_dl/extractor/ceskatelevize.py b/youtube_dl/extractor/ceskatelevize.py index 1ec58f7..7cb4efb 100644 --- a/youtube_dl/extractor/ceskatelevize.py +++ b/youtube_dl/extractor/ceskatelevize.py @@ -147,6 +147,8 @@ class CeskaTelevizeIE(InfoExtractor): is_live = item.get('type') == 'LIVE' formats = [] for format_id, stream_url in item.get('streamUrls', {}).items(): + if 'drmOnly=true' in stream_url: + continue if 'playerType=flash' in stream_url: stream_formats = self._extract_m3u8_formats( stream_url, playlist_id, 'mp4', 'm3u8_native', diff --git a/youtube_dl/extractor/channel9.py b/youtube_dl/extractor/channel9.py index 81108e7..09cacf6 100644 --- a/youtube_dl/extractor/channel9.py +++ b/youtube_dl/extractor/channel9.py @@ -32,7 +32,7 @@ class Channel9IE(InfoExtractor): 'upload_date': '20130828', 'session_code': 'KOS002', 'session_room': 'Arena 1A', - 'session_speakers': ['Andrew Coates', 'Brady Gaster', 'Mads Kristensen', 'Ed Blankenship', 'Patrick Klug'], + 'session_speakers': 'count:5', }, }, { 'url': 'http://channel9.msdn.com/posts/Self-service-BI-with-Power-BI-nuclear-testing', @@ -65,14 +65,14 @@ class Channel9IE(InfoExtractor): 'skip_download': True, }, }, { - 'url': 'https://channel9.msdn.com/Niners/Splendid22/Queue/76acff796e8f411184b008028e0d492b/RSS', + 'url': 'https://channel9.msdn.com/Events/DEVintersection/DEVintersection-2016/RSS', 'info_dict': { - 'id': 'Niners/Splendid22/Queue/76acff796e8f411184b008028e0d492b', - 'title': 'Channel 9', + 'id': 'Events/DEVintersection/DEVintersection-2016', + 'title': 'DEVintersection 2016 Orlando Sessions', }, - 'playlist_mincount': 100, + 'playlist_mincount': 14, }, { - 'url': 'https://channel9.msdn.com/Events/DEVintersection/DEVintersection-2016/RSS', + 'url': 'https://channel9.msdn.com/Niners/Splendid22/Queue/76acff796e8f411184b008028e0d492b/RSS', 'only_matching': True, }, { 'url': 'https://channel9.msdn.com/Events/Speakers/scott-hanselman/RSS?UrlSafeName=scott-hanselman', @@ -112,11 +112,11 @@ class Channel9IE(InfoExtractor): episode_data), content_path) content_id = episode_data['contentId'] is_session = '/Sessions(' in episode_data['api'] - content_url = 'https://channel9.msdn.com/odata' + episode_data['api'] + content_url = 'https://channel9.msdn.com/odata' + episode_data['api'] + '?$select=Captions,CommentCount,MediaLengthInSeconds,PublishedDate,Rating,RatingCount,Title,VideoMP4High,VideoMP4Low,VideoMP4Medium,VideoPlayerPreviewImage,VideoWMV,VideoWMVHQ,Views,' if is_session: - content_url += '?$expand=Speakers' + content_url += 'Code,Description,Room,Slides,Speakers,ZipFile&$expand=Speakers' else: - content_url += '?$expand=Authors' + content_url += 'Authors,Body&$expand=Authors' content_data = self._download_json(content_url, content_id) title = content_data['Title'] @@ -210,7 +210,7 @@ class Channel9IE(InfoExtractor): 'id': content_id, 'title': title, 'description': clean_html(content_data.get('Description') or content_data.get('Body')), - 'thumbnail': content_data.get('Thumbnail') or content_data.get('VideoPlayerPreviewImage'), + 'thumbnail': content_data.get('VideoPlayerPreviewImage'), 'duration': int_or_none(content_data.get('MediaLengthInSeconds')), 'timestamp': parse_iso8601(content_data.get('PublishedDate')), 'avg_rating': int_or_none(content_data.get('Rating')), diff --git a/youtube_dl/extractor/chaturbate.py b/youtube_dl/extractor/chaturbate.py index e2b828d..a459dcb 100644 --- a/youtube_dl/extractor/chaturbate.py +++ b/youtube_dl/extractor/chaturbate.py @@ -3,11 +3,15 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from ..utils import ExtractorError +from ..utils import ( + ExtractorError, + lowercase_escape, + url_or_none, +) class ChaturbateIE(InfoExtractor): - _VALID_URL = r'https?://(?:[^/]+\.)?chaturbate\.com/(?P[^/?#]+)' + _VALID_URL = r'https?://(?:[^/]+\.)?chaturbate\.com/(?:fullvideo/?\?.*?\bb=)?(?P[^/?&#]+)' _TESTS = [{ 'url': 'https://www.chaturbate.com/siswet19/', 'info_dict': { @@ -21,6 +25,9 @@ class ChaturbateIE(InfoExtractor): 'skip_download': True, }, 'skip': 'Room is offline', + }, { + 'url': 'https://chaturbate.com/fullvideo/?b=caylin', + 'only_matching': True, }, { 'url': 'https://en.chaturbate.com/siswet19/', 'only_matching': True, @@ -32,14 +39,34 @@ class ChaturbateIE(InfoExtractor): video_id = self._match_id(url) webpage = self._download_webpage( - url, video_id, headers=self.geo_verification_headers()) + 'https://chaturbate.com/%s/' % video_id, video_id, + headers=self.geo_verification_headers()) - m3u8_urls = [] + found_m3u8_urls = [] + + data = self._parse_json( + self._search_regex( + r'initialRoomDossier\s*=\s*(["\'])(?P(?:(?!\1).)+)\1', + webpage, 'data', default='{}', group='value'), + video_id, transform_source=lowercase_escape, fatal=False) + if data: + m3u8_url = url_or_none(data.get('hls_source')) + if m3u8_url: + found_m3u8_urls.append(m3u8_url) - for m in re.finditer( - r'(["\'])(?Phttp.+?\.m3u8.*?)\1', webpage): - m3u8_fast_url, m3u8_no_fast_url = m.group('url'), m.group( - 'url').replace('_fast', '') + if not found_m3u8_urls: + for m in re.finditer( + r'(\\u002[27])(?Phttp.+?\.m3u8.*?)\1', webpage): + found_m3u8_urls.append(lowercase_escape(m.group('url'))) + + if not found_m3u8_urls: + for m in re.finditer( + r'(["\'])(?Phttp.+?\.m3u8.*?)\1', webpage): + found_m3u8_urls.append(m.group('url')) + + m3u8_urls = [] + for found_m3u8_url in found_m3u8_urls: + m3u8_fast_url, m3u8_no_fast_url = found_m3u8_url, found_m3u8_url.replace('_fast', '') for m3u8_url in (m3u8_fast_url, m3u8_no_fast_url): if m3u8_url not in m3u8_urls: m3u8_urls.append(m3u8_url) @@ -59,7 +86,12 @@ class ChaturbateIE(InfoExtractor): formats = [] for m3u8_url in m3u8_urls: - m3u8_id = 'fast' if '_fast' in m3u8_url else 'slow' + for known_id in ('fast', 'slow'): + if '_%s' % known_id in m3u8_url: + m3u8_id = known_id + break + else: + m3u8_id = None formats.extend(self._extract_m3u8_formats( m3u8_url, video_id, ext='mp4', # ffmpeg skips segments for fast m3u8 diff --git a/youtube_dl/extractor/cloudflarestream.py b/youtube_dl/extractor/cloudflarestream.py index 8ff2c65..2fdcfbb 100644 --- a/youtube_dl/extractor/cloudflarestream.py +++ b/youtube_dl/extractor/cloudflarestream.py @@ -1,20 +1,24 @@ # coding: utf-8 from __future__ import unicode_literals +import base64 import re from .common import InfoExtractor class CloudflareStreamIE(InfoExtractor): + _DOMAIN_RE = r'(?:cloudflarestream\.com|(?:videodelivery|bytehighway)\.net)' + _EMBED_RE = r'embed\.%s/embed/[^/]+\.js\?.*?\bvideo=' % _DOMAIN_RE + _ID_RE = r'[\da-f]{32}|[\w-]+\.[\w-]+\.[\w-]+' _VALID_URL = r'''(?x) https?:// (?: - (?:watch\.)?(?:cloudflarestream\.com|videodelivery\.net)/| - embed\.(?:cloudflarestream\.com|videodelivery\.net)/embed/[^/]+\.js\?.*?\bvideo= + (?:watch\.)?%s/| + %s ) - (?P[\da-f]+) - ''' + (?P%s) + ''' % (_DOMAIN_RE, _EMBED_RE, _ID_RE) _TESTS = [{ 'url': 'https://embed.cloudflarestream.com/embed/we4g.fla9.latest.js?video=31c9291ab41fac05471db4e73aa11717', 'info_dict': { @@ -41,23 +45,28 @@ class CloudflareStreamIE(InfoExtractor): return [ mobj.group('url') for mobj in re.finditer( - r']+\bsrc=(["\'])(?P(?:https?:)?//embed\.(?:cloudflarestream\.com|videodelivery\.net)/embed/[^/]+\.js\?.*?\bvideo=[\da-f]+?.*?)\1', + r']+\bsrc=(["\'])(?P(?:https?:)?//%s(?:%s).*?)\1' % (CloudflareStreamIE._EMBED_RE, CloudflareStreamIE._ID_RE), webpage)] def _real_extract(self, url): video_id = self._match_id(url) + domain = 'bytehighway.net' if 'bytehighway.net/' in url else 'videodelivery.net' + base_url = 'https://%s/%s/' % (domain, video_id) + if '.' in video_id: + video_id = self._parse_json(base64.urlsafe_b64decode( + video_id.split('.')[1]), video_id)['sub'] + manifest_base_url = base_url + 'manifest/video.' formats = self._extract_m3u8_formats( - 'https://cloudflarestream.com/%s/manifest/video.m3u8' % video_id, - video_id, 'mp4', entry_protocol='m3u8_native', m3u8_id='hls', - fatal=False) + manifest_base_url + 'm3u8', video_id, 'mp4', + 'm3u8_native', m3u8_id='hls', fatal=False) formats.extend(self._extract_mpd_formats( - 'https://cloudflarestream.com/%s/manifest/video.mpd' % video_id, - video_id, mpd_id='dash', fatal=False)) + manifest_base_url + 'mpd', video_id, mpd_id='dash', fatal=False)) self._sort_formats(formats) return { 'id': video_id, 'title': video_id, + 'thumbnail': base_url + 'thumbnails/thumbnail.jpg', 'formats': formats, } diff --git a/youtube_dl/extractor/comcarcoff.py b/youtube_dl/extractor/comcarcoff.py deleted file mode 100644 index 588aad0..0000000 --- a/youtube_dl/extractor/comcarcoff.py +++ /dev/null @@ -1,74 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..compat import compat_str -from ..utils import ( - int_or_none, - parse_duration, - parse_iso8601, -) - - -class ComCarCoffIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?comediansincarsgettingcoffee\.com/(?P[a-z0-9\-]*)' - _TESTS = [{ - 'url': 'http://comediansincarsgettingcoffee.com/miranda-sings-happy-thanksgiving-miranda/', - 'info_dict': { - 'id': '2494164', - 'ext': 'mp4', - 'upload_date': '20141127', - 'timestamp': 1417107600, - 'duration': 1232, - 'title': 'Happy Thanksgiving Miranda', - 'description': 'Jerry Seinfeld and his special guest Miranda Sings cruise around town in search of coffee, complaining and apologizing along the way.', - }, - 'params': { - 'skip_download': 'requires ffmpeg', - } - }] - - def _real_extract(self, url): - display_id = self._match_id(url) - if not display_id: - display_id = 'comediansincarsgettingcoffee.com' - webpage = self._download_webpage(url, display_id) - - full_data = self._parse_json( - self._search_regex( - r'window\.app\s*=\s*({.+?});\n', webpage, 'full data json'), - display_id)['videoData'] - - display_id = full_data['activeVideo']['video'] - video_data = full_data.get('videos', {}).get(display_id) or full_data['singleshots'][display_id] - - video_id = compat_str(video_data['mediaId']) - title = video_data['title'] - formats = self._extract_m3u8_formats( - video_data['mediaUrl'], video_id, 'mp4') - self._sort_formats(formats) - - thumbnails = [{ - 'url': video_data['images']['thumb'], - }, { - 'url': video_data['images']['poster'], - }] - - timestamp = int_or_none(video_data.get('pubDateTime')) or parse_iso8601( - video_data.get('pubDate')) - duration = int_or_none(video_data.get('durationSeconds')) or parse_duration( - video_data.get('duration')) - - return { - 'id': video_id, - 'display_id': display_id, - 'title': title, - 'description': video_data.get('description'), - 'timestamp': timestamp, - 'duration': duration, - 'thumbnails': thumbnails, - 'formats': formats, - 'season_number': int_or_none(video_data.get('season')), - 'episode_number': int_or_none(video_data.get('episode')), - 'webpage_url': 'http://comediansincarsgettingcoffee.com/%s' % (video_data.get('urlSlug', video_data.get('slug'))), - } diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index 8597866..eaae5e4 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -1424,12 +1424,10 @@ class InfoExtractor(object): try: self._request_webpage(url, video_id, 'Checking %s URL' % item, headers=headers) return True - except ExtractorError as e: - if isinstance(e.cause, compat_urllib_error.URLError): - self.to_screen( - '%s: %s URL is invalid, skipping' % (video_id, item)) - return False - raise + except ExtractorError: + self.to_screen( + '%s: %s URL is invalid, skipping' % (video_id, item)) + return False def http_scheme(self): """ Either "http:" or "https:", depending on the user's preferences """ @@ -1457,14 +1455,14 @@ class InfoExtractor(object): def _extract_f4m_formats(self, manifest_url, video_id, preference=None, f4m_id=None, transform_source=lambda s: fix_xml_ampersands(s).strip(), - fatal=True, m3u8_id=None): + fatal=True, m3u8_id=None, data=None, headers={}, query={}): manifest = self._download_xml( manifest_url, video_id, 'Downloading f4m manifest', 'Unable to download f4m manifest', # Some manifests may be malformed, e.g. prosiebensat1 generated manifests # (see https://github.com/ytdl-org/youtube-dl/issues/6215#issuecomment-121704244) transform_source=transform_source, - fatal=fatal) + fatal=fatal, data=data, headers=headers, query=query) if manifest is False: return [] @@ -1588,12 +1586,13 @@ class InfoExtractor(object): def _extract_m3u8_formats(self, m3u8_url, video_id, ext=None, entry_protocol='m3u8', preference=None, m3u8_id=None, note=None, errnote=None, - fatal=True, live=False): + fatal=True, live=False, data=None, headers={}, + query={}): res = self._download_webpage_handle( m3u8_url, video_id, note=note or 'Downloading m3u8 information', errnote=errnote or 'Failed to download m3u8 information', - fatal=fatal) + fatal=fatal, data=data, headers=headers, query=query) if res is False: return [] @@ -1767,6 +1766,19 @@ class InfoExtractor(object): # the same GROUP-ID f['acodec'] = 'none' formats.append(f) + + # for DailyMotion + progressive_uri = last_stream_inf.get('PROGRESSIVE-URI') + if progressive_uri: + http_f = f.copy() + del http_f['manifest_url'] + http_f.update({ + 'format_id': f['format_id'].replace('hls-', 'http-'), + 'protocol': 'http', + 'url': progressive_uri, + }) + formats.append(http_f) + last_stream_inf = {} return formats @@ -2011,12 +2023,12 @@ class InfoExtractor(object): }) return entries - def _extract_mpd_formats(self, mpd_url, video_id, mpd_id=None, note=None, errnote=None, fatal=True, formats_dict={}): + def _extract_mpd_formats(self, mpd_url, video_id, mpd_id=None, note=None, errnote=None, fatal=True, formats_dict={}, data=None, headers={}, query={}): res = self._download_xml_handle( mpd_url, video_id, note=note or 'Downloading MPD manifest', errnote=errnote or 'Failed to download MPD manifest', - fatal=fatal) + fatal=fatal, data=data, headers=headers, query=query) if res is False: return [] mpd_doc, urlh = res @@ -2319,12 +2331,12 @@ class InfoExtractor(object): self.report_warning('Unknown MIME type %s in DASH manifest' % mime_type) return formats - def _extract_ism_formats(self, ism_url, video_id, ism_id=None, note=None, errnote=None, fatal=True): + def _extract_ism_formats(self, ism_url, video_id, ism_id=None, note=None, errnote=None, fatal=True, data=None, headers={}, query={}): res = self._download_xml_handle( ism_url, video_id, note=note or 'Downloading ISM manifest', errnote=errnote or 'Failed to download ISM manifest', - fatal=fatal) + fatal=fatal, data=data, headers=headers, query=query) if res is False: return [] ism_doc, urlh = res @@ -2691,7 +2703,7 @@ class InfoExtractor(object): entry = { 'id': this_video_id, 'title': unescapeHTML(video_data['title'] if require_title else video_data.get('title')), - 'description': video_data.get('description'), + 'description': clean_html(video_data.get('description')), 'thumbnail': urljoin(base_url, self._proto_relative_url(video_data.get('image'))), 'timestamp': int_or_none(video_data.get('pubdate')), 'duration': float_or_none(jwplayer_data.get('duration') or video_data.get('duration')), diff --git a/youtube_dl/extractor/contv.py b/youtube_dl/extractor/contv.py new file mode 100644 index 0000000..84b462d --- /dev/null +++ b/youtube_dl/extractor/contv.py @@ -0,0 +1,118 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + float_or_none, + int_or_none, +) + + +class CONtvIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?contv\.com/details-movie/(?P[^/]+)' + _TESTS = [{ + 'url': 'https://www.contv.com/details-movie/CEG10022949/days-of-thrills-&-laughter', + 'info_dict': { + 'id': 'CEG10022949', + 'ext': 'mp4', + 'title': 'Days Of Thrills & Laughter', + 'description': 'md5:5d6b3d0b1829bb93eb72898c734802eb', + 'upload_date': '20180703', + 'timestamp': 1530634789.61, + }, + 'params': { + # m3u8 download + 'skip_download': True, + }, + }, { + 'url': 'https://www.contv.com/details-movie/CLIP-show_fotld_bts/fight-of-the-living-dead:-behind-the-scenes-bites', + 'info_dict': { + 'id': 'CLIP-show_fotld_bts', + 'title': 'Fight of the Living Dead: Behind the Scenes Bites', + }, + 'playlist_mincount': 7, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + details = self._download_json( + 'http://metax.contv.live.junctiontv.net/metax/2.5/details/' + video_id, + video_id, query={'device': 'web'}) + + if details.get('type') == 'episodic': + seasons = self._download_json( + 'http://metax.contv.live.junctiontv.net/metax/2.5/seriesfeed/json/' + video_id, + video_id) + entries = [] + for season in seasons: + for episode in season.get('episodes', []): + episode_id = episode.get('id') + if not episode_id: + continue + entries.append(self.url_result( + 'https://www.contv.com/details-movie/' + episode_id, + CONtvIE.ie_key(), episode_id)) + return self.playlist_result(entries, video_id, details.get('title')) + + m_details = details['details'] + title = details['title'] + + formats = [] + + media_hls_url = m_details.get('media_hls_url') + if media_hls_url: + formats.extend(self._extract_m3u8_formats( + media_hls_url, video_id, 'mp4', + m3u8_id='hls', fatal=False)) + + media_mp4_url = m_details.get('media_mp4_url') + if media_mp4_url: + formats.append({ + 'format_id': 'http', + 'url': media_mp4_url, + }) + + self._sort_formats(formats) + + subtitles = {} + captions = m_details.get('captions') or {} + for caption_url in captions.values(): + subtitles.setdefault('en', []).append({ + 'url': caption_url + }) + + thumbnails = [] + for image in m_details.get('images', []): + image_url = image.get('url') + if not image_url: + continue + thumbnails.append({ + 'url': image_url, + 'width': int_or_none(image.get('width')), + 'height': int_or_none(image.get('height')), + }) + + description = None + for p in ('large_', 'medium_', 'small_', ''): + d = m_details.get(p + 'description') + if d: + description = d + break + + return { + 'id': video_id, + 'title': title, + 'formats': formats, + 'thumbnails': thumbnails, + 'description': description, + 'timestamp': float_or_none(details.get('metax_added_on'), 1000), + 'subtitles': subtitles, + 'duration': float_or_none(m_details.get('duration'), 1000), + 'view_count': int_or_none(details.get('num_watched')), + 'like_count': int_or_none(details.get('num_fav')), + 'categories': details.get('category'), + 'tags': details.get('tags'), + 'season_number': int_or_none(details.get('season')), + 'episode_number': int_or_none(details.get('episode')), + 'release_year': int_or_none(details.get('pub_year')), + } diff --git a/youtube_dl/extractor/corus.py b/youtube_dl/extractor/corus.py index a1b2518..e11aadf 100644 --- a/youtube_dl/extractor/corus.py +++ b/youtube_dl/extractor/corus.py @@ -4,7 +4,12 @@ from __future__ import unicode_literals import re from .theplatform import ThePlatformFeedIE -from ..utils import int_or_none +from ..utils import ( + dict_get, + ExtractorError, + float_or_none, + int_or_none, +) class CorusIE(ThePlatformFeedIE): @@ -12,24 +17,49 @@ class CorusIE(ThePlatformFeedIE): https?:// (?:www\.)? (?P - (?:globaltv|etcanada)\.com| - (?:hgtv|foodnetwork|slice|history|showcase|bigbrothercanada)\.ca + (?: + globaltv| + etcanada| + seriesplus| + wnetwork| + ytv + )\.com| + (?: + hgtv| + foodnetwork| + slice| + history| + showcase| + bigbrothercanada| + abcspark| + disney(?:channel|lachaine) + )\.ca + ) + /(?:[^/]+/)* + (?: + video\.html\?.*?\bv=| + videos?/(?:[^/]+/)*(?:[a-z0-9-]+-)? + ) + (?P + [\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}| + (?:[A-Z]{4})?\d{12,20} ) - /(?:video/(?:[^/]+/)?|(?:[^/]+/)+(?:videos/[a-z0-9-]+-|video\.html\?.*?\bv=)) - (?P\d+) ''' _TESTS = [{ 'url': 'http://www.hgtv.ca/shows/bryan-inc/videos/movie-night-popcorn-with-bryan-870923331648/', - 'md5': '05dcbca777bf1e58c2acbb57168ad3a6', 'info_dict': { 'id': '870923331648', 'ext': 'mp4', 'title': 'Movie Night Popcorn with Bryan', 'description': 'Bryan whips up homemade popcorn, the old fashion way for Jojo and Lincoln.', - 'uploader': 'SHWM-NEW', 'upload_date': '20170206', 'timestamp': 1486392197, }, + 'params': { + 'format': 'bestvideo', + 'skip_download': True, + }, + 'expected_warnings': ['Failed to parse JSON'], }, { 'url': 'http://www.foodnetwork.ca/shows/chopped/video/episode/chocolate-obsession/video.html?v=872683587753', 'only_matching': True, @@ -48,58 +78,83 @@ class CorusIE(ThePlatformFeedIE): }, { 'url': 'https://www.bigbrothercanada.ca/video/big-brother-canada-704/1457812035894/', 'only_matching': True + }, { + 'url': 'https://www.seriesplus.com/emissions/dre-mary-mort-sur-ordonnance/videos/deux-coeurs-battant/SERP0055626330000200/', + 'only_matching': True + }, { + 'url': 'https://www.disneychannel.ca/shows/gabby-duran-the-unsittables/video/crybaby-duran-clip/2f557eec-0588-11ea-ae2b-e2c6776b770e/', + 'only_matching': True }] - - _TP_FEEDS = { - 'globaltv': { - 'feed_id': 'ChQqrem0lNUp', - 'account_id': 2269680845, - }, - 'etcanada': { - 'feed_id': 'ChQqrem0lNUp', - 'account_id': 2269680845, - }, - 'hgtv': { - 'feed_id': 'L0BMHXi2no43', - 'account_id': 2414428465, - }, - 'foodnetwork': { - 'feed_id': 'ukK8o58zbRmJ', - 'account_id': 2414429569, - }, - 'slice': { - 'feed_id': '5tUJLgV2YNJ5', - 'account_id': 2414427935, - }, - 'history': { - 'feed_id': 'tQFx_TyyEq4J', - 'account_id': 2369613659, - }, - 'showcase': { - 'feed_id': '9H6qyshBZU3E', - 'account_id': 2414426607, - }, - 'bigbrothercanada': { - 'feed_id': 'ChQqrem0lNUp', - 'account_id': 2269680845, - }, + _GEO_BYPASS = False + _SITE_MAP = { + 'globaltv': 'series', + 'etcanada': 'series', + 'foodnetwork': 'food', + 'bigbrothercanada': 'series', + 'disneychannel': 'disneyen', + 'disneylachaine': 'disneyfr', } def _real_extract(self, url): domain, video_id = re.match(self._VALID_URL, url).groups() - feed_info = self._TP_FEEDS[domain.split('.')[0]] - return self._extract_feed_info('dtjsEC', feed_info['feed_id'], 'byId=' + video_id, video_id, lambda e: { - 'episode_number': int_or_none(e.get('pl1$episode')), - 'season_number': int_or_none(e.get('pl1$season')), - 'series': e.get('pl1$show'), - }, { - 'HLS': { - 'manifest': 'm3u', - }, - 'DesktopHLS Default': { - 'manifest': 'm3u', - }, - 'MP4 MBR': { - 'manifest': 'm3u', - }, - }, feed_info['account_id']) + site = domain.split('.')[0] + path = self._SITE_MAP.get(site, site) + if path != 'series': + path = 'migration/' + path + video = self._download_json( + 'https://globalcontent.corusappservices.com/templates/%s/playlist/' % path, + video_id, query={'byId': video_id}, + headers={'Accept': 'application/json'})[0] + title = video['title'] + + formats = [] + for source in video.get('sources', []): + smil_url = source.get('file') + if not smil_url: + continue + source_type = source.get('type') + note = 'Downloading%s smil file' % (' ' + source_type if source_type else '') + resp = self._download_webpage( + smil_url, video_id, note, fatal=False, + headers=self.geo_verification_headers()) + if not resp: + continue + error = self._parse_json(resp, video_id, fatal=False) + if error: + if error.get('exception') == 'GeoLocationBlocked': + self.raise_geo_restricted(countries=['CA']) + raise ExtractorError(error['description']) + smil = self._parse_xml(resp, video_id, fatal=False) + if smil is None: + continue + namespace = self._parse_smil_namespace(smil) + formats.extend(self._parse_smil_formats( + smil, smil_url, video_id, namespace)) + if not formats and video.get('drm'): + raise ExtractorError('This video is DRM protected.', expected=True) + self._sort_formats(formats) + + subtitles = {} + for track in video.get('tracks', []): + track_url = track.get('file') + if not track_url: + continue + lang = 'fr' if site in ('disneylachaine', 'seriesplus') else 'en' + subtitles.setdefault(lang, []).append({'url': track_url}) + + metadata = video.get('metadata') or {} + get_number = lambda x: int_or_none(video.get('pl1$' + x) or metadata.get(x + 'Number')) + + return { + 'id': video_id, + 'title': title, + 'formats': formats, + 'thumbnail': dict_get(video, ('defaultThumbnailUrl', 'thumbnail', 'image')), + 'description': video.get('description'), + 'timestamp': int_or_none(video.get('availableDate'), 1000), + 'subtitles': subtitles, + 'duration': float_or_none(metadata.get('duration')), + 'series': dict_get(video, ('show', 'pl1$show')), + 'season_number': get_number('season'), + 'episode_number': get_number('episode'), + } diff --git a/youtube_dl/extractor/dailymotion.py b/youtube_dl/extractor/dailymotion.py index 7459719..327fdb0 100644 --- a/youtube_dl/extractor/dailymotion.py +++ b/youtube_dl/extractor/dailymotion.py @@ -1,50 +1,93 @@ # coding: utf-8 from __future__ import unicode_literals -import base64 import functools -import hashlib -import itertools import json -import random import re -import string from .common import InfoExtractor -from ..compat import compat_struct_pack +from ..compat import compat_HTTPError from ..utils import ( - determine_ext, - error_to_compat_str, + age_restricted, + clean_html, ExtractorError, int_or_none, - mimetype2ext, OnDemandPagedList, - parse_iso8601, - sanitized_Request, - str_to_int, try_get, unescapeHTML, - update_url_query, - url_or_none, urlencode_postdata, ) class DailymotionBaseInfoExtractor(InfoExtractor): - @staticmethod - def _build_request(url): - """Build a request with the family filter disabled""" - request = sanitized_Request(url) - request.add_header('Cookie', 'family_filter=off; ff=off') - return request + _FAMILY_FILTER = None + _HEADERS = { + 'Content-Type': 'application/json', + 'Origin': 'https://www.dailymotion.com', + } + _NETRC_MACHINE = 'dailymotion' - def _download_webpage_handle_no_ff(self, url, *args, **kwargs): - request = self._build_request(url) - return self._download_webpage_handle(request, *args, **kwargs) + def _get_dailymotion_cookies(self): + return self._get_cookies('https://www.dailymotion.com/') - def _download_webpage_no_ff(self, url, *args, **kwargs): - request = self._build_request(url) - return self._download_webpage(request, *args, **kwargs) + @staticmethod + def _get_cookie_value(cookies, name): + cookie = cookies.get('name') + if cookie: + return cookie.value + + def _set_dailymotion_cookie(self, name, value): + self._set_cookie('www.dailymotion.com', name, value) + + def _real_initialize(self): + cookies = self._get_dailymotion_cookies() + ff = self._get_cookie_value(cookies, 'ff') + self._FAMILY_FILTER = ff == 'on' if ff else age_restricted(18, self._downloader.params.get('age_limit')) + self._set_dailymotion_cookie('ff', 'on' if self._FAMILY_FILTER else 'off') + + def _call_api(self, object_type, xid, object_fields, note, filter_extra=None): + if not self._HEADERS.get('Authorization'): + cookies = self._get_dailymotion_cookies() + token = self._get_cookie_value(cookies, 'access_token') or self._get_cookie_value(cookies, 'client_token') + if not token: + data = { + 'client_id': 'f1a362d288c1b98099c7', + 'client_secret': 'eea605b96e01c796ff369935357eca920c5da4c5', + } + username, password = self._get_login_info() + if username: + data.update({ + 'grant_type': 'password', + 'password': password, + 'username': username, + }) + else: + data['grant_type'] = 'client_credentials' + try: + token = self._download_json( + 'https://graphql.api.dailymotion.com/oauth/token', + None, 'Downloading Access Token', + data=urlencode_postdata(data))['access_token'] + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 400: + raise ExtractorError(self._parse_json( + e.cause.read().decode(), xid)['error_description'], expected=True) + raise + self._set_dailymotion_cookie('access_token' if username else 'client_token', token) + self._HEADERS['Authorization'] = 'Bearer ' + token + + resp = self._download_json( + 'https://graphql.api.dailymotion.com/', xid, note, data=json.dumps({ + 'query': '''{ + %s(xid: "%s"%s) { + %s + } +}''' % (object_type, xid, ', ' + filter_extra if filter_extra else '', object_fields), + }).encode(), headers=self._HEADERS) + obj = resp['data'][object_type] + if not obj: + raise ExtractorError(resp['errors'][0]['message'], expected=True) + return obj class DailymotionIE(DailymotionBaseInfoExtractor): @@ -54,18 +97,9 @@ class DailymotionIE(DailymotionBaseInfoExtractor): (?:(?:www|touch)\.)?dailymotion\.[a-z]{2,3}/(?:(?:(?:embed|swf|\#)/)?video|swf)| (?:www\.)?lequipe\.fr/video ) - /(?P[^/?_]+) + /(?P[^/?_]+)(?:.+?\bplaylist=(?Px[0-9a-z]+))? ''' IE_NAME = 'dailymotion' - - _FORMATS = [ - ('stream_h264_ld_url', 'ld'), - ('stream_h264_url', 'standard'), - ('stream_h264_hq_url', 'hq'), - ('stream_h264_hd_url', 'hd'), - ('stream_h264_hd1080_url', 'hd180'), - ] - _TESTS = [{ 'url': 'http://www.dailymotion.com/video/x5kesuj_office-christmas-party-review-jason-bateman-olivia-munn-t-j-miller_news', 'md5': '074b95bdee76b9e3654137aee9c79dfe', @@ -74,7 +108,6 @@ class DailymotionIE(DailymotionBaseInfoExtractor): 'ext': 'mp4', 'title': 'Office Christmas Party Review – Jason Bateman, Olivia Munn, T.J. Miller', 'description': 'Office Christmas Party Review - Jason Bateman, Olivia Munn, T.J. Miller', - 'thumbnail': r're:^https?:.*\.(?:jpg|png)$', 'duration': 187, 'timestamp': 1493651285, 'upload_date': '20170501', @@ -146,7 +179,16 @@ class DailymotionIE(DailymotionBaseInfoExtractor): }, { 'url': 'https://www.lequipe.fr/video/k7MtHciueyTcrFtFKA2', 'only_matching': True, + }, { + 'url': 'https://www.dailymotion.com/video/x3z49k?playlist=xv4bw', + 'only_matching': True, }] + _GEO_BYPASS = False + _COMMON_MEDIA_FIELDS = '''description + geoblockedCountries { + allowed + } + xid''' @staticmethod def _extract_urls(webpage): @@ -162,264 +204,140 @@ class DailymotionIE(DailymotionBaseInfoExtractor): return urls def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage_no_ff( - 'https://www.dailymotion.com/video/%s' % video_id, video_id) - - age_limit = self._rta_search(webpage) - - description = self._og_search_description( - webpage, default=None) or self._html_search_meta( - 'description', webpage, 'description') - - view_count_str = self._search_regex( - (r']+itemprop="interactionCount"[^>]+content="UserPlays:([\s\d,.]+)"', - r'video_views_count[^>]+>\s+([\s\d\,.]+)'), - webpage, 'view count', default=None) - if view_count_str: - view_count_str = re.sub(r'\s', '', view_count_str) - view_count = str_to_int(view_count_str) - comment_count = int_or_none(self._search_regex( - r']+itemprop="interactionCount"[^>]+content="UserComments:(\d+)"', - webpage, 'comment count', default=None)) - - player_v5 = self._search_regex( - [r'buildPlayer\(({.+?})\);\n', # See https://github.com/ytdl-org/youtube-dl/issues/7826 - r'playerV5\s*=\s*dmp\.create\([^,]+?,\s*({.+?})\);', - r'buildPlayer\(({.+?})\);', - r'var\s+config\s*=\s*({.+?});', - # New layout regex (see https://github.com/ytdl-org/youtube-dl/issues/13580) - r'__PLAYER_CONFIG__\s*=\s*({.+?});'], - webpage, 'player v5', default=None) - if player_v5: - player = self._parse_json(player_v5, video_id, fatal=False) or {} - metadata = try_get(player, lambda x: x['metadata'], dict) - if not metadata: - metadata_url = url_or_none(try_get( - player, lambda x: x['context']['metadata_template_url1'])) - if metadata_url: - metadata_url = metadata_url.replace(':videoId', video_id) - else: - metadata_url = update_url_query( - 'https://www.dailymotion.com/player/metadata/video/%s' - % video_id, { - 'embedder': url, - 'integration': 'inline', - 'GK_PV5_NEON': '1', - }) - metadata = self._download_json( - metadata_url, video_id, 'Downloading metadata JSON') - - if try_get(metadata, lambda x: x['error']['type']) == 'password_protected': - password = self._downloader.params.get('videopassword') - if password: - r = int(metadata['id'][1:], 36) - us64e = lambda x: base64.urlsafe_b64encode(x).decode().strip('=') - t = ''.join(random.choice(string.ascii_letters) for i in range(10)) - n = us64e(compat_struct_pack('I', r)) - i = us64e(hashlib.md5(('%s%d%s' % (password, r, t)).encode()).digest()) - metadata = self._download_json( - 'http://www.dailymotion.com/player/metadata/video/p' + i + t + n, video_id) - - self._check_error(metadata) - - formats = [] - for quality, media_list in metadata['qualities'].items(): - for media in media_list: - media_url = media.get('url') - if not media_url: - continue - type_ = media.get('type') - if type_ == 'application/vnd.lumberjack.manifest': - continue - ext = mimetype2ext(type_) or determine_ext(media_url) - if ext == 'm3u8': - m3u8_formats = self._extract_m3u8_formats( - media_url, video_id, 'mp4', preference=-1, - m3u8_id='hls', fatal=False) - for f in m3u8_formats: - f['url'] = f['url'].split('#')[0] - formats.append(f) - elif ext == 'f4m': - formats.extend(self._extract_f4m_formats( - media_url, video_id, preference=-1, f4m_id='hds', fatal=False)) - else: - f = { - 'url': media_url, - 'format_id': 'http-%s' % quality, - 'ext': ext, - } - m = re.search(r'H264-(?P\d+)x(?P\d+)', media_url) - if m: - f.update({ - 'width': int(m.group('width')), - 'height': int(m.group('height')), - }) - formats.append(f) - self._sort_formats(formats) - - title = metadata['title'] - duration = int_or_none(metadata.get('duration')) - timestamp = int_or_none(metadata.get('created_time')) - thumbnail = metadata.get('poster_url') - uploader = metadata.get('owner', {}).get('screenname') - uploader_id = metadata.get('owner', {}).get('id') - - subtitles = {} - subtitles_data = metadata.get('subtitles', {}).get('data', {}) - if subtitles_data and isinstance(subtitles_data, dict): - for subtitle_lang, subtitle in subtitles_data.items(): - subtitles[subtitle_lang] = [{ - 'ext': determine_ext(subtitle_url), - 'url': subtitle_url, - } for subtitle_url in subtitle.get('urls', [])] - - return { - 'id': video_id, - 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'duration': duration, - 'timestamp': timestamp, - 'uploader': uploader, - 'uploader_id': uploader_id, - 'age_limit': age_limit, - 'view_count': view_count, - 'comment_count': comment_count, - 'formats': formats, - 'subtitles': subtitles, - } - - # vevo embed - vevo_id = self._search_regex( - r'[\w]*)', - webpage, 'vevo embed', default=None) - if vevo_id: - return self.url_result('vevo:%s' % vevo_id, 'Vevo') - - # fallback old player - embed_page = self._download_webpage_no_ff( - 'https://www.dailymotion.com/embed/video/%s' % video_id, - video_id, 'Downloading embed page') - - timestamp = parse_iso8601(self._html_search_meta( - 'video:release_date', webpage, 'upload date')) - - info = self._parse_json( - self._search_regex( - r'var info = ({.*?}),$', embed_page, - 'video info', flags=re.MULTILINE), - video_id) - - self._check_error(info) + video_id, playlist_id = re.match(self._VALID_URL, url).groups() + + if playlist_id: + if not self._downloader.params.get('noplaylist'): + self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % playlist_id) + return self.url_result( + 'http://www.dailymotion.com/playlist/' + playlist_id, + 'DailymotionPlaylist', playlist_id) + self.to_screen('Downloading just video %s because of --no-playlist' % video_id) + + password = self._downloader.params.get('videopassword') + media = self._call_api( + 'media', video_id, '''... on Video { + %s + stats { + likes { + total + } + views { + total + } + } + } + ... on Live { + %s + audienceCount + isOnAir + }''' % (self._COMMON_MEDIA_FIELDS, self._COMMON_MEDIA_FIELDS), 'Downloading media JSON metadata', + 'password: "%s"' % self._downloader.params.get('videopassword') if password else None) + xid = media['xid'] + + metadata = self._download_json( + 'https://www.dailymotion.com/player/metadata/video/' + xid, + xid, 'Downloading metadata JSON', + query={'app': 'com.dailymotion.neon'}) + + error = metadata.get('error') + if error: + title = error.get('title') or error['raw_message'] + # See https://developer.dailymotion.com/api#access-error + if error.get('code') == 'DM007': + allowed_countries = try_get(media, lambda x: x['geoblockedCountries']['allowed'], list) + self.raise_geo_restricted(msg=title, countries=allowed_countries) + raise ExtractorError( + '%s said: %s' % (self.IE_NAME, title), expected=True) + title = metadata['title'] + is_live = media.get('isOnAir') formats = [] - for (key, format_id) in self._FORMATS: - video_url = info.get(key) - if video_url is not None: - m_size = re.search(r'H264-(\d+)x(\d+)', video_url) - if m_size is not None: - width, height = map(int_or_none, (m_size.group(1), m_size.group(2))) + for quality, media_list in metadata['qualities'].items(): + for m in media_list: + media_url = m.get('url') + media_type = m.get('type') + if not media_url or media_type == 'application/vnd.lumberjack.manifest': + continue + if media_type == 'application/x-mpegURL': + formats.extend(self._extract_m3u8_formats( + media_url, video_id, 'mp4', + 'm3u8' if is_live else 'm3u8_native', + m3u8_id='hls', fatal=False)) else: - width, height = None, None - formats.append({ - 'url': video_url, - 'ext': 'mp4', - 'format_id': format_id, - 'width': width, - 'height': height, - }) + f = { + 'url': media_url, + 'format_id': 'http-' + quality, + } + m = re.search(r'/H264-(\d+)x(\d+)(?:-(60)/)?', media_url) + if m: + width, height, fps = map(int_or_none, m.groups()) + f.update({ + 'fps': fps, + 'height': height, + 'width': width, + }) + formats.append(f) + for f in formats: + f['url'] = f['url'].split('#')[0] + if not f.get('fps') and f['format_id'].endswith('@60'): + f['fps'] = 60 self._sort_formats(formats) - # subtitles - video_subtitles = self.extract_subtitles(video_id, webpage) - - title = self._og_search_title(webpage, default=None) - if title is None: - title = self._html_search_regex( - r'(?s)]*>(.*?)', webpage, - 'title') + subtitles = {} + subtitles_data = try_get(metadata, lambda x: x['subtitles']['data'], dict) or {} + for subtitle_lang, subtitle in subtitles_data.items(): + subtitles[subtitle_lang] = [{ + 'url': subtitle_url, + } for subtitle_url in subtitle.get('urls', [])] + + thumbnails = [] + for height, poster_url in metadata.get('posters', {}).items(): + thumbnails.append({ + 'height': int_or_none(height), + 'id': height, + 'url': poster_url, + }) + + owner = metadata.get('owner') or {} + stats = media.get('stats') or {} + get_count = lambda x: int_or_none(try_get(stats, lambda y: y[x + 's']['total'])) return { 'id': video_id, + 'title': self._live_title(title) if is_live else title, + 'description': clean_html(media.get('description')), + 'thumbnails': thumbnails, + 'duration': int_or_none(metadata.get('duration')) or None, + 'timestamp': int_or_none(metadata.get('created_time')), + 'uploader': owner.get('screenname'), + 'uploader_id': owner.get('id') or metadata.get('screenname'), + 'age_limit': 18 if metadata.get('explicit') else 0, + 'tags': metadata.get('tags'), + 'view_count': get_count('view') or int_or_none(media.get('audienceCount')), + 'like_count': get_count('like'), 'formats': formats, - 'uploader': info['owner.screenname'], - 'timestamp': timestamp, - 'title': title, - 'description': description, - 'subtitles': video_subtitles, - 'thumbnail': info['thumbnail_url'], - 'age_limit': age_limit, - 'view_count': view_count, - 'duration': info['duration'] + 'subtitles': subtitles, + 'is_live': is_live, } - def _check_error(self, info): - error = info.get('error') - if error: - title = error.get('title') or error['message'] - # See https://developer.dailymotion.com/api#access-error - if error.get('code') == 'DM007': - self.raise_geo_restricted(msg=title) - raise ExtractorError( - '%s said: %s' % (self.IE_NAME, title), expected=True) - - def _get_subtitles(self, video_id, webpage): - try: - sub_list = self._download_webpage( - 'https://api.dailymotion.com/video/%s/subtitles?fields=id,language,url' % video_id, - video_id, note=False) - except ExtractorError as err: - self._downloader.report_warning('unable to download video subtitles: %s' % error_to_compat_str(err)) - return {} - info = json.loads(sub_list) - if (info['total'] > 0): - sub_lang_list = dict((l['language'], [{'url': l['url'], 'ext': 'srt'}]) for l in info['list']) - return sub_lang_list - self._downloader.report_warning('video doesn\'t have subtitles') - return {} - -class DailymotionPlaylistIE(DailymotionBaseInfoExtractor): - IE_NAME = 'dailymotion:playlist' - _VALID_URL = r'(?:https?://)?(?:www\.)?dailymotion\.[a-z]{2,3}/playlist/(?Px[0-9a-z]+)' - _TESTS = [{ - 'url': 'http://www.dailymotion.com/playlist/xv4bw_nqtv_sport/1#video=xl8v3q', - 'info_dict': { - 'title': 'SPORT', - 'id': 'xv4bw', - }, - 'playlist_mincount': 20, - }] +class DailymotionPlaylistBaseIE(DailymotionBaseInfoExtractor): _PAGE_SIZE = 100 - def _fetch_page(self, playlist_id, authorizaion, page): + def _fetch_page(self, playlist_id, page): page += 1 - videos = self._download_json( - 'https://graphql.api.dailymotion.com', - playlist_id, 'Downloading page %d' % page, - data=json.dumps({ - 'query': '''{ - collection(xid: "%s") { - videos(first: %d, page: %d) { - pageInfo { - hasNextPage - nextPage - } + videos = self._call_api( + self._OBJECT_TYPE, playlist_id, + '''videos(allowExplicit: %s, first: %d, page: %d) { edges { node { xid url } } - } - } -}''' % (playlist_id, self._PAGE_SIZE, page) - }).encode(), headers={ - 'Authorization': authorizaion, - 'Origin': 'https://www.dailymotion.com', - })['data']['collection']['videos'] + }''' % ('false' if self._FAMILY_FILTER else 'true', self._PAGE_SIZE, page), + 'Downloading page %d' % page)['videos'] for edge in videos['edges']: node = edge['node'] yield self.url_result( @@ -427,86 +345,49 @@ class DailymotionPlaylistIE(DailymotionBaseInfoExtractor): def _real_extract(self, url): playlist_id = self._match_id(url) - webpage = self._download_webpage(url, playlist_id) - api = self._parse_json(self._search_regex( - r'__PLAYER_CONFIG__\s*=\s*({.+?});', - webpage, 'player config'), playlist_id)['context']['api'] - auth = self._download_json( - api.get('auth_url', 'https://graphql.api.dailymotion.com/oauth/token'), - playlist_id, data=urlencode_postdata({ - 'client_id': api.get('client_id', 'f1a362d288c1b98099c7'), - 'client_secret': api.get('client_secret', 'eea605b96e01c796ff369935357eca920c5da4c5'), - 'grant_type': 'client_credentials', - })) - authorizaion = '%s %s' % (auth.get('token_type', 'Bearer'), auth['access_token']) entries = OnDemandPagedList(functools.partial( - self._fetch_page, playlist_id, authorizaion), self._PAGE_SIZE) + self._fetch_page, playlist_id), self._PAGE_SIZE) return self.playlist_result( - entries, playlist_id, - self._og_search_title(webpage)) + entries, playlist_id) + + +class DailymotionPlaylistIE(DailymotionPlaylistBaseIE): + IE_NAME = 'dailymotion:playlist' + _VALID_URL = r'(?:https?://)?(?:www\.)?dailymotion\.[a-z]{2,3}/playlist/(?Px[0-9a-z]+)' + _TESTS = [{ + 'url': 'http://www.dailymotion.com/playlist/xv4bw_nqtv_sport/1#video=xl8v3q', + 'info_dict': { + 'id': 'xv4bw', + }, + 'playlist_mincount': 20, + }] + _OBJECT_TYPE = 'collection' -class DailymotionUserIE(DailymotionBaseInfoExtractor): +class DailymotionUserIE(DailymotionPlaylistBaseIE): IE_NAME = 'dailymotion:user' - _VALID_URL = r'https?://(?:www\.)?dailymotion\.[a-z]{2,3}/(?!(?:embed|swf|#|video|playlist)/)(?:(?:old/)?user/)?(?P[^/]+)' - _MORE_PAGES_INDICATOR = r'(?s)
.*?[^/]+)' _TESTS = [{ 'url': 'https://www.dailymotion.com/user/nqtv', 'info_dict': { 'id': 'nqtv', - 'title': 'Rémi Gaillard', }, - 'playlist_mincount': 100, + 'playlist_mincount': 152, }, { 'url': 'http://www.dailymotion.com/user/UnderProject', 'info_dict': { 'id': 'UnderProject', - 'title': 'UnderProject', }, - 'playlist_mincount': 1800, - 'expected_warnings': [ - 'Stopped at duplicated page', - ], + 'playlist_mincount': 1000, 'skip': 'Takes too long time', + }, { + 'url': 'https://www.dailymotion.com/user/nqtv', + 'info_dict': { + 'id': 'nqtv', + }, + 'playlist_mincount': 148, + 'params': { + 'age_limit': 0, + }, }] - - def _extract_entries(self, id): - video_ids = set() - processed_urls = set() - for pagenum in itertools.count(1): - page_url = self._PAGE_TEMPLATE % (id, pagenum) - webpage, urlh = self._download_webpage_handle_no_ff( - page_url, id, 'Downloading page %s' % pagenum) - if urlh.geturl() in processed_urls: - self.report_warning('Stopped at duplicated page %s, which is the same as %s' % ( - page_url, urlh.geturl()), id) - break - - processed_urls.add(urlh.geturl()) - - for video_id in re.findall(r'data-xid="(.+?)"', webpage): - if video_id not in video_ids: - yield self.url_result( - 'http://www.dailymotion.com/video/%s' % video_id, - DailymotionIE.ie_key(), video_id) - video_ids.add(video_id) - - if re.search(self._MORE_PAGES_INDICATOR, webpage) is None: - break - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - user = mobj.group('user') - webpage = self._download_webpage( - 'https://www.dailymotion.com/user/%s' % user, user) - full_user = unescapeHTML(self._html_search_regex( - r'' % re.escape(user), - webpage, 'user')) - - return { - '_type': 'playlist', - 'id': user, - 'title': full_user, - 'entries': self._extract_entries(user), - } + _OBJECT_TYPE = 'channel' diff --git a/youtube_dl/extractor/daisuki.py b/youtube_dl/extractor/daisuki.py deleted file mode 100644 index dbc1aa5..0000000 --- a/youtube_dl/extractor/daisuki.py +++ /dev/null @@ -1,154 +0,0 @@ -from __future__ import unicode_literals - -import base64 -import json -import random -import re - -from .common import InfoExtractor -from ..aes import ( - aes_cbc_decrypt, - aes_cbc_encrypt, -) -from ..compat import compat_b64decode -from ..utils import ( - bytes_to_intlist, - bytes_to_long, - extract_attributes, - ExtractorError, - intlist_to_bytes, - js_to_json, - int_or_none, - long_to_bytes, - pkcs1pad, -) - - -class DaisukiMottoIE(InfoExtractor): - _VALID_URL = r'https?://motto\.daisuki\.net/framewatch/embed/[^/]+/(?P[0-9a-zA-Z]{3})' - - _TEST = { - 'url': 'http://motto.daisuki.net/framewatch/embed/embedDRAGONBALLSUPERUniverseSurvivalsaga/V2e/760/428', - 'info_dict': { - 'id': 'V2e', - 'ext': 'mp4', - 'title': '#117 SHOWDOWN OF LOVE! ANDROIDS VS UNIVERSE 2!!', - 'subtitles': { - 'mul': [{ - 'ext': 'ttml', - }], - }, - }, - 'params': { - 'skip_download': True, # AES-encrypted HLS stream - }, - } - - # The public key in PEM format can be found in clientlibs_anime_watch.min.js - _RSA_KEY = (0xc5524c25e8e14b366b3754940beeb6f96cb7e2feef0b932c7659a0c5c3bf173d602464c2df73d693b513ae06ff1be8f367529ab30bf969c5640522181f2a0c51ea546ae120d3d8d908595e4eff765b389cde080a1ef7f1bbfb07411cc568db73b7f521cedf270cbfbe0ddbc29b1ac9d0f2d8f4359098caffee6d07915020077d, 65537) - - def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - - flashvars = self._parse_json(self._search_regex( - r'(?s)var\s+flashvars\s*=\s*({.+?});', webpage, 'flashvars'), - video_id, transform_source=js_to_json) - - iv = [0] * 16 - - data = {} - for key in ('device_cd', 'mv_id', 'ss1_prm', 'ss2_prm', 'ss3_prm', 'ss_id'): - data[key] = flashvars.get(key, '') - - encrypted_rtn = None - - # Some AES keys are rejected. Try it with different AES keys - for idx in range(5): - aes_key = [random.randint(0, 254) for _ in range(32)] - padded_aeskey = intlist_to_bytes(pkcs1pad(aes_key, 128)) - - n, e = self._RSA_KEY - encrypted_aeskey = long_to_bytes(pow(bytes_to_long(padded_aeskey), e, n)) - init_data = self._download_json( - 'http://motto.daisuki.net/fastAPI/bgn/init/', - video_id, query={ - 's': flashvars.get('s', ''), - 'c': flashvars.get('ss3_prm', ''), - 'e': url, - 'd': base64.b64encode(intlist_to_bytes(aes_cbc_encrypt( - bytes_to_intlist(json.dumps(data)), - aes_key, iv))).decode('ascii'), - 'a': base64.b64encode(encrypted_aeskey).decode('ascii'), - }, note='Downloading JSON metadata' + (' (try #%d)' % (idx + 1) if idx > 0 else '')) - - if 'rtn' in init_data: - encrypted_rtn = init_data['rtn'] - break - - self._sleep(5, video_id) - - if encrypted_rtn is None: - raise ExtractorError('Failed to fetch init data') - - rtn = self._parse_json( - intlist_to_bytes(aes_cbc_decrypt(bytes_to_intlist( - compat_b64decode(encrypted_rtn)), - aes_key, iv)).decode('utf-8').rstrip('\0'), - video_id) - - title = rtn['title_str'] - - formats = self._extract_m3u8_formats( - rtn['play_url'], video_id, ext='mp4', entry_protocol='m3u8_native') - - subtitles = {} - caption_url = rtn.get('caption_url') - if caption_url: - # mul: multiple languages - subtitles['mul'] = [{ - 'url': caption_url, - 'ext': 'ttml', - }] - - return { - 'id': video_id, - 'title': title, - 'formats': formats, - 'subtitles': subtitles, - } - - -class DaisukiMottoPlaylistIE(InfoExtractor): - _VALID_URL = r'https?://motto\.daisuki\.net/(?Pinformation)/' - - _TEST = { - 'url': 'http://motto.daisuki.net/information/', - 'info_dict': { - 'title': 'DRAGON BALL SUPER', - }, - 'playlist_mincount': 117, - } - - def _real_extract(self, url): - playlist_id = self._match_id(url) - - webpage = self._download_webpage(url, playlist_id) - - entries = [] - for li in re.findall(r'(]+?data-product_id="[a-zA-Z0-9]{3}"[^>]+>)', webpage): - attr = extract_attributes(li) - ad_id = attr.get('data-ad_id') - product_id = attr.get('data-product_id') - if ad_id and product_id: - episode_id = attr.get('data-chapter') - entries.append({ - '_type': 'url_transparent', - 'url': 'http://motto.daisuki.net/framewatch/embed/%s/%s/760/428' % (ad_id, product_id), - 'episode_id': episode_id, - 'episode_number': int_or_none(episode_id), - 'ie_key': 'DaisukiMotto', - }) - - return self.playlist_result(entries, playlist_title='DRAGON BALL SUPER') diff --git a/youtube_dl/extractor/daum.py b/youtube_dl/extractor/daum.py index 76f0218..1370955 100644 --- a/youtube_dl/extractor/daum.py +++ b/youtube_dl/extractor/daum.py @@ -2,25 +2,21 @@ from __future__ import unicode_literals -import re import itertools from .common import InfoExtractor from ..compat import ( compat_parse_qs, compat_urllib_parse_unquote, - compat_urllib_parse_urlencode, compat_urlparse, ) -from ..utils import ( - int_or_none, - str_to_int, - xpath_text, - unescapeHTML, -) -class DaumIE(InfoExtractor): +class DaumBaseIE(InfoExtractor): + _KAKAO_EMBED_BASE = 'http://tv.kakao.com/embed/player/cliplink/' + + +class DaumIE(DaumBaseIE): _VALID_URL = r'https?://(?:(?:m\.)?tvpot\.daum\.net/v/|videofarm\.daum\.net/controller/player/VodPlayer\.swf\?vid=)(?P[^?#&]+)' IE_NAME = 'daum.net' @@ -36,6 +32,9 @@ class DaumIE(InfoExtractor): 'duration': 2117, 'view_count': int, 'comment_count': int, + 'uploader_id': 186139, + 'uploader': '콘간지', + 'timestamp': 1387310323, }, }, { 'url': 'http://m.tvpot.daum.net/v/65139429', @@ -44,11 +43,14 @@ class DaumIE(InfoExtractor): 'ext': 'mp4', 'title': '1297회, \'아빠 아들로 태어나길 잘 했어\' 민수, 감동의 눈물[아빠 어디가] 20150118', 'description': 'md5:79794514261164ff27e36a21ad229fc5', - 'upload_date': '20150604', + 'upload_date': '20150118', 'thumbnail': r're:^https?://.*\.(?:jpg|png)', 'duration': 154, 'view_count': int, 'comment_count': int, + 'uploader': 'MBC 예능', + 'uploader_id': 132251, + 'timestamp': 1421604228, }, }, { 'url': 'http://tvpot.daum.net/v/07dXWRka62Y%24', @@ -59,12 +61,15 @@ class DaumIE(InfoExtractor): 'id': 'vwIpVpCQsT8$', 'ext': 'flv', 'title': '01-Korean War ( Trouble on the horizon )', - 'description': '\nKorean War 01\nTrouble on the horizon\n전쟁의 먹구름', + 'description': 'Korean War 01\r\nTrouble on the horizon\r\n전쟁의 먹구름', 'upload_date': '20080223', 'thumbnail': r're:^https?://.*\.(?:jpg|png)', 'duration': 249, 'view_count': int, 'comment_count': int, + 'uploader': '까칠한 墮落始祖 황비홍님의', + 'uploader_id': 560824, + 'timestamp': 1203770745, }, }, { # Requires dte_type=WEB (#9972) @@ -73,60 +78,24 @@ class DaumIE(InfoExtractor): 'info_dict': { 'id': 's3794Uf1NZeZ1qMpGpeqeRU', 'ext': 'mp4', - 'title': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny) [쇼! 음악중심] 508회 20160611', - 'description': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)\n\n[쇼! 음악중심] 20160611, 507회', - 'upload_date': '20160611', + 'title': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)', + 'description': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)\r\n\r\n[쇼! 음악중심] 20160611, 507회', + 'upload_date': '20170129', + 'uploader': '쇼! 음악중심', + 'uploader_id': 2653210, + 'timestamp': 1485684628, }, }] def _real_extract(self, url): video_id = compat_urllib_parse_unquote(self._match_id(url)) - movie_data = self._download_json( - 'http://videofarm.daum.net/controller/api/closed/v1_2/IntegratedMovieData.json', - video_id, 'Downloading video formats info', query={'vid': video_id, 'dte_type': 'WEB'}) - - # For urls like http://m.tvpot.daum.net/v/65139429, where the video_id is really a clipid - if not movie_data.get('output_list', {}).get('output_list') and re.match(r'^\d+$', video_id): - return self.url_result('http://tvpot.daum.net/clip/ClipView.do?clipid=%s' % video_id) - - info = self._download_xml( - 'http://tvpot.daum.net/clip/ClipInfoXml.do', video_id, - 'Downloading video info', query={'vid': video_id}) - - formats = [] - for format_el in movie_data['output_list']['output_list']: - profile = format_el['profile'] - format_query = compat_urllib_parse_urlencode({ - 'vid': video_id, - 'profile': profile, - }) - url_doc = self._download_xml( - 'http://videofarm.daum.net/controller/api/open/v1_2/MovieLocation.apixml?' + format_query, - video_id, note='Downloading video data for %s format' % profile) - format_url = url_doc.find('result/url').text - formats.append({ - 'url': format_url, - 'format_id': profile, - 'width': int_or_none(format_el.get('width')), - 'height': int_or_none(format_el.get('height')), - 'filesize': int_or_none(format_el.get('filesize')), - }) - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': info.find('TITLE').text, - 'formats': formats, - 'thumbnail': xpath_text(info, 'THUMB_URL'), - 'description': xpath_text(info, 'CONTENTS'), - 'duration': int_or_none(xpath_text(info, 'DURATION')), - 'upload_date': info.find('REGDTTM').text[:8], - 'view_count': str_to_int(xpath_text(info, 'PLAY_CNT')), - 'comment_count': str_to_int(xpath_text(info, 'COMMENT_CNT')), - } + if not video_id.isdigit(): + video_id += '@my' + return self.url_result( + self._KAKAO_EMBED_BASE + video_id, 'Kakao', video_id) -class DaumClipIE(InfoExtractor): +class DaumClipIE(DaumBaseIE): _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/(?:clip/ClipView.(?:do|tv)|mypot/View.do)\?.*?clipid=(?P\d+)' IE_NAME = 'daum.net:clip' _URL_TEMPLATE = 'http://tvpot.daum.net/clip/ClipView.do?clipid=%s' @@ -142,6 +111,9 @@ class DaumClipIE(InfoExtractor): 'thumbnail': r're:^https?://.*\.(?:jpg|png)', 'duration': 3868, 'view_count': int, + 'uploader': 'GOMeXP', + 'uploader_id': 6667, + 'timestamp': 1377911092, }, }, { 'url': 'http://m.tvpot.daum.net/clip/ClipView.tv?clipid=54999425', @@ -154,22 +126,8 @@ class DaumClipIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - clip_info = self._download_json( - 'http://tvpot.daum.net/mypot/json/GetClipInfo.do?clipid=%s' % video_id, - video_id, 'Downloading clip info')['clip_bean'] - - return { - '_type': 'url_transparent', - 'id': video_id, - 'url': 'http://tvpot.daum.net/v/%s' % clip_info['vid'], - 'title': unescapeHTML(clip_info['title']), - 'thumbnail': clip_info.get('thumb_url'), - 'description': clip_info.get('contents'), - 'duration': int_or_none(clip_info.get('duration')), - 'upload_date': clip_info.get('up_date')[:8], - 'view_count': int_or_none(clip_info.get('play_count')), - 'ie_key': 'Daum', - } + return self.url_result( + self._KAKAO_EMBED_BASE + video_id, 'Kakao', video_id) class DaumListIE(InfoExtractor): diff --git a/youtube_dl/extractor/dctp.py b/youtube_dl/extractor/dctp.py index 04ff214..e700f8d 100644 --- a/youtube_dl/extractor/dctp.py +++ b/youtube_dl/extractor/dctp.py @@ -16,10 +16,11 @@ class DctpTvIE(InfoExtractor): _TESTS = [{ # 4x3 'url': 'http://www.dctp.tv/filme/videoinstallation-fuer-eine-kaufhausfassade/', + 'md5': '3ffbd1556c3fe210724d7088fad723e3', 'info_dict': { 'id': '95eaa4f33dad413aa17b4ee613cccc6c', 'display_id': 'videoinstallation-fuer-eine-kaufhausfassade', - 'ext': 'flv', + 'ext': 'm4v', 'title': 'Videoinstallation für eine Kaufhausfassade', 'description': 'Kurzfilm', 'thumbnail': r're:^https?://.*\.jpg$', @@ -27,10 +28,6 @@ class DctpTvIE(InfoExtractor): 'timestamp': 1302172322, 'upload_date': '20110407', }, - 'params': { - # rtmp download - 'skip_download': True, - }, }, { # 16x9 'url': 'http://www.dctp.tv/filme/sind-youtuber-die-besseren-lehrer/', @@ -59,33 +56,26 @@ class DctpTvIE(InfoExtractor): uuid = media['uuid'] title = media['title'] - ratio = '16x9' if media.get('is_wide') else '4x3' - play_path = 'mp4:%s_dctp_0500_%s.m4v' % (uuid, ratio) - - servers = self._download_json( - 'http://www.dctp.tv/streaming_servers/', display_id, - note='Downloading server list JSON', fatal=False) - - if servers: - endpoint = next( - server['endpoint'] - for server in servers - if url_or_none(server.get('endpoint')) - and 'cloudfront' in server['endpoint']) - else: - endpoint = 'rtmpe://s2pqqn4u96e4j8.cloudfront.net/cfx/st/' - - app = self._search_regex( - r'^rtmpe?://[^/]+/(?P.*)$', endpoint, 'app') - - formats = [{ - 'url': endpoint, - 'app': app, - 'play_path': play_path, - 'page_url': url, - 'player_url': 'http://svm-prod-dctptv-static.s3.amazonaws.com/dctptv-relaunch2012-110.swf', - 'ext': 'flv', - }] + is_wide = media.get('is_wide') + formats = [] + + def add_formats(suffix): + templ = 'https://%%s/%s_dctp_%s.m4v' % (uuid, suffix) + formats.extend([{ + 'format_id': 'hls-' + suffix, + 'url': templ % 'cdn-segments.dctp.tv' + '/playlist.m3u8', + 'protocol': 'm3u8_native', + }, { + 'format_id': 's3-' + suffix, + 'url': templ % 'completed-media.s3.amazonaws.com', + }, { + 'format_id': 'http-' + suffix, + 'url': templ % 'cdn-media.dctp.tv', + }]) + + add_formats('0500_' + ('16x9' if is_wide else '4x3')) + if is_wide: + add_formats('720p') thumbnails = [] images = media.get('images') diff --git a/youtube_dl/extractor/discovery.py b/youtube_dl/extractor/discovery.py index 6a2712c..e0139cc 100644 --- a/youtube_dl/extractor/discovery.py +++ b/youtube_dl/extractor/discovery.py @@ -13,8 +13,8 @@ from ..compat import compat_HTTPError class DiscoveryIE(DiscoveryGoBaseIE): _VALID_URL = r'''(?x)https?:// (?P - (?:(?:www|go)\.)?discovery| - (?:www\.)? + go\.discovery| + www\. (?: investigationdiscovery| discoverylife| @@ -22,8 +22,7 @@ class DiscoveryIE(DiscoveryGoBaseIE): ahctv| destinationamerica| sciencechannel| - tlc| - velocity + tlc )| watch\. (?: @@ -83,7 +82,7 @@ class DiscoveryIE(DiscoveryGoBaseIE): 'authRel': 'authorization', 'client_id': '3020a40c2356a645b4b4', 'nonce': ''.join([random.choice(string.ascii_letters) for _ in range(32)]), - 'redirectUri': 'https://fusion.ddmcdn.com/app/mercury-sdk/180/redirectHandler.html?https://www.%s.com' % site, + 'redirectUri': 'https://www.discovery.com/', })['access_token'] headers = self.geo_verification_headers() diff --git a/youtube_dl/extractor/discoverynetworks.py b/youtube_dl/extractor/discoverynetworks.py index fba1ef2..607a549 100644 --- a/youtube_dl/extractor/discoverynetworks.py +++ b/youtube_dl/extractor/discoverynetworks.py @@ -3,63 +3,38 @@ from __future__ import unicode_literals import re -from .brightcove import BrightcoveLegacyIE from .dplay import DPlayIE -from ..compat import ( - compat_parse_qs, - compat_urlparse, -) -from ..utils import smuggle_url class DiscoveryNetworksDeIE(DPlayIE): - _VALID_URL = r'''(?x)https?://(?:www\.)?(?Pdiscovery|tlc|animalplanet|dmax)\.de/ - (?: - .*\#(?P\d+)| - (?:[^/]+/)*videos/(?P[^/?#]+)| - programme/(?P[^/]+)/video/(?P[^/]+) - )''' + _VALID_URL = r'https?://(?:www\.)?(?P(?:tlc|dmax)\.de|dplay\.co\.uk)/(?:programme|show)/(?P[^/]+)/video/(?P[^/]+)' _TESTS = [{ - 'url': 'http://www.tlc.de/sendungen/breaking-amish/videos/#3235167922001', + 'url': 'https://www.tlc.de/programme/breaking-amish/video/die-welt-da-drauen/DCB331270001100', 'info_dict': { - 'id': '3235167922001', + 'id': '78867', 'ext': 'mp4', - 'title': 'Breaking Amish: Die Welt da draußen', - 'description': ( - 'Vier Amische und eine Mennonitin wagen in New York' - ' den Sprung in ein komplett anderes Leben. Begleitet sie auf' - ' ihrem spannenden Weg.'), - 'timestamp': 1396598084, - 'upload_date': '20140404', - 'uploader_id': '1659832546', + 'title': 'Die Welt da draußen', + 'description': 'md5:61033c12b73286e409d99a41742ef608', + 'timestamp': 1554069600, + 'upload_date': '20190331', + }, + 'params': { + 'format': 'bestvideo', + 'skip_download': True, }, }, { - 'url': 'http://www.dmax.de/programme/storage-hunters-uk/videos/storage-hunters-uk-episode-6/', + 'url': 'https://www.dmax.de/programme/dmax-highlights/video/tuning-star-sidney-hoffmann-exklusiv-bei-dmax/191023082312316', 'only_matching': True, }, { - 'url': 'http://www.discovery.de/#5332316765001', + 'url': 'https://www.dplay.co.uk/show/ghost-adventures/video/hotel-leger-103620/EHD_280313B', 'only_matching': True, }] - BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/1659832546/default_default/index.html?videoId=%s' def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - alternate_id = mobj.group('alternate_id') - if alternate_id: - self._initialize_geo_bypass({ - 'countries': ['DE'], - }) - return self._get_disco_api_info( - url, '%s/%s' % (mobj.group('programme'), alternate_id), - 'sonic-eu1-prod.disco-api.com', mobj.group('site') + 'de') - brightcove_id = mobj.group('id') - if not brightcove_id: - title = mobj.group('title') - webpage = self._download_webpage(url, title) - brightcove_legacy_url = BrightcoveLegacyIE._extract_brightcove_url(webpage) - brightcove_id = compat_parse_qs(compat_urlparse.urlparse( - brightcove_legacy_url).query)['@videoPlayer'][0] - return self.url_result(smuggle_url( - self.BRIGHTCOVE_URL_TEMPLATE % brightcove_id, {'geo_countries': ['DE']}), - 'BrightcoveNew', brightcove_id) + domain, programme, alternate_id = re.match(self._VALID_URL, url).groups() + country = 'GB' if domain == 'dplay.co.uk' else 'DE' + realm = 'questuk' if country == 'GB' else domain.replace('.', '') + return self._get_disco_api_info( + url, '%s/%s' % (programme, alternate_id), + 'sonic-eu1-prod.disco-api.com', realm, country) diff --git a/youtube_dl/extractor/dplay.py b/youtube_dl/extractor/dplay.py index ebf5951..a7b9db5 100644 --- a/youtube_dl/extractor/dplay.py +++ b/youtube_dl/extractor/dplay.py @@ -1,74 +1,68 @@ # coding: utf-8 from __future__ import unicode_literals -import json import re -import time from .common import InfoExtractor -from ..compat import ( - compat_HTTPError, - compat_str, - compat_urlparse, -) +from ..compat import compat_HTTPError from ..utils import ( determine_ext, ExtractorError, float_or_none, int_or_none, - remove_end, - try_get, - unified_strdate, unified_timestamp, - update_url_query, - urljoin, - USER_AGENTS, ) class DPlayIE(InfoExtractor): - _VALID_URL = r'https?://(?Pwww\.(?Pdplay\.(?Pdk|se|no)))/(?:video(?:er|s)/)?(?P[^/]+/[^/?#]+)' + _VALID_URL = r'''(?x)https?:// + (?P + (?:www\.)?(?Pdplay\.(?Pdk|fi|jp|se|no))| + (?Pes|it)\.dplay\.com + )/[^/]+/(?P[^/]+/[^/?#]+)''' _TESTS = [{ # non geo restricted, via secure api, unsigned download hls URL - 'url': 'http://www.dplay.se/nugammalt-77-handelser-som-format-sverige/season-1-svensken-lar-sig-njuta-av-livet/', + 'url': 'https://www.dplay.se/videos/nugammalt-77-handelser-som-format-sverige/nugammalt-77-handelser-som-format-sverige-101', 'info_dict': { - 'id': '3172', - 'display_id': 'nugammalt-77-handelser-som-format-sverige/season-1-svensken-lar-sig-njuta-av-livet', + 'id': '13628', + 'display_id': 'nugammalt-77-handelser-som-format-sverige/nugammalt-77-handelser-som-format-sverige-101', 'ext': 'mp4', 'title': 'Svensken lär sig njuta av livet', 'description': 'md5:d3819c9bccffd0fe458ca42451dd50d8', - 'duration': 2650, - 'timestamp': 1365454320, + 'duration': 2649.856, + 'timestamp': 1365453720, 'upload_date': '20130408', - 'creator': 'Kanal 5 (Home)', + 'creator': 'Kanal 5', 'series': 'Nugammalt - 77 händelser som format Sverige', 'season_number': 1, 'episode_number': 1, - 'age_limit': 0, + }, + 'params': { + 'format': 'bestvideo', + 'skip_download': True, }, }, { # geo restricted, via secure api, unsigned download hls URL - 'url': 'http://www.dplay.dk/mig-og-min-mor/season-6-episode-12/', + 'url': 'http://www.dplay.dk/videoer/ted-bundy-mind-of-a-monster/ted-bundy-mind-of-a-monster', 'info_dict': { - 'id': '70816', - 'display_id': 'mig-og-min-mor/season-6-episode-12', + 'id': '104465', + 'display_id': 'ted-bundy-mind-of-a-monster/ted-bundy-mind-of-a-monster', 'ext': 'mp4', - 'title': 'Episode 12', - 'description': 'md5:9c86e51a93f8a4401fc9641ef9894c90', - 'duration': 2563, - 'timestamp': 1429696800, - 'upload_date': '20150422', - 'creator': 'Kanal 4 (Home)', - 'series': 'Mig og min mor', - 'season_number': 6, - 'episode_number': 12, - 'age_limit': 0, + 'title': 'Ted Bundy: Mind Of A Monster', + 'description': 'md5:8b780f6f18de4dae631668b8a9637995', + 'duration': 5290.027, + 'timestamp': 1570694400, + 'upload_date': '20191010', + 'creator': 'ID - Investigation Discovery', + 'series': 'Ted Bundy: Mind Of A Monster', + 'season_number': 1, + 'episode_number': 1, + }, + 'params': { + 'format': 'bestvideo', + 'skip_download': True, }, - }, { - # geo restricted, via direct unsigned hls URL - 'url': 'http://www.dplay.no/pga-tour/season-1-hoydepunkter-18-21-februar/', - 'only_matching': True, }, { # disco-api 'url': 'https://www.dplay.no/videoer/i-kongens-klr/sesong-1-episode-7', @@ -89,19 +83,59 @@ class DPlayIE(InfoExtractor): 'format': 'bestvideo', 'skip_download': True, }, + 'skip': 'Available for Premium users', }, { - - 'url': 'https://www.dplay.dk/videoer/singleliv/season-5-episode-3', + 'url': 'http://it.dplay.com/nove/biografie-imbarazzanti/luigi-di-maio-la-psicosi-di-stanislawskij/', + 'md5': '2b808ffb00fc47b884a172ca5d13053c', + 'info_dict': { + 'id': '6918', + 'display_id': 'biografie-imbarazzanti/luigi-di-maio-la-psicosi-di-stanislawskij', + 'ext': 'mp4', + 'title': 'Luigi Di Maio: la psicosi di Stanislawskij', + 'description': 'md5:3c7a4303aef85868f867a26f5cc14813', + 'thumbnail': r're:^https?://.*\.jpe?g', + 'upload_date': '20160524', + 'timestamp': 1464076800, + 'series': 'Biografie imbarazzanti', + 'season_number': 1, + 'episode': 'Episode 1', + 'episode_number': 1, + }, + }, { + 'url': 'https://es.dplay.com/dmax/la-fiebre-del-oro/temporada-8-episodio-1/', + 'info_dict': { + 'id': '21652', + 'display_id': 'la-fiebre-del-oro/temporada-8-episodio-1', + 'ext': 'mp4', + 'title': 'Episodio 1', + 'description': 'md5:b9dcff2071086e003737485210675f69', + 'thumbnail': r're:^https?://.*\.png', + 'upload_date': '20180709', + 'timestamp': 1531173540, + 'series': 'La fiebre del oro', + 'season_number': 8, + 'episode': 'Episode 1', + 'episode_number': 1, + }, + 'params': { + 'skip_download': True, + }, + }, { + 'url': 'https://www.dplay.fi/videot/shifting-gears-with-aaron-kaufman/episode-16', 'only_matching': True, }, { - 'url': 'https://www.dplay.se/videos/sofias-anglar/sofias-anglar-1001', + 'url': 'https://www.dplay.jp/video/gold-rush/24086', 'only_matching': True, }] - def _get_disco_api_info(self, url, display_id, disco_host, realm): - disco_base = 'https://' + disco_host + def _get_disco_api_info(self, url, display_id, disco_host, realm, country): + geo_countries = [country.upper()] + self._initialize_geo_bypass({ + 'countries': geo_countries, + }) + disco_base = 'https://%s/' % disco_host token = self._download_json( - '%s/token' % disco_base, display_id, 'Downloading token', + disco_base + 'token', display_id, 'Downloading token', query={ 'realm': realm, })['data']['attributes']['token'] @@ -110,17 +144,35 @@ class DPlayIE(InfoExtractor): 'Authorization': 'Bearer ' + token, } video = self._download_json( - '%s/content/videos/%s' % (disco_base, display_id), display_id, + disco_base + 'content/videos/' + display_id, display_id, headers=headers, query={ - 'include': 'show' + 'fields[channel]': 'name', + 'fields[image]': 'height,src,width', + 'fields[show]': 'name', + 'fields[tag]': 'name', + 'fields[video]': 'description,episodeNumber,name,publishStart,seasonNumber,videoDuration', + 'include': 'images,primaryChannel,show,tags' }) video_id = video['data']['id'] info = video['data']['attributes'] - title = info['name'] + title = info['name'].strip() formats = [] - for format_id, format_dict in self._download_json( - '%s/playback/videoPlaybackInfo/%s' % (disco_base, video_id), - display_id, headers=headers)['data']['attributes']['streaming'].items(): + try: + streaming = self._download_json( + disco_base + 'playback/videoPlaybackInfo/' + video_id, + display_id, headers=headers)['data']['attributes']['streaming'] + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403: + info = self._parse_json(e.cause.read().decode('utf-8'), display_id) + error = info['errors'][0] + error_code = error.get('code') + if error_code == 'access.denied.geoblocked': + self.raise_geo_restricted(countries=geo_countries) + elif error_code == 'access.denied.missingpackage': + self.raise_login_required() + raise ExtractorError(info['errors'][0]['detail'], expected=True) + raise + for format_id, format_dict in streaming.items(): if not isinstance(format_dict, dict): continue format_url = format_dict.get('url') @@ -142,235 +194,54 @@ class DPlayIE(InfoExtractor): }) self._sort_formats(formats) - series = None - try: - included = video.get('included') - if isinstance(included, list): - show = next(e for e in included if e.get('type') == 'show') - series = try_get( - show, lambda x: x['attributes']['name'], compat_str) - except StopIteration: - pass + creator = series = None + tags = [] + thumbnails = [] + included = video.get('included') or [] + if isinstance(included, list): + for e in included: + attributes = e.get('attributes') + if not attributes: + continue + e_type = e.get('type') + if e_type == 'channel': + creator = attributes.get('name') + elif e_type == 'image': + src = attributes.get('src') + if src: + thumbnails.append({ + 'url': src, + 'width': int_or_none(attributes.get('width')), + 'height': int_or_none(attributes.get('height')), + }) + if e_type == 'show': + series = attributes.get('name') + elif e_type == 'tag': + name = attributes.get('name') + if name: + tags.append(name) return { 'id': video_id, 'display_id': display_id, 'title': title, 'description': info.get('description'), - 'duration': float_or_none( - info.get('videoDuration'), scale=1000), + 'duration': float_or_none(info.get('videoDuration'), 1000), 'timestamp': unified_timestamp(info.get('publishStart')), 'series': series, 'season_number': int_or_none(info.get('seasonNumber')), 'episode_number': int_or_none(info.get('episodeNumber')), - 'age_limit': int_or_none(info.get('minimum_age')), + 'creator': creator, + 'tags': tags, + 'thumbnails': thumbnails, 'formats': formats, } def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) display_id = mobj.group('id') - domain = mobj.group('domain') - - self._initialize_geo_bypass({ - 'countries': [mobj.group('country').upper()], - }) - - webpage = self._download_webpage(url, display_id) - - video_id = self._search_regex( - r'data-video-id=["\'](\d+)', webpage, 'video id', default=None) - - if not video_id: - host = mobj.group('host') - return self._get_disco_api_info( - url, display_id, 'disco-api.' + host, host.replace('.', '')) - - info = self._download_json( - 'http://%s/api/v2/ajax/videos?video_id=%s' % (domain, video_id), - video_id)['data'][0] - - title = info['title'] - - PROTOCOLS = ('hls', 'hds') - formats = [] - - def extract_formats(protocol, manifest_url): - if protocol == 'hls': - m3u8_formats = self._extract_m3u8_formats( - manifest_url, video_id, ext='mp4', - entry_protocol='m3u8_native', m3u8_id=protocol, fatal=False) - # Sometimes final URLs inside m3u8 are unsigned, let's fix this - # ourselves. Also fragments' URLs are only served signed for - # Safari user agent. - query = compat_urlparse.parse_qs(compat_urlparse.urlparse(manifest_url).query) - for m3u8_format in m3u8_formats: - m3u8_format.update({ - 'url': update_url_query(m3u8_format['url'], query), - 'http_headers': { - 'User-Agent': USER_AGENTS['Safari'], - }, - }) - formats.extend(m3u8_formats) - elif protocol == 'hds': - formats.extend(self._extract_f4m_formats( - manifest_url + '&hdcore=3.8.0&plugin=flowplayer-3.8.0.0', - video_id, f4m_id=protocol, fatal=False)) - - domain_tld = domain.split('.')[-1] - if domain_tld in ('se', 'dk', 'no'): - for protocol in PROTOCOLS: - # Providing dsc-geo allows to bypass geo restriction in some cases - self._set_cookie( - 'secure.dplay.%s' % domain_tld, 'dsc-geo', - json.dumps({ - 'countryCode': domain_tld.upper(), - 'expiry': (time.time() + 20 * 60) * 1000, - })) - stream = self._download_json( - 'https://secure.dplay.%s/secure/api/v2/user/authorization/stream/%s?stream_type=%s' - % (domain_tld, video_id, protocol), video_id, - 'Downloading %s stream JSON' % protocol, fatal=False) - if stream and stream.get(protocol): - extract_formats(protocol, stream[protocol]) - - # The last resort is to try direct unsigned hls/hds URLs from info dictionary. - # Sometimes this does work even when secure API with dsc-geo has failed (e.g. - # http://www.dplay.no/pga-tour/season-1-hoydepunkter-18-21-februar/). - if not formats: - for protocol in PROTOCOLS: - if info.get(protocol): - extract_formats(protocol, info[protocol]) - - self._sort_formats(formats) - - subtitles = {} - for lang in ('se', 'sv', 'da', 'nl', 'no'): - for format_id in ('web_vtt', 'vtt', 'srt'): - subtitle_url = info.get('subtitles_%s_%s' % (lang, format_id)) - if subtitle_url: - subtitles.setdefault(lang, []).append({'url': subtitle_url}) - - return { - 'id': video_id, - 'display_id': display_id, - 'title': title, - 'description': info.get('video_metadata_longDescription'), - 'duration': int_or_none(info.get('video_metadata_length'), scale=1000), - 'timestamp': int_or_none(info.get('video_publish_date')), - 'creator': info.get('video_metadata_homeChannel'), - 'series': info.get('video_metadata_show'), - 'season_number': int_or_none(info.get('season')), - 'episode_number': int_or_none(info.get('episode')), - 'age_limit': int_or_none(info.get('minimum_age')), - 'formats': formats, - 'subtitles': subtitles, - } - - -class DPlayItIE(InfoExtractor): - _VALID_URL = r'https?://it\.dplay\.com/[^/]+/[^/]+/(?P[^/?#]+)' - _GEO_COUNTRIES = ['IT'] - _TEST = { - 'url': 'http://it.dplay.com/nove/biografie-imbarazzanti/luigi-di-maio-la-psicosi-di-stanislawskij/', - 'md5': '2b808ffb00fc47b884a172ca5d13053c', - 'info_dict': { - 'id': '6918', - 'display_id': 'luigi-di-maio-la-psicosi-di-stanislawskij', - 'ext': 'mp4', - 'title': 'Biografie imbarazzanti: Luigi Di Maio: la psicosi di Stanislawskij', - 'description': 'md5:3c7a4303aef85868f867a26f5cc14813', - 'thumbnail': r're:^https?://.*\.jpe?g', - 'upload_date': '20160524', - 'series': 'Biografie imbarazzanti', - 'season_number': 1, - 'episode': 'Luigi Di Maio: la psicosi di Stanislawskij', - 'episode_number': 1, - }, - } - - def _real_extract(self, url): - display_id = self._match_id(url) - - webpage = self._download_webpage(url, display_id) - - title = remove_end(self._og_search_title(webpage), ' | Dplay') - - video_id = None - - info = self._search_regex( - r'playback_json\s*:\s*JSON\.parse\s*\(\s*("(?:\\.|[^"\\])+?")', - webpage, 'playback JSON', default=None) - if info: - for _ in range(2): - info = self._parse_json(info, display_id, fatal=False) - if not info: - break - else: - video_id = try_get(info, lambda x: x['data']['id']) - - if not info: - info_url = self._search_regex( - (r'playback_json_url\s*:\s*(["\'])(?P(?:(?!\1).)+)\1', - r'url\s*[:=]\s*["\'](?P(?:https?:)?//[^/]+/playback/videoPlaybackInfo/\d+)'), - webpage, 'info url', group='url') - - info_url = urljoin(url, info_url) - video_id = info_url.rpartition('/')[-1] - - try: - info = self._download_json( - info_url, display_id, headers={ - 'Authorization': 'Bearer %s' % self._get_cookies(url).get( - 'dplayit_token').value, - 'Referer': url, - }) - if isinstance(info, compat_str): - info = self._parse_json(info, display_id) - except ExtractorError as e: - if isinstance(e.cause, compat_HTTPError) and e.cause.code in (400, 403): - info = self._parse_json(e.cause.read().decode('utf-8'), display_id) - error = info['errors'][0] - if error.get('code') == 'access.denied.geoblocked': - self.raise_geo_restricted( - msg=error.get('detail'), countries=self._GEO_COUNTRIES) - raise ExtractorError(info['errors'][0]['detail'], expected=True) - raise - - hls_url = info['data']['attributes']['streaming']['hls']['url'] - - formats = self._extract_m3u8_formats( - hls_url, display_id, ext='mp4', entry_protocol='m3u8_native', - m3u8_id='hls') - self._sort_formats(formats) - - series = self._html_search_regex( - r'(?s)]+class=["\'].*?\bshow_title\b.*?["\'][^>]*>(.+?)

', - webpage, 'series', fatal=False) - episode = self._search_regex( - r']+class=["\'].*?\bdesc_ep\b.*?["\'][^>]*>\s*
\s*([^<]+)', - webpage, 'episode', fatal=False) - - mobj = re.search( - r'(?s)]+class=["\']dates["\'][^>]*>.+?\bS\.(?P\d+)\s+E\.(?P\d+)\s*-\s*(?P\d{2}/\d{2}/\d{4})', - webpage) - if mobj: - season_number = int(mobj.group('season_number')) - episode_number = int(mobj.group('episode_number')) - upload_date = unified_strdate(mobj.group('upload_date')) - else: - season_number = episode_number = upload_date = None - - return { - 'id': compat_str(video_id or display_id), - 'display_id': display_id, - 'title': title, - 'description': self._og_search_description(webpage), - 'thumbnail': self._og_search_thumbnail(webpage), - 'series': series, - 'season_number': season_number, - 'episode': episode, - 'episode_number': episode_number, - 'upload_date': upload_date, - 'formats': formats, - } + domain = mobj.group('domain').lstrip('www.') + country = mobj.group('country') or mobj.group('subdomain_country') + host = 'disco-api.' + domain if domain.startswith('dplay.') else 'eu2-prod.disco-api.com' + return self._get_disco_api_info( + url, display_id, host, 'dplay' + country, country) diff --git a/youtube_dl/extractor/drtv.py b/youtube_dl/extractor/drtv.py index 218f102..390e79f 100644 --- a/youtube_dl/extractor/drtv.py +++ b/youtube_dl/extractor/drtv.py @@ -17,6 +17,7 @@ from ..utils import ( float_or_none, mimetype2ext, str_or_none, + try_get, unified_timestamp, update_url_query, url_or_none, @@ -24,7 +25,14 @@ from ..utils import ( class DRTVIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?dr\.dk/(?:tv/se|nyheder|radio(?:/ondemand)?)/(?:[^/]+/)*(?P[\da-z-]+)(?:[/#?]|$)' + _VALID_URL = r'''(?x) + https?:// + (?: + (?:www\.)?dr\.dk/(?:tv/se|nyheder|radio(?:/ondemand)?)/(?:[^/]+/)*| + (?:www\.)?(?:dr\.dk|dr-massive\.com)/drtv/(?:se|episode)/ + ) + (?P[\da-z_-]+) + ''' _GEO_BYPASS = False _GEO_COUNTRIES = ['DK'] IE_NAME = 'drtv' @@ -83,6 +91,26 @@ class DRTVIE(InfoExtractor): }, { 'url': 'https://www.dr.dk/radio/p4kbh/regionale-nyheder-kh4/p4-nyheder-2019-06-26-17-30-9', 'only_matching': True, + }, { + 'url': 'https://www.dr.dk/drtv/se/bonderoeven_71769', + 'info_dict': { + 'id': '00951930010', + 'ext': 'mp4', + 'title': 'Bonderøven (1:8)', + 'description': 'md5:3cf18fc0d3b205745d4505f896af8121', + 'timestamp': 1546542000, + 'upload_date': '20190103', + 'duration': 2576.6, + }, + 'params': { + 'skip_download': True, + }, + }, { + 'url': 'https://www.dr.dk/drtv/episode/bonderoeven_71769', + 'only_matching': True, + }, { + 'url': 'https://dr-massive.com/drtv/se/bonderoeven_71769', + 'only_matching': True, }] def _real_extract(self, url): @@ -100,13 +128,32 @@ class DRTVIE(InfoExtractor): webpage, 'video id', default=None) if not video_id: - video_id = compat_urllib_parse_unquote(self._search_regex( + video_id = self._search_regex( r'(urn(?:%3A|:)dr(?:%3A|:)mu(?:%3A|:)programcard(?:%3A|:)[\da-f]+)', - webpage, 'urn')) + webpage, 'urn', default=None) + if video_id: + video_id = compat_urllib_parse_unquote(video_id) + + _PROGRAMCARD_BASE = 'https://www.dr.dk/mu-online/api/1.4/programcard' + query = {'expanded': 'true'} + + if video_id: + programcard_url = '%s/%s' % (_PROGRAMCARD_BASE, video_id) + else: + programcard_url = _PROGRAMCARD_BASE + page = self._parse_json( + self._search_regex( + r'data\s*=\s*({.+?})\s*(?:;|https?)://(?:www\.)?dumpert\.nl/(?:mediabase|embed)/(?P[0-9]+/[0-9a-zA-Z]+)' + _VALID_URL = r'(?Phttps?)://(?:(?:www|legacy)\.)?dumpert\.nl/(?:mediabase|embed|item)/(?P[0-9]+[/_][0-9a-zA-Z]+)' _TESTS = [{ - 'url': 'http://www.dumpert.nl/mediabase/6646981/951bc60f/', + 'url': 'https://www.dumpert.nl/item/6646981_951bc60f', 'md5': '1b9318d7d5054e7dcb9dc7654f21d643', 'info_dict': { 'id': '6646981/951bc60f', @@ -24,46 +21,60 @@ class DumpertIE(InfoExtractor): 'thumbnail': r're:^https?://.*\.jpg$', } }, { - 'url': 'http://www.dumpert.nl/embed/6675421/dc440fe7/', + 'url': 'https://www.dumpert.nl/embed/6675421_dc440fe7', + 'only_matching': True, + }, { + 'url': 'http://legacy.dumpert.nl/mediabase/6646981/951bc60f', + 'only_matching': True, + }, { + 'url': 'http://legacy.dumpert.nl/embed/6675421/dc440fe7', 'only_matching': True, }] def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') - protocol = mobj.group('protocol') - - url = '%s://www.dumpert.nl/mediabase/%s' % (protocol, video_id) - req = sanitized_Request(url) - req.add_header('Cookie', 'nsfw=1; cpc=10') - webpage = self._download_webpage(req, video_id) - - files_base64 = self._search_regex( - r'data-files="([^"]+)"', webpage, 'data files') - - files = self._parse_json( - compat_b64decode(files_base64).decode('utf-8'), - video_id) + video_id = self._match_id(url).replace('_', '/') + item = self._download_json( + 'http://api-live.dumpert.nl/mobile_api/json/info/' + video_id.replace('/', '_'), + video_id)['items'][0] + title = item['title'] + media = next(m for m in item['media'] if m.get('mediatype') == 'VIDEO') quality = qualities(['flv', 'mobile', 'tablet', '720p']) - - formats = [{ - 'url': video_url, - 'format_id': format_id, - 'quality': quality(format_id), - } for format_id, video_url in files.items() if format_id != 'still'] + formats = [] + for variant in media.get('variants', []): + uri = variant.get('uri') + if not uri: + continue + version = variant.get('version') + formats.append({ + 'url': uri, + 'format_id': version, + 'quality': quality(version), + }) self._sort_formats(formats) - title = self._html_search_meta( - 'title', webpage) or self._og_search_title(webpage) - description = self._html_search_meta( - 'description', webpage) or self._og_search_description(webpage) - thumbnail = files.get('still') or self._og_search_thumbnail(webpage) + thumbnails = [] + stills = item.get('stills') or {} + for t in ('thumb', 'still'): + for s in ('', '-medium', '-large'): + still_id = t + s + still_url = stills.get(still_id) + if not still_url: + continue + thumbnails.append({ + 'id': still_id, + 'url': still_url, + }) + + stats = item.get('stats') or {} return { 'id': video_id, 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'formats': formats + 'description': item.get('description'), + 'thumbnails': thumbnails, + 'formats': formats, + 'duration': int_or_none(media.get('duration')), + 'like_count': int_or_none(stats.get('kudos_total')), + 'view_count': int_or_none(stats.get('views_total')), } diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index 44120ca..1cab440 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -18,10 +18,10 @@ from .acast import ( ACastIE, ACastChannelIE, ) -from .addanime import AddAnimeIE from .adn import ADNIE from .adobeconnect import AdobeConnectIE from .adobetv import ( + AdobeTVEmbedIE, AdobeTVIE, AdobeTVShowIE, AdobeTVChannelIE, @@ -80,7 +80,6 @@ from .awaan import ( ) from .azmedien import AZMedienIE from .baidu import BaiduVideoIE -from .bambuser import BambuserIE, BambuserChannelIE from .bandcamp import BandcampIE, BandcampAlbumIE, BandcampWeeklyIE from .bbc import ( BBCCoUkIE, @@ -224,13 +223,13 @@ from .comedycentral import ( ComedyCentralTVIE, ToshIE, ) -from .comcarcoff import ComCarCoffIE from .commonmistakes import CommonMistakesIE, UnicodeBOMIE from .commonprotocols import ( MmsIE, RtmpIE, ) from .condenast import CondeNastIE +from .contv import CONtvIE from .corus import CorusIE from .cracked import CrackedIE from .crackle import CrackleIE @@ -254,10 +253,6 @@ from .dailymotion import ( DailymotionPlaylistIE, DailymotionUserIE, ) -from .daisuki import ( - DaisukiMottoIE, - DaisukiMottoPlaylistIE, -) from .daum import ( DaumIE, DaumClipIE, @@ -276,10 +271,7 @@ from .douyutv import ( DouyuShowIE, DouyuTVIE, ) -from .dplay import ( - DPlayIE, - DPlayItIE, -) +from .dplay import DPlayIE from .dreisat import DreiSatIE from .drbonanza import DRBonanzaIE from .drtuber import DrTuberIE @@ -358,7 +350,6 @@ from .firsttv import FirstTVIE from .fivemin import FiveMinIE from .fivetv import FiveTVIE from .flickr import FlickrIE -from .flipagram import FlipagramIE from .folketinget import FolketingetIE from .footyroom import FootyRoomIE from .formula1 import Formula1IE @@ -369,7 +360,10 @@ from .fourtube import ( FuxIE, ) from .fox import FOXIE -from .fox9 import FOX9IE +from .fox9 import ( + FOX9IE, + FOX9NewsIE, +) from .foxgay import FoxgayIE from .foxnews import ( FoxNewsIE, @@ -402,10 +396,6 @@ from .fusion import FusionIE from .fxnetworks import FXNetworksIE from .gaia import GaiaIE from .gameinformer import GameInformerIE -from .gameone import ( - GameOneIE, - GameOnePlaylistIE, -) from .gamespot import GameSpotIE from .gamestar import GameStarIE from .gaskrank import GaskrankIE @@ -421,7 +411,6 @@ from .globo import ( GloboArticleIE, ) from .go import GoIE -from .go90 import Go90IE from .godtube import GodTubeIE from .golem import GolemIE from .googledrive import GoogleDriveIE @@ -430,7 +419,6 @@ from .googlesearch import GoogleSearchIE from .goshgay import GoshgayIE from .gputechconf import GPUTechConfIE from .groupon import GrouponIE -from .hark import HarkIE from .hbo import HBOIE from .hearthisat import HearThisAtIE from .heise import HeiseIE @@ -462,7 +450,6 @@ from .hungama import ( HungamaSongIE, ) from .hypem import HypemIE -from .iconosquare import IconosquareIE from .ign import ( IGNIE, OneUPIE, @@ -521,10 +508,9 @@ from .keezmovies import KeezMoviesIE from .ketnet import KetnetIE from .khanacademy import KhanAcademyIE from .kickstarter import KickStarterIE +from .kinja import KinjaEmbedIE from .kinopoisk import KinoPoiskIE -from .keek import KeekIE from .konserthusetplay import KonserthusetPlayIE -from .kontrtube import KontrTubeIE from .krasview import KrasViewIE from .ku6 import Ku6IE from .kusi import KUSIIE @@ -548,7 +534,6 @@ from .lcp import ( LcpPlayIE, LcpIE, ) -from .learnr import LearnrIE from .lecture2go import Lecture2GoIE from .lecturio import ( LecturioIE, @@ -600,13 +585,11 @@ from .lynda import ( LyndaCourseIE ) from .m6 import M6IE -from .macgamestore import MacGameStoreIE from .mailru import ( MailRuIE, MailRuMusicIE, MailRuMusicSearchIE, ) -from .makertv import MakerTVIE from .malltv import MallTVIE from .mangomolo import ( MangomoloVideoIE, @@ -640,17 +623,15 @@ from .microsoftvirtualacademy import ( MicrosoftVirtualAcademyIE, MicrosoftVirtualAcademyCourseIE, ) -from .minhateca import MinhatecaIE from .ministrygrid import MinistryGridIE from .minoto import MinotoIE from .miomio import MioMioIE -from .mit import TechTVMITIE, MITIE, OCWMITIE +from .mit import TechTVMITIE, OCWMITIE from .mitele import MiTeleIE from .mixcloud import ( MixcloudIE, MixcloudUserIE, MixcloudPlaylistIE, - MixcloudStreamIE, ) from .mlb import MLBIE from .mnet import MnetIE @@ -672,10 +653,9 @@ from .mtv import ( MTVVideoIE, MTVServicesEmbeddedIE, MTVDEIE, - MTV81IE, + MTVJapanIE, ) from .muenchentv import MuenchenTVIE -from .musicplayon import MusicPlayOnIE from .mwave import MwaveIE, MwaveMeetGreetIE from .mychannels import MyChannelsIE from .myspace import MySpaceIE, MySpaceAlbumIE @@ -815,10 +795,6 @@ from .ooyala import ( OoyalaIE, OoyalaExternalIE, ) -from .openload import ( - OpenloadIE, - VerystreamIE, -) from .ora import OraTVIE from .orf import ( ORFTVthekIE, @@ -832,7 +808,6 @@ from .packtpub import ( PacktPubIE, PacktPubCourseIE, ) -from .pandatv import PandaTVIE from .pandoratv import PandoraTVIE from .parliamentliveuk import ParliamentLiveUKIE from .patreon import PatreonIE @@ -893,7 +868,6 @@ from .puhutv import ( PuhuTVSerieIE, ) from .presstv import PressTVIE -from .promptfile import PromptFileIE from .prosiebensat1 import ProSiebenSat1IE from .puls4 import Puls4IE from .pyvideo import PyvideoIE @@ -945,10 +919,6 @@ from .rentv import ( from .restudy import RestudyIE from .reuters import ReutersIE from .reverbnation import ReverbNationIE -from .revision3 import ( - Revision3EmbedIE, - Revision3IE, -) from .rice import RICEIE from .rmcdecouverte import RMCDecouverteIE from .ro220 import Ro220IE @@ -992,11 +962,17 @@ from .savefrom import SaveFromIE from .sbs import SBSIE from .screencast import ScreencastIE from .screencastomatic import ScreencastOMaticIE -from .scrippsnetworks import ScrippsNetworksWatchIE +from .scrippsnetworks import ( + ScrippsNetworksWatchIE, + ScrippsNetworksIE, +) +from .scte import ( + SCTEIE, + SCTECourseIE, +) from .seeker import SeekerIE from .senateisvp import SenateISVPIE from .sendtonews import SendtoNewsIE -from .servingsys import ServingSysIE from .servus import ServusIE from .sevenplus import SevenPlusIE from .sexu import SexuIE @@ -1037,6 +1013,7 @@ from .snotr import SnotrIE from .sohu import SohuIE from .sonyliv import SonyLIVIE from .soundcloud import ( + SoundcloudEmbedIE, SoundcloudIE, SoundcloudSetIE, SoundcloudUserIE, @@ -1080,7 +1057,6 @@ from .srmediathek import SRMediathekIE from .stanfordoc import StanfordOpenClassroomIE from .steam import SteamIE from .streamable import StreamableIE -from .streamango import StreamangoIE from .streamcloud import StreamcloudIE from .streamcz import StreamCZIE from .streetvoice import StreetVoiceIE @@ -1129,12 +1105,14 @@ from .telegraaf import TelegraafIE from .telemb import TeleMBIE from .telequebec import ( TeleQuebecIE, + TeleQuebecSquatIE, TeleQuebecEmissionIE, TeleQuebecLiveIE, ) from .teletask import TeleTaskIE from .telewebion import TelewebionIE from .tennistv import TennisTVIE +from .tenplay import TenPlayIE from .testurl import TestURLIE from .tf1 import TF1IE from .tfo import TFOIE @@ -1187,10 +1165,14 @@ from .tunein import ( ) from .tunepk import TunePkIE from .turbo import TurboIE -from .tutv import TutvIE from .tv2 import ( TV2IE, TV2ArticleIE, + KatsomoIE, +) +from .tv2dk import ( + TV2DKIE, + TV2DKBornholmPlayIE, ) from .tv2hu import TV2HuIE from .tv4 import TV4IE @@ -1248,13 +1230,17 @@ from .twitter import ( TwitterCardIE, TwitterIE, TwitterAmplifyIE, + TwitterBroadcastIE, ) from .udemy import ( UdemyIE, UdemyCourseIE ) from .udn import UDNEmbedIE -from .ufctv import UFCTVIE +from .ufctv import ( + UFCTVIE, + UFCArabiaIE, +) from .uktvplay import UKTVPlayIE from .digiteka import DigitekaIE from .dlive import ( @@ -1282,7 +1268,6 @@ from .varzesh3 import Varzesh3IE from .vbox7 import Vbox7IE from .veehd import VeeHDIE from .veoh import VeohIE -from .vessel import VesselIE from .vesti import VestiIE from .vevo import ( VevoIE, @@ -1309,7 +1294,6 @@ from .videomore import ( VideomoreVideoIE, VideomoreSeasonIE, ) -from .videopremium import VideoPremiumIE from .videopress import VideoPressIE from .vidio import VidioIE from .vidlii import VidLiiIE @@ -1324,7 +1308,6 @@ from .viewlift import ( ViewLiftIE, ViewLiftEmbedIE, ) -from .viewster import ViewsterIE from .viidea import ViideaIE from .vimeo import ( VimeoIE, @@ -1413,7 +1396,6 @@ from .weibo import ( WeiboMobileIE ) from .weiqitv import WeiqiTVIE -from .wimp import WimpIE from .wistia import WistiaIE from .worldstarhiphop import WorldStarHipHopIE from .wsj import ( diff --git a/youtube_dl/extractor/facebook.py b/youtube_dl/extractor/facebook.py index a3dcdca..ce64e26 100644 --- a/youtube_dl/extractor/facebook.py +++ b/youtube_dl/extractor/facebook.py @@ -334,7 +334,7 @@ class FacebookIE(InfoExtractor): if not video_data: server_js_data = self._parse_json( self._search_regex( - r'bigPipe\.onPageletArrive\(({.+?})\)\s*;\s*}\s*\)\s*,\s*["\']onPageletArrive\s+(?:stream_pagelet|pagelet_group_mall|permalink_video_pagelet)', + r'bigPipe\.onPageletArrive\(({.+?})\)\s*;\s*}\s*\)\s*,\s*["\']onPageletArrive\s+(?:pagelet_group_mall|permalink_video_pagelet|hyperfeed_story_id_\d+)', webpage, 'js data', default='{}'), video_id, transform_source=js_to_json, fatal=False) video_data = extract_from_jsmods_instances(server_js_data) @@ -379,6 +379,7 @@ class FacebookIE(InfoExtractor): if not video_data: raise ExtractorError('Cannot parse data') + subtitles = {} formats = [] for f in video_data: format_id = f['stream_type'] @@ -402,9 +403,17 @@ class FacebookIE(InfoExtractor): if dash_manifest: formats.extend(self._parse_mpd_formats( compat_etree_fromstring(compat_urllib_parse_unquote_plus(dash_manifest)))) + subtitles_src = f[0].get('subtitles_src') + if subtitles_src: + subtitles.setdefault('en', []).append({'url': subtitles_src}) if not formats: raise ExtractorError('Cannot find video formats') + # Downloads with browser's User-Agent are rate limited. Working around + # with non-browser User-Agent. + for f in formats: + f.setdefault('http_headers', {})['User-Agent'] = 'facebookexternalhit/1.1' + self._sort_formats(formats) video_title = self._html_search_regex( @@ -442,6 +451,7 @@ class FacebookIE(InfoExtractor): 'timestamp': timestamp, 'thumbnail': thumbnail, 'view_count': view_count, + 'subtitles': subtitles, } return webpage, info_dict diff --git a/youtube_dl/extractor/flipagram.py b/youtube_dl/extractor/flipagram.py deleted file mode 100644 index b7be40f..0000000 --- a/youtube_dl/extractor/flipagram.py +++ /dev/null @@ -1,115 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..compat import compat_str -from ..utils import ( - int_or_none, - float_or_none, - try_get, - unified_timestamp, -) - - -class FlipagramIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?flipagram\.com/f/(?P[^/?#&]+)' - _TEST = { - 'url': 'https://flipagram.com/f/nyvTSJMKId', - 'md5': '888dcf08b7ea671381f00fab74692755', - 'info_dict': { - 'id': 'nyvTSJMKId', - 'ext': 'mp4', - 'title': 'Flipagram by sjuria101 featuring Midnight Memories by One Direction', - 'description': 'md5:d55e32edc55261cae96a41fa85ff630e', - 'duration': 35.571, - 'timestamp': 1461244995, - 'upload_date': '20160421', - 'uploader': 'kitty juria', - 'uploader_id': 'sjuria101', - 'creator': 'kitty juria', - 'view_count': int, - 'like_count': int, - 'repost_count': int, - 'comment_count': int, - 'comments': list, - 'formats': 'mincount:2', - }, - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - - video_data = self._parse_json( - self._search_regex( - r'window\.reactH2O\s*=\s*({.+});', webpage, 'video data'), - video_id) - - flipagram = video_data['flipagram'] - video = flipagram['video'] - - json_ld = self._search_json_ld(webpage, video_id, default={}) - title = json_ld.get('title') or flipagram['captionText'] - description = json_ld.get('description') or flipagram.get('captionText') - - formats = [{ - 'url': video['url'], - 'width': int_or_none(video.get('width')), - 'height': int_or_none(video.get('height')), - 'filesize': int_or_none(video_data.get('size')), - }] - - preview_url = try_get( - flipagram, lambda x: x['music']['track']['previewUrl'], compat_str) - if preview_url: - formats.append({ - 'url': preview_url, - 'ext': 'm4a', - 'vcodec': 'none', - }) - - self._sort_formats(formats) - - counts = flipagram.get('counts', {}) - user = flipagram.get('user', {}) - video_data = flipagram.get('video', {}) - - thumbnails = [{ - 'url': self._proto_relative_url(cover['url']), - 'width': int_or_none(cover.get('width')), - 'height': int_or_none(cover.get('height')), - 'filesize': int_or_none(cover.get('size')), - } for cover in flipagram.get('covers', []) if cover.get('url')] - - # Note that this only retrieves comments that are initially loaded. - # For videos with large amounts of comments, most won't be retrieved. - comments = [] - for comment in video_data.get('comments', {}).get(video_id, {}).get('items', []): - text = comment.get('comment') - if not text or not isinstance(text, list): - continue - comments.append({ - 'author': comment.get('user', {}).get('name'), - 'author_id': comment.get('user', {}).get('username'), - 'id': comment.get('id'), - 'text': text[0], - 'timestamp': unified_timestamp(comment.get('created')), - }) - - return { - 'id': video_id, - 'title': title, - 'description': description, - 'duration': float_or_none(flipagram.get('duration'), 1000), - 'thumbnails': thumbnails, - 'timestamp': unified_timestamp(flipagram.get('iso8601Created')), - 'uploader': user.get('name'), - 'uploader_id': user.get('username'), - 'creator': user.get('name'), - 'view_count': int_or_none(counts.get('plays')), - 'like_count': int_or_none(counts.get('likes')), - 'repost_count': int_or_none(counts.get('reflips')), - 'comment_count': int_or_none(counts.get('comments')), - 'comments': comments, - 'formats': formats, - } diff --git a/youtube_dl/extractor/fox9.py b/youtube_dl/extractor/fox9.py index 17dfffa..91f8f7b 100644 --- a/youtube_dl/extractor/fox9.py +++ b/youtube_dl/extractor/fox9.py @@ -1,13 +1,23 @@ # coding: utf-8 from __future__ import unicode_literals -from .anvato import AnvatoIE +from .common import InfoExtractor -class FOX9IE(AnvatoIE): - _VALID_URL = r'https?://(?:www\.)?fox9\.com/(?:[^/]+/)+(?P\d+)-story' - _TESTS = [{ - 'url': 'http://www.fox9.com/news/215123287-story', +class FOX9IE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?fox9\.com/video/(?P\d+)' + + def _real_extract(self, url): + video_id = self._match_id(url) + return self.url_result( + 'anvato:anvato_epfox_app_web_prod_b3373168e12f423f41504f207000188daf88251b:' + video_id, + 'Anvato', video_id) + + +class FOX9NewsIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?fox9\.com/news/(?P[^/?&#]+)' + _TEST = { + 'url': 'https://www.fox9.com/news/black-bear-in-tree-draws-crowd-in-downtown-duluth-minnesota', 'md5': 'd6e1b2572c3bab8a849c9103615dd243', 'info_dict': { 'id': '314473', @@ -21,22 +31,11 @@ class FOX9IE(AnvatoIE): 'categories': ['News', 'Sports'], 'tags': ['news', 'video'], }, - }, { - 'url': 'http://www.fox9.com/news/investigators/214070684-story', - 'only_matching': True, - }] + } def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - - video_id = self._parse_json( - self._search_regex( - r"this\.videosJson\s*=\s*'(\[.+?\])';", - webpage, 'anvato playlist'), - video_id)[0]['video'] - - return self._get_anvato_videos( - 'anvato_epfox_app_web_prod_b3373168e12f423f41504f207000188daf88251b', - video_id) + display_id = self._match_id(url) + webpage = self._download_webpage(url, display_id) + anvato_id = self._search_regex( + r'anvatoId\s*:\s*[\'"](\d+)', webpage, 'anvato id') + return self.url_result('https://www.fox9.com/video/' + anvato_id, 'FOX9') diff --git a/youtube_dl/extractor/gameone.py b/youtube_dl/extractor/gameone.py deleted file mode 100644 index a07d698..0000000 --- a/youtube_dl/extractor/gameone.py +++ /dev/null @@ -1,134 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..utils import ( - xpath_with_ns, - parse_iso8601, - float_or_none, - int_or_none, -) - -NAMESPACE_MAP = { - 'media': 'http://search.yahoo.com/mrss/', -} - -# URL prefix to download the mp4 files directly instead of streaming via rtmp -# Credits go to XBox-Maniac -# http://board.jdownloader.org/showpost.php?p=185835&postcount=31 -RAW_MP4_URL = 'http://cdn.riptide-mtvn.com/' - - -class GameOneIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?gameone\.de/tv/(?P\d+)' - _TESTS = [ - { - 'url': 'http://www.gameone.de/tv/288', - 'md5': '136656b7fb4c9cb4a8e2d500651c499b', - 'info_dict': { - 'id': '288', - 'ext': 'mp4', - 'title': 'Game One - Folge 288', - 'duration': 1238, - 'thumbnail': 'http://s3.gameone.de/gameone/assets/video_metas/teaser_images/000/643/636/big/640x360.jpg', - 'description': 'FIFA-Pressepokal 2014, Star Citizen, Kingdom Come: Deliverance, Project Cars, Schöner Trants Nerdquiz Folge 2 Runde 1', - 'age_limit': 16, - 'upload_date': '20140513', - 'timestamp': 1399980122, - } - }, - { - 'url': 'http://gameone.de/tv/220', - 'md5': '5227ca74c4ae6b5f74c0510a7c48839e', - 'info_dict': { - 'id': '220', - 'ext': 'mp4', - 'upload_date': '20120918', - 'description': 'Jet Set Radio HD, Tekken Tag Tournament 2, Source Filmmaker', - 'timestamp': 1347971451, - 'title': 'Game One - Folge 220', - 'duration': 896.62, - 'age_limit': 16, - } - } - - ] - - def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - og_video = self._og_search_video_url(webpage, secure=False) - description = self._html_search_meta('description', webpage) - age_limit = int( - self._search_regex( - r'age=(\d+)', - self._html_search_meta( - 'age-de-meta-label', - webpage), - 'age_limit', - '0')) - mrss_url = self._search_regex(r'mrss=([^&]+)', og_video, 'mrss') - - mrss = self._download_xml(mrss_url, video_id, 'Downloading mrss') - title = mrss.find('.//item/title').text - thumbnail = mrss.find('.//item/image').get('url') - timestamp = parse_iso8601(mrss.find('.//pubDate').text, delimiter=' ') - content = mrss.find(xpath_with_ns('.//media:content', NAMESPACE_MAP)) - content_url = content.get('url') - - content = self._download_xml( - content_url, - video_id, - 'Downloading media:content') - rendition_items = content.findall('.//rendition') - duration = float_or_none(rendition_items[0].get('duration')) - formats = [ - { - 'url': re.sub(r'.*/(r2)', RAW_MP4_URL + r'\1', r.find('./src').text), - 'width': int_or_none(r.get('width')), - 'height': int_or_none(r.get('height')), - 'tbr': int_or_none(r.get('bitrate')), - } - for r in rendition_items - ] - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': title, - 'thumbnail': thumbnail, - 'duration': duration, - 'formats': formats, - 'description': description, - 'age_limit': age_limit, - 'timestamp': timestamp, - } - - -class GameOnePlaylistIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?gameone\.de(?:/tv)?/?$' - IE_NAME = 'gameone:playlist' - _TEST = { - 'url': 'http://www.gameone.de/tv', - 'info_dict': { - 'title': 'GameOne', - }, - 'playlist_mincount': 294, - } - - def _real_extract(self, url): - webpage = self._download_webpage('http://www.gameone.de/tv', 'TV') - max_id = max(map(int, re.findall(r'
]+?src="((?:https?:)?//(?:(?:www|static)\.)?rtl\.nl/(?:system/videoplayer/[^"]+(?:video_)?)?embed[^"]+)"', @@ -2633,9 +2630,9 @@ class GenericIE(InfoExtractor): return self.url_result(mobj.group('url'), 'VK') # Look for embedded Odnoklassniki player - mobj = re.search(r']+?src=(["\'])(?Phttps?://(?:odnoklassniki|ok)\.ru/videoembed/.+?)\1', webpage) - if mobj is not None: - return self.url_result(mobj.group('url'), 'Odnoklassniki') + odnoklassniki_url = OdnoklassnikiIE._extract_url(webpage) + if odnoklassniki_url: + return self.url_result(odnoklassniki_url, OdnoklassnikiIE.ie_key()) # Look for embedded ivi player mobj = re.search(r']+?src=(["\'])(?Phttps?://(?:www\.)?ivi\.ru/video/player.+?)\1', webpage) @@ -2754,9 +2751,9 @@ class GenericIE(InfoExtractor): return self.url_result(myvi_url) # Look for embedded soundcloud player - soundcloud_urls = SoundcloudIE._extract_urls(webpage) + soundcloud_urls = SoundcloudEmbedIE._extract_urls(webpage) if soundcloud_urls: - return self.playlist_from_matches(soundcloud_urls, video_id, video_title, getter=unescapeHTML, ie=SoundcloudIE.ie_key()) + return self.playlist_from_matches(soundcloud_urls, video_id, video_title, getter=unescapeHTML) # Look for tunein player tunein_urls = TuneInBaseIE._extract_urls(webpage) @@ -2899,6 +2896,12 @@ class GenericIE(InfoExtractor): if senate_isvp_url: return self.url_result(senate_isvp_url, 'SenateISVP') + # Look for Kinja embeds + kinja_embed_urls = KinjaEmbedIE._extract_urls(webpage, url) + if kinja_embed_urls: + return self.playlist_from_matches( + kinja_embed_urls, video_id, video_title) + # Look for OnionStudios embeds onionstudios_url = OnionStudiosIE._extract_url(webpage) if onionstudios_url: @@ -2960,7 +2963,7 @@ class GenericIE(InfoExtractor): # Look for VODPlatform embeds mobj = re.search( - r']+src=(["\'])(?P(?:https?:)?//(?:www\.)?vod-platform\.net/[eE]mbed/.+?)\1', + r']+src=(["\'])(?P(?:https?:)?//(?:(?:www\.)?vod-platform\.net|embed\.kwikmotion\.com)/[eE]mbed/.+?)\1', webpage) if mobj is not None: return self.url_result( @@ -2968,10 +2971,14 @@ class GenericIE(InfoExtractor): # Look for Mangomolo embeds mobj = re.search( - r'''(?x)]+src=(["\'])(?P(?:https?:)?//(?:www\.)?admin\.mangomolo\.com/analytics/index\.php/customers/embed/ + r'''(?x)]+src=(["\'])(?P(?:https?:)?// + (?: + admin\.mangomolo\.com/analytics/index\.php/customers/embed| + player\.mangomolo\.com/v1 + )/ (?: video\?.*?\bid=(?P\d+)| - index\?.*?\bchannelid=(?P(?:[A-Za-z0-9+/=]|%2B|%2F|%3D)+) + (?:index|live)\?.*?\bchannelid=(?P(?:[A-Za-z0-9+/=]|%2B|%2F|%3D)+) ).+?)\1''', webpage) if mobj is not None: info = { @@ -3040,18 +3047,6 @@ class GenericIE(InfoExtractor): return self.playlist_from_matches( twentymin_urls, video_id, video_title, ie=TwentyMinutenIE.ie_key()) - # Look for Openload embeds - openload_urls = OpenloadIE._extract_urls(webpage) - if openload_urls: - return self.playlist_from_matches( - openload_urls, video_id, video_title, ie=OpenloadIE.ie_key()) - - # Look for Verystream embeds - verystream_urls = VerystreamIE._extract_urls(webpage) - if verystream_urls: - return self.playlist_from_matches( - verystream_urls, video_id, video_title, ie=VerystreamIE.ie_key()) - # Look for VideoPress embeds videopress_urls = VideoPressIE._extract_urls(webpage) if videopress_urls: diff --git a/youtube_dl/extractor/gfycat.py b/youtube_dl/extractor/gfycat.py index bbe3cb2..18a30fe 100644 --- a/youtube_dl/extractor/gfycat.py +++ b/youtube_dl/extractor/gfycat.py @@ -11,7 +11,7 @@ from ..utils import ( class GfycatIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?gfycat\.com/(?:ru/|ifr/|gifs/detail/)?(?P[^-/?#]+)' + _VALID_URL = r'https?://(?:(?:www|giant|thumbs)\.)?gfycat\.com/(?:ru/|ifr/|gifs/detail/)?(?P[^-/?#\.]+)' _TESTS = [{ 'url': 'http://gfycat.com/DeadlyDecisiveGermanpinscher', 'info_dict': { @@ -53,6 +53,12 @@ class GfycatIE(InfoExtractor): }, { 'url': 'https://gfycat.com/acceptablehappygoluckyharborporpoise-baseball', 'only_matching': True + }, { + 'url': 'https://thumbs.gfycat.com/acceptablehappygoluckyharborporpoise-size_restricted.gif', + 'only_matching': True + }, { + 'url': 'https://giant.gfycat.com/acceptablehappygoluckyharborporpoise.mp4', + 'only_matching': True }] def _real_extract(self, url): diff --git a/youtube_dl/extractor/globo.py b/youtube_dl/extractor/globo.py index fb8f767..60d842d 100644 --- a/youtube_dl/extractor/globo.py +++ b/youtube_dl/extractor/globo.py @@ -96,21 +96,31 @@ class GloboIE(InfoExtractor): video = self._download_json( 'http://api.globovideos.com/videos/%s/playlist' % video_id, video_id)['videos'][0] + if video.get('encrypted') is True: + raise ExtractorError('This video is DRM protected.', expected=True) title = video['title'] formats = [] + subtitles = {} for resource in video['resources']: resource_id = resource.get('_id') resource_url = resource.get('url') - if not resource_id or not resource_url: + resource_type = resource.get('type') + if not resource_url or (resource_type == 'media' and not resource_id) or resource_type not in ('subtitle', 'media'): + continue + + if resource_type == 'subtitle': + subtitles.setdefault(resource.get('language') or 'por', []).append({ + 'url': resource_url, + }) continue security = self._download_json( 'http://security.video.globo.com/videos/%s/hash' % video_id, video_id, 'Downloading security hash for %s' % resource_id, query={ - 'player': 'flash', - 'version': '17.0.0.132', + 'player': 'desktop', + 'version': '5.19.1', 'resource_id': resource_id, }) @@ -123,18 +133,23 @@ class GloboIE(InfoExtractor): continue hash_code = security_hash[:2] - received_time = security_hash[2:12] - received_random = security_hash[12:22] - received_md5 = security_hash[22:] - - sign_time = compat_str(int(received_time) + 86400) padding = '%010d' % random.randint(1, 10000000000) - - md5_data = (received_md5 + sign_time + padding + '0xFF01DD').encode() + if hash_code in ('04', '14'): + received_time = security_hash[3:13] + received_md5 = security_hash[24:] + hash_prefix = security_hash[:23] + elif hash_code in ('02', '12', '03', '13'): + received_time = security_hash[2:12] + received_md5 = security_hash[22:] + padding += '1' + hash_prefix = '05' + security_hash[:22] + + padded_sign_time = compat_str(int(received_time) + 86400) + padding + md5_data = (received_md5 + padded_sign_time + '0xAC10FD').encode() signed_md5 = base64.urlsafe_b64encode(hashlib.md5(md5_data).digest()).decode().strip('=') - signed_hash = hash_code + received_time + received_random + sign_time + padding + signed_md5 + signed_hash = hash_prefix + padded_sign_time + signed_md5 + signed_url = '%s?h=%s&k=html5&a=%s&u=%s' % (resource_url, signed_hash, 'F' if video.get('subscriber_only') else 'A', security.get('user') or '') - signed_url = '%s?h=%s&k=%s' % (resource_url, signed_hash, 'flash') if resource_id.endswith('m3u8') or resource_url.endswith('.m3u8'): formats.extend(self._extract_m3u8_formats( signed_url, resource_id, 'mp4', entry_protocol='m3u8_native', @@ -164,7 +179,8 @@ class GloboIE(InfoExtractor): 'duration': duration, 'uploader': uploader, 'uploader_id': uploader_id, - 'formats': formats + 'formats': formats, + 'subtitles': subtitles, } diff --git a/youtube_dl/extractor/go.py b/youtube_dl/extractor/go.py index 03e48f4..03cfba9 100644 --- a/youtube_dl/extractor/go.py +++ b/youtube_dl/extractor/go.py @@ -40,8 +40,17 @@ class GoIE(AdobePassIE): 'resource_id': 'Disney', } } - _VALID_URL = r'https?://(?:(?:(?P%s)\.)?go|(?Pdisneynow))\.com/(?:(?:[^/]+/)*(?Pvdka\w+)|(?:[^/]+/)*(?P[^/?#]+))'\ - % '|'.join(list(_SITE_INFO.keys()) + ['disneynow']) + _VALID_URL = r'''(?x) + https?:// + (?: + (?:(?P%s)\.)?go| + (?Pabc|freeform|disneynow) + )\.com/ + (?: + (?:[^/]+/)*(?P[Vv][Dd][Kk][Aa]\w+)| + (?:[^/]+/)*(?P[^/?\#]+) + ) + ''' % '|'.join(list(_SITE_INFO.keys())) _TESTS = [{ 'url': 'http://abc.go.com/shows/designated-survivor/video/most-recent/VDKA3807643', 'info_dict': { @@ -54,6 +63,7 @@ class GoIE(AdobePassIE): # m3u8 download 'skip_download': True, }, + 'skip': 'This content is no longer available.', }, { 'url': 'http://watchdisneyxd.go.com/doraemon', 'info_dict': { @@ -61,6 +71,34 @@ class GoIE(AdobePassIE): 'id': 'SH55574025', }, 'playlist_mincount': 51, + }, { + 'url': 'http://freeform.go.com/shows/shadowhunters/episodes/season-2/1-this-guilty-blood', + 'info_dict': { + 'id': 'VDKA3609139', + 'ext': 'mp4', + 'title': 'This Guilty Blood', + 'description': 'md5:f18e79ad1c613798d95fdabfe96cd292', + 'age_limit': 14, + }, + 'params': { + 'geo_bypass_ip_block': '3.244.239.0/24', + # m3u8 download + 'skip_download': True, + }, + }, { + 'url': 'https://abc.com/shows/the-rookie/episode-guide/season-02/03-the-bet', + 'info_dict': { + 'id': 'VDKA13435179', + 'ext': 'mp4', + 'title': 'The Bet', + 'description': 'md5:c66de8ba2e92c6c5c113c3ade84ab404', + 'age_limit': 14, + }, + 'params': { + 'geo_bypass_ip_block': '3.244.239.0/24', + # m3u8 download + 'skip_download': True, + }, }, { 'url': 'http://abc.go.com/shows/the-catch/episode-guide/season-01/10-the-wedding', 'only_matching': True, @@ -95,10 +133,13 @@ class GoIE(AdobePassIE): if not video_id or not site_info: webpage = self._download_webpage(url, display_id or video_id) video_id = self._search_regex( - # There may be inner quotes, e.g. data-video-id="'VDKA3609139'" - # from http://freeform.go.com/shows/shadowhunters/episodes/season-2/1-this-guilty-blood - r'data-video-id=["\']*(VDKA\w+)', webpage, 'video id', - default=video_id) + ( + # There may be inner quotes, e.g. data-video-id="'VDKA3609139'" + # from http://freeform.go.com/shows/shadowhunters/episodes/season-2/1-this-guilty-blood + r'data-video-id=["\']*(VDKA\w+)', + # https://abc.com/shows/the-rookie/episode-guide/season-02/03-the-bet + r'\b(?:video)?id["\']\s*:\s*["\'](VDKA\w+)' + ), webpage, 'video id', default=video_id) if not site_info: brand = self._search_regex( (r'data-brand=\s*["\']\s*(\d+)', diff --git a/youtube_dl/extractor/go90.py b/youtube_dl/extractor/go90.py deleted file mode 100644 index c3ea717..0000000 --- a/youtube_dl/extractor/go90.py +++ /dev/null @@ -1,149 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..compat import compat_HTTPError -from ..utils import ( - determine_ext, - ExtractorError, - int_or_none, - parse_age_limit, - parse_iso8601, -) - - -class Go90IE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?go90\.com/(?:videos|embed)/(?P[0-9a-zA-Z]+)' - _TESTS = [{ - 'url': 'https://www.go90.com/videos/84BUqjLpf9D', - 'md5': 'efa7670dbbbf21a7b07b360652b24a32', - 'info_dict': { - 'id': '84BUqjLpf9D', - 'ext': 'mp4', - 'title': 'Daily VICE - Inside The Utah Coalition Against Pornography Convention', - 'description': 'VICE\'s Karley Sciortino meets with activists who discuss the state\'s strong anti-porn stance. Then, VICE Sports explains NFL contracts.', - 'timestamp': 1491868800, - 'upload_date': '20170411', - 'age_limit': 14, - } - }, { - 'url': 'https://www.go90.com/embed/261MflWkD3N', - 'only_matching': True, - }] - _GEO_BYPASS = False - - def _real_extract(self, url): - video_id = self._match_id(url) - - try: - headers = self.geo_verification_headers() - headers.update({ - 'Content-Type': 'application/json; charset=utf-8', - }) - video_data = self._download_json( - 'https://www.go90.com/api/view/items/' + video_id, video_id, - headers=headers, data=b'{"client":"web","device_type":"pc"}') - except ExtractorError as e: - if isinstance(e.cause, compat_HTTPError) and e.cause.code == 400: - message = self._parse_json(e.cause.read().decode(), None)['error']['message'] - if 'region unavailable' in message: - self.raise_geo_restricted(countries=['US']) - raise ExtractorError(message, expected=True) - raise - - if video_data.get('requires_drm'): - raise ExtractorError('This video is DRM protected.', expected=True) - main_video_asset = video_data['main_video_asset'] - - episode_number = int_or_none(video_data.get('episode_number')) - series = None - season = None - season_id = None - season_number = None - for metadata in video_data.get('__children', {}).get('Item', {}).values(): - if metadata.get('type') == 'show': - series = metadata.get('title') - elif metadata.get('type') == 'season': - season = metadata.get('title') - season_id = metadata.get('id') - season_number = int_or_none(metadata.get('season_number')) - - title = episode = video_data.get('title') or series - if series and series != title: - title = '%s - %s' % (series, title) - - thumbnails = [] - formats = [] - subtitles = {} - for asset in video_data.get('assets'): - if asset.get('id') == main_video_asset: - for source in asset.get('sources', []): - source_location = source.get('location') - if not source_location: - continue - source_type = source.get('type') - if source_type == 'hls': - m3u8_formats = self._extract_m3u8_formats( - source_location, video_id, 'mp4', - 'm3u8_native', m3u8_id='hls', fatal=False) - for f in m3u8_formats: - mobj = re.search(r'/hls-(\d+)-(\d+)K', f['url']) - if mobj: - height, tbr = mobj.groups() - height = int_or_none(height) - f.update({ - 'height': f.get('height') or height, - 'width': f.get('width') or int_or_none(height / 9.0 * 16.0 if height else None), - 'tbr': f.get('tbr') or int_or_none(tbr), - }) - formats.extend(m3u8_formats) - elif source_type == 'dash': - formats.extend(self._extract_mpd_formats( - source_location, video_id, mpd_id='dash', fatal=False)) - else: - formats.append({ - 'format_id': source.get('name'), - 'url': source_location, - 'width': int_or_none(source.get('width')), - 'height': int_or_none(source.get('height')), - 'tbr': int_or_none(source.get('bitrate')), - }) - - for caption in asset.get('caption_metadata', []): - caption_url = caption.get('source_url') - if not caption_url: - continue - subtitles.setdefault(caption.get('language', 'en'), []).append({ - 'url': caption_url, - 'ext': determine_ext(caption_url, 'vtt'), - }) - elif asset.get('type') == 'image': - asset_location = asset.get('location') - if not asset_location: - continue - thumbnails.append({ - 'url': asset_location, - 'width': int_or_none(asset.get('width')), - 'height': int_or_none(asset.get('height')), - }) - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': title, - 'formats': formats, - 'thumbnails': thumbnails, - 'description': video_data.get('short_description'), - 'like_count': int_or_none(video_data.get('like_count')), - 'timestamp': parse_iso8601(video_data.get('released_at')), - 'series': series, - 'episode': episode, - 'season': season, - 'season_id': season_id, - 'season_number': season_number, - 'episode_number': episode_number, - 'subtitles': subtitles, - 'age_limit': parse_age_limit(video_data.get('rating')), - } diff --git a/youtube_dl/extractor/hark.py b/youtube_dl/extractor/hark.py deleted file mode 100644 index 342a613..0000000 --- a/youtube_dl/extractor/hark.py +++ /dev/null @@ -1,33 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor - - -class HarkIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?hark\.com/clips/(?P.+?)-.+' - _TEST = { - 'url': 'http://www.hark.com/clips/mmbzyhkgny-obama-beyond-the-afghan-theater-we-only-target-al-qaeda-on-may-23-2013', - 'md5': '6783a58491b47b92c7c1af5a77d4cbee', - 'info_dict': { - 'id': 'mmbzyhkgny', - 'ext': 'mp3', - 'title': 'Obama: \'Beyond The Afghan Theater, We Only Target Al Qaeda\' on May 23, 2013', - 'description': 'President Barack Obama addressed the nation live on May 23, 2013 in a speech aimed at addressing counter-terrorism policies including the use of drone strikes, detainees at Guantanamo Bay prison facility, and American citizens who are terrorists.', - 'duration': 11, - } - } - - def _real_extract(self, url): - video_id = self._match_id(url) - data = self._download_json( - 'http://www.hark.com/clips/%s.json' % video_id, video_id) - - return { - 'id': video_id, - 'url': data['url'], - 'title': data['name'], - 'description': data.get('description'), - 'thumbnail': data.get('image_original'), - 'duration': data.get('duration'), - } diff --git a/youtube_dl/extractor/hotstar.py b/youtube_dl/extractor/hotstar.py index f9f7c5a..f97eefa 100644 --- a/youtube_dl/extractor/hotstar.py +++ b/youtube_dl/extractor/hotstar.py @@ -118,6 +118,7 @@ class HotStarIE(HotStarBaseIE): if video_data.get('drmProtected'): raise ExtractorError('This video is DRM protected.', expected=True) + headers = {'Referer': url} formats = [] geo_restricted = False playback_sets = self._call_api_v2('h/v2/play', video_id)['playBackSets'] @@ -137,10 +138,11 @@ class HotStarIE(HotStarBaseIE): if 'package:hls' in tags or ext == 'm3u8': formats.extend(self._extract_m3u8_formats( format_url, video_id, 'mp4', - entry_protocol='m3u8_native', m3u8_id='hls')) + entry_protocol='m3u8_native', + m3u8_id='hls', headers=headers)) elif 'package:dash' in tags or ext == 'mpd': formats.extend(self._extract_mpd_formats( - format_url, video_id, mpd_id='dash')) + format_url, video_id, mpd_id='dash', headers=headers)) elif ext == 'f4m': # produce broken files pass @@ -158,6 +160,9 @@ class HotStarIE(HotStarBaseIE): self.raise_geo_restricted(countries=['IN']) self._sort_formats(formats) + for f in formats: + f.setdefault('http_headers', {}).update(headers) + return { 'id': video_id, 'title': title, diff --git a/youtube_dl/extractor/iconosquare.py b/youtube_dl/extractor/iconosquare.py deleted file mode 100644 index a39f422..0000000 --- a/youtube_dl/extractor/iconosquare.py +++ /dev/null @@ -1,85 +0,0 @@ -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..utils import ( - int_or_none, - get_element_by_id, - remove_end, -) - - -class IconosquareIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?(?:iconosquare\.com|statigr\.am)/p/(?P[^/]+)' - _TEST = { - 'url': 'http://statigr.am/p/522207370455279102_24101272', - 'md5': '6eb93b882a3ded7c378ee1d6884b1814', - 'info_dict': { - 'id': '522207370455279102_24101272', - 'ext': 'mp4', - 'title': 'Instagram photo by @aguynamedpatrick (Patrick Janelle)', - 'description': 'md5:644406a9ec27457ed7aa7a9ebcd4ce3d', - 'timestamp': 1376471991, - 'upload_date': '20130814', - 'uploader': 'aguynamedpatrick', - 'uploader_id': '24101272', - 'comment_count': int, - 'like_count': int, - }, - } - - def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - - media = self._parse_json( - get_element_by_id('mediaJson', webpage), - video_id) - - formats = [{ - 'url': f['url'], - 'format_id': format_id, - 'width': int_or_none(f.get('width')), - 'height': int_or_none(f.get('height')) - } for format_id, f in media['videos'].items()] - self._sort_formats(formats) - - title = remove_end(self._og_search_title(webpage), ' - via Iconosquare') - - timestamp = int_or_none(media.get('created_time') or media.get('caption', {}).get('created_time')) - description = media.get('caption', {}).get('text') - - uploader = media.get('user', {}).get('username') - uploader_id = media.get('user', {}).get('id') - - comment_count = int_or_none(media.get('comments', {}).get('count')) - like_count = int_or_none(media.get('likes', {}).get('count')) - - thumbnails = [{ - 'url': t['url'], - 'id': thumbnail_id, - 'width': int_or_none(t.get('width')), - 'height': int_or_none(t.get('height')) - } for thumbnail_id, t in media.get('images', {}).items()] - - comments = [{ - 'id': comment.get('id'), - 'text': comment['text'], - 'timestamp': int_or_none(comment.get('created_time')), - 'author': comment.get('from', {}).get('full_name'), - 'author_id': comment.get('from', {}).get('username'), - } for comment in media.get('comments', {}).get('data', []) if 'text' in comment] - - return { - 'id': video_id, - 'title': title, - 'description': description, - 'thumbnails': thumbnails, - 'timestamp': timestamp, - 'uploader': uploader, - 'uploader_id': uploader_id, - 'comment_count': comment_count, - 'like_count': like_count, - 'formats': formats, - 'comments': comments, - } diff --git a/youtube_dl/extractor/imggaming.py b/youtube_dl/extractor/imggaming.py new file mode 100644 index 0000000..e11f920 --- /dev/null +++ b/youtube_dl/extractor/imggaming.py @@ -0,0 +1,133 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import json +import re + +from .common import InfoExtractor +from ..compat import compat_HTTPError +from ..utils import ( + ExtractorError, + int_or_none, + str_or_none, + try_get, +) + + +class ImgGamingBaseIE(InfoExtractor): + _API_BASE = 'https://dce-frontoffice.imggaming.com/api/v2/' + _API_KEY = '857a1e5d-e35e-4fdf-805b-a87b6f8364bf' + _HEADERS = None + _MANIFEST_HEADERS = {'Accept-Encoding': 'identity'} + _REALM = None + _VALID_URL_TEMPL = r'https?://(?P%s)/(?Plive|playlist|video)/(?P\d+)(?:\?.*?\bplaylistId=(?P\d+))?' + + def _real_initialize(self): + self._HEADERS = { + 'Realm': 'dce.' + self._REALM, + 'x-api-key': self._API_KEY, + } + + email, password = self._get_login_info() + if email is None: + self.raise_login_required() + + p_headers = self._HEADERS.copy() + p_headers['Content-Type'] = 'application/json' + self._HEADERS['Authorization'] = 'Bearer ' + self._download_json( + self._API_BASE + 'login', + None, 'Logging in', data=json.dumps({ + 'id': email, + 'secret': password, + }).encode(), headers=p_headers)['authorisationToken'] + + def _call_api(self, path, media_id): + return self._download_json( + self._API_BASE + path + media_id, media_id, headers=self._HEADERS) + + def _extract_dve_api_url(self, media_id, media_type): + stream_path = 'stream' + if media_type == 'video': + stream_path += '/vod/' + else: + stream_path += '?eventId=' + try: + return self._call_api( + stream_path, media_id)['playerUrlCallback'] + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403: + raise ExtractorError( + self._parse_json(e.cause.read().decode(), media_id)['messages'][0], + expected=True) + raise + + def _real_extract(self, url): + domain, media_type, media_id, playlist_id = re.match(self._VALID_URL, url).groups() + + if playlist_id: + if self._downloader.params.get('noplaylist'): + self.to_screen('Downloading just video %s because of --no-playlist' % media_id) + else: + self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % playlist_id) + media_type, media_id = 'playlist', playlist_id + + if media_type == 'playlist': + playlist = self._call_api('vod/playlist/', media_id) + entries = [] + for video in try_get(playlist, lambda x: x['videos']['vods']) or []: + video_id = str_or_none(video.get('id')) + if not video_id: + continue + entries.append(self.url_result( + 'https://%s/video/%s' % (domain, video_id), + self.ie_key(), video_id)) + return self.playlist_result( + entries, media_id, playlist.get('title'), + playlist.get('description')) + + dve_api_url = self._extract_dve_api_url(media_id, media_type) + video_data = self._download_json(dve_api_url, media_id) + is_live = media_type == 'live' + if is_live: + title = self._live_title(self._call_api('event/', media_id)['title']) + else: + title = video_data['name'] + + formats = [] + for proto in ('hls', 'dash'): + media_url = video_data.get(proto + 'Url') or try_get(video_data, lambda x: x[proto]['url']) + if not media_url: + continue + if proto == 'hls': + m3u8_formats = self._extract_m3u8_formats( + media_url, media_id, 'mp4', 'm3u8' if is_live else 'm3u8_native', + m3u8_id='hls', fatal=False, headers=self._MANIFEST_HEADERS) + for f in m3u8_formats: + f.setdefault('http_headers', {}).update(self._MANIFEST_HEADERS) + formats.append(f) + else: + formats.extend(self._extract_mpd_formats( + media_url, media_id, mpd_id='dash', fatal=False, + headers=self._MANIFEST_HEADERS)) + self._sort_formats(formats) + + subtitles = {} + for subtitle in video_data.get('subtitles', []): + subtitle_url = subtitle.get('url') + if not subtitle_url: + continue + subtitles.setdefault(subtitle.get('lang', 'en_US'), []).append({ + 'url': subtitle_url, + }) + + return { + 'id': media_id, + 'title': title, + 'formats': formats, + 'thumbnail': video_data.get('thumbnailUrl'), + 'description': video_data.get('description'), + 'duration': int_or_none(video_data.get('duration')), + 'tags': video_data.get('tags'), + 'is_live': is_live, + 'subtitles': subtitles, + } diff --git a/youtube_dl/extractor/internetvideoarchive.py b/youtube_dl/extractor/internetvideoarchive.py index 76cc5ec..59b0a90 100644 --- a/youtube_dl/extractor/internetvideoarchive.py +++ b/youtube_dl/extractor/internetvideoarchive.py @@ -1,15 +1,13 @@ from __future__ import unicode_literals +import json +import re + from .common import InfoExtractor from ..compat import ( compat_parse_qs, compat_urlparse, ) -from ..utils import ( - determine_ext, - int_or_none, - xpath_text, -) class InternetVideoArchiveIE(InfoExtractor): @@ -20,7 +18,7 @@ class InternetVideoArchiveIE(InfoExtractor): 'info_dict': { 'id': '194487', 'ext': 'mp4', - 'title': 'KICK-ASS 2', + 'title': 'Kick-Ass 2', 'description': 'md5:c189d5b7280400630a1d3dd17eaa8d8a', }, 'params': { @@ -33,68 +31,34 @@ class InternetVideoArchiveIE(InfoExtractor): def _build_json_url(query): return 'http://video.internetvideoarchive.net/player/6/configuration.ashx?' + query - @staticmethod - def _build_xml_url(query): - return 'http://video.internetvideoarchive.net/flash/players/flashconfiguration.aspx?' + query - def _real_extract(self, url): - query = compat_urlparse.urlparse(url).query - query_dic = compat_parse_qs(query) - video_id = query_dic['publishedid'][0] - - if '/player/' in url: - configuration = self._download_json(url, video_id) - - # There are multiple videos in the playlist whlie only the first one - # matches the video played in browsers - video_info = configuration['playlist'][0] - title = video_info['title'] - - formats = [] - for source in video_info['sources']: - file_url = source['file'] - if determine_ext(file_url) == 'm3u8': - m3u8_formats = self._extract_m3u8_formats( - file_url, video_id, 'mp4', 'm3u8_native', m3u8_id='hls', fatal=False) - if m3u8_formats: - formats.extend(m3u8_formats) - file_url = m3u8_formats[0]['url'] - formats.extend(self._extract_f4m_formats( - file_url.replace('.m3u8', '.f4m'), - video_id, f4m_id='hds', fatal=False)) - formats.extend(self._extract_mpd_formats( - file_url.replace('.m3u8', '.mpd'), - video_id, mpd_id='dash', fatal=False)) - else: - a_format = { - 'url': file_url, - } - - if source.get('label') and source['label'][-4:] == ' kbs': - tbr = int_or_none(source['label'][:-4]) - a_format.update({ - 'tbr': tbr, - 'format_id': 'http-%d' % tbr, - }) - formats.append(a_format) - - self._sort_formats(formats) - - description = video_info.get('description') - thumbnail = video_info.get('image') - else: - configuration = self._download_xml(url, video_id) - formats = [{ - 'url': xpath_text(configuration, './file', 'file URL', fatal=True), - }] - thumbnail = xpath_text(configuration, './image', 'thumbnail') - title = 'InternetVideoArchive video %s' % video_id - description = None + query = compat_parse_qs(compat_urlparse.urlparse(url).query) + video_id = query['publishedid'][0] + data = self._download_json( + 'https://video.internetvideoarchive.net/videojs7/videojs7.ivasettings.ashx', + video_id, data=json.dumps({ + 'customerid': query['customerid'][0], + 'publishedid': video_id, + }).encode()) + title = data['Title'] + formats = self._extract_m3u8_formats( + data['VideoUrl'], video_id, 'mp4', + 'm3u8_native', m3u8_id='hls', fatal=False) + file_url = formats[0]['url'] + if '.ism/' in file_url: + replace_url = lambda x: re.sub(r'\.ism/[^?]+', '.ism/' + x, file_url) + formats.extend(self._extract_f4m_formats( + replace_url('.f4m'), video_id, f4m_id='hds', fatal=False)) + formats.extend(self._extract_mpd_formats( + replace_url('.mpd'), video_id, mpd_id='dash', fatal=False)) + formats.extend(self._extract_ism_formats( + replace_url('Manifest'), video_id, ism_id='mss', fatal=False)) + self._sort_formats(formats) return { 'id': video_id, 'title': title, 'formats': formats, - 'thumbnail': thumbnail, - 'description': description, + 'thumbnail': data.get('PosterUrl'), + 'description': data.get('Description'), } diff --git a/youtube_dl/extractor/ivi.py b/youtube_dl/extractor/ivi.py index 86c014b..b5a740a 100644 --- a/youtube_dl/extractor/ivi.py +++ b/youtube_dl/extractor/ivi.py @@ -1,8 +1,9 @@ # coding: utf-8 from __future__ import unicode_literals -import re import json +import re +import sys from .common import InfoExtractor from ..utils import ( @@ -18,6 +19,8 @@ class IviIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?ivi\.(?:ru|tv)/(?:watch/(?:[^/]+/)?|video/player\?.*?videoId=)(?P\d+)' _GEO_BYPASS = False _GEO_COUNTRIES = ['RU'] + _LIGHT_KEY = b'\xf1\x02\x32\xb7\xbc\x5c\x7a\xe8\xf7\x96\xc1\x33\x2b\x27\xa1\x8c' + _LIGHT_URL = 'https://api.ivi.ru/light/' _TESTS = [ # Single movie @@ -80,48 +83,96 @@ class IviIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - data = { + data = json.dumps({ 'method': 'da.content.get', 'params': [ video_id, { - 'site': 's183', + 'site': 's%d', 'referrer': 'http://www.ivi.ru/watch/%s' % video_id, 'contentid': video_id } ] - } + }) - video_json = self._download_json( - 'http://api.digitalaccess.ru/api/json/', video_id, - 'Downloading video JSON', data=json.dumps(data)) - - if 'error' in video_json: - error = video_json['error'] - origin = error['origin'] - if origin == 'NotAllowedForLocation': - self.raise_geo_restricted( - msg=error['message'], countries=self._GEO_COUNTRIES) - elif origin == 'NoRedisValidData': - raise ExtractorError('Video %s does not exist' % video_id, expected=True) - raise ExtractorError( - 'Unable to download video %s: %s' % (video_id, error['message']), - expected=True) + bundled = hasattr(sys, 'frozen') - result = video_json['result'] + for site in (353, 183): + content_data = (data % site).encode() + if site == 353: + if bundled: + continue + try: + from Cryptodome.Cipher import Blowfish + from Cryptodome.Hash import CMAC + pycryptodomex_found = True + except ImportError: + pycryptodomex_found = False + continue - quality = qualities(self._KNOWN_FORMATS) + timestamp = (self._download_json( + self._LIGHT_URL, video_id, + 'Downloading timestamp JSON', data=json.dumps({ + 'method': 'da.timestamp.get', + 'params': [] + }).encode(), fatal=False) or {}).get('result') + if not timestamp: + continue - formats = [{ - 'url': x['url'], - 'format_id': x.get('content_format'), - 'quality': quality(x.get('content_format')), - } for x in result['files'] if x.get('url')] + query = { + 'ts': timestamp, + 'sign': CMAC.new(self._LIGHT_KEY, timestamp.encode() + content_data, Blowfish).hexdigest(), + } + else: + query = {} - self._sort_formats(formats) + video_json = self._download_json( + self._LIGHT_URL, video_id, + 'Downloading video JSON', data=content_data, query=query) + error = video_json.get('error') + if error: + origin = error.get('origin') + message = error.get('message') or error.get('user_message') + extractor_msg = 'Unable to download video %s' + if origin == 'NotAllowedForLocation': + self.raise_geo_restricted(message, self._GEO_COUNTRIES) + elif origin == 'NoRedisValidData': + extractor_msg = 'Video %s does not exist' + elif site == 353: + continue + elif bundled: + raise ExtractorError( + 'This feature does not work from bundled exe. Run youtube-dl from sources.', + expected=True) + elif not pycryptodomex_found: + raise ExtractorError( + 'pycryptodomex not found. Please install it.', + expected=True) + elif message: + extractor_msg += ': ' + message + raise ExtractorError(extractor_msg % video_id, expected=True) + else: + break + + result = video_json['result'] title = result['title'] - duration = int_or_none(result.get('duration')) + quality = qualities(self._KNOWN_FORMATS) + + formats = [] + for f in result.get('files', []): + f_url = f.get('url') + content_format = f.get('content_format') + if not f_url or '-MDRM-' in content_format or '-FPS-' in content_format: + continue + formats.append({ + 'url': f_url, + 'format_id': content_format, + 'quality': quality(content_format), + 'filesize': int_or_none(f.get('size_in_bytes')), + }) + self._sort_formats(formats) + compilation = result.get('compilation') episode = title if compilation else None @@ -158,7 +209,7 @@ class IviIE(InfoExtractor): 'episode_number': episode_number, 'thumbnails': thumbnails, 'description': description, - 'duration': duration, + 'duration': int_or_none(result.get('duration')), 'formats': formats, } @@ -188,7 +239,7 @@ class IviCompilationIE(InfoExtractor): self.url_result( 'http://www.ivi.ru/watch/%s/%s' % (compilation_id, serie), IviIE.ie_key()) for serie in re.findall( - r']+data-id="\1"' % compilation_id, html)] + r']+\bhref=["\']/watch/%s/(\d+)["\']' % compilation_id, html)] def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) diff --git a/youtube_dl/extractor/jamendo.py b/youtube_dl/extractor/jamendo.py index c218276..490efa8 100644 --- a/youtube_dl/extractor/jamendo.py +++ b/youtube_dl/extractor/jamendo.py @@ -1,38 +1,26 @@ # coding: utf-8 from __future__ import unicode_literals -import re +import hashlib +import random -from ..compat import compat_urlparse +from ..compat import compat_str from .common import InfoExtractor -from ..utils import parse_duration - - -class JamendoBaseIE(InfoExtractor): - def _extract_meta(self, webpage, fatal=True): - title = self._og_search_title( - webpage, default=None) or self._search_regex( - r'([^<]+)', webpage, - 'title', default=None) - if title: - title = self._search_regex( - r'(.+?)\s*\|\s*Jamendo Music', title, 'title', default=None) - if not title: - title = self._html_search_meta( - 'name', webpage, 'title', fatal=fatal) - mobj = re.search(r'(.+) - (.+)', title or '') - artist, second = mobj.groups() if mobj else [None] * 2 - return title, artist, second - - -class JamendoIE(JamendoBaseIE): +from ..utils import ( + clean_html, + int_or_none, + try_get, +) + + +class JamendoIE(InfoExtractor): _VALID_URL = r'''(?x) https?:// (?: licensing\.jamendo\.com/[^/]+| (?:www\.)?jamendo\.com ) - /track/(?P<id>[0-9]+)/(?P<display_id>[^/?#&]+) + /track/(?P<id>[0-9]+)(?:/(?P<display_id>[^/?#&]+))? ''' _TESTS = [{ 'url': 'https://www.jamendo.com/track/196219/stories-from-emona-i', @@ -45,7 +33,9 @@ class JamendoIE(JamendoBaseIE): 'artist': 'Maya Filipič', 'track': 'Stories from Emona I', 'duration': 210, - 'thumbnail': r're:^https?://.*\.jpg' + 'thumbnail': r're:^https?://.*\.jpg', + 'timestamp': 1217438117, + 'upload_date': '20080730', } }, { 'url': 'https://licensing.jamendo.com/en/track/1496667/energetic-rock', @@ -53,15 +43,20 @@ class JamendoIE(JamendoBaseIE): }] def _real_extract(self, url): - mobj = self._VALID_URL_RE.match(url) - track_id = mobj.group('id') - display_id = mobj.group('display_id') - + track_id, display_id = self._VALID_URL_RE.match(url).groups() webpage = self._download_webpage( - 'https://www.jamendo.com/track/%s/%s' % (track_id, display_id), - display_id) - - title, artist, track = self._extract_meta(webpage) + 'https://www.jamendo.com/track/' + track_id, track_id) + models = self._parse_json(self._html_search_regex( + r"data-bundled-models='([^']+)", + webpage, 'bundled models'), track_id) + track = models['track']['models'][0] + title = track_name = track['name'] + get_model = lambda x: try_get(models, lambda y: y[x]['models'][0], dict) or {} + artist = get_model('artist') + artist_name = artist.get('name') + if artist_name: + title = '%s - %s' % (artist_name, title) + album = get_model('album') formats = [{ 'url': 'https://%s.jamendo.com/?trackid=%s&format=%s&from=app-97dab294' @@ -77,31 +72,58 @@ class JamendoIE(JamendoBaseIE): ))] self._sort_formats(formats) - thumbnail = self._html_search_meta( - 'image', webpage, 'thumbnail', fatal=False) - duration = parse_duration(self._search_regex( - r'<span[^>]+itemprop=["\']duration["\'][^>]+content=["\'](.+?)["\']', - webpage, 'duration', fatal=False)) + urls = [] + thumbnails = [] + for _, covers in track.get('cover', {}).items(): + for cover_id, cover_url in covers.items(): + if not cover_url or cover_url in urls: + continue + urls.append(cover_url) + size = int_or_none(cover_id.lstrip('size')) + thumbnails.append({ + 'id': cover_id, + 'url': cover_url, + 'width': size, + 'height': size, + }) + + tags = [] + for tag in track.get('tags', []): + tag_name = tag.get('name') + if not tag_name: + continue + tags.append(tag_name) + + stats = track.get('stats') or {} return { 'id': track_id, 'display_id': display_id, - 'thumbnail': thumbnail, + 'thumbnails': thumbnails, 'title': title, - 'duration': duration, - 'artist': artist, - 'track': track, - 'formats': formats + 'description': track.get('description'), + 'duration': int_or_none(track.get('duration')), + 'artist': artist_name, + 'track': track_name, + 'album': album.get('name'), + 'formats': formats, + 'license': '-'.join(track.get('licenseCC', [])) or None, + 'timestamp': int_or_none(track.get('dateCreated')), + 'view_count': int_or_none(stats.get('listenedAll')), + 'like_count': int_or_none(stats.get('favorited')), + 'average_rating': int_or_none(stats.get('averageNote')), + 'tags': tags, } -class JamendoAlbumIE(JamendoBaseIE): - _VALID_URL = r'https?://(?:www\.)?jamendo\.com/album/(?P<id>[0-9]+)/(?P<display_id>[\w-]+)' +class JamendoAlbumIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?jamendo\.com/album/(?P<id>[0-9]+)' _TEST = { 'url': 'https://www.jamendo.com/album/121486/duck-on-cover', 'info_dict': { 'id': '121486', - 'title': 'Shearer - Duck On Cover' + 'title': 'Duck On Cover', + 'description': 'md5:c2920eaeef07d7af5b96d7c64daf1239', }, 'playlist': [{ 'md5': 'e1a2fcb42bda30dfac990212924149a8', @@ -111,6 +133,8 @@ class JamendoAlbumIE(JamendoBaseIE): 'title': 'Shearer - Warmachine', 'artist': 'Shearer', 'track': 'Warmachine', + 'timestamp': 1368089771, + 'upload_date': '20130509', } }, { 'md5': '1f358d7b2f98edfe90fd55dac0799d50', @@ -120,6 +144,8 @@ class JamendoAlbumIE(JamendoBaseIE): 'title': 'Shearer - Without Your Ghost', 'artist': 'Shearer', 'track': 'Without Your Ghost', + 'timestamp': 1368089771, + 'upload_date': '20130509', } }], 'params': { @@ -127,24 +153,35 @@ class JamendoAlbumIE(JamendoBaseIE): } } + def _call_api(self, resource, resource_id): + path = '/api/%ss' % resource + rand = compat_str(random.random()) + return self._download_json( + 'https://www.jamendo.com' + path, resource_id, query={ + 'id[]': resource_id, + }, headers={ + 'X-Jam-Call': '$%s*%s~' % (hashlib.sha1((path + rand).encode()).hexdigest(), rand) + })[0] + def _real_extract(self, url): - mobj = self._VALID_URL_RE.match(url) - album_id = mobj.group('id') - - webpage = self._download_webpage(url, mobj.group('display_id')) - - title, artist, album = self._extract_meta(webpage, fatal=False) - - entries = [{ - '_type': 'url_transparent', - 'url': compat_urlparse.urljoin(url, m.group('path')), - 'ie_key': JamendoIE.ie_key(), - 'id': self._search_regex( - r'/track/(\d+)', m.group('path'), 'track id', default=None), - 'artist': artist, - 'album': album, - } for m in re.finditer( - r'<a[^>]+href=(["\'])(?P<path>(?:(?!\1).)+)\1[^>]+class=["\'][^>]*js-trackrow-albumpage-link', - webpage)] - - return self.playlist_result(entries, album_id, title) + album_id = self._match_id(url) + album = self._call_api('album', album_id) + album_name = album.get('name') + + entries = [] + for track in album.get('tracks', []): + track_id = track.get('id') + if not track_id: + continue + track_id = compat_str(track_id) + entries.append({ + '_type': 'url_transparent', + 'url': 'https://www.jamendo.com/track/' + track_id, + 'ie_key': JamendoIE.ie_key(), + 'id': track_id, + 'album': album_name, + }) + + return self.playlist_result( + entries, album_id, album_name, + clean_html(try_get(album, lambda x: x['description']['en'], compat_str))) diff --git a/youtube_dl/extractor/kakao.py b/youtube_dl/extractor/kakao.py index 7fa140b..32935bb 100644 --- a/youtube_dl/extractor/kakao.py +++ b/youtube_dl/extractor/kakao.py @@ -6,14 +6,15 @@ from .common import InfoExtractor from ..compat import compat_str from ..utils import ( int_or_none, + strip_or_none, unified_timestamp, update_url_query, ) class KakaoIE(InfoExtractor): - _VALID_URL = r'https?://tv\.kakao\.com/channel/(?P<channel>\d+)/cliplink/(?P<id>\d+)' - _API_BASE = 'http://tv.kakao.com/api/v1/ft/cliplinks' + _VALID_URL = r'https?://(?:play-)?tv\.kakao\.com/(?:channel/\d+|embed/player)/cliplink/(?P<id>\d+|[^?#&]+@my)' + _API_BASE_TMPL = 'http://tv.kakao.com/api/v1/ft/cliplinks/%s/' _TESTS = [{ 'url': 'http://tv.kakao.com/channel/2671005/cliplink/301965083', @@ -36,7 +37,7 @@ class KakaoIE(InfoExtractor): 'description': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)\r\n\r\n[쇼! 음악중심] 20160611, 507회', 'title': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)', 'uploader_id': 2653210, - 'uploader': '쇼 음악중심', + 'uploader': '쇼! 음악중심', 'timestamp': 1485684628, 'upload_date': '20170129', } @@ -44,6 +45,8 @@ class KakaoIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) + display_id = video_id.rstrip('@my') + api_base = self._API_BASE_TMPL % video_id player_header = { 'Referer': update_url_query( @@ -55,20 +58,23 @@ class KakaoIE(InfoExtractor): }) } - QUERY_COMMON = { + query = { 'player': 'monet_html5', 'referer': url, 'uuid': '', 'service': 'kakao_tv', 'section': '', 'dteType': 'PC', + 'fields': ','.join([ + '-*', 'tid', 'clipLink', 'displayTitle', 'clip', 'title', + 'description', 'channelId', 'createTime', 'duration', 'playCount', + 'likeCount', 'commentCount', 'tagList', 'channel', 'name', + 'clipChapterThumbnailList', 'thumbnailUrl', 'timeInSec', 'isDefault', + 'videoOutputList', 'width', 'height', 'kbps', 'profile', 'label']) } - query = QUERY_COMMON.copy() - query['fields'] = 'clipLink,clip,channel,hasPlusFriend,-service,-tagList' impress = self._download_json( - '%s/%s/impress' % (self._API_BASE, video_id), - video_id, 'Downloading video info', + api_base + 'impress', display_id, 'Downloading video info', query=query, headers=player_header) clip_link = impress['clipLink'] @@ -76,32 +82,22 @@ class KakaoIE(InfoExtractor): title = clip.get('title') or clip_link.get('displayTitle') - tid = impress.get('tid', '') - - query = QUERY_COMMON.copy() - query.update({ - 'tid': tid, - 'profile': 'HIGH', - }) - raw = self._download_json( - '%s/%s/raw' % (self._API_BASE, video_id), - video_id, 'Downloading video formats info', - query=query, headers=player_header) + query['tid'] = impress.get('tid', '') formats = [] - for fmt in raw.get('outputList', []): + for fmt in clip.get('videoOutputList', []): try: profile_name = fmt['profile'] + if profile_name == 'AUDIO': + continue + query.update({ + 'profile': profile_name, + 'fields': '-*,url', + }) fmt_url_json = self._download_json( - '%s/%s/raw/videolocation' % (self._API_BASE, video_id), - video_id, + api_base + 'raw/videolocation', display_id, 'Downloading video URL for profile %s' % profile_name, - query={ - 'service': 'kakao_tv', - 'section': '', - 'tid': tid, - 'profile': profile_name - }, headers=player_header, fatal=False) + query=query, headers=player_header, fatal=False) if fmt_url_json is None: continue @@ -113,7 +109,8 @@ class KakaoIE(InfoExtractor): 'width': int_or_none(fmt.get('width')), 'height': int_or_none(fmt.get('height')), 'format_note': fmt.get('label'), - 'filesize': int_or_none(fmt.get('filesize')) + 'filesize': int_or_none(fmt.get('filesize')), + 'tbr': int_or_none(fmt.get('kbps')), }) except KeyError: pass @@ -134,9 +131,9 @@ class KakaoIE(InfoExtractor): }) return { - 'id': video_id, + 'id': display_id, 'title': title, - 'description': clip.get('description'), + 'description': strip_or_none(clip.get('description')), 'uploader': clip_link.get('channel', {}).get('name'), 'uploader_id': clip_link.get('channelId'), 'thumbnails': thumbs, @@ -146,4 +143,5 @@ class KakaoIE(InfoExtractor): 'like_count': int_or_none(clip.get('likeCount')), 'comment_count': int_or_none(clip.get('commentCount')), 'formats': formats, + 'tags': clip.get('tagList'), } diff --git a/youtube_dl/extractor/kaltura.py b/youtube_dl/extractor/kaltura.py index 0a73342..2d38b75 100644 --- a/youtube_dl/extractor/kaltura.py +++ b/youtube_dl/extractor/kaltura.py @@ -151,14 +151,15 @@ class KalturaIE(InfoExtractor): if mobj: embed_info = mobj.groupdict() for k, v in embed_info.items(): - embed_info[k] = v.strip() + if v: + embed_info[k] = v.strip() url = 'kaltura:%(partner_id)s:%(id)s' % embed_info escaped_pid = re.escape(embed_info['partner_id']) - service_url = re.search( - r'<script[^>]+src=["\']((?:https?:)?//.+?)/p/%s/sp/%s00/embedIframeJs' % (escaped_pid, escaped_pid), + service_mobj = re.search( + r'<script[^>]+src=(["\'])(?P<id>(?:https?:)?//(?:(?!\1).)+)/p/%s/sp/%s00/embedIframeJs' % (escaped_pid, escaped_pid), webpage) - if service_url: - url = smuggle_url(url, {'service_url': service_url.group(1)}) + if service_mobj: + url = smuggle_url(url, {'service_url': service_mobj.group('id')}) return url def _kaltura_api_call(self, video_id, actions, service_url=None, *args, **kwargs): diff --git a/youtube_dl/extractor/keek.py b/youtube_dl/extractor/keek.py deleted file mode 100644 index 94a03d2..0000000 --- a/youtube_dl/extractor/keek.py +++ /dev/null @@ -1,39 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor - - -class KeekIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?keek\.com/keek/(?P<id>\w+)' - IE_NAME = 'keek' - _TEST = { - 'url': 'https://www.keek.com/keek/NODfbab', - 'md5': '9b0636f8c0f7614afa4ea5e4c6e57e83', - 'info_dict': { - 'id': 'NODfbab', - 'ext': 'mp4', - 'title': 'md5:35d42050a3ece241d5ddd7fdcc6fd896', - 'uploader': 'ytdl', - 'uploader_id': 'eGT5bab', - }, - } - - def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - - return { - 'id': video_id, - 'url': self._og_search_video_url(webpage), - 'ext': 'mp4', - 'title': self._og_search_description(webpage).strip(), - 'thumbnail': self._og_search_thumbnail(webpage), - 'uploader': self._search_regex( - r'data-username=(["\'])(?P<uploader>.+?)\1', webpage, - 'uploader', fatal=False, group='uploader'), - 'uploader_id': self._search_regex( - r'data-user-id=(["\'])(?P<uploader_id>.+?)\1', webpage, - 'uploader id', fatal=False, group='uploader_id'), - } diff --git a/youtube_dl/extractor/kinja.py b/youtube_dl/extractor/kinja.py new file mode 100644 index 0000000..79e3026 --- /dev/null +++ b/youtube_dl/extractor/kinja.py @@ -0,0 +1,221 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..compat import ( + compat_str, + compat_urllib_parse_unquote, +) +from ..utils import ( + int_or_none, + parse_iso8601, + strip_or_none, + try_get, + unescapeHTML, + urljoin, +) + + +class KinjaEmbedIE(InfoExtractor): + IENAME = 'kinja:embed' + _DOMAIN_REGEX = r'''(?:[^.]+\.)? + (?: + avclub| + clickhole| + deadspin| + gizmodo| + jalopnik| + jezebel| + kinja| + kotaku| + lifehacker| + splinternews| + the(?:inventory|onion|root|takeout) + )\.com''' + _COMMON_REGEX = r'''/ + (?: + ajax/inset| + embed/video + )/iframe\?.*?\bid=''' + _VALID_URL = r'''(?x)https?://%s%s + (?P<type> + fb| + imgur| + instagram| + jwp(?:layer)?-video| + kinjavideo| + mcp| + megaphone| + ooyala| + soundcloud(?:-playlist)?| + tumblr-post| + twitch-stream| + twitter| + ustream-channel| + vimeo| + vine| + youtube-(?:list|video) + )-(?P<id>[^&]+)''' % (_DOMAIN_REGEX, _COMMON_REGEX) + _TESTS = [{ + 'url': 'https://kinja.com/ajax/inset/iframe?id=fb-10103303356633621', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=kinjavideo-100313', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=megaphone-PPY1300931075', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=ooyala-xzMXhleDpopuT0u1ijt_qZj3Va-34pEX%2FZTIxYmJjZDM2NWYzZDViZGRiOWJjYzc5', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=soundcloud-128574047', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=soundcloud-playlist-317413750', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=tumblr-post-160130699814-daydreams-at-midnight', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=twitch-stream-libratus_extra', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=twitter-1068875942473404422', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=ustream-channel-10414700', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=vimeo-120153502', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=vine-5BlvV5qqPrD', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=youtube-list-BCQ3KyrPjgA/PLE6509247C270A72E', + 'only_matching': True, + }, { + 'url': 'https://kinja.com/ajax/inset/iframe?id=youtube-video-00QyL0AgPAE', + 'only_matching': True, + }] + _JWPLATFORM_PROVIDER = ('cdn.jwplayer.com/v2/media/', 'JWPlatform') + _PROVIDER_MAP = { + 'fb': ('facebook.com/video.php?v=', 'Facebook'), + 'imgur': ('imgur.com/', 'Imgur'), + 'instagram': ('instagram.com/p/', 'Instagram'), + 'jwplayer-video': _JWPLATFORM_PROVIDER, + 'jwp-video': _JWPLATFORM_PROVIDER, + 'megaphone': ('player.megaphone.fm/', 'Generic'), + 'ooyala': ('player.ooyala.com/player.js?embedCode=', 'Ooyala'), + 'soundcloud': ('api.soundcloud.com/tracks/', 'Soundcloud'), + 'soundcloud-playlist': ('api.soundcloud.com/playlists/', 'SoundcloudPlaylist'), + 'tumblr-post': ('%s.tumblr.com/post/%s', 'Tumblr'), + 'twitch-stream': ('twitch.tv/', 'TwitchStream'), + 'twitter': ('twitter.com/i/cards/tfw/v1/', 'TwitterCard'), + 'ustream-channel': ('ustream.tv/embed/', 'Ustream'), + 'vimeo': ('vimeo.com/', 'Vimeo'), + 'vine': ('vine.co/v/', 'Vine'), + 'youtube-list': ('youtube.com/embed/%s?list=%s', 'YoutubePlaylist'), + 'youtube-video': ('youtube.com/embed/', 'Youtube'), + } + + @staticmethod + def _extract_urls(webpage, url): + return [urljoin(url, unescapeHTML(mobj.group('url'))) for mobj in re.finditer( + r'(?x)<iframe[^>]+?src=(?P<q>["\'])(?P<url>(?:(?:https?:)?//%s)?%s(?:(?!\1).)+)\1' % (KinjaEmbedIE._DOMAIN_REGEX, KinjaEmbedIE._COMMON_REGEX), + webpage)] + + def _real_extract(self, url): + video_type, video_id = re.match(self._VALID_URL, url).groups() + + provider = self._PROVIDER_MAP.get(video_type) + if provider: + video_id = compat_urllib_parse_unquote(video_id) + if video_type == 'tumblr-post': + video_id, blog = video_id.split('-', 1) + result_url = provider[0] % (blog, video_id) + elif video_type == 'youtube-list': + video_id, playlist_id = video_id.split('/') + result_url = provider[0] % (video_id, playlist_id) + else: + if video_type == 'ooyala': + video_id = video_id.split('/')[0] + result_url = provider[0] + video_id + return self.url_result('http://' + result_url, provider[1]) + + if video_type == 'kinjavideo': + data = self._download_json( + 'https://kinja.com/api/core/video/views/videoById', + video_id, query={'videoId': video_id})['data'] + title = data['title'] + + formats = [] + for k in ('signedPlaylist', 'streaming'): + m3u8_url = data.get(k + 'Url') + if m3u8_url: + formats.extend(self._extract_m3u8_formats( + m3u8_url, video_id, 'mp4', 'm3u8_native', + m3u8_id='hls', fatal=False)) + self._sort_formats(formats) + + thumbnail = None + poster = data.get('poster') or {} + poster_id = poster.get('id') + if poster_id: + thumbnail = 'https://i.kinja-img.com/gawker-media/image/upload/%s.%s' % (poster_id, poster.get('format') or 'jpg') + + return { + 'id': video_id, + 'title': title, + 'description': strip_or_none(data.get('description')), + 'formats': formats, + 'tags': data.get('tags'), + 'timestamp': int_or_none(try_get( + data, lambda x: x['postInfo']['publishTimeMillis']), 1000), + 'thumbnail': thumbnail, + 'uploader': data.get('network'), + } + else: + video_data = self._download_json( + 'https://api.vmh.univision.com/metadata/v1/content/' + video_id, + video_id)['videoMetadata'] + iptc = video_data['photoVideoMetadataIPTC'] + title = iptc['title']['en'] + fmg = video_data.get('photoVideoMetadata_fmg') or {} + tvss_domain = fmg.get('tvssDomain') or 'https://auth.univision.com' + data = self._download_json( + tvss_domain + '/api/v3/video-auth/url-signature-tokens', + video_id, query={'mcpids': video_id})['data'][0] + formats = [] + + rendition_url = data.get('renditionUrl') + if rendition_url: + formats = self._extract_m3u8_formats( + rendition_url, video_id, 'mp4', + 'm3u8_native', m3u8_id='hls', fatal=False) + + fallback_rendition_url = data.get('fallbackRenditionUrl') + if fallback_rendition_url: + formats.append({ + 'format_id': 'fallback', + 'tbr': int_or_none(self._search_regex( + r'_(\d+)\.mp4', fallback_rendition_url, + 'bitrate', default=None)), + 'url': fallback_rendition_url, + }) + + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'thumbnail': try_get(iptc, lambda x: x['cloudinaryLink']['link'], compat_str), + 'uploader': fmg.get('network'), + 'duration': int_or_none(iptc.get('fileDuration')), + 'formats': formats, + 'description': try_get(iptc, lambda x: x['description']['en'], compat_str), + 'timestamp': parse_iso8601(iptc.get('dateReleased')), + } diff --git a/youtube_dl/extractor/kontrtube.py b/youtube_dl/extractor/kontrtube.py deleted file mode 100644 index 1fda451..0000000 --- a/youtube_dl/extractor/kontrtube.py +++ /dev/null @@ -1,73 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..utils import ( - int_or_none, - parse_duration, -) - - -class KontrTubeIE(InfoExtractor): - IE_NAME = 'kontrtube' - IE_DESC = 'KontrTube.ru - Труба зовёт' - _VALID_URL = r'https?://(?:www\.)?kontrtube\.ru/videos/(?P<id>\d+)/(?P<display_id>[^/]+)/' - - _TEST = { - 'url': 'http://www.kontrtube.ru/videos/2678/nad-olimpiyskoy-derevney-v-sochi-podnyat-rossiyskiy-flag/', - 'md5': '975a991a4926c9a85f383a736a2e6b80', - 'info_dict': { - 'id': '2678', - 'display_id': 'nad-olimpiyskoy-derevney-v-sochi-podnyat-rossiyskiy-flag', - 'ext': 'mp4', - 'title': 'Над олимпийской деревней в Сочи поднят российский флаг', - 'description': 'md5:80edc4c613d5887ae8ccf1d59432be41', - 'thumbnail': 'http://www.kontrtube.ru/contents/videos_screenshots/2000/2678/preview.mp4.jpg', - 'duration': 270, - } - } - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') - display_id = mobj.group('display_id') - - webpage = self._download_webpage( - url, display_id, 'Downloading page') - - video_url = self._search_regex( - r"video_url\s*:\s*'(.+?)/?',", webpage, 'video URL') - thumbnail = self._search_regex( - r"preview_url\s*:\s*'(.+?)/?',", webpage, 'thumbnail', fatal=False) - title = self._html_search_regex( - r'(?s)<h2>(.+?)</h2>', webpage, 'title') - description = self._html_search_meta( - 'description', webpage, 'description') - - duration = self._search_regex( - r'Длительность: <em>([^<]+)</em>', webpage, 'duration', fatal=False) - if duration: - duration = parse_duration(duration.replace('мин', 'min').replace('сек', 'sec')) - - view_count = self._search_regex( - r'Просмотров: <em>([^<]+)</em>', - webpage, 'view count', fatal=False) - if view_count: - view_count = int_or_none(view_count.replace(' ', '')) - - comment_count = int_or_none(self._search_regex( - r'Комментарии \((\d+)\)<', webpage, ' comment count', fatal=False)) - - return { - 'id': video_id, - 'display_id': display_id, - 'url': video_url, - 'thumbnail': thumbnail, - 'title': title, - 'description': description, - 'duration': duration, - 'view_count': int_or_none(view_count), - 'comment_count': int_or_none(comment_count), - } diff --git a/youtube_dl/extractor/la7.py b/youtube_dl/extractor/la7.py index 6373268..c3b4ffa 100644 --- a/youtube_dl/extractor/la7.py +++ b/youtube_dl/extractor/la7.py @@ -20,7 +20,7 @@ class LA7IE(InfoExtractor): 'url': 'http://www.la7.it/crozza/video/inccool8-02-10-2015-163722', 'md5': '8b613ffc0c4bf9b9e377169fc19c214c', 'info_dict': { - 'id': 'inccool8-02-10-2015-163722', + 'id': '0_42j6wd36', 'ext': 'mp4', 'title': 'Inc.Cool8', 'description': 'Benvenuti nell\'incredibile mondo della INC. COOL. 8. dove “INC.” sta per “Incorporated” “COOL” sta per “fashion” ed Eight sta per il gesto atletico', @@ -57,7 +57,7 @@ class LA7IE(InfoExtractor): return { '_type': 'url_transparent', 'url': smuggle_url('kaltura:103:%s' % player_data['vid'], { - 'service_url': 'http://kdam.iltrovatore.it', + 'service_url': 'http://nkdam.iltrovatore.it', }), 'id': video_id, 'title': player_data['title'], diff --git a/youtube_dl/extractor/learnr.py b/youtube_dl/extractor/learnr.py deleted file mode 100644 index 1435e09..0000000 --- a/youtube_dl/extractor/learnr.py +++ /dev/null @@ -1,33 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor - - -class LearnrIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?learnr\.pro/view/video/(?P<id>[0-9]+)' - _TEST = { - 'url': 'http://www.learnr.pro/view/video/51624-web-development-tutorial-for-beginners-1-how-to-build-webpages-with-html-css-javascript', - 'md5': '3719fdf0a68397f49899e82c308a89de', - 'info_dict': { - 'id': '51624', - 'ext': 'mp4', - 'title': 'Web Development Tutorial for Beginners (#1) - How to build webpages with HTML, CSS, Javascript', - 'description': 'md5:b36dbfa92350176cdf12b4d388485503', - 'uploader': 'LearnCode.academy', - 'uploader_id': 'learncodeacademy', - 'upload_date': '20131021', - }, - 'add_ie': ['Youtube'], - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - - return { - '_type': 'url_transparent', - 'url': self._search_regex( - r"videoId\s*:\s*'([^']+)'", webpage, 'youtube id'), - 'id': video_id, - } diff --git a/youtube_dl/extractor/lego.py b/youtube_dl/extractor/lego.py index b312e77..1e3c19d 100644 --- a/youtube_dl/extractor/lego.py +++ b/youtube_dl/extractor/lego.py @@ -2,23 +2,24 @@ from __future__ import unicode_literals import re +import uuid from .common import InfoExtractor -from ..compat import compat_str +from ..compat import compat_HTTPError from ..utils import ( - unescapeHTML, - parse_duration, - get_element_by_class, + ExtractorError, + int_or_none, + qualities, ) class LEGOIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?lego\.com/(?P<locale>[^/]+)/(?:[^/]+/)*videos/(?:[^/]+/)*[^/?#]+-(?P<id>[0-9a-f]+)' + _VALID_URL = r'https?://(?:www\.)?lego\.com/(?P<locale>[a-z]{2}-[a-z]{2})/(?:[^/]+/)*videos/(?:[^/]+/)*[^/?#]+-(?P<id>[0-9a-f]{32})' _TESTS = [{ 'url': 'http://www.lego.com/en-us/videos/themes/club/blocumentary-kawaguchi-55492d823b1b4d5e985787fa8c2973b1', 'md5': 'f34468f176cfd76488767fc162c405fa', 'info_dict': { - 'id': '55492d823b1b4d5e985787fa8c2973b1', + 'id': '55492d82-3b1b-4d5e-9857-87fa8c2973b1_en-US', 'ext': 'mp4', 'title': 'Blocumentary Great Creations: Akiyuki Kawaguchi', 'description': 'Blocumentary Great Creations: Akiyuki Kawaguchi', @@ -26,103 +27,123 @@ class LEGOIE(InfoExtractor): }, { # geo-restricted but the contentUrl contain a valid url 'url': 'http://www.lego.com/nl-nl/videos/themes/nexoknights/episode-20-kingdom-of-heroes-13bdc2299ab24d9685701a915b3d71e7##sp=399', - 'md5': '4c3fec48a12e40c6e5995abc3d36cc2e', + 'md5': 'c7420221f7ffd03ff056f9db7f8d807c', 'info_dict': { - 'id': '13bdc2299ab24d9685701a915b3d71e7', + 'id': '13bdc229-9ab2-4d96-8570-1a915b3d71e7_nl-NL', 'ext': 'mp4', - 'title': 'Aflevering 20 - Helden van het koninkrijk', + 'title': 'Aflevering 20: Helden van het koninkrijk', 'description': 'md5:8ee499aac26d7fa8bcb0cedb7f9c3941', + 'age_limit': 5, }, }, { - # special characters in title - 'url': 'http://www.lego.com/en-us/starwars/videos/lego-star-wars-force-surprise-9685ee9d12e84ff38e84b4e3d0db533d', + # with subtitle + 'url': 'https://www.lego.com/nl-nl/kids/videos/classic/creative-storytelling-the-little-puppy-aa24f27c7d5242bc86102ebdc0f24cba', 'info_dict': { - 'id': '9685ee9d12e84ff38e84b4e3d0db533d', + 'id': 'aa24f27c-7d52-42bc-8610-2ebdc0f24cba_nl-NL', 'ext': 'mp4', - 'title': 'Force Surprise – LEGO® Star Wars™ Microfighters', - 'description': 'md5:9c673c96ce6f6271b88563fe9dc56de3', + 'title': 'De kleine puppy', + 'description': 'md5:5b725471f849348ac73f2e12cfb4be06', + 'age_limit': 1, + 'subtitles': { + 'nl': [{ + 'ext': 'srt', + 'url': r're:^https://.+\.srt$', + }], + }, }, 'params': { 'skip_download': True, }, }] - _BITRATES = [256, 512, 1024, 1536, 2560] + _QUALITIES = { + 'Lowest': (64, 180, 320), + 'Low': (64, 270, 480), + 'Medium': (96, 360, 640), + 'High': (128, 540, 960), + 'Highest': (128, 720, 1280), + } def _real_extract(self, url): locale, video_id = re.match(self._VALID_URL, url).groups() - webpage = self._download_webpage(url, video_id) - title = get_element_by_class('video-header', webpage).strip() - progressive_base = 'https://lc-mediaplayerns-live-s.legocdn.com/' - streaming_base = 'http://legoprod-f.akamaihd.net/' - content_url = self._html_search_meta('contentUrl', webpage) - path = self._search_regex( - r'(?:https?:)?//[^/]+/(?:[iz]/s/)?public/(.+)_[0-9,]+\.(?:mp4|webm)', - content_url, 'video path', default=None) - if not path: - player_url = self._proto_relative_url(self._search_regex( - r'<iframe[^>]+src="((?:https?)?//(?:www\.)?lego\.com/[^/]+/mediaplayer/video/[^"]+)', - webpage, 'player url', default=None)) - if not player_url: - base_url = self._proto_relative_url(self._search_regex( - r'data-baseurl="([^"]+)"', webpage, 'base url', - default='http://www.lego.com/%s/mediaplayer/video/' % locale)) - player_url = base_url + video_id - player_webpage = self._download_webpage(player_url, video_id) - video_data = self._parse_json(unescapeHTML(self._search_regex( - r"video='([^']+)'", player_webpage, 'video data')), video_id) - progressive_base = self._search_regex( - r'data-video-progressive-url="([^"]+)"', - player_webpage, 'progressive base', default='https://lc-mediaplayerns-live-s.legocdn.com/') - streaming_base = self._search_regex( - r'data-video-streaming-url="([^"]+)"', - player_webpage, 'streaming base', default='http://legoprod-f.akamaihd.net/') - item_id = video_data['ItemId'] + countries = [locale.split('-')[1].upper()] + self._initialize_geo_bypass({ + 'countries': countries, + }) - net_storage_path = video_data.get('NetStoragePath') or '/'.join([item_id[:2], item_id[2:4]]) - base_path = '_'.join([item_id, video_data['VideoId'], video_data['Locale'], compat_str(video_data['VideoVersion'])]) - path = '/'.join([net_storage_path, base_path]) - streaming_path = ','.join(map(lambda bitrate: compat_str(bitrate), self._BITRATES)) + try: + item = self._download_json( + # https://contentfeed.services.lego.com/api/v2/item/[VIDEO_ID]?culture=[LOCALE]&contentType=Video + 'https://services.slingshot.lego.com/mediaplayer/v2', + video_id, query={ + 'videoId': '%s_%s' % (uuid.UUID(video_id), locale), + }, headers=self.geo_verification_headers()) + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 451: + self.raise_geo_restricted(countries=countries) + raise - formats = self._extract_akamai_formats( - '%si/s/public/%s_,%s,.mp4.csmil/master.m3u8' % (streaming_base, path, streaming_path), video_id) - m3u8_formats = list(filter( - lambda f: f.get('protocol') == 'm3u8_native' and f.get('vcodec') != 'none', - formats)) - if len(m3u8_formats) == len(self._BITRATES): - self._sort_formats(m3u8_formats) - for bitrate, m3u8_format in zip(self._BITRATES, m3u8_formats): - progressive_base_url = '%spublic/%s_%d.' % (progressive_base, path, bitrate) - mp4_f = m3u8_format.copy() - mp4_f.update({ - 'url': progressive_base_url + 'mp4', - 'format_id': m3u8_format['format_id'].replace('hls', 'mp4'), - 'protocol': 'http', - }) - web_f = { - 'url': progressive_base_url + 'webm', - 'format_id': m3u8_format['format_id'].replace('hls', 'webm'), - 'width': m3u8_format['width'], - 'height': m3u8_format['height'], - 'tbr': m3u8_format.get('tbr'), - 'ext': 'webm', + video = item['Video'] + video_id = video['Id'] + title = video['Title'] + + q = qualities(['Lowest', 'Low', 'Medium', 'High', 'Highest']) + formats = [] + for video_source in item.get('VideoFormats', []): + video_source_url = video_source.get('Url') + if not video_source_url: + continue + video_source_format = video_source.get('Format') + if video_source_format == 'F4M': + formats.extend(self._extract_f4m_formats( + video_source_url, video_id, + f4m_id=video_source_format, fatal=False)) + elif video_source_format == 'M3U8': + formats.extend(self._extract_m3u8_formats( + video_source_url, video_id, 'mp4', 'm3u8_native', + m3u8_id=video_source_format, fatal=False)) + else: + video_source_quality = video_source.get('Quality') + format_id = [] + for v in (video_source_format, video_source_quality): + if v: + format_id.append(v) + f = { + 'format_id': '-'.join(format_id), + 'quality': q(video_source_quality), + 'url': video_source_url, } - formats.extend([web_f, mp4_f]) - else: - for bitrate in self._BITRATES: - for ext in ('web', 'mp4'): - formats.append({ - 'format_id': '%s-%s' % (ext, bitrate), - 'url': '%spublic/%s_%d.%s' % (progressive_base, path, bitrate, ext), - 'tbr': bitrate, - 'ext': ext, - }) + quality = self._QUALITIES.get(video_source_quality) + if quality: + f.update({ + 'abr': quality[0], + 'height': quality[1], + 'width': quality[2], + }), + formats.append(f) self._sort_formats(formats) + subtitles = {} + sub_file_id = video.get('SubFileId') + if sub_file_id and sub_file_id != '00000000-0000-0000-0000-000000000000': + net_storage_path = video.get('NetstoragePath') + invariant_id = video.get('InvariantId') + video_file_id = video.get('VideoFileId') + video_version = video.get('VideoVersion') + if net_storage_path and invariant_id and video_file_id and video_version: + subtitles.setdefault(locale[:2], []).append({ + 'url': 'https://lc-mediaplayerns-live-s.legocdn.com/public/%s/%s_%s_%s_%s_sub.srt' % (net_storage_path, invariant_id, video_file_id, locale, video_version), + }) + return { 'id': video_id, 'title': title, - 'description': self._html_search_meta('description', webpage), - 'thumbnail': self._html_search_meta('thumbnail', webpage), - 'duration': parse_duration(self._html_search_meta('duration', webpage)), + 'description': video.get('Description'), + 'thumbnail': video.get('GeneratedCoverImage') or video.get('GeneratedThumbnail'), + 'duration': int_or_none(video.get('Length')), 'formats': formats, + 'subtitles': subtitles, + 'age_limit': int_or_none(video.get('AgeFrom')), + 'season': video.get('SeasonTitle'), + 'season_number': int_or_none(video.get('Season')) or None, + 'episode_number': int_or_none(video.get('Episode')) or None, } diff --git a/youtube_dl/extractor/lnkgo.py b/youtube_dl/extractor/lnkgo.py index cfec0d3..3e71852 100644 --- a/youtube_dl/extractor/lnkgo.py +++ b/youtube_dl/extractor/lnkgo.py @@ -5,24 +5,27 @@ import re from .common import InfoExtractor from ..utils import ( + clean_html, + compat_str, int_or_none, - unified_strdate, + parse_iso8601, ) class LnkGoIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?lnkgo\.(?:alfa\.)?lt/visi-video/(?P<show>[^/]+)/ziurek-(?P<id>[A-Za-z0-9-]+)' + _VALID_URL = r'https?://(?:www\.)?lnk(?:go)?\.(?:alfa\.)?lt/(?:visi-video/[^/]+|video)/(?P<id>[A-Za-z0-9-]+)(?:/(?P<episode_id>\d+))?' _TESTS = [{ - 'url': 'http://lnkgo.alfa.lt/visi-video/yra-kaip-yra/ziurek-yra-kaip-yra-162', + 'url': 'http://www.lnkgo.lt/visi-video/aktualai-pratesimas/ziurek-putka-trys-klausimai', 'info_dict': { - 'id': '46712', + 'id': '10809', 'ext': 'mp4', - 'title': 'Yra kaip yra', - 'upload_date': '20150107', - 'description': 'md5:d82a5e36b775b7048617f263a0e3475e', - 'age_limit': 7, - 'duration': 3019, - 'thumbnail': r're:^https?://.*\.jpg$' + 'title': "Put'ka: Trys Klausimai", + 'upload_date': '20161216', + 'description': 'Seniai matytas Put’ka užduoda tris klausimėlius. Pabandykime surasti atsakymus.', + 'age_limit': 18, + 'duration': 117, + 'thumbnail': r're:^https?://.*\.jpg$', + 'timestamp': 1481904000, }, 'params': { 'skip_download': True, # HLS download @@ -30,20 +33,21 @@ class LnkGoIE(InfoExtractor): }, { 'url': 'http://lnkgo.alfa.lt/visi-video/aktualai-pratesimas/ziurek-nerdas-taiso-kompiuteri-2', 'info_dict': { - 'id': '47289', + 'id': '10467', 'ext': 'mp4', 'title': 'Nėrdas: Kompiuterio Valymas', 'upload_date': '20150113', 'description': 'md5:7352d113a242a808676ff17e69db6a69', 'age_limit': 18, 'duration': 346, - 'thumbnail': r're:^https?://.*\.jpg$' + 'thumbnail': r're:^https?://.*\.jpg$', + 'timestamp': 1421164800, }, 'params': { 'skip_download': True, # HLS download }, }, { - 'url': 'http://www.lnkgo.lt/visi-video/aktualai-pratesimas/ziurek-putka-trys-klausimai', + 'url': 'https://lnk.lt/video/neigalieji-tv-bokste/37413', 'only_matching': True, }] _AGE_LIMITS = { @@ -51,66 +55,34 @@ class LnkGoIE(InfoExtractor): 'N-14': 14, 'S': 18, } + _M3U8_TEMPL = 'https://vod.lnk.lt/lnk_vod/lnk/lnk/%s:%s/playlist.m3u8%s' def _real_extract(self, url): - display_id = self._match_id(url) - - webpage = self._download_webpage( - url, display_id, 'Downloading player webpage') - - video_id = self._search_regex( - r'data-ep="([^"]+)"', webpage, 'video ID') - title = self._og_search_title(webpage) - description = self._og_search_description(webpage) - upload_date = unified_strdate(self._search_regex( - r'class="[^"]*meta-item[^"]*air-time[^"]*">.*?<strong>([^<]+)</strong>', webpage, 'upload date', fatal=False)) - - thumbnail_w = int_or_none( - self._og_search_property('image:width', webpage, 'thumbnail width', fatal=False)) - thumbnail_h = int_or_none( - self._og_search_property('image:height', webpage, 'thumbnail height', fatal=False)) - thumbnail = { - 'url': self._og_search_thumbnail(webpage), - } - if thumbnail_w and thumbnail_h: - thumbnail.update({ - 'width': thumbnail_w, - 'height': thumbnail_h, - }) - - config = self._parse_json(self._search_regex( - r'episodePlayer\((\{.*?\}),\s*\{', webpage, 'sources'), video_id) - - if config.get('pGeo'): - self.report_warning( - 'This content might not be available in your country due to copyright reasons') + display_id, video_id = re.match(self._VALID_URL, url).groups() - formats = [{ - 'format_id': 'hls', - 'ext': 'mp4', - 'url': config['EpisodeVideoLink_HLS'], - }] - - m = re.search(r'^(?P<url>rtmp://[^/]+/(?P<app>[^/]+))/(?P<play_path>.+)$', config['EpisodeVideoLink']) - if m: - formats.append({ - 'format_id': 'rtmp', - 'ext': 'flv', - 'url': m.group('url'), - 'play_path': m.group('play_path'), - 'page_url': url, - }) + video_info = self._download_json( + 'https://lnk.lt/api/main/video-page/%s/%s/false' % (display_id, video_id or '0'), + display_id)['videoConfig']['videoInfo'] + video_id = compat_str(video_info['id']) + title = video_info['title'] + prefix = 'smil' if video_info.get('isQualityChangeAvailable') else 'mp4' + formats = self._extract_m3u8_formats( + self._M3U8_TEMPL % (prefix, video_info['videoUrl'], video_info.get('secureTokenParams') or ''), + video_id, 'mp4', 'm3u8_native') self._sort_formats(formats) + poster_image = video_info.get('posterImage') + return { 'id': video_id, 'display_id': display_id, 'title': title, 'formats': formats, - 'thumbnails': [thumbnail], - 'duration': int_or_none(config.get('VideoTime')), - 'description': description, - 'age_limit': self._AGE_LIMITS.get(config.get('PGRating'), 0), - 'upload_date': upload_date, + 'thumbnail': 'https://lnk.lt/all-images/' + poster_image if poster_image else None, + 'duration': int_or_none(video_info.get('duration')), + 'description': clean_html(video_info.get('htmlDescription')), + 'age_limit': self._AGE_LIMITS.get(video_info.get('pgRating'), 0), + 'timestamp': parse_iso8601(video_info.get('airDate')), + 'view_count': int_or_none(video_info.get('viewsCount')), } diff --git a/youtube_dl/extractor/macgamestore.py b/youtube_dl/extractor/macgamestore.py deleted file mode 100644 index 43db992..0000000 --- a/youtube_dl/extractor/macgamestore.py +++ /dev/null @@ -1,42 +0,0 @@ -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..utils import ExtractorError - - -class MacGameStoreIE(InfoExtractor): - IE_NAME = 'macgamestore' - IE_DESC = 'MacGameStore trailers' - _VALID_URL = r'https?://(?:www\.)?macgamestore\.com/mediaviewer\.php\?trailer=(?P<id>\d+)' - - _TEST = { - 'url': 'http://www.macgamestore.com/mediaviewer.php?trailer=2450', - 'md5': '8649b8ea684b6666b4c5be736ecddc61', - 'info_dict': { - 'id': '2450', - 'ext': 'm4v', - 'title': 'Crow', - } - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage( - url, video_id, 'Downloading trailer page') - - if '>Missing Media<' in webpage: - raise ExtractorError( - 'Trailer %s does not exist' % video_id, expected=True) - - video_title = self._html_search_regex( - r'<title>MacGameStore: (.*?) Trailer', webpage, 'title') - - video_url = self._html_search_regex( - r'(?s)', - webpage, 'video URL') - - return { - 'id': video_id, - 'url': video_url, - 'title': video_title - } diff --git a/youtube_dl/extractor/mailru.py b/youtube_dl/extractor/mailru.py index 6b0e64b..5023479 100644 --- a/youtube_dl/extractor/mailru.py +++ b/youtube_dl/extractor/mailru.py @@ -20,10 +20,10 @@ class MailRuIE(InfoExtractor): IE_DESC = 'Видео@Mail.Ru' _VALID_URL = r'''(?x) https?:// - (?:(?:www|m)\.)?my\.mail\.ru/ + (?:(?:www|m)\.)?my\.mail\.ru/+ (?: video/.*\#video=/?(?P(?:[^/]+/){3}\d+)| - (?:(?P(?:[^/]+/){2})video/(?P[^/]+/\d+))\.html| + (?:(?P(?:[^/]+/+){2})video/(?P[^/]+/\d+))\.html| (?:video/embed|\+/video/meta)/(?P\d+) ) ''' @@ -85,6 +85,14 @@ class MailRuIE(InfoExtractor): { 'url': 'http://my.mail.ru/+/video/meta/7949340477499637815', 'only_matching': True, + }, + { + 'url': 'https://my.mail.ru//list/sinyutin10/video/_myvideo/4.html', + 'only_matching': True, + }, + { + 'url': 'https://my.mail.ru//list//sinyutin10/video/_myvideo/4.html', + 'only_matching': True, } ] @@ -237,7 +245,7 @@ class MailRuMusicSearchBaseIE(InfoExtractor): class MailRuMusicIE(MailRuMusicSearchBaseIE): IE_NAME = 'mailru:music' IE_DESC = 'Музыка@Mail.Ru' - _VALID_URL = r'https?://my\.mail\.ru/music/songs/[^/?#&]+-(?P[\da-f]+)' + _VALID_URL = r'https?://my\.mail\.ru/+music/+songs/+[^/?#&]+-(?P[\da-f]+)' _TESTS = [{ 'url': 'https://my.mail.ru/music/songs/%D0%BC8%D0%BB8%D1%82%D1%85-l-a-h-luciferian-aesthetics-of-herrschaft-single-2017-4e31f7125d0dfaef505d947642366893', 'md5': '0f8c22ef8c5d665b13ac709e63025610', @@ -273,7 +281,7 @@ class MailRuMusicIE(MailRuMusicSearchBaseIE): class MailRuMusicSearchIE(MailRuMusicSearchBaseIE): IE_NAME = 'mailru:music:search' IE_DESC = 'Музыка@Mail.Ru' - _VALID_URL = r'https?://my\.mail\.ru/music/search/(?P[^/?#&]+)' + _VALID_URL = r'https?://my\.mail\.ru/+music/+search/+(?P[^/?#&]+)' _TESTS = [{ 'url': 'https://my.mail.ru/music/search/black%20shadow', 'info_dict': { diff --git a/youtube_dl/extractor/makertv.py b/youtube_dl/extractor/makertv.py deleted file mode 100644 index 8eda69c..0000000 --- a/youtube_dl/extractor/makertv.py +++ /dev/null @@ -1,32 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor - - -class MakerTVIE(InfoExtractor): - _VALID_URL = r'https?://(?:(?:www\.)?maker\.tv/(?:[^/]+/)*video|makerplayer\.com/embed/maker)/(?P[a-zA-Z0-9]{12})' - _TEST = { - 'url': 'http://www.maker.tv/video/Fh3QgymL9gsc', - 'md5': 'ca237a53a8eb20b6dc5bd60564d4ab3e', - 'info_dict': { - 'id': 'Fh3QgymL9gsc', - 'ext': 'mp4', - 'title': 'Maze Runner: The Scorch Trials Official Movie Review', - 'description': 'md5:11ff3362d7ef1d679fdb649f6413975a', - 'upload_date': '20150918', - 'timestamp': 1442549540, - } - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - jwplatform_id = self._search_regex(r'jw_?id="([^"]+)"', webpage, 'jwplatform id') - - return { - '_type': 'url_transparent', - 'id': video_id, - 'url': 'jwplatform:%s' % jwplatform_id, - 'ie_key': 'JWPlatform', - } diff --git a/youtube_dl/extractor/mangomolo.py b/youtube_dl/extractor/mangomolo.py index 482175a..acee370 100644 --- a/youtube_dl/extractor/mangomolo.py +++ b/youtube_dl/extractor/mangomolo.py @@ -10,18 +10,21 @@ from ..utils import int_or_none class MangomoloBaseIE(InfoExtractor): + _BASE_REGEX = r'https?://(?:admin\.mangomolo\.com/analytics/index\.php/customers/embed/|player\.mangomolo\.com/v1/)' + def _get_real_id(self, page_id): return page_id def _real_extract(self, url): page_id = self._get_real_id(self._match_id(url)) - webpage = self._download_webpage(url, page_id) + webpage = self._download_webpage( + 'https://player.mangomolo.com/v1/%s?%s' % (self._TYPE, url.split('?')[1]), page_id) hidden_inputs = self._hidden_inputs(webpage) m3u8_entry_protocol = 'm3u8' if self._IS_LIVE else 'm3u8_native' format_url = self._html_search_regex( [ - r'file\s*:\s*"(https?://[^"]+?/playlist\.m3u8)', + r'(?:file|src)\s*:\s*"(https?://[^"]+?/playlist\.m3u8)', r']+href="(rtsp://[^"]+)"' ], webpage, 'format url') formats = self._extract_wowza_formats( @@ -39,14 +42,16 @@ class MangomoloBaseIE(InfoExtractor): class MangomoloVideoIE(MangomoloBaseIE): - IE_NAME = 'mangomolo:video' - _VALID_URL = r'https?://admin\.mangomolo\.com/analytics/index\.php/customers/embed/video\?.*?\bid=(?P\d+)' + _TYPE = 'video' + IE_NAME = 'mangomolo:' + _TYPE + _VALID_URL = MangomoloBaseIE._BASE_REGEX + r'video\?.*?\bid=(?P\d+)' _IS_LIVE = False class MangomoloLiveIE(MangomoloBaseIE): - IE_NAME = 'mangomolo:live' - _VALID_URL = r'https?://admin\.mangomolo\.com/analytics/index\.php/customers/embed/index\?.*?\bchannelid=(?P(?:[A-Za-z0-9+/=]|%2B|%2F|%3D)+)' + _TYPE = 'live' + IE_NAME = 'mangomolo:' + _TYPE + _VALID_URL = MangomoloBaseIE._BASE_REGEX + r'(live|index)\?.*?\bchannelid=(?P(?:[A-Za-z0-9+/=]|%2B|%2F|%3D)+)' _IS_LIVE = True def _get_real_id(self, page_id): diff --git a/youtube_dl/extractor/mediaset.py b/youtube_dl/extractor/mediaset.py index df37487..027a790 100644 --- a/youtube_dl/extractor/mediaset.py +++ b/youtube_dl/extractor/mediaset.py @@ -27,7 +27,7 @@ class MediasetIE(ThePlatformBaseIE): (?:video|on-demand)/(?:[^/]+/)+[^/]+_| player/index\.html\?.*?\bprogramGuid= ) - )(?P[0-9A-Z]{16}) + )(?P[0-9A-Z]{16,}) ''' _TESTS = [{ # full episode @@ -62,7 +62,6 @@ class MediasetIE(ThePlatformBaseIE): 'uploader': 'Canale 5', 'uploader_id': 'C5', }, - 'expected_warnings': ['HTTP Error 403: Forbidden'], }, { # clip 'url': 'https://www.mediasetplay.mediaset.it/video/gogglebox/un-grande-classico-della-commedia-sexy_FAFU000000661680', @@ -78,6 +77,18 @@ class MediasetIE(ThePlatformBaseIE): }, { 'url': 'mediaset:FAFU000000665924', 'only_matching': True, + }, { + 'url': 'https://www.mediasetplay.mediaset.it/video/mediasethaacuoreilfuturo/palmieri-alicudi-lisola-dei-tre-bambini-felici--un-decreto-per-alicudi-e-tutte-le-microscuole_FD00000000102295', + 'only_matching': True, + }, { + 'url': 'https://www.mediasetplay.mediaset.it/video/cherryseason/anticipazioni-degli-episodi-del-23-ottobre_F306837101005C02', + 'only_matching': True, + }, { + 'url': 'https://www.mediasetplay.mediaset.it/video/tg5/ambiente-onda-umana-per-salvare-il-pianeta_F309453601079D01', + 'only_matching': True, + }, { + 'url': 'https://www.mediasetplay.mediaset.it/video/grandefratellovip/benedetta-una-doccia-gelata_F309344401044C135', + 'only_matching': True, }] @staticmethod @@ -109,6 +120,11 @@ class MediasetIE(ThePlatformBaseIE): entries.append(embed_url) return entries + def _parse_smil_formats(self, smil, smil_url, video_id, namespace=None, f4m_params=None, transform_rtmp_url=None): + for video in smil.findall(self._xpath_ns('.//video', namespace)): + video.attrib['src'] = re.sub(r'(https?://vod05)t(-mediaset-it\.akamaized\.net/.+?.mpd)\?.+', r'\1\2', video.attrib['src']) + return super(MediasetIE, self)._parse_smil_formats(smil, smil_url, video_id, namespace, f4m_params, transform_rtmp_url) + def _real_extract(self, url): guid = self._match_id(url) tp_path = 'PR1GhC/media/guid/2702976343/' + guid @@ -118,14 +134,15 @@ class MediasetIE(ThePlatformBaseIE): subtitles = {} first_e = None for asset_type in ('SD', 'HD'): - for f in ('MPEG4', 'MPEG-DASH', 'M3U', 'ISM'): + # TODO: fixup ISM+none manifest URLs + for f in ('MPEG4', 'MPEG-DASH+none', 'M3U+none'): try: tp_formats, tp_subtitles = self._extract_theplatform_smil( update_url_query('http://link.theplatform.%s/s/%s' % (self._TP_TLD, tp_path), { 'mbr': 'true', 'formats': f, 'assetTypes': asset_type, - }), guid, 'Downloading %s %s SMIL data' % (f, asset_type)) + }), guid, 'Downloading %s %s SMIL data' % (f.split('+')[0], asset_type)) except ExtractorError as e: if not first_e: first_e = e diff --git a/youtube_dl/extractor/minhateca.py b/youtube_dl/extractor/minhateca.py deleted file mode 100644 index dccc542..0000000 --- a/youtube_dl/extractor/minhateca.py +++ /dev/null @@ -1,70 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..utils import ( - int_or_none, - parse_duration, - parse_filesize, - sanitized_Request, - urlencode_postdata, -) - - -class MinhatecaIE(InfoExtractor): - _VALID_URL = r'https?://minhateca\.com\.br/[^?#]+,(?P[0-9]+)\.' - _TEST = { - 'url': 'http://minhateca.com.br/pereba/misc/youtube-dl+test+video,125848331.mp4(video)', - 'info_dict': { - 'id': '125848331', - 'ext': 'mp4', - 'title': 'youtube-dl test video', - 'thumbnail': r're:^https?://.*\.jpg$', - 'filesize_approx': 1530000, - 'duration': 9, - 'view_count': int, - } - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - - token = self._html_search_regex( - r'(.*?)', webpage, 'title') - title, _, ext = title_str.rpartition('.') - filesize_approx = parse_filesize(self._html_search_regex( - r'

(.*?)

', - webpage, 'file size approximation', fatal=False)) - duration = parse_duration(self._html_search_regex( - r'(?s)

.*?class="bold">(.*?)<', - webpage, 'duration', fatal=False)) - view_count = int_or_none(self._html_search_regex( - r'

([0-9]+)

', - webpage, 'view count', fatal=False)) - - return { - 'id': video_id, - 'url': video_url, - 'title': title, - 'ext': ext, - 'filesize_approx': filesize_approx, - 'duration': duration, - 'view_count': view_count, - 'thumbnail': self._og_search_thumbnail(webpage), - } diff --git a/youtube_dl/extractor/mit.py b/youtube_dl/extractor/mit.py index 1aea78d..e1506a7 100644 --- a/youtube_dl/extractor/mit.py +++ b/youtube_dl/extractor/mit.py @@ -65,30 +65,6 @@ class TechTVMITIE(InfoExtractor): } -class MITIE(TechTVMITIE): - IE_NAME = 'video.mit.edu' - _VALID_URL = r'https?://video\.mit\.edu/watch/(?P[^/]+)' - - _TEST = { - 'url': 'http://video.mit.edu/watch/the-government-is-profiling-you-13222/', - 'md5': '7db01d5ccc1895fc5010e9c9e13648da', - 'info_dict': { - 'id': '21783', - 'ext': 'mp4', - 'title': 'The Government is Profiling You', - 'description': 'md5:ad5795fe1e1623b73620dbfd47df9afd', - }, - } - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - page_title = mobj.group('title') - webpage = self._download_webpage(url, page_title) - embed_url = self._search_regex( - r'<iframe .*?src="(.+?)"', webpage, 'embed url') - return self.url_result(embed_url) - - class OCWMITIE(InfoExtractor): IE_NAME = 'ocw.mit.edu' _VALID_URL = r'^https?://ocw\.mit\.edu/courses/(?P<topic>[a-z0-9\-]+)' diff --git a/youtube_dl/extractor/mitele.py b/youtube_dl/extractor/mitele.py index 40f214a..ad9da96 100644 --- a/youtube_dl/extractor/mitele.py +++ b/youtube_dl/extractor/mitele.py @@ -4,8 +4,8 @@ from __future__ import unicode_literals from .common import InfoExtractor from ..utils import ( int_or_none, + parse_iso8601, smuggle_url, - parse_duration, ) @@ -18,16 +18,18 @@ class MiTeleIE(InfoExtractor): 'info_dict': { 'id': 'FhYW1iNTE6J6H7NkQRIEzfne6t2quqPg', 'ext': 'mp4', - 'title': 'Tor, la web invisible', - 'description': 'md5:3b6fce7eaa41b2d97358726378d9369f', + 'title': 'Diario de La redacción Programa 144', + 'description': 'md5:07c35a7b11abb05876a6a79185b58d27', 'series': 'Diario de', - 'season': 'La redacción', + 'season': 'Season 14', 'season_number': 14, - 'season_id': 'diario_de_t14_11981', - 'episode': 'Programa 144', + 'episode': 'Tor, la web invisible', 'episode_number': 3, 'thumbnail': r're:(?i)^https?://.*\.jpg$', 'duration': 2913, + 'age_limit': 16, + 'timestamp': 1471209401, + 'upload_date': '20160814', }, 'add_ie': ['Ooyala'], }, { @@ -39,13 +41,15 @@ class MiTeleIE(InfoExtractor): 'title': 'Cuarto Milenio Temporada 6 Programa 226', 'description': 'md5:5ff132013f0cd968ffbf1f5f3538a65f', 'series': 'Cuarto Milenio', - 'season': 'Temporada 6', + 'season': 'Season 6', 'season_number': 6, - 'season_id': 'cuarto_milenio_t06_12715', - 'episode': 'Programa 226', + 'episode': 'Episode 24', 'episode_number': 24, 'thumbnail': r're:(?i)^https?://.*\.jpg$', 'duration': 7313, + 'age_limit': 12, + 'timestamp': 1471209021, + 'upload_date': '20160814', }, 'params': { 'skip_download': True, @@ -54,67 +58,36 @@ class MiTeleIE(InfoExtractor): }, { 'url': 'http://www.mitele.es/series-online/la-que-se-avecina/57aac5c1c915da951a8b45ed/player', 'only_matching': True, + }, { + 'url': 'https://www.mitele.es/programas-tv/diario-de/la-redaccion/programa-144-40_1006364575251/player/', + 'only_matching': True, }] def _real_extract(self, url): - video_id = self._match_id(url) - - paths = self._download_json( - 'https://www.mitele.es/amd/agp/web/metadata/general_configuration', - video_id, 'Downloading paths JSON') - - ooyala_s = paths['general_configuration']['api_configuration']['ooyala_search'] - base_url = ooyala_s.get('base_url', 'cdn-search-mediaset.carbyne.ps.ooyala.com') - full_path = ooyala_s.get('full_path', '/search/v1/full/providers/') - source = self._download_json( - '%s://%s%s%s/docs/%s' % ( - ooyala_s.get('protocol', 'https'), base_url, full_path, - ooyala_s.get('provider_id', '104951'), video_id), - video_id, 'Downloading data JSON', query={ - 'include_titles': 'Series,Season', - 'product_name': ooyala_s.get('product_name', 'test'), - 'format': 'full', - })['hits']['hits'][0]['_source'] - - embedCode = source['offers'][0]['embed_codes'][0] - titles = source['localizable_titles'][0] - - title = titles.get('title_medium') or titles['title_long'] - - description = titles.get('summary_long') or titles.get('summary_medium') - - def get(key1, key2): - value1 = source.get(key1) - if not value1 or not isinstance(value1, list): - return - if not isinstance(value1[0], dict): - return - return value1[0].get(key2) - - series = get('localizable_titles_series', 'title_medium') - - season = get('localizable_titles_season', 'title_medium') - season_number = int_or_none(source.get('season_number')) - season_id = source.get('season_id') - - episode = titles.get('title_sort_name') - episode_number = int_or_none(source.get('episode_number')) - - duration = parse_duration(get('videos', 'duration')) + display_id = self._match_id(url) + webpage = self._download_webpage(url, display_id) + pre_player = self._parse_json(self._search_regex( + r'window\.\$REACTBASE_STATE\.prePlayer_mtweb\s*=\s*({.+})', + webpage, 'Pre Player'), display_id)['prePlayer'] + title = pre_player['title'] + video = pre_player['video'] + video_id = video['dataMediaId'] + content = pre_player.get('content') or {} + info = content.get('info') or {} return { '_type': 'url_transparent', # for some reason only HLS is supported - 'url': smuggle_url('ooyala:' + embedCode, {'supportedformats': 'm3u8,dash'}), + 'url': smuggle_url('ooyala:' + video_id, {'supportedformats': 'm3u8,dash'}), 'id': video_id, 'title': title, - 'description': description, - 'series': series, - 'season': season, - 'season_number': season_number, - 'season_id': season_id, - 'episode': episode, - 'episode_number': episode_number, - 'duration': duration, - 'thumbnail': get('images', 'url'), + 'description': info.get('synopsis'), + 'series': content.get('title'), + 'season_number': int_or_none(info.get('season_number')), + 'episode': content.get('subtitle'), + 'episode_number': int_or_none(info.get('episode_number')), + 'duration': int_or_none(info.get('duration')), + 'thumbnail': video.get('dataPoster'), + 'age_limit': int_or_none(info.get('rating')), + 'timestamp': parse_iso8601(pre_player.get('publishedTime')), } diff --git a/youtube_dl/extractor/mixcloud.py b/youtube_dl/extractor/mixcloud.py index bf5353e..9759560 100644 --- a/youtube_dl/extractor/mixcloud.py +++ b/youtube_dl/extractor/mixcloud.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals -import functools import itertools import re @@ -11,28 +10,37 @@ from ..compat import ( compat_ord, compat_str, compat_urllib_parse_unquote, - compat_urlparse, compat_zip ) from ..utils import ( - clean_html, - ExtractorError, int_or_none, - OnDemandPagedList, - str_to_int, + parse_iso8601, + strip_or_none, try_get, - urljoin, ) -class MixcloudIE(InfoExtractor): +class MixcloudBaseIE(InfoExtractor): + def _call_api(self, object_type, object_fields, display_id, username, slug=None): + lookup_key = object_type + 'Lookup' + return self._download_json( + 'https://www.mixcloud.com/graphql', display_id, query={ + 'query': '''{ + %s(lookup: {username: "%s"%s}) { + %s + } +}''' % (lookup_key, username, ', slug: "%s"' % slug if slug else '', object_fields) + })['data'][lookup_key] + + +class MixcloudIE(MixcloudBaseIE): _VALID_URL = r'https?://(?:(?:www|beta|m)\.)?mixcloud\.com/([^/]+)/(?!stream|uploads|favorites|listens|playlists)([^/]+)' IE_NAME = 'mixcloud' _TESTS = [{ 'url': 'http://www.mixcloud.com/dholbach/cryptkeeper/', 'info_dict': { - 'id': 'dholbach-cryptkeeper', + 'id': 'dholbach_cryptkeeper', 'ext': 'm4a', 'title': 'Cryptkeeper', 'description': 'After quite a long silence from myself, finally another Drum\'n\'Bass mix with my favourite current dance floor bangers.', @@ -40,11 +48,13 @@ class MixcloudIE(InfoExtractor): 'uploader_id': 'dholbach', 'thumbnail': r're:https?://.*\.jpg', 'view_count': int, + 'timestamp': 1321359578, + 'upload_date': '20111115', }, }, { 'url': 'http://www.mixcloud.com/gillespeterson/caribou-7-inch-vinyl-mix-chat/', 'info_dict': { - 'id': 'gillespeterson-caribou-7-inch-vinyl-mix-chat', + 'id': 'gillespeterson_caribou-7-inch-vinyl-mix-chat', 'ext': 'mp3', 'title': 'Caribou 7 inch Vinyl Mix & Chat', 'description': 'md5:2b8aec6adce69f9d41724647c65875e8', @@ -52,11 +62,14 @@ class MixcloudIE(InfoExtractor): 'uploader_id': 'gillespeterson', 'thumbnail': 're:https?://.*', 'view_count': int, + 'timestamp': 1422987057, + 'upload_date': '20150203', }, }, { 'url': 'https://beta.mixcloud.com/RedLightRadio/nosedrip-15-red-light-radio-01-18-2016/', 'only_matching': True, }] + _DECRYPTION_KEY = 'IFYOUWANTTHEARTISTSTOGETPAIDDONOTDOWNLOADFROMMIXCLOUD' @staticmethod def _decrypt_xor_cipher(key, ciphertext): @@ -66,176 +79,193 @@ class MixcloudIE(InfoExtractor): for ch, k in compat_zip(ciphertext, itertools.cycle(key))]) def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - uploader = mobj.group(1) - cloudcast_name = mobj.group(2) - track_id = compat_urllib_parse_unquote('-'.join((uploader, cloudcast_name))) + username, slug = re.match(self._VALID_URL, url).groups() + username, slug = compat_urllib_parse_unquote(username), compat_urllib_parse_unquote(slug) + track_id = '%s_%s' % (username, slug) + + cloudcast = self._call_api('cloudcast', '''audioLength + comments(first: 100) { + edges { + node { + comment + created + user { + displayName + username + } + } + } + totalCount + } + description + favorites { + totalCount + } + featuringArtistList + isExclusive + name + owner { + displayName + url + username + } + picture(width: 1024, height: 1024) { + url + } + plays + publishDate + reposts { + totalCount + } + streamInfo { + dashUrl + hlsUrl + url + } + tags { + tag { + name + } + }''', track_id, username, slug) - webpage = self._download_webpage(url, track_id) + title = cloudcast['name'] - # Legacy path - encrypted_play_info = self._search_regex( - r'm-play-info="([^"]+)"', webpage, 'play info', default=None) + stream_info = cloudcast['streamInfo'] + formats = [] - if encrypted_play_info is not None: - # Decode - encrypted_play_info = compat_b64decode(encrypted_play_info) - else: - # New path - full_info_json = self._parse_json(self._html_search_regex( - r'<script id="relay-data" type="text/x-mixcloud">([^<]+)</script>', - webpage, 'play info'), 'play info') - for item in full_info_json: - item_data = try_get( - item, lambda x: x['cloudcast']['data']['cloudcastLookup'], - dict) - if try_get(item_data, lambda x: x['streamInfo']['url']): - info_json = item_data - break - else: - raise ExtractorError('Failed to extract matching stream info') - - message = self._html_search_regex( - r'(?s)<div[^>]+class="global-message cloudcast-disabled-notice-light"[^>]*>(.+?)<(?:a|/div)', - webpage, 'error message', default=None) - - js_url = self._search_regex( - r'<script[^>]+\bsrc=["\"](https://(?:www\.)?mixcloud\.com/media/(?:js2/www_js_4|js/www)\.[^>]+\.js)', - webpage, 'js url') - js = self._download_webpage(js_url, track_id, 'Downloading JS') - # Known plaintext attack - if encrypted_play_info: - kps = ['{"stream_url":'] - kpa_target = encrypted_play_info - else: - kps = ['https://', 'http://'] - kpa_target = compat_b64decode(info_json['streamInfo']['url']) - for kp in kps: - partial_key = self._decrypt_xor_cipher(kpa_target, kp) - for quote in ["'", '"']: - key = self._search_regex( - r'{0}({1}[^{0}]*){0}'.format(quote, re.escape(partial_key)), - js, 'encryption key', default=None) - if key is not None: - break + for url_key in ('url', 'hlsUrl', 'dashUrl'): + format_url = stream_info.get(url_key) + if not format_url: + continue + decrypted = self._decrypt_xor_cipher( + self._DECRYPTION_KEY, compat_b64decode(format_url)) + if url_key == 'hlsUrl': + formats.extend(self._extract_m3u8_formats( + decrypted, track_id, 'mp4', entry_protocol='m3u8_native', + m3u8_id='hls', fatal=False)) + elif url_key == 'dashUrl': + formats.extend(self._extract_mpd_formats( + decrypted, track_id, mpd_id='dash', fatal=False)) else: + formats.append({ + 'format_id': 'http', + 'url': decrypted, + 'downloader_options': { + # Mixcloud starts throttling at >~5M + 'http_chunk_size': 5242880, + }, + }) + + if not formats and cloudcast.get('isExclusive'): + self.raise_login_required() + + self._sort_formats(formats) + + comments = [] + for edge in (try_get(cloudcast, lambda x: x['comments']['edges']) or []): + node = edge.get('node') or {} + text = strip_or_none(node.get('comment')) + if not text: continue - break - else: - raise ExtractorError('Failed to extract encryption key') - - if encrypted_play_info is not None: - play_info = self._parse_json(self._decrypt_xor_cipher(key, encrypted_play_info), 'play info') - if message and 'stream_url' not in play_info: - raise ExtractorError('%s said: %s' % (self.IE_NAME, message), expected=True) - song_url = play_info['stream_url'] - formats = [{ - 'format_id': 'normal', - 'url': song_url - }] - - title = self._html_search_regex(r'm-title="([^"]+)"', webpage, 'title') - thumbnail = self._proto_relative_url(self._html_search_regex( - r'm-thumbnail-url="([^"]+)"', webpage, 'thumbnail', fatal=False)) - uploader = self._html_search_regex( - r'm-owner-name="([^"]+)"', webpage, 'uploader', fatal=False) - uploader_id = self._search_regex( - r'\s+"profile": "([^"]+)",', webpage, 'uploader id', fatal=False) - description = self._og_search_description(webpage) - view_count = str_to_int(self._search_regex( - [r'<meta itemprop="interactionCount" content="UserPlays:([0-9]+)"', - r'/listeners/?">([0-9,.]+)</a>', - r'(?:m|data)-tooltip=["\']([\d,.]+) plays'], - webpage, 'play count', default=None)) + user = node.get('user') or {} + comments.append({ + 'author': user.get('displayName'), + 'author_id': user.get('username'), + 'text': text, + 'timestamp': parse_iso8601(node.get('created')), + }) - else: - title = info_json['name'] - thumbnail = urljoin( - 'https://thumbnailer.mixcloud.com/unsafe/600x600/', - try_get(info_json, lambda x: x['picture']['urlRoot'], compat_str)) - uploader = try_get(info_json, lambda x: x['owner']['displayName']) - uploader_id = try_get(info_json, lambda x: x['owner']['username']) - description = try_get(info_json, lambda x: x['description']) - view_count = int_or_none(try_get(info_json, lambda x: x['plays'])) - - stream_info = info_json['streamInfo'] - formats = [] - - def decrypt_url(f_url): - for k in (key, 'IFYOUWANTTHEARTISTSTOGETPAIDDONOTDOWNLOADFROMMIXCLOUD'): - decrypted_url = self._decrypt_xor_cipher(k, f_url) - if re.search(r'^https?://[0-9A-Za-z.]+/[0-9A-Za-z/.?=&_-]+$', decrypted_url): - return decrypted_url - - for url_key in ('url', 'hlsUrl', 'dashUrl'): - format_url = stream_info.get(url_key) - if not format_url: - continue - decrypted = decrypt_url(compat_b64decode(format_url)) - if not decrypted: - continue - if url_key == 'hlsUrl': - formats.extend(self._extract_m3u8_formats( - decrypted, track_id, 'mp4', entry_protocol='m3u8_native', - m3u8_id='hls', fatal=False)) - elif url_key == 'dashUrl': - formats.extend(self._extract_mpd_formats( - decrypted, track_id, mpd_id='dash', fatal=False)) - else: - formats.append({ - 'format_id': 'http', - 'url': decrypted, - 'downloader_options': { - # Mixcloud starts throttling at >~5M - 'http_chunk_size': 5242880, - }, - }) - self._sort_formats(formats) + tags = [] + for t in cloudcast.get('tags'): + tag = try_get(t, lambda x: x['tag']['name'], compat_str) + if not tag: + tags.append(tag) + + get_count = lambda x: int_or_none(try_get(cloudcast, lambda y: y[x]['totalCount'])) + + owner = cloudcast.get('owner') or {} return { 'id': track_id, 'title': title, 'formats': formats, - 'description': description, - 'thumbnail': thumbnail, - 'uploader': uploader, - 'uploader_id': uploader_id, - 'view_count': view_count, + 'description': cloudcast.get('description'), + 'thumbnail': try_get(cloudcast, lambda x: x['picture']['url'], compat_str), + 'uploader': owner.get('displayName'), + 'timestamp': parse_iso8601(cloudcast.get('publishDate')), + 'uploader_id': owner.get('username'), + 'uploader_url': owner.get('url'), + 'duration': int_or_none(cloudcast.get('audioLength')), + 'view_count': int_or_none(cloudcast.get('plays')), + 'like_count': get_count('favorites'), + 'repost_count': get_count('reposts'), + 'comment_count': get_count('comments'), + 'comments': comments, + 'tags': tags, + 'artist': ', '.join(cloudcast.get('featuringArtistList') or []) or None, } -class MixcloudPlaylistBaseIE(InfoExtractor): - _PAGE_SIZE = 24 +class MixcloudPlaylistBaseIE(MixcloudBaseIE): + def _get_cloudcast(self, node): + return node - def _find_urls_in_page(self, page): - for url in re.findall(r'm-play-button m-url="(?P<url>[^"]+)"', page): - yield self.url_result( - compat_urlparse.urljoin('https://www.mixcloud.com', clean_html(url)), - MixcloudIE.ie_key()) + def _get_playlist_title(self, title, slug): + return title + + def _real_extract(self, url): + username, slug = re.match(self._VALID_URL, url).groups() + username = compat_urllib_parse_unquote(username) + if not slug: + slug = 'uploads' + else: + slug = compat_urllib_parse_unquote(slug) + playlist_id = '%s_%s' % (username, slug) - def _fetch_tracks_page(self, path, video_id, page_name, current_page, real_page_number=None): - real_page_number = real_page_number or current_page + 1 - return self._download_webpage( - 'https://www.mixcloud.com/%s/' % path, video_id, - note='Download %s (page %d)' % (page_name, current_page + 1), - errnote='Unable to download %s' % page_name, - query={'page': real_page_number, 'list': 'main', '_ajax': '1'}, - headers={'X-Requested-With': 'XMLHttpRequest'}) + is_playlist_type = self._ROOT_TYPE == 'playlist' + playlist_type = 'items' if is_playlist_type else slug + list_filter = '' - def _tracks_page_func(self, page, video_id, page_name, current_page): - resp = self._fetch_tracks_page(page, video_id, page_name, current_page) + has_next_page = True + entries = [] + while has_next_page: + playlist = self._call_api( + self._ROOT_TYPE, '''%s + %s + %s(first: 100%s) { + edges { + node { + %s + } + } + pageInfo { + endCursor + hasNextPage + } + }''' % (self._TITLE_KEY, self._DESCRIPTION_KEY, playlist_type, list_filter, self._NODE_TEMPLATE), + playlist_id, username, slug if is_playlist_type else None) + + items = playlist.get(playlist_type) or {} + for edge in items.get('edges', []): + cloudcast = self._get_cloudcast(edge.get('node') or {}) + cloudcast_url = cloudcast.get('url') + if not cloudcast_url: + continue + entries.append(self.url_result( + cloudcast_url, MixcloudIE.ie_key(), cloudcast.get('slug'))) - for item in self._find_urls_in_page(resp): - yield item + page_info = items['pageInfo'] + has_next_page = page_info['hasNextPage'] + list_filter = ', after: "%s"' % page_info['endCursor'] - def _get_user_description(self, page_content): - return self._html_search_regex( - r'<div[^>]+class="profile-bio"[^>]*>(.+?)</div>', - page_content, 'user description', fatal=False) + return self.playlist_result( + entries, playlist_id, + self._get_playlist_title(playlist[self._TITLE_KEY], slug), + playlist.get(self._DESCRIPTION_KEY)) class MixcloudUserIE(MixcloudPlaylistBaseIE): - _VALID_URL = r'https?://(?:www\.)?mixcloud\.com/(?P<user>[^/]+)/(?P<type>uploads|favorites|listens)?/?$' + _VALID_URL = r'https?://(?:www\.)?mixcloud\.com/(?P<id>[^/]+)/(?P<type>uploads|favorites|listens|stream)?/?$' IE_NAME = 'mixcloud:user' _TESTS = [{ @@ -243,68 +273,58 @@ class MixcloudUserIE(MixcloudPlaylistBaseIE): 'info_dict': { 'id': 'dholbach_uploads', 'title': 'Daniel Holbach (uploads)', - 'description': 'md5:def36060ac8747b3aabca54924897e47', + 'description': 'md5:b60d776f0bab534c5dabe0a34e47a789', }, - 'playlist_mincount': 11, + 'playlist_mincount': 36, }, { 'url': 'http://www.mixcloud.com/dholbach/uploads/', 'info_dict': { 'id': 'dholbach_uploads', 'title': 'Daniel Holbach (uploads)', - 'description': 'md5:def36060ac8747b3aabca54924897e47', + 'description': 'md5:b60d776f0bab534c5dabe0a34e47a789', }, - 'playlist_mincount': 11, + 'playlist_mincount': 36, }, { 'url': 'http://www.mixcloud.com/dholbach/favorites/', 'info_dict': { 'id': 'dholbach_favorites', 'title': 'Daniel Holbach (favorites)', - 'description': 'md5:def36060ac8747b3aabca54924897e47', - }, - 'params': { - 'playlist_items': '1-100', + 'description': 'md5:b60d776f0bab534c5dabe0a34e47a789', }, - 'playlist_mincount': 100, + # 'params': { + # 'playlist_items': '1-100', + # }, + 'playlist_mincount': 396, }, { 'url': 'http://www.mixcloud.com/dholbach/listens/', 'info_dict': { 'id': 'dholbach_listens', 'title': 'Daniel Holbach (listens)', - 'description': 'md5:def36060ac8747b3aabca54924897e47', + 'description': 'md5:b60d776f0bab534c5dabe0a34e47a789', }, - 'params': { - 'playlist_items': '1-100', + # 'params': { + # 'playlist_items': '1-100', + # }, + 'playlist_mincount': 1623, + 'skip': 'Large list', + }, { + 'url': 'https://www.mixcloud.com/FirstEar/stream/', + 'info_dict': { + 'id': 'FirstEar_stream', + 'title': 'First Ear (stream)', + 'description': 'Curators of good music\r\n\r\nfirstearmusic.com', }, - 'playlist_mincount': 100, + 'playlist_mincount': 271, }] - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - user_id = mobj.group('user') - list_type = mobj.group('type') - - # if only a profile URL was supplied, default to download all uploads - if list_type is None: - list_type = 'uploads' - - video_id = '%s_%s' % (user_id, list_type) + _TITLE_KEY = 'displayName' + _DESCRIPTION_KEY = 'biog' + _ROOT_TYPE = 'user' + _NODE_TEMPLATE = '''slug + url''' - profile = self._download_webpage( - 'https://www.mixcloud.com/%s/' % user_id, video_id, - note='Downloading user profile', - errnote='Unable to download user profile') - - username = self._og_search_title(profile) - description = self._get_user_description(profile) - - entries = OnDemandPagedList( - functools.partial( - self._tracks_page_func, - '%s/%s' % (user_id, list_type), video_id, 'list of %s' % list_type), - self._PAGE_SIZE) - - return self.playlist_result( - entries, video_id, '%s (%s)' % (username, list_type), description) + def _get_playlist_title(self, title, slug): + return '%s (%s)' % (title, slug) class MixcloudPlaylistIE(MixcloudPlaylistBaseIE): @@ -312,87 +332,20 @@ class MixcloudPlaylistIE(MixcloudPlaylistBaseIE): IE_NAME = 'mixcloud:playlist' _TESTS = [{ - 'url': 'https://www.mixcloud.com/RedBullThre3style/playlists/tokyo-finalists-2015/', - 'info_dict': { - 'id': 'RedBullThre3style_tokyo-finalists-2015', - 'title': 'National Champions 2015', - 'description': 'md5:6ff5fb01ac76a31abc9b3939c16243a3', - }, - 'playlist_mincount': 16, - }, { 'url': 'https://www.mixcloud.com/maxvibes/playlists/jazzcat-on-ness-radio/', - 'only_matching': True, - }] - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - user_id = mobj.group('user') - playlist_id = mobj.group('playlist') - video_id = '%s_%s' % (user_id, playlist_id) - - webpage = self._download_webpage( - url, user_id, - note='Downloading playlist page', - errnote='Unable to download playlist page') - - title = self._html_search_regex( - r'<a[^>]+class="parent active"[^>]*><b>\d+</b><span[^>]*>([^<]+)', - webpage, 'playlist title', - default=None) or self._og_search_title(webpage, fatal=False) - description = self._get_user_description(webpage) - - entries = OnDemandPagedList( - functools.partial( - self._tracks_page_func, - '%s/playlists/%s' % (user_id, playlist_id), video_id, 'tracklist'), - self._PAGE_SIZE) - - return self.playlist_result(entries, video_id, title, description) - - -class MixcloudStreamIE(MixcloudPlaylistBaseIE): - _VALID_URL = r'https?://(?:www\.)?mixcloud\.com/(?P<id>[^/]+)/stream/?$' - IE_NAME = 'mixcloud:stream' - - _TEST = { - 'url': 'https://www.mixcloud.com/FirstEar/stream/', 'info_dict': { - 'id': 'FirstEar', - 'title': 'First Ear', - 'description': 'Curators of good music\nfirstearmusic.com', + 'id': 'maxvibes_jazzcat-on-ness-radio', + 'title': 'Ness Radio sessions', }, - 'playlist_mincount': 192, - } - - def _real_extract(self, url): - user_id = self._match_id(url) - - webpage = self._download_webpage(url, user_id) - - entries = [] - prev_page_url = None - - def _handle_page(page): - entries.extend(self._find_urls_in_page(page)) - return self._search_regex( - r'm-next-page-url="([^"]+)"', page, - 'next page URL', default=None) - - next_page_url = _handle_page(webpage) - - for idx in itertools.count(0): - if not next_page_url or prev_page_url == next_page_url: - break - - prev_page_url = next_page_url - current_page = int(self._search_regex( - r'\?page=(\d+)', next_page_url, 'next page number')) - - next_page_url = _handle_page(self._fetch_tracks_page( - '%s/stream' % user_id, user_id, 'stream', idx, - real_page_number=current_page)) - - username = self._og_search_title(webpage) - description = self._get_user_description(webpage) - - return self.playlist_result(entries, user_id, username, description) + 'playlist_mincount': 59, + }] + _TITLE_KEY = 'name' + _DESCRIPTION_KEY = 'description' + _ROOT_TYPE = 'playlist' + _NODE_TEMPLATE = '''cloudcast { + slug + url + }''' + + def _get_cloudcast(self, node): + return node.get('cloudcast') or {} diff --git a/youtube_dl/extractor/msn.py b/youtube_dl/extractor/msn.py index 0460cf4..e59b0b7 100644 --- a/youtube_dl/extractor/msn.py +++ b/youtube_dl/extractor/msn.py @@ -14,20 +14,27 @@ from ..utils import ( class MSNIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?msn\.com/(?:[^/]+/)+(?P<display_id>[^/]+)/[a-z]{2}-(?P<id>[\da-zA-Z]+)' + _VALID_URL = r'https?://(?:(?:www|preview)\.)?msn\.com/(?:[^/]+/)+(?P<display_id>[^/]+)/[a-z]{2}-(?P<id>[\da-zA-Z]+)' _TESTS = [{ - 'url': 'http://www.msn.com/en-ae/foodanddrink/joinourtable/criminal-minds-shemar-moore-shares-a-touching-goodbye-message/vp-BBqQYNE', - 'md5': '8442f66c116cbab1ff7098f986983458', + 'url': 'https://www.msn.com/en-in/money/video/7-ways-to-get-rid-of-chest-congestion/vi-BBPxU6d', + 'md5': '087548191d273c5c55d05028f8d2cbcd', 'info_dict': { - 'id': 'BBqQYNE', - 'display_id': 'criminal-minds-shemar-moore-shares-a-touching-goodbye-message', + 'id': 'BBPxU6d', + 'display_id': '7-ways-to-get-rid-of-chest-congestion', 'ext': 'mp4', - 'title': 'Criminal Minds - Shemar Moore Shares A Touching Goodbye Message', - 'description': 'md5:e8e89b897b222eb33a6b5067a8f1bc25', - 'duration': 104, - 'uploader': 'CBS Entertainment', - 'uploader_id': 'IT0X5aoJ6bJgYerJXSDCgFmYPB1__54v', + 'title': 'Seven ways to get rid of chest congestion', + 'description': '7 Ways to Get Rid of Chest Congestion', + 'duration': 88, + 'uploader': 'Health', + 'uploader_id': 'BBPrMqa', }, + }, { + # Article, multiple Dailymotion Embeds + 'url': 'https://www.msn.com/en-in/money/sports/hottest-football-wags-greatest-footballers-turned-managers-and-more/ar-BBpc7Nl', + 'info_dict': { + 'id': 'BBpc7Nl', + }, + 'playlist_mincount': 4, }, { 'url': 'http://www.msn.com/en-ae/news/offbeat/meet-the-nine-year-old-self-made-millionaire/ar-BBt6ZKf', 'only_matching': True, @@ -41,75 +48,124 @@ class MSNIE(InfoExtractor): }, { 'url': 'http://www.msn.com/en-ae/entertainment/bollywood/watch-how-salman-khan-reacted-when-asked-if-he-would-apologize-for-his-‘raped-woman’-comment/vi-AAhvzW6', 'only_matching': True, + }, { + # Vidible(AOL) Embed + 'url': 'https://www.msn.com/en-us/money/other/jupiter-is-about-to-come-so-close-you-can-see-its-moons-with-binoculars/vi-AACqsHR', + 'only_matching': True, + }, { + # Dailymotion Embed + 'url': 'https://www.msn.com/es-ve/entretenimiento/watch/winston-salem-paire-refait-des-siennes-en-perdant-sa-raquette-au-service/vp-AAG704L', + 'only_matching': True, + }, { + # YouTube Embed + 'url': 'https://www.msn.com/en-in/money/news/meet-vikram-%E2%80%94-chandrayaan-2s-lander/vi-AAGUr0v', + 'only_matching': True, + }, { + # NBCSports Embed + 'url': 'https://www.msn.com/en-us/money/football_nfl/week-13-preview-redskins-vs-panthers/vi-BBXsCDb', + 'only_matching': True, }] def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id, display_id = mobj.group('id', 'display_id') + display_id, page_id = re.match(self._VALID_URL, url).groups() webpage = self._download_webpage(url, display_id) - video = self._parse_json( - self._search_regex( - r'data-metadata\s*=\s*(["\'])(?P<data>.+?)\1', - webpage, 'video data', default='{}', group='data'), - display_id, transform_source=unescapeHTML) + entries = [] + for _, metadata in re.findall(r'data-metadata\s*=\s*(["\'])(?P<data>.+?)\1', webpage): + video = self._parse_json(unescapeHTML(metadata), display_id) + + provider_id = video.get('providerId') + player_name = video.get('playerName') + if player_name and provider_id: + entry = None + if player_name == 'AOL': + if provider_id.startswith('http'): + provider_id = self._search_regex( + r'https?://delivery\.vidible\.tv/video/redirect/([0-9a-f]{24})', + provider_id, 'vidible id') + entry = self.url_result( + 'aol-video:' + provider_id, 'Aol', provider_id) + elif player_name == 'Dailymotion': + entry = self.url_result( + 'https://www.dailymotion.com/video/' + provider_id, + 'Dailymotion', provider_id) + elif player_name == 'YouTube': + entry = self.url_result( + provider_id, 'Youtube', provider_id) + elif player_name == 'NBCSports': + entry = self.url_result( + 'http://vplayer.nbcsports.com/p/BxmELC/nbcsports_embed/select/media/' + provider_id, + 'NBCSportsVPlayer', provider_id) + if entry: + entries.append(entry) + continue + + video_id = video['uuid'] + title = video['title'] + + formats = [] + for file_ in video.get('videoFiles', []): + format_url = file_.get('url') + if not format_url: + continue + if 'format=m3u8-aapl' in format_url: + # m3u8_native should not be used here until + # https://github.com/ytdl-org/youtube-dl/issues/9913 is fixed + formats.extend(self._extract_m3u8_formats( + format_url, display_id, 'mp4', + m3u8_id='hls', fatal=False)) + elif 'format=mpd-time-csf' in format_url: + formats.extend(self._extract_mpd_formats( + format_url, display_id, 'dash', fatal=False)) + elif '.ism' in format_url: + if format_url.endswith('.ism'): + format_url += '/manifest' + formats.extend(self._extract_ism_formats( + format_url, display_id, 'mss', fatal=False)) + else: + format_id = file_.get('formatCode') + formats.append({ + 'url': format_url, + 'ext': 'mp4', + 'format_id': format_id, + 'width': int_or_none(file_.get('width')), + 'height': int_or_none(file_.get('height')), + 'vbr': int_or_none(self._search_regex(r'_(\d+)\.mp4', format_url, 'vbr', default=None)), + 'preference': 1 if format_id == '1001' else None, + }) + self._sort_formats(formats) + + subtitles = {} + for file_ in video.get('files', []): + format_url = file_.get('url') + format_code = file_.get('formatCode') + if not format_url or not format_code: + continue + if compat_str(format_code) == '3100': + subtitles.setdefault(file_.get('culture', 'en'), []).append({ + 'ext': determine_ext(format_url, 'ttml'), + 'url': format_url, + }) - if not video: + entries.append({ + 'id': video_id, + 'display_id': display_id, + 'title': title, + 'description': video.get('description'), + 'thumbnail': video.get('headlineImage', {}).get('url'), + 'duration': int_or_none(video.get('durationSecs')), + 'uploader': video.get('sourceFriendly'), + 'uploader_id': video.get('providerId'), + 'creator': video.get('creator'), + 'subtitles': subtitles, + 'formats': formats, + }) + + if not entries: error = unescapeHTML(self._search_regex( r'data-error=(["\'])(?P<error>.+?)\1', webpage, 'error', group='error')) raise ExtractorError('%s said: %s' % (self.IE_NAME, error), expected=True) - title = video['title'] - - formats = [] - for file_ in video.get('videoFiles', []): - format_url = file_.get('url') - if not format_url: - continue - if 'm3u8' in format_url: - # m3u8_native should not be used here until - # https://github.com/ytdl-org/youtube-dl/issues/9913 is fixed - m3u8_formats = self._extract_m3u8_formats( - format_url, display_id, 'mp4', - m3u8_id='hls', fatal=False) - formats.extend(m3u8_formats) - elif determine_ext(format_url) == 'ism': - formats.extend(self._extract_ism_formats( - format_url + '/Manifest', display_id, 'mss', fatal=False)) - else: - formats.append({ - 'url': format_url, - 'ext': 'mp4', - 'format_id': 'http', - 'width': int_or_none(file_.get('width')), - 'height': int_or_none(file_.get('height')), - }) - self._sort_formats(formats) - - subtitles = {} - for file_ in video.get('files', []): - format_url = file_.get('url') - format_code = file_.get('formatCode') - if not format_url or not format_code: - continue - if compat_str(format_code) == '3100': - subtitles.setdefault(file_.get('culture', 'en'), []).append({ - 'ext': determine_ext(format_url, 'ttml'), - 'url': format_url, - }) - - return { - 'id': video_id, - 'display_id': display_id, - 'title': title, - 'description': video.get('description'), - 'thumbnail': video.get('headlineImage', {}).get('url'), - 'duration': int_or_none(video.get('durationSecs')), - 'uploader': video.get('sourceFriendly'), - 'uploader_id': video.get('providerId'), - 'creator': video.get('creator'), - 'subtitles': subtitles, - 'formats': formats, - } + return self.playlist_result(entries, page_id) diff --git a/youtube_dl/extractor/mtv.py b/youtube_dl/extractor/mtv.py index 7a3b57a..fedd5f4 100644 --- a/youtube_dl/extractor/mtv.py +++ b/youtube_dl/extractor/mtv.py @@ -1,3 +1,4 @@ +# coding: utf-8 from __future__ import unicode_literals import re @@ -349,33 +350,29 @@ class MTVIE(MTVServicesInfoExtractor): }] -class MTV81IE(InfoExtractor): - IE_NAME = 'mtv81' - _VALID_URL = r'https?://(?:www\.)?mtv81\.com/videos/(?P<id>[^/?#.]+)' +class MTVJapanIE(MTVServicesInfoExtractor): + IE_NAME = 'mtvjapan' + _VALID_URL = r'https?://(?:www\.)?mtvjapan\.com/videos/(?P<id>[0-9a-z]+)' _TEST = { - 'url': 'http://www.mtv81.com/videos/artist-to-watch/the-godfather-of-japanese-hip-hop-segment-1/', - 'md5': '1edbcdf1e7628e414a8c5dcebca3d32b', + 'url': 'http://www.mtvjapan.com/videos/prayht/fresh-info-cadillac-escalade', 'info_dict': { - 'id': '5e14040d-18a4-47c4-a582-43ff602de88e', + 'id': 'bc01da03-6fe5-4284-8880-f291f4e368f5', 'ext': 'mp4', - 'title': 'Unlocking The Truth|July 18, 2016|1|101|Trailer', - 'description': '"Unlocking the Truth" premieres August 17th at 11/10c.', - 'timestamp': 1468846800, - 'upload_date': '20160718', + 'title': '【Fresh Info】Cadillac ESCALADE Sport Edition', + }, + 'params': { + 'skip_download': True, }, } + _GEO_COUNTRIES = ['JP'] + _FEED_URL = 'http://feeds.mtvnservices.com/od/feed/intl-mrss-player-feed' - def _extract_mgid(self, webpage): - return self._search_regex( - r'getTheVideo\((["\'])(?P<id>mgid:.+?)\1', webpage, - 'mgid', group='id') - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - mgid = self._extract_mgid(webpage) - return self.url_result('http://media.mtvnservices.com/embed/%s' % mgid) + def _get_feed_query(self, uri): + return { + 'arcEp': 'mtvjapan.com', + 'mgid': uri, + } class MTVVideoIE(MTVServicesInfoExtractor): @@ -425,14 +422,14 @@ class MTVVideoIE(MTVServicesInfoExtractor): class MTVDEIE(MTVServicesInfoExtractor): IE_NAME = 'mtv.de' - _VALID_URL = r'https?://(?:www\.)?mtv\.de/(?:artists|shows|news)/(?:[^/]+/)*(?P<id>\d+)-[^/#?]+/*(?:[#?].*)?$' + _VALID_URL = r'https?://(?:www\.)?mtv\.de/(?:musik/videoclips|folgen|news)/(?P<id>[0-9a-z]+)' _TESTS = [{ - 'url': 'http://www.mtv.de/artists/10571-cro/videos/61131-traum', + 'url': 'http://www.mtv.de/musik/videoclips/2gpnv7/Traum', 'info_dict': { - 'id': 'music_video-a50bc5f0b3aa4b3190aa', - 'ext': 'flv', - 'title': 'MusicVideo_cro-traum', - 'description': 'Cro - Traum', + 'id': 'd5d472bc-f5b7-11e5-bffd-a4badb20dab5', + 'ext': 'mp4', + 'title': 'Traum', + 'description': 'Traum', }, 'params': { # rtmp download @@ -441,11 +438,12 @@ class MTVDEIE(MTVServicesInfoExtractor): 'skip': 'Blocked at Travis CI', }, { # mediagen URL without query (e.g. http://videos.mtvnn.com/mediagen/e865da714c166d18d6f80893195fcb97) - 'url': 'http://www.mtv.de/shows/933-teen-mom-2/staffeln/5353/folgen/63565-enthullungen', + 'url': 'http://www.mtv.de/folgen/6b1ylu/teen-mom-2-enthuellungen-S5-F1', 'info_dict': { - 'id': 'local_playlist-f5ae778b9832cc837189', - 'ext': 'flv', - 'title': 'Episode_teen-mom-2_shows_season-5_episode-1_full-episode_part1', + 'id': '1e5a878b-31c5-11e7-a442-0e40cf2fc285', + 'ext': 'mp4', + 'title': 'Teen Mom 2', + 'description': 'md5:dc65e357ef7e1085ed53e9e9d83146a7', }, 'params': { # rtmp download @@ -453,7 +451,7 @@ class MTVDEIE(MTVServicesInfoExtractor): }, 'skip': 'Blocked at Travis CI', }, { - 'url': 'http://www.mtv.de/news/77491-mtv-movies-spotlight-pixels-teil-3', + 'url': 'http://www.mtv.de/news/glolix/77491-mtv-movies-spotlight--pixels--teil-3', 'info_dict': { 'id': 'local_playlist-4e760566473c4c8c5344', 'ext': 'mp4', @@ -466,25 +464,11 @@ class MTVDEIE(MTVServicesInfoExtractor): }, 'skip': 'Das Video kann zur Zeit nicht abgespielt werden.', }] + _GEO_COUNTRIES = ['DE'] + _FEED_URL = 'http://feeds.mtvnservices.com/od/feed/intl-mrss-player-feed' - def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - - playlist = self._parse_json( - self._search_regex( - r'window\.pagePlaylist\s*=\s*(\[.+?\]);\n', webpage, 'page playlist'), - video_id) - - def _mrss_url(item): - return item['mrss'] + item.get('mrssvars', '') - - # news pages contain single video in playlist with different id - if len(playlist) == 1: - return self._get_videos_info_from_url(_mrss_url(playlist[0]), video_id) - - for item in playlist: - item_id = item.get('id') - if item_id and compat_str(item_id) == video_id: - return self._get_videos_info_from_url(_mrss_url(item), video_id) + def _get_feed_query(self, uri): + return { + 'arcEp': 'mtv.de', + 'mgid': uri, + } diff --git a/youtube_dl/extractor/musicplayon.py b/youtube_dl/extractor/musicplayon.py deleted file mode 100644 index 1854d59..0000000 --- a/youtube_dl/extractor/musicplayon.py +++ /dev/null @@ -1,66 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..compat import compat_urlparse -from ..utils import ( - int_or_none, - js_to_json, - mimetype2ext, -) - - -class MusicPlayOnIE(InfoExtractor): - _VALID_URL = r'https?://(?:.+?\.)?musicplayon\.com/play(?:-touch)?\?(?:v|pl=\d+&play)=(?P<id>\d+)' - - _TESTS = [{ - 'url': 'http://en.musicplayon.com/play?v=433377', - 'md5': '00cdcdea1726abdf500d1e7fd6dd59bb', - 'info_dict': { - 'id': '433377', - 'ext': 'mp4', - 'title': 'Rick Ross - Interview On Chelsea Lately (2014)', - 'description': 'Rick Ross Interview On Chelsea Lately', - 'duration': 342, - 'uploader': 'ultrafish', - }, - }, { - 'url': 'http://en.musicplayon.com/play?pl=102&play=442629', - 'only_matching': True, - }] - - _URL_TEMPLATE = 'http://en.musicplayon.com/play?v=%s' - - def _real_extract(self, url): - video_id = self._match_id(url) - url = self._URL_TEMPLATE % video_id - - page = self._download_webpage(url, video_id) - - title = self._og_search_title(page) - description = self._og_search_description(page) - thumbnail = self._og_search_thumbnail(page) - duration = self._html_search_meta('video:duration', page, 'duration', fatal=False) - view_count = self._og_search_property('count', page, fatal=False) - uploader = self._html_search_regex( - r'<div>by <a href="[^"]+" class="purple">([^<]+)</a></div>', page, 'uploader', fatal=False) - - sources = self._parse_json( - self._search_regex(r'setup\[\'_sources\'\]\s*=\s*([^;]+);', page, 'video sources'), - video_id, transform_source=js_to_json) - formats = [{ - 'url': compat_urlparse.urljoin(url, source['src']), - 'ext': mimetype2ext(source.get('type')), - 'format_note': source.get('data-res'), - } for source in sources] - - return { - 'id': video_id, - 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'uploader': uploader, - 'duration': int_or_none(duration), - 'view_count': int_or_none(view_count), - 'formats': formats, - } diff --git a/youtube_dl/extractor/myspass.py b/youtube_dl/extractor/myspass.py index 2afe535..db7ebc9 100644 --- a/youtube_dl/extractor/myspass.py +++ b/youtube_dl/extractor/myspass.py @@ -1,73 +1,56 @@ +# coding: utf-8 from __future__ import unicode_literals -import os.path + +import re from .common import InfoExtractor -from ..compat import ( - compat_urllib_parse_urlparse, -) +from ..compat import compat_str from ..utils import ( - ExtractorError, + int_or_none, + parse_duration, + xpath_text, ) class MySpassIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?myspass\.de/.*' + _VALID_URL = r'https?://(?:www\.)?myspass\.de/([^/]+/)*(?P<id>\d+)' _TEST = { 'url': 'http://www.myspass.de/myspass/shows/tvshows/absolute-mehrheit/Absolute-Mehrheit-vom-17022013-Die-Highlights-Teil-2--/11741/', 'md5': '0b49f4844a068f8b33f4b7c88405862b', 'info_dict': { 'id': '11741', 'ext': 'mp4', - 'description': 'Wer kann in die Fu\u00dfstapfen von Wolfgang Kubicki treten und die Mehrheit der Zuschauer hinter sich versammeln? Wird vielleicht sogar die Absolute Mehrheit geknackt und der Jackpot von 200.000 Euro mit nach Hause genommen?', - 'title': 'Absolute Mehrheit vom 17.02.2013 - Die Highlights, Teil 2', + 'description': 'Wer kann in die Fußstapfen von Wolfgang Kubicki treten und die Mehrheit der Zuschauer hinter sich versammeln? Wird vielleicht sogar die Absolute Mehrheit geknackt und der Jackpot von 200.000 Euro mit nach Hause genommen?', + 'title': '17.02.2013 - Die Highlights, Teil 2', }, } def _real_extract(self, url): - META_DATA_URL_TEMPLATE = 'http://www.myspass.de/myspass/includes/apps/video/getvideometadataxml.php?id=%s' + video_id = self._match_id(url) - # video id is the last path element of the URL - # usually there is a trailing slash, so also try the second but last - url_path = compat_urllib_parse_urlparse(url).path - url_parent_path, video_id = os.path.split(url_path) - if not video_id: - _, video_id = os.path.split(url_parent_path) - - # get metadata - metadata_url = META_DATA_URL_TEMPLATE % video_id metadata = self._download_xml( - metadata_url, video_id, transform_source=lambda s: s.strip()) - - # extract values from metadata - url_flv_el = metadata.find('url_flv') - if url_flv_el is None: - raise ExtractorError('Unable to extract download url') - video_url = url_flv_el.text - title_el = metadata.find('title') - if title_el is None: - raise ExtractorError('Unable to extract title') - title = title_el.text - format_id_el = metadata.find('format_id') - if format_id_el is None: - format = 'mp4' - else: - format = format_id_el.text - description_el = metadata.find('description') - if description_el is not None: - description = description_el.text - else: - description = None - imagePreview_el = metadata.find('imagePreview') - if imagePreview_el is not None: - thumbnail = imagePreview_el.text - else: - thumbnail = None + 'http://www.myspass.de/myspass/includes/apps/video/getvideometadataxml.php?id=' + video_id, + video_id) + + title = xpath_text(metadata, 'title', fatal=True) + video_url = xpath_text(metadata, 'url_flv', 'download url', True) + video_id_int = int(video_id) + for group in re.search(r'/myspass2009/\d+/(\d+)/(\d+)/(\d+)/', video_url).groups(): + group_int = int(group) + if group_int > video_id_int: + video_url = video_url.replace( + group, compat_str(group_int // video_id_int)) return { 'id': video_id, 'url': video_url, 'title': title, - 'format': format, - 'thumbnail': thumbnail, - 'description': description, + 'thumbnail': xpath_text(metadata, 'imagePreview'), + 'description': xpath_text(metadata, 'description'), + 'duration': parse_duration(xpath_text(metadata, 'duration')), + 'series': xpath_text(metadata, 'format'), + 'season_number': int_or_none(xpath_text(metadata, 'season')), + 'season_id': xpath_text(metadata, 'season_id'), + 'episode': title, + 'episode_number': int_or_none(xpath_text(metadata, 'episode')), } diff --git a/youtube_dl/extractor/naver.py b/youtube_dl/extractor/naver.py index bb3d944..61fc591 100644 --- a/youtube_dl/extractor/naver.py +++ b/youtube_dl/extractor/naver.py @@ -1,68 +1,33 @@ # coding: utf-8 from __future__ import unicode_literals +import re + from .common import InfoExtractor from ..utils import ( + clean_html, + dict_get, ExtractorError, int_or_none, + parse_duration, + try_get, update_url_query, ) -class NaverIE(InfoExtractor): - _VALID_URL = r'https?://(?:m\.)?tv(?:cast)?\.naver\.com/v/(?P<id>\d+)' +class NaverBaseIE(InfoExtractor): + _CAPTION_EXT_RE = r'\.(?:ttml|vtt)' - _TESTS = [{ - 'url': 'http://tv.naver.com/v/81652', - 'info_dict': { - 'id': '81652', - 'ext': 'mp4', - 'title': '[9월 모의고사 해설강의][수학_김상희] 수학 A형 16~20번', - 'description': '합격불변의 법칙 메가스터디 | 메가스터디 수학 김상희 선생님이 9월 모의고사 수학A형 16번에서 20번까지 해설강의를 공개합니다.', - 'upload_date': '20130903', - }, - }, { - 'url': 'http://tv.naver.com/v/395837', - 'md5': '638ed4c12012c458fefcddfd01f173cd', - 'info_dict': { - 'id': '395837', - 'ext': 'mp4', - 'title': '9년이 지나도 아픈 기억, 전효성의 아버지', - 'description': 'md5:5bf200dcbf4b66eb1b350d1eb9c753f7', - 'upload_date': '20150519', - }, - 'skip': 'Georestricted', - }, { - 'url': 'http://tvcast.naver.com/v/81652', - 'only_matching': True, - }] - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - - vid = self._search_regex( - r'videoId["\']\s*:\s*(["\'])(?P<value>(?:(?!\1).)+)\1', webpage, - 'video id', fatal=None, group='value') - in_key = self._search_regex( - r'inKey["\']\s*:\s*(["\'])(?P<value>(?:(?!\1).)+)\1', webpage, - 'key', default=None, group='value') - - if not vid or not in_key: - error = self._html_search_regex( - r'(?s)<div class="(?:nation_error|nation_box|error_box)">\s*(?:<!--.*?-->)?\s*<p class="[^"]+">(?P<msg>.+?)</p>\s*</div>', - webpage, 'error', default=None) - if error: - raise ExtractorError(error, expected=True) - raise ExtractorError('couldn\'t extract vid and key') + def _extract_video_info(self, video_id, vid, key): video_data = self._download_json( 'http://play.rmcnmv.naver.com/vod/play/v2.0/' + vid, video_id, query={ - 'key': in_key, + 'key': key, }) meta = video_data['meta'] title = meta['subject'] formats = [] + get_list = lambda x: try_get(video_data, lambda y: y[x + 's']['list'], list) or [] def extract_formats(streams, stream_type, query={}): for stream in streams: @@ -73,7 +38,7 @@ class NaverIE(InfoExtractor): encoding_option = stream.get('encodingOption', {}) bitrate = stream.get('bitrate', {}) formats.append({ - 'format_id': '%s_%s' % (stream.get('type') or stream_type, encoding_option.get('id') or encoding_option.get('name')), + 'format_id': '%s_%s' % (stream.get('type') or stream_type, dict_get(encoding_option, ('name', 'id'))), 'url': stream_url, 'width': int_or_none(encoding_option.get('width')), 'height': int_or_none(encoding_option.get('height')), @@ -83,7 +48,7 @@ class NaverIE(InfoExtractor): 'protocol': 'm3u8_native' if stream_type == 'HLS' else None, }) - extract_formats(video_data.get('videos', {}).get('list', []), 'H264') + extract_formats(get_list('video'), 'H264') for stream_set in video_data.get('streams', []): query = {} for param in stream_set.get('keys', []): @@ -101,28 +66,101 @@ class NaverIE(InfoExtractor): 'mp4', 'm3u8_native', m3u8_id=stream_type, fatal=False)) self._sort_formats(formats) + replace_ext = lambda x, y: re.sub(self._CAPTION_EXT_RE, '.' + y, x) + + def get_subs(caption_url): + if re.search(self._CAPTION_EXT_RE, caption_url): + return [{ + 'url': replace_ext(caption_url, 'ttml'), + }, { + 'url': replace_ext(caption_url, 'vtt'), + }] + else: + return [{'url': caption_url}] + + automatic_captions = {} subtitles = {} - for caption in video_data.get('captions', {}).get('list', []): + for caption in get_list('caption'): caption_url = caption.get('source') if not caption_url: continue - subtitles.setdefault(caption.get('language') or caption.get('locale'), []).append({ - 'url': caption_url, - }) + sub_dict = automatic_captions if caption.get('type') == 'auto' else subtitles + sub_dict.setdefault(dict_get(caption, ('locale', 'language')), []).extend(get_subs(caption_url)) - upload_date = self._search_regex( - r'<span[^>]+class="date".*?(\d{4}\.\d{2}\.\d{2})', - webpage, 'upload date', fatal=False) - if upload_date: - upload_date = upload_date.replace('.', '') + user = meta.get('user', {}) return { 'id': video_id, 'title': title, 'formats': formats, 'subtitles': subtitles, - 'description': self._og_search_description(webpage), - 'thumbnail': meta.get('cover', {}).get('source') or self._og_search_thumbnail(webpage), + 'automatic_captions': automatic_captions, + 'thumbnail': try_get(meta, lambda x: x['cover']['source']), 'view_count': int_or_none(meta.get('count')), - 'upload_date': upload_date, + 'uploader_id': user.get('id'), + 'uploader': user.get('name'), + 'uploader_url': user.get('url'), } + + +class NaverIE(NaverBaseIE): + _VALID_URL = r'https?://(?:m\.)?tv(?:cast)?\.naver\.com/(?:v|embed)/(?P<id>\d+)' + _GEO_BYPASS = False + _TESTS = [{ + 'url': 'http://tv.naver.com/v/81652', + 'info_dict': { + 'id': '81652', + 'ext': 'mp4', + 'title': '[9월 모의고사 해설강의][수학_김상희] 수학 A형 16~20번', + 'description': '메가스터디 수학 김상희 선생님이 9월 모의고사 수학A형 16번에서 20번까지 해설강의를 공개합니다.', + 'timestamp': 1378200754, + 'upload_date': '20130903', + 'uploader': '메가스터디, 합격불변의 법칙', + 'uploader_id': 'megastudy', + }, + }, { + 'url': 'http://tv.naver.com/v/395837', + 'md5': '8a38e35354d26a17f73f4e90094febd3', + 'info_dict': { + 'id': '395837', + 'ext': 'mp4', + 'title': '9년이 지나도 아픈 기억, 전효성의 아버지', + 'description': 'md5:eb6aca9d457b922e43860a2a2b1984d3', + 'timestamp': 1432030253, + 'upload_date': '20150519', + 'uploader': '4가지쇼 시즌2', + 'uploader_id': 'wrappinguser29', + }, + 'skip': 'Georestricted', + }, { + 'url': 'http://tvcast.naver.com/v/81652', + 'only_matching': True, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + content = self._download_json( + 'https://tv.naver.com/api/json/v/' + video_id, + video_id, headers=self.geo_verification_headers()) + player_info_json = content.get('playerInfoJson') or {} + current_clip = player_info_json.get('currentClip') or {} + + vid = current_clip.get('videoId') + in_key = current_clip.get('inKey') + + if not vid or not in_key: + player_auth = try_get(player_info_json, lambda x: x['playerOption']['auth']) + if player_auth == 'notCountry': + self.raise_geo_restricted(countries=['KR']) + elif player_auth == 'notLogin': + self.raise_login_required() + raise ExtractorError('couldn\'t extract vid and key') + info = self._extract_video_info(video_id, vid, in_key) + info.update({ + 'description': clean_html(current_clip.get('description')), + 'timestamp': int_or_none(current_clip.get('firstExposureTime'), 1000), + 'duration': parse_duration(current_clip.get('displayPlayTime')), + 'like_count': int_or_none(current_clip.get('recommendPoint')), + 'age_limit': 19 if current_clip.get('adult') else None, + }) + return info diff --git a/youtube_dl/extractor/nbc.py b/youtube_dl/extractor/nbc.py index 3282f84..6f3cb30 100644 --- a/youtube_dl/extractor/nbc.py +++ b/youtube_dl/extractor/nbc.py @@ -9,10 +9,13 @@ from .theplatform import ThePlatformIE from .adobepass import AdobePassIE from ..compat import compat_urllib_parse_unquote from ..utils import ( + int_or_none, + js_to_json, + parse_duration, smuggle_url, try_get, + unified_timestamp, update_url_query, - int_or_none, ) @@ -84,28 +87,61 @@ class NBCIE(AdobePassIE): def _real_extract(self, url): permalink, video_id = re.match(self._VALID_URL, url).groups() permalink = 'http' + compat_urllib_parse_unquote(permalink) - response = self._download_json( - 'https://api.nbc.com/v3/videos', video_id, query={ - 'filter[permalink]': permalink, - 'fields[videos]': 'description,entitlement,episodeNumber,guid,keywords,seasonNumber,title,vChipRating', - 'fields[shows]': 'shortTitle', - 'include': 'show.shortTitle', - }) - video_data = response['data'][0]['attributes'] + video_data = self._download_json( + 'https://friendship.nbc.co/v2/graphql', video_id, query={ + 'query': '''query bonanzaPage( + $app: NBCUBrands! = nbc + $name: String! + $oneApp: Boolean + $platform: SupportedPlatforms! = web + $type: EntityPageType! = VIDEO + $userId: String! +) { + bonanzaPage( + app: $app + name: $name + oneApp: $oneApp + platform: $platform + type: $type + userId: $userId + ) { + metadata { + ... on VideoPageData { + description + episodeNumber + keywords + locked + mpxAccountId + mpxGuid + rating + resourceId + seasonNumber + secondaryTitle + seriesShortTitle + } + } + } +}''', + 'variables': json.dumps({ + 'name': permalink, + 'oneApp': True, + 'userId': '0', + }), + })['data']['bonanzaPage']['metadata'] query = { 'mbr': 'true', 'manifest': 'm3u', } - video_id = video_data['guid'] - title = video_data['title'] - if video_data.get('entitlement') == 'auth': + video_id = video_data['mpxGuid'] + title = video_data['secondaryTitle'] + if video_data.get('locked'): resource = self._get_mvpd_resource( - 'nbcentertainment', title, video_id, - video_data.get('vChipRating')) + video_data.get('resourceId') or 'nbcentertainment', + title, video_id, video_data.get('rating')) query['auth'] = self._extract_mvpd_auth( url, video_id, 'nbcentertainment', resource) theplatform_url = smuggle_url(update_url_query( - 'http://link.theplatform.com/s/NnzsPC/media/guid/2410887629/' + video_id, + 'http://link.theplatform.com/s/NnzsPC/media/guid/%s/%s' % (video_data.get('mpxAccountId') or '2410887629', video_id), query), {'force_smil_url': True}) return { '_type': 'url_transparent', @@ -117,7 +153,7 @@ class NBCIE(AdobePassIE): 'season_number': int_or_none(video_data.get('seasonNumber')), 'episode_number': int_or_none(video_data.get('episodeNumber')), 'episode': title, - 'series': try_get(response, lambda x: x['included'][0]['attributes']['shortTitle']), + 'series': video_data.get('seriesShortTitle'), 'ie_key': 'ThePlatform', } @@ -272,13 +308,12 @@ class NBCNewsIE(ThePlatformIE): _TESTS = [ { 'url': 'http://www.nbcnews.com/watch/nbcnews-com/how-twitter-reacted-to-the-snowden-interview-269389891880', - 'md5': 'af1adfa51312291a017720403826bb64', + 'md5': 'cf4bc9e6ce0130f00f545d80ecedd4bf', 'info_dict': { 'id': '269389891880', 'ext': 'mp4', 'title': 'How Twitter Reacted To The Snowden Interview', 'description': 'md5:65a0bd5d76fe114f3c2727aa3a81fe64', - 'uploader': 'NBCU-NEWS', 'timestamp': 1401363060, 'upload_date': '20140529', }, @@ -296,28 +331,26 @@ class NBCNewsIE(ThePlatformIE): }, { 'url': 'http://www.nbcnews.com/nightly-news/video/nightly-news-with-brian-williams-full-broadcast-february-4-394064451844', - 'md5': '73135a2e0ef819107bbb55a5a9b2a802', + 'md5': '8eb831eca25bfa7d25ddd83e85946548', 'info_dict': { 'id': '394064451844', 'ext': 'mp4', 'title': 'Nightly News with Brian Williams Full Broadcast (February 4)', 'description': 'md5:1c10c1eccbe84a26e5debb4381e2d3c5', 'timestamp': 1423104900, - 'uploader': 'NBCU-NEWS', 'upload_date': '20150205', }, }, { 'url': 'http://www.nbcnews.com/business/autos/volkswagen-11-million-vehicles-could-have-suspect-software-emissions-scandal-n431456', - 'md5': 'a49e173825e5fcd15c13fc297fced39d', + 'md5': '4a8c4cec9e1ded51060bdda36ff0a5c0', 'info_dict': { - 'id': '529953347624', + 'id': 'n431456', 'ext': 'mp4', - 'title': 'Volkswagen U.S. Chief:\xa0 We Have Totally Screwed Up', - 'description': 'md5:c8be487b2d80ff0594c005add88d8351', + 'title': "Volkswagen U.S. Chief: We 'Totally Screwed Up'", + 'description': 'md5:d22d1281a24f22ea0880741bb4dd6301', 'upload_date': '20150922', 'timestamp': 1442917800, - 'uploader': 'NBCU-NEWS', }, }, { @@ -330,7 +363,6 @@ class NBCNewsIE(ThePlatformIE): 'description': 'md5:74752b7358afb99939c5f8bb2d1d04b1', 'upload_date': '20160420', 'timestamp': 1461152093, - 'uploader': 'NBCU-NEWS', }, }, { @@ -344,7 +376,6 @@ class NBCNewsIE(ThePlatformIE): 'thumbnail': r're:^https?://.*\.jpg$', 'timestamp': 1406937606, 'upload_date': '20140802', - 'uploader': 'NBCU-NEWS', }, }, { @@ -360,20 +391,61 @@ class NBCNewsIE(ThePlatformIE): def _real_extract(self, url): video_id = self._match_id(url) - if not video_id.isdigit(): - webpage = self._download_webpage(url, video_id) + webpage = self._download_webpage(url, video_id) - data = self._parse_json(self._search_regex( - r'window\.__data\s*=\s*({.+});', webpage, - 'bootstrap json'), video_id) - video_id = data['article']['content'][0]['primaryMedia']['video']['mpxMetadata']['id'] + data = self._parse_json(self._search_regex( + r'window\.__data\s*=\s*({.+});', webpage, + 'bootstrap json'), video_id, js_to_json) + video_data = try_get(data, lambda x: x['video']['current'], dict) + if not video_data: + video_data = data['article']['content'][0]['primaryMedia']['video'] + title = video_data['headline']['primary'] + + formats = [] + for va in video_data.get('videoAssets', []): + public_url = va.get('publicUrl') + if not public_url: + continue + if '://link.theplatform.com/' in public_url: + public_url = update_url_query(public_url, {'format': 'redirect'}) + format_id = va.get('format') + if format_id == 'M3U': + formats.extend(self._extract_m3u8_formats( + public_url, video_id, 'mp4', 'm3u8_native', + m3u8_id=format_id, fatal=False)) + continue + tbr = int_or_none(va.get('bitrate'), 1000) + if tbr: + format_id += '-%d' % tbr + formats.append({ + 'format_id': format_id, + 'url': public_url, + 'width': int_or_none(va.get('width')), + 'height': int_or_none(va.get('height')), + 'tbr': tbr, + 'ext': 'mp4', + }) + self._sort_formats(formats) + + subtitles = {} + closed_captioning = video_data.get('closedCaptioning') + if closed_captioning: + for cc_url in closed_captioning.values(): + if not cc_url: + continue + subtitles.setdefault('en', []).append({ + 'url': cc_url, + }) return { - '_type': 'url_transparent', 'id': video_id, - # http://feed.theplatform.com/f/2E2eJC/nbcnews also works - 'url': update_url_query('http://feed.theplatform.com/f/2E2eJC/nnd_NBCNews', {'byId': video_id}), - 'ie_key': 'ThePlatformFeed', + 'title': title, + 'description': try_get(video_data, lambda x: x['description']['primary']), + 'thumbnail': try_get(video_data, lambda x: x['primaryImage']['url']['primary']), + 'duration': parse_duration(video_data.get('duration')), + 'timestamp': unified_timestamp(video_data.get('datePublished')), + 'formats': formats, + 'subtitles': subtitles, } diff --git a/youtube_dl/extractor/ndr.py b/youtube_dl/extractor/ndr.py index aec2ea1..9c8bf05 100644 --- a/youtube_dl/extractor/ndr.py +++ b/youtube_dl/extractor/ndr.py @@ -9,6 +9,8 @@ from ..utils import ( int_or_none, parse_iso8601, qualities, + try_get, + urljoin, ) @@ -220,11 +222,17 @@ class NDREmbedBaseIE(InfoExtractor): upload_date = ppjson.get('config', {}).get('publicationDate') duration = int_or_none(config.get('duration')) - thumbnails = [{ - 'id': thumbnail.get('quality') or thumbnail_id, - 'url': thumbnail['src'], - 'preference': quality_key(thumbnail.get('quality')), - } for thumbnail_id, thumbnail in config.get('poster', {}).items() if thumbnail.get('src')] + thumbnails = [] + poster = try_get(config, lambda x: x['poster'], dict) or {} + for thumbnail_id, thumbnail in poster.items(): + thumbnail_url = urljoin(url, thumbnail.get('src')) + if not thumbnail_url: + continue + thumbnails.append({ + 'id': thumbnail.get('quality') or thumbnail_id, + 'url': thumbnail_url, + 'preference': quality_key(thumbnail.get('quality')), + }) return { 'id': video_id, diff --git a/youtube_dl/extractor/nexx.py b/youtube_dl/extractor/nexx.py index 82d526c..586c1b7 100644 --- a/youtube_dl/extractor/nexx.py +++ b/youtube_dl/extractor/nexx.py @@ -108,7 +108,7 @@ class NexxIE(InfoExtractor): @staticmethod def _extract_domain_id(webpage): mobj = re.search( - r'<script\b[^>]+\bsrc=["\'](?:https?:)?//require\.nexx(?:\.cloud|cdn\.com)/(?P<id>\d+)', + r'<script\b[^>]+\bsrc=["\'](?:https?:)?//(?:require|arc)\.nexx(?:\.cloud|cdn\.com)/(?:sdk/)?(?P<id>\d+)', webpage) return mobj.group('id') if mobj else None @@ -123,7 +123,7 @@ class NexxIE(InfoExtractor): domain_id = NexxIE._extract_domain_id(webpage) if domain_id: for video_id in re.findall( - r'(?is)onPLAYReady.+?_play\.init\s*\(.+?\s*,\s*["\']?(\d+)', + r'(?is)onPLAYReady.+?_play\.(?:init|(?:control\.)?addPlayer)\s*\(.+?\s*,\s*["\']?(\d+)', webpage): entries.append( 'https://api.nexx.cloud/v3/%s/videos/byid/%s' @@ -295,13 +295,23 @@ class NexxIE(InfoExtractor): video = None + def find_video(result): + if isinstance(result, dict): + return result + elif isinstance(result, list): + vid = int(video_id) + for v in result: + if try_get(v, lambda x: x['general']['ID'], int) == vid: + return v + return None + response = self._download_json( 'https://arc.nexx.cloud/api/video/%s.json' % video_id, video_id, fatal=False) if response and isinstance(response, dict): result = response.get('result') - if result and isinstance(result, dict): - video = result + if result: + video = find_video(result) # not all videos work via arc, e.g. nexx:741:1269984 if not video: @@ -348,7 +358,7 @@ class NexxIE(InfoExtractor): request_token = hashlib.md5( ''.join((op, domain_id, secret)).encode('utf-8')).hexdigest() - video = self._call_api( + result = self._call_api( domain_id, 'videos/%s/%s' % (op, video_id), video_id, data={ 'additionalfields': 'language,channel,actors,studio,licenseby,slug,subtitle,teaser,description', 'addInteractionOptions': '1', @@ -363,6 +373,7 @@ class NexxIE(InfoExtractor): 'X-Request-CID': cid, 'X-Request-Token': request_token, }) + video = find_video(result) general = video['general'] title = general['title'] @@ -399,8 +410,8 @@ class NexxIE(InfoExtractor): class NexxEmbedIE(InfoExtractor): - _VALID_URL = r'https?://embed\.nexx(?:\.cloud|cdn\.com)/\d+/(?P<id>[^/?#&]+)' - _TEST = { + _VALID_URL = r'https?://embed\.nexx(?:\.cloud|cdn\.com)/\d+/(?:video/)?(?P<id>[^/?#&]+)' + _TESTS = [{ 'url': 'http://embed.nexx.cloud/748/KC1614647Z27Y7T?autoplay=1', 'md5': '16746bfc28c42049492385c989b26c4a', 'info_dict': { @@ -409,7 +420,6 @@ class NexxEmbedIE(InfoExtractor): 'title': 'Nervenkitzel Achterbahn', 'alt_title': 'Karussellbauer in Deutschland', 'description': 'md5:ffe7b1cc59a01f585e0569949aef73cc', - 'release_year': 2005, 'creator': 'SPIEGEL TV', 'thumbnail': r're:^https?://.*\.jpg$', 'duration': 2761, @@ -420,7 +430,10 @@ class NexxEmbedIE(InfoExtractor): 'format': 'bestvideo', 'skip_download': True, }, - } + }, { + 'url': 'https://embed.nexx.cloud/11888/video/DSRTO7UVOX06S7', + 'only_matching': True, + }] @staticmethod def _extract_urls(webpage): diff --git a/youtube_dl/extractor/nintendo.py b/youtube_dl/extractor/nintendo.py index 4b4e66b..ff8f70b 100644 --- a/youtube_dl/extractor/nintendo.py +++ b/youtube_dl/extractor/nintendo.py @@ -5,13 +5,12 @@ import re from .common import InfoExtractor from .ooyala import OoyalaIE -from ..utils import unescapeHTML class NintendoIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?nintendo\.com/games/detail/(?P<id>[^/?#&]+)' + _VALID_URL = r'https?://(?:www\.)?nintendo\.com/(?:games/detail|nintendo-direct)/(?P<id>[^/?#&]+)' _TESTS = [{ - 'url': 'http://www.nintendo.com/games/detail/yEiAzhU2eQI1KZ7wOHhngFoAHc1FpHwj', + 'url': 'https://www.nintendo.com/games/detail/duck-hunt-wii-u/', 'info_dict': { 'id': 'MzMmticjp0VPzO3CCj4rmFOuohEuEWoW', 'ext': 'flv', @@ -28,7 +27,19 @@ class NintendoIE(InfoExtractor): 'id': 'tokyo-mirage-sessions-fe-wii-u', 'title': 'Tokyo Mirage Sessions ♯FE', }, - 'playlist_count': 3, + 'playlist_count': 4, + }, { + 'url': 'https://www.nintendo.com/nintendo-direct/09-04-2019/', + 'info_dict': { + 'id': 'J2bXdmaTE6fe3dWJTPcc7m23FNbc_A1V', + 'ext': 'mp4', + 'title': 'Switch_ROS_ND0904-H264.mov', + 'duration': 2324.758, + }, + 'params': { + 'skip_download': True, + }, + 'add_ie': ['Ooyala'], }] def _real_extract(self, url): @@ -39,8 +50,11 @@ class NintendoIE(InfoExtractor): entries = [ OoyalaIE._build_url_result(m.group('code')) for m in re.finditer( - r'class=(["\'])embed-video\1[^>]+data-video-code=(["\'])(?P<code>(?:(?!\2).)+)\2', - webpage)] + r'data-(?:video-id|directVideoId)=(["\'])(?P<code>(?:(?!\1).)+)\1', webpage)] + + title = self._html_search_regex( + r'(?s)<(?:span|div)[^>]+class="(?:title|wrapper)"[^>]*>.*?<h1>(.+?)</h1>', + webpage, 'title', fatal=False) return self.playlist_result( - entries, page_id, unescapeHTML(self._og_search_title(webpage, fatal=False))) + entries, page_id, title) diff --git a/youtube_dl/extractor/nonktube.py b/youtube_dl/extractor/nonktube.py index 63e58aa..ca1424e 100644 --- a/youtube_dl/extractor/nonktube.py +++ b/youtube_dl/extractor/nonktube.py @@ -25,9 +25,14 @@ class NonkTubeIE(NuevoBaseIE): def _real_extract(self, url): video_id = self._match_id(url) - info = self._extract_nuevo( - 'https://www.nonktube.com/media/nuevo/econfig.php?key=%s' - % video_id, video_id) + webpage = self._download_webpage(url, video_id) - info['age_limit'] = 18 + title = self._og_search_title(webpage) + info = self._parse_html5_media_entries(url, webpage, video_id)[0] + + info.update({ + 'id': video_id, + 'title': title, + 'age_limit': 18, + }) return info diff --git a/youtube_dl/extractor/nrk.py b/youtube_dl/extractor/nrk.py index 5f43e69..9411553 100644 --- a/youtube_dl/extractor/nrk.py +++ b/youtube_dl/extractor/nrk.py @@ -12,6 +12,7 @@ from ..utils import ( ExtractorError, int_or_none, JSON_LD_RE, + js_to_json, NO_DEFAULT, parse_age_limit, parse_duration, @@ -105,6 +106,7 @@ class NRKBaseIE(InfoExtractor): MESSAGES = { 'ProgramRightsAreNotReady': 'Du kan dessverre ikke se eller høre programmet', 'ProgramRightsHasExpired': 'Programmet har gÃ¥tt ut', + 'NoProgramRights': 'Ikke tilgjengelig', 'ProgramIsGeoBlocked': 'NRK har ikke rettigheter til Ã¥ vise dette programmet utenfor Norge', } message_type = data.get('messageType', '') @@ -255,6 +257,17 @@ class NRKTVIE(NRKBaseIE): ''' % _EPISODE_RE _API_HOSTS = ('psapi-ne.nrk.no', 'psapi-we.nrk.no') _TESTS = [{ + 'url': 'https://tv.nrk.no/program/MDDP12000117', + 'md5': '8270824df46ec629b66aeaa5796b36fb', + 'info_dict': { + 'id': 'MDDP12000117AA', + 'ext': 'mp4', + 'title': 'Alarm Trolltunga', + 'description': 'md5:46923a6e6510eefcce23d5ef2a58f2ce', + 'duration': 2223, + 'age_limit': 6, + }, + }, { 'url': 'https://tv.nrk.no/serie/20-spoersmaal-tv/MUHH48000314/23-05-2014', 'md5': '9a167e54d04671eb6317a37b7bc8a280', 'info_dict': { @@ -266,6 +279,7 @@ class NRKTVIE(NRKBaseIE): 'series': '20 spørsmÃ¥l', 'episode': '23.05.2014', }, + 'skip': 'NoProgramRights', }, { 'url': 'https://tv.nrk.no/program/mdfp15000514', 'info_dict': { @@ -370,7 +384,24 @@ class NRKTVIE(NRKBaseIE): class NRKTVEpisodeIE(InfoExtractor): _VALID_URL = r'https?://tv\.nrk\.no/serie/(?P<id>[^/]+/sesong/\d+/episode/\d+)' - _TEST = { + _TESTS = [{ + 'url': 'https://tv.nrk.no/serie/hellums-kro/sesong/1/episode/2', + 'info_dict': { + 'id': 'MUHH36005220BA', + 'ext': 'mp4', + 'title': 'Kro, krig og kjærlighet 2:6', + 'description': 'md5:b32a7dc0b1ed27c8064f58b97bda4350', + 'duration': 1563, + 'series': 'Hellums kro', + 'season_number': 1, + 'episode_number': 2, + 'episode': '2:6', + 'age_limit': 6, + }, + 'params': { + 'skip_download': True, + }, + }, { 'url': 'https://tv.nrk.no/serie/backstage/sesong/1/episode/8', 'info_dict': { 'id': 'MSUI14000816AA', @@ -386,7 +417,8 @@ class NRKTVEpisodeIE(InfoExtractor): 'params': { 'skip_download': True, }, - } + 'skip': 'ProgramRightsHasExpired', + }] def _real_extract(self, url): display_id = self._match_id(url) @@ -406,10 +438,10 @@ class NRKTVSerieBaseIE(InfoExtractor): def _extract_series(self, webpage, display_id, fatal=True): config = self._parse_json( self._search_regex( - (r'INITIAL_DATA_*\s*=\s*({.+?})\s*;', + (r'INITIAL_DATA(?:_V\d)?_*\s*=\s*({.+?})\s*;', r'({.+?})\s*,\s*"[^"]+"\s*\)\s*</script>'), webpage, 'config', default='{}' if not fatal else NO_DEFAULT), - display_id, fatal=False) + display_id, fatal=False, transform_source=js_to_json) if not config: return return try_get( @@ -479,6 +511,14 @@ class NRKTVSeriesIE(NRKTVSerieBaseIE): _VALID_URL = r'https?://(?:tv|radio)\.nrk(?:super)?\.no/serie/(?P<id>[^/]+)' _ITEM_RE = r'(?:data-season=["\']|id=["\']season-)(?P<id>\d+)' _TESTS = [{ + 'url': 'https://tv.nrk.no/serie/blank', + 'info_dict': { + 'id': 'blank', + 'title': 'Blank', + 'description': 'md5:7664b4e7e77dc6810cd3bca367c25b6e', + }, + 'playlist_mincount': 30, + }, { # new layout, seasons 'url': 'https://tv.nrk.no/serie/backstage', 'info_dict': { @@ -648,7 +688,7 @@ class NRKSkoleIE(InfoExtractor): _TESTS = [{ 'url': 'https://www.nrk.no/skole/?page=search&q=&mediaId=14099', - 'md5': '6bc936b01f9dd8ed45bc58b252b2d9b6', + 'md5': '18c12c3d071953c3bf8d54ef6b2587b7', 'info_dict': { 'id': '6021', 'ext': 'mp4', diff --git a/youtube_dl/extractor/nrl.py b/youtube_dl/extractor/nrl.py index 798b91e..22a2df8 100644 --- a/youtube_dl/extractor/nrl.py +++ b/youtube_dl/extractor/nrl.py @@ -23,8 +23,8 @@ class NRLTVIE(InfoExtractor): def _real_extract(self, url): display_id = self._match_id(url) webpage = self._download_webpage(url, display_id) - q_data = self._parse_json(self._search_regex( - r"(?s)q-data='({.+?})'", webpage, 'player data'), display_id) + q_data = self._parse_json(self._html_search_regex( + r'(?s)q-data="({.+?})"', webpage, 'player data'), display_id) ooyala_id = q_data['videoId'] return self.url_result( 'ooyala:' + ooyala_id, 'Ooyala', ooyala_id, q_data.get('title')) diff --git a/youtube_dl/extractor/ntvru.py b/youtube_dl/extractor/ntvru.py index 4f9cedb..c47d1df 100644 --- a/youtube_dl/extractor/ntvru.py +++ b/youtube_dl/extractor/ntvru.py @@ -3,9 +3,10 @@ from __future__ import unicode_literals from .common import InfoExtractor from ..utils import ( - clean_html, - xpath_text, int_or_none, + strip_or_none, + unescapeHTML, + xpath_text, ) @@ -47,10 +48,10 @@ class NTVRuIE(InfoExtractor): 'duration': 1496, }, }, { - 'url': 'http://www.ntv.ru/kino/Koma_film', - 'md5': 'f825770930937aa7e5aca0dc0d29319a', + 'url': 'https://www.ntv.ru/kino/Koma_film/m70281/o336036/video/', + 'md5': 'e9c7cde24d9d3eaed545911a04e6d4f4', 'info_dict': { - 'id': '1007609', + 'id': '1126480', 'ext': 'mp4', 'title': 'Остросюжетный фильм «Кома»', 'description': 'Остросюжетный фильм «Кома»', @@ -68,6 +69,10 @@ class NTVRuIE(InfoExtractor): 'thumbnail': r're:^http://.*\.jpg', 'duration': 2590, }, + }, { + # Schemeless file URL + 'url': 'https://www.ntv.ru/video/1797442', + 'only_matching': True, }] _VIDEO_ID_REGEXES = [ @@ -96,37 +101,31 @@ class NTVRuIE(InfoExtractor): 'http://www.ntv.ru/vi%s/' % video_id, video_id, 'Downloading video XML') - title = clean_html(xpath_text(player, './data/title', 'title', fatal=True)) - description = clean_html(xpath_text(player, './data/description', 'description')) + title = strip_or_none(unescapeHTML(xpath_text(player, './data/title', 'title', fatal=True))) video = player.find('./data/video') - video_id = xpath_text(video, './id', 'video id') - thumbnail = xpath_text(video, './splash', 'thumbnail') - duration = int_or_none(xpath_text(video, './totaltime', 'duration')) - view_count = int_or_none(xpath_text(video, './views', 'view count')) - - token = self._download_webpage( - 'http://stat.ntv.ru/services/access/token', - video_id, 'Downloading access token') formats = [] for format_id in ['', 'hi', 'webm']: - file_ = video.find('./%sfile' % format_id) - if file_ is None: + file_ = xpath_text(video, './%sfile' % format_id) + if not file_: continue - size = video.find('./%ssize' % format_id) + if file_.startswith('//'): + file_ = self._proto_relative_url(file_) + elif not file_.startswith('http'): + file_ = 'http://media.ntv.ru/vod/' + file_ formats.append({ - 'url': 'http://media2.ntv.ru/vod/%s&tok=%s' % (file_.text, token), - 'filesize': int_or_none(size.text if size is not None else None), + 'url': file_, + 'filesize': int_or_none(xpath_text(video, './%ssize' % format_id)), }) self._sort_formats(formats) return { - 'id': video_id, + 'id': xpath_text(video, './id'), 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'duration': duration, - 'view_count': view_count, + 'description': strip_or_none(unescapeHTML(xpath_text(player, './data/description'))), + 'thumbnail': xpath_text(video, './splash'), + 'duration': int_or_none(xpath_text(video, './totaltime')), + 'view_count': int_or_none(xpath_text(video, './views')), 'formats': formats, } diff --git a/youtube_dl/extractor/odnoklassniki.py b/youtube_dl/extractor/odnoklassniki.py index 114b93c..7ed9fac 100644 --- a/youtube_dl/extractor/odnoklassniki.py +++ b/youtube_dl/extractor/odnoklassniki.py @@ -1,6 +1,8 @@ # coding: utf-8 from __future__ import unicode_literals +import re + from .common import InfoExtractor from ..compat import ( compat_etree_fromstring, @@ -121,6 +123,13 @@ class OdnoklassnikiIE(InfoExtractor): 'only_matching': True, }] + @staticmethod + def _extract_url(webpage): + mobj = re.search( + r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//(?:odnoklassniki|ok)\.ru/videoembed/.+?)\1', webpage) + if mobj: + return mobj.group('url') + def _real_extract(self, url): start_time = int_or_none(compat_parse_qs( compat_urllib_parse_urlparse(url).query).get('fromTime', [None])[0]) diff --git a/youtube_dl/extractor/onet.py b/youtube_dl/extractor/onet.py index 58da1bc..e55b2ac 100644 --- a/youtube_dl/extractor/onet.py +++ b/youtube_dl/extractor/onet.py @@ -20,6 +20,8 @@ from ..utils import ( class OnetBaseIE(InfoExtractor): + _URL_BASE_RE = r'https?://(?:(?:www\.)?onet\.tv|onet100\.vod\.pl)/[a-z]/' + def _search_mvp_id(self, webpage): return self._search_regex( r'id=(["\'])mvp:(?P<id>.+?)\1', webpage, 'mvp id', group='id') @@ -45,7 +47,7 @@ class OnetBaseIE(InfoExtractor): video = response['result'].get('0') formats = [] - for _, formats_dict in video['formats'].items(): + for format_type, formats_dict in video['formats'].items(): if not isinstance(formats_dict, dict): continue for format_id, format_list in formats_dict.items(): @@ -56,21 +58,31 @@ class OnetBaseIE(InfoExtractor): if not video_url: continue ext = determine_ext(video_url) - if format_id == 'ism': + if format_id.startswith('ism'): formats.extend(self._extract_ism_formats( video_url, video_id, 'mss', fatal=False)) elif ext == 'mpd': formats.extend(self._extract_mpd_formats( video_url, video_id, mpd_id='dash', fatal=False)) + elif format_id.startswith('hls'): + formats.extend(self._extract_m3u8_formats( + video_url, video_id, 'mp4', 'm3u8_native', + m3u8_id='hls', fatal=False)) else: - formats.append({ + http_f = { 'url': video_url, 'format_id': format_id, - 'height': int_or_none(f.get('vertical_resolution')), - 'width': int_or_none(f.get('horizontal_resolution')), 'abr': float_or_none(f.get('audio_bitrate')), - 'vbr': float_or_none(f.get('video_bitrate')), - }) + } + if format_type == 'audio': + http_f['vcodec'] = 'none' + else: + http_f.update({ + 'height': int_or_none(f.get('vertical_resolution')), + 'width': int_or_none(f.get('horizontal_resolution')), + 'vbr': float_or_none(f.get('video_bitrate')), + }) + formats.append(http_f) self._sort_formats(formats) meta = video.get('meta', {}) @@ -105,12 +117,12 @@ class OnetMVPIE(OnetBaseIE): class OnetIE(OnetBaseIE): - _VALID_URL = r'https?://(?:www\.)?onet\.tv/[a-z]/[a-z]+/(?P<display_id>[0-9a-z-]+)/(?P<id>[0-9a-z]+)' + _VALID_URL = OnetBaseIE._URL_BASE_RE + r'[a-z]+/(?P<display_id>[0-9a-z-]+)/(?P<id>[0-9a-z]+)' IE_NAME = 'onet.tv' - _TEST = { + _TESTS = [{ 'url': 'http://onet.tv/k/openerfestival/open-er-festival-2016-najdziwniejsze-wymagania-gwiazd/qbpyqc', - 'md5': 'e3ffbf47590032ac3f27249204173d50', + 'md5': '436102770fb095c75b8bb0392d3da9ff', 'info_dict': { 'id': 'qbpyqc', 'display_id': 'open-er-festival-2016-najdziwniejsze-wymagania-gwiazd', @@ -120,7 +132,10 @@ class OnetIE(OnetBaseIE): 'upload_date': '20160705', 'timestamp': 1467721580, }, - } + }, { + 'url': 'https://onet100.vod.pl/k/openerfestival/open-er-festival-2016-najdziwniejsze-wymagania-gwiazd/qbpyqc', + 'only_matching': True, + }] def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) @@ -140,18 +155,21 @@ class OnetIE(OnetBaseIE): class OnetChannelIE(OnetBaseIE): - _VALID_URL = r'https?://(?:www\.)?onet\.tv/[a-z]/(?P<id>[a-z]+)(?:[?#]|$)' + _VALID_URL = OnetBaseIE._URL_BASE_RE + r'(?P<id>[a-z]+)(?:[?#]|$)' IE_NAME = 'onet.tv:channel' - _TEST = { + _TESTS = [{ 'url': 'http://onet.tv/k/openerfestival', 'info_dict': { 'id': 'openerfestival', - 'title': 'Open\'er Festival Live', - 'description': 'Dziękujemy, że oglądaliście transmisje. Zobaczcie nasze relacje i wywiady z artystami.', + 'title': "Open'er Festival", + 'description': "Tak było na Open'er Festival 2016! Oglądaj nasze reportaże i wywiady z artystami.", }, - 'playlist_mincount': 46, - } + 'playlist_mincount': 35, + }, { + 'url': 'https://onet100.vod.pl/k/openerfestival', + 'only_matching': True, + }] def _real_extract(self, url): channel_id = self._match_id(url) @@ -173,7 +191,7 @@ class OnetChannelIE(OnetBaseIE): 'Downloading channel %s - add --no-playlist to just download video %s' % ( channel_id, video_name)) matches = re.findall( - r'<a[^>]+href=[\'"](https?://(?:www\.)?onet\.tv/[a-z]/[a-z]+/[0-9a-z-]+/[0-9a-z]+)', + r'<a[^>]+href=[\'"](%s[a-z]+/[0-9a-z-]+/[0-9a-z]+)' % self._URL_BASE_RE, webpage) entries = [ self.url_result(video_link, OnetIE.ie_key()) diff --git a/youtube_dl/extractor/onionstudios.py b/youtube_dl/extractor/onionstudios.py index c6e3d56..cf5c39e 100644 --- a/youtube_dl/extractor/onionstudios.py +++ b/youtube_dl/extractor/onionstudios.py @@ -4,12 +4,8 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from ..utils import ( - determine_ext, - int_or_none, - float_or_none, - mimetype2ext, -) +from ..compat import compat_str +from ..utils import js_to_json class OnionStudiosIE(InfoExtractor): @@ -17,14 +13,16 @@ class OnionStudiosIE(InfoExtractor): _TESTS = [{ 'url': 'http://www.onionstudios.com/videos/hannibal-charges-forward-stops-for-a-cocktail-2937', - 'md5': '719d1f8c32094b8c33902c17bcae5e34', + 'md5': '5a118d466d62b5cd03647cf2c593977f', 'info_dict': { - 'id': '2937', + 'id': '3459881', 'ext': 'mp4', 'title': 'Hannibal charges forward, stops for a cocktail', + 'description': 'md5:545299bda6abf87e5ec666548c6a9448', 'thumbnail': r're:^https?://.*\.jpg$', - 'uploader': 'The A.V. Club', - 'uploader_id': 'the-av-club', + 'uploader': 'a.v. club', + 'upload_date': '20150619', + 'timestamp': 1434728546, }, }, { 'url': 'http://www.onionstudios.com/embed?id=2855&autoplay=true', @@ -44,38 +42,12 @@ class OnionStudiosIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - video_data = self._download_json( - 'http://www.onionstudios.com/video/%s.json' % video_id, video_id) - - title = video_data['title'] - - formats = [] - for source in video_data.get('sources', []): - source_url = source.get('url') - if not source_url: - continue - ext = mimetype2ext(source.get('content_type')) or determine_ext(source_url) - if ext == 'm3u8': - formats.extend(self._extract_m3u8_formats( - source_url, video_id, 'mp4', 'm3u8_native', m3u8_id='hls', fatal=False)) - else: - tbr = int_or_none(source.get('bitrate')) - formats.append({ - 'format_id': ext + ('-%d' % tbr if tbr else ''), - 'url': source_url, - 'width': int_or_none(source.get('width')), - 'tbr': tbr, - 'ext': ext, - }) - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': title, - 'thumbnail': video_data.get('poster_url'), - 'uploader': video_data.get('channel_name'), - 'uploader_id': video_data.get('channel_slug'), - 'duration': float_or_none(video_data.get('duration', 1000)), - 'tags': video_data.get('tags'), - 'formats': formats, - } + webpage = self._download_webpage( + 'http://onionstudios.com/embed/dc94dc2899fe644c0e7241fa04c1b732.js', + video_id) + mcp_id = compat_str(self._parse_json(self._search_regex( + r'window\.mcpMapping\s*=\s*({.+?});', webpage, + 'MCP Mapping'), video_id, js_to_json)[video_id]['mcp_id']) + return self.url_result( + 'http://kinja.com/ajax/inset/iframe?id=mcp-' + mcp_id, + 'KinjaEmbed', mcp_id) diff --git a/youtube_dl/extractor/ooyala.py b/youtube_dl/extractor/ooyala.py index 995b24d..eb957b8 100644 --- a/youtube_dl/extractor/ooyala.py +++ b/youtube_dl/extractor/ooyala.py @@ -1,12 +1,12 @@ from __future__ import unicode_literals +import base64 import re from .common import InfoExtractor from ..compat import ( compat_b64decode, compat_str, - compat_urllib_parse_urlencode, ) from ..utils import ( determine_ext, @@ -21,9 +21,9 @@ from ..utils import ( class OoyalaBaseIE(InfoExtractor): _PLAYER_BASE = 'http://player.ooyala.com/' _CONTENT_TREE_BASE = _PLAYER_BASE + 'player_api/v1/content_tree/' - _AUTHORIZATION_URL_TEMPLATE = _PLAYER_BASE + 'sas/player_api/v2/authorization/embed_code/%s/%s?' + _AUTHORIZATION_URL_TEMPLATE = _PLAYER_BASE + 'sas/player_api/v2/authorization/embed_code/%s/%s' - def _extract(self, content_tree_url, video_id, domain='example.org', supportedformats=None, embed_token=None): + def _extract(self, content_tree_url, video_id, domain=None, supportedformats=None, embed_token=None): content_tree = self._download_json(content_tree_url, video_id)['content_tree'] metadata = content_tree[list(content_tree)[0]] embed_code = metadata['embed_code'] @@ -31,59 +31,62 @@ class OoyalaBaseIE(InfoExtractor): title = metadata['title'] auth_data = self._download_json( - self._AUTHORIZATION_URL_TEMPLATE % (pcode, embed_code) - + compat_urllib_parse_urlencode({ - 'domain': domain, + self._AUTHORIZATION_URL_TEMPLATE % (pcode, embed_code), + video_id, headers=self.geo_verification_headers(), query={ + 'domain': domain or 'player.ooyala.com', 'supportedFormats': supportedformats or 'mp4,rtmp,m3u8,hds,dash,smooth', 'embedToken': embed_token, - }), video_id, headers=self.geo_verification_headers()) - - cur_auth_data = auth_data['authorization_data'][embed_code] + })['authorization_data'][embed_code] urls = [] formats = [] - if cur_auth_data['authorized']: - for stream in cur_auth_data['streams']: - url_data = try_get(stream, lambda x: x['url']['data'], compat_str) - if not url_data: - continue - s_url = compat_b64decode(url_data).decode('utf-8') - if not s_url or s_url in urls: - continue - urls.append(s_url) - ext = determine_ext(s_url, None) - delivery_type = stream.get('delivery_type') - if delivery_type == 'hls' or ext == 'm3u8': - formats.extend(self._extract_m3u8_formats( - re.sub(r'/ip(?:ad|hone)/', '/all/', s_url), embed_code, 'mp4', 'm3u8_native', - m3u8_id='hls', fatal=False)) - elif delivery_type == 'hds' or ext == 'f4m': - formats.extend(self._extract_f4m_formats( - s_url + '?hdcore=3.7.0', embed_code, f4m_id='hds', fatal=False)) - elif delivery_type == 'dash' or ext == 'mpd': - formats.extend(self._extract_mpd_formats( - s_url, embed_code, mpd_id='dash', fatal=False)) - elif delivery_type == 'smooth': - self._extract_ism_formats( - s_url, embed_code, ism_id='mss', fatal=False) - elif ext == 'smil': - formats.extend(self._extract_smil_formats( - s_url, embed_code, fatal=False)) - else: - formats.append({ - 'url': s_url, - 'ext': ext or delivery_type, - 'vcodec': stream.get('video_codec'), - 'format_id': delivery_type, - 'width': int_or_none(stream.get('width')), - 'height': int_or_none(stream.get('height')), - 'abr': int_or_none(stream.get('audio_bitrate')), - 'vbr': int_or_none(stream.get('video_bitrate')), - 'fps': float_or_none(stream.get('framerate')), - }) - else: + streams = auth_data.get('streams') or [{ + 'delivery_type': 'hls', + 'url': { + 'data': base64.b64encode(('http://player.ooyala.com/hls/player/all/%s.m3u8' % embed_code).encode()).decode(), + } + }] + for stream in streams: + url_data = try_get(stream, lambda x: x['url']['data'], compat_str) + if not url_data: + continue + s_url = compat_b64decode(url_data).decode('utf-8') + if not s_url or s_url in urls: + continue + urls.append(s_url) + ext = determine_ext(s_url, None) + delivery_type = stream.get('delivery_type') + if delivery_type == 'hls' or ext == 'm3u8': + formats.extend(self._extract_m3u8_formats( + re.sub(r'/ip(?:ad|hone)/', '/all/', s_url), embed_code, 'mp4', 'm3u8_native', + m3u8_id='hls', fatal=False)) + elif delivery_type == 'hds' or ext == 'f4m': + formats.extend(self._extract_f4m_formats( + s_url + '?hdcore=3.7.0', embed_code, f4m_id='hds', fatal=False)) + elif delivery_type == 'dash' or ext == 'mpd': + formats.extend(self._extract_mpd_formats( + s_url, embed_code, mpd_id='dash', fatal=False)) + elif delivery_type == 'smooth': + self._extract_ism_formats( + s_url, embed_code, ism_id='mss', fatal=False) + elif ext == 'smil': + formats.extend(self._extract_smil_formats( + s_url, embed_code, fatal=False)) + else: + formats.append({ + 'url': s_url, + 'ext': ext or delivery_type, + 'vcodec': stream.get('video_codec'), + 'format_id': delivery_type, + 'width': int_or_none(stream.get('width')), + 'height': int_or_none(stream.get('height')), + 'abr': int_or_none(stream.get('audio_bitrate')), + 'vbr': int_or_none(stream.get('video_bitrate')), + 'fps': float_or_none(stream.get('framerate')), + }) + if not formats and not auth_data.get('authorized'): raise ExtractorError('%s said: %s' % ( - self.IE_NAME, cur_auth_data['message']), expected=True) + self.IE_NAME, auth_data['message']), expected=True) self._sort_formats(formats) subtitles = {} diff --git a/youtube_dl/extractor/openload.py b/youtube_dl/extractor/openload.py index 1fe5817..0c20d01 100644 --- a/youtube_dl/extractor/openload.py +++ b/youtube_dl/extractor/openload.py @@ -3,21 +3,17 @@ from __future__ import unicode_literals import json import os -import re import subprocess import tempfile -from .common import InfoExtractor from ..compat import ( compat_urlparse, compat_kwargs, ) from ..utils import ( check_executable, - determine_ext, encodeArgument, ExtractorError, - get_element_by_id, get_exe_version, is_outdated_version, std_headers, @@ -240,259 +236,3 @@ class PhantomJSwrapper(object): self._load_cookies() return (html, encodeArgument(out)) - - -class OpenloadIE(InfoExtractor): - _DOMAINS = r''' - (?: - openload\.(?:co|io|link|pw)| - oload\.(?:tv|best|biz|stream|site|xyz|win|download|cloud|cc|icu|fun|club|info|online|press|pw|life|live|space|services|website|vip)| - oladblock\.(?:services|xyz|me)|openloed\.co - ) - ''' - _VALID_URL = r'''(?x) - https?:// - (?P<host> - (?:www\.)? - %s - )/ - (?:f|embed)/ - (?P<id>[a-zA-Z0-9-_]+) - ''' % _DOMAINS - _EMBED_WORD = 'embed' - _STREAM_WORD = 'f' - _REDIR_WORD = 'stream' - _URL_IDS = ('streamurl', 'streamuri', 'streamurj') - _TESTS = [{ - 'url': 'https://openload.co/f/kUEfGclsU9o', - 'md5': 'bf1c059b004ebc7a256f89408e65c36e', - 'info_dict': { - 'id': 'kUEfGclsU9o', - 'ext': 'mp4', - 'title': 'skyrim_no-audio_1080.mp4', - 'thumbnail': r're:^https?://.*\.jpg$', - }, - }, { - 'url': 'https://openload.co/embed/rjC09fkPLYs', - 'info_dict': { - 'id': 'rjC09fkPLYs', - 'ext': 'mp4', - 'title': 'movie.mp4', - 'thumbnail': r're:^https?://.*\.jpg$', - 'subtitles': { - 'en': [{ - 'ext': 'vtt', - }], - }, - }, - 'params': { - 'skip_download': True, # test subtitles only - }, - }, { - 'url': 'https://openload.co/embed/kUEfGclsU9o/skyrim_no-audio_1080.mp4', - 'only_matching': True, - }, { - 'url': 'https://openload.io/f/ZAn6oz-VZGE/', - 'only_matching': True, - }, { - 'url': 'https://openload.co/f/_-ztPaZtMhM/', - 'only_matching': True, - }, { - # unavailable via https://openload.co/f/Sxz5sADo82g/, different layout - # for title and ext - 'url': 'https://openload.co/embed/Sxz5sADo82g/', - 'only_matching': True, - }, { - # unavailable via https://openload.co/embed/e-Ixz9ZR5L0/ but available - # via https://openload.co/f/e-Ixz9ZR5L0/ - 'url': 'https://openload.co/f/e-Ixz9ZR5L0/', - 'only_matching': True, - }, { - 'url': 'https://oload.tv/embed/KnG-kKZdcfY/', - 'only_matching': True, - }, { - 'url': 'http://www.openload.link/f/KnG-kKZdcfY', - 'only_matching': True, - }, { - 'url': 'https://oload.stream/f/KnG-kKZdcfY', - 'only_matching': True, - }, { - 'url': 'https://oload.xyz/f/WwRBpzW8Wtk', - 'only_matching': True, - }, { - 'url': 'https://oload.win/f/kUEfGclsU9o', - 'only_matching': True, - }, { - 'url': 'https://oload.download/f/kUEfGclsU9o', - 'only_matching': True, - }, { - 'url': 'https://oload.cloud/f/4ZDnBXRWiB8', - 'only_matching': True, - }, { - # Its title has not got its extension but url has it - 'url': 'https://oload.download/f/N4Otkw39VCw/Tomb.Raider.2018.HDRip.XviD.AC3-EVO.avi.mp4', - 'only_matching': True, - }, { - 'url': 'https://oload.cc/embed/5NEAbI2BDSk', - 'only_matching': True, - }, { - 'url': 'https://oload.icu/f/-_i4y_F_Hs8', - 'only_matching': True, - }, { - 'url': 'https://oload.fun/f/gb6G1H4sHXY', - 'only_matching': True, - }, { - 'url': 'https://oload.club/f/Nr1L-aZ2dbQ', - 'only_matching': True, - }, { - 'url': 'https://oload.info/f/5NEAbI2BDSk', - 'only_matching': True, - }, { - 'url': 'https://openload.pw/f/WyKgK8s94N0', - 'only_matching': True, - }, { - 'url': 'https://oload.pw/f/WyKgK8s94N0', - 'only_matching': True, - }, { - 'url': 'https://oload.live/f/-Z58UZ-GR4M', - 'only_matching': True, - }, { - 'url': 'https://oload.space/f/IY4eZSst3u8/', - 'only_matching': True, - }, { - 'url': 'https://oload.services/embed/bs1NWj1dCag/', - 'only_matching': True, - }, { - 'url': 'https://oload.online/f/W8o2UfN1vNY/', - 'only_matching': True, - }, { - 'url': 'https://oload.press/embed/drTBl1aOTvk/', - 'only_matching': True, - }, { - 'url': 'https://oload.website/embed/drTBl1aOTvk/', - 'only_matching': True, - }, { - 'url': 'https://oload.life/embed/oOzZjNPw9Dc/', - 'only_matching': True, - }, { - 'url': 'https://oload.biz/f/bEk3Gp8ARr4/', - 'only_matching': True, - }, { - 'url': 'https://oload.best/embed/kkz9JgVZeWc/', - 'only_matching': True, - }, { - 'url': 'https://oladblock.services/f/b8NWEgkqNLI/', - 'only_matching': True, - }, { - 'url': 'https://oladblock.xyz/f/b8NWEgkqNLI/', - 'only_matching': True, - }, { - 'url': 'https://oladblock.me/f/b8NWEgkqNLI/', - 'only_matching': True, - }, { - 'url': 'https://openloed.co/f/b8NWEgkqNLI/', - 'only_matching': True, - }, { - 'url': 'https://oload.vip/f/kUEfGclsU9o', - 'only_matching': True, - }] - - @classmethod - def _extract_urls(cls, webpage): - return re.findall( - r'(?x)<iframe[^>]+src=["\']((?:https?://)?%s/%s/[a-zA-Z0-9-_]+)' - % (cls._DOMAINS, cls._EMBED_WORD), webpage) - - def _extract_decrypted_page(self, page_url, webpage, video_id): - phantom = PhantomJSwrapper(self, required_version='2.0') - webpage, _ = phantom.get(page_url, html=webpage, video_id=video_id) - return webpage - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - host = mobj.group('host') - video_id = mobj.group('id') - - url_pattern = 'https://%s/%%s/%s/' % (host, video_id) - - for path in (self._EMBED_WORD, self._STREAM_WORD): - page_url = url_pattern % path - last = path == self._STREAM_WORD - webpage = self._download_webpage( - page_url, video_id, 'Downloading %s webpage' % path, - fatal=last) - if not webpage: - continue - if 'File not found' in webpage or 'deleted by the owner' in webpage: - if not last: - continue - raise ExtractorError('File not found', expected=True, video_id=video_id) - break - - webpage = self._extract_decrypted_page(page_url, webpage, video_id) - for element_id in self._URL_IDS: - decoded_id = get_element_by_id(element_id, webpage) - if decoded_id: - break - if not decoded_id: - decoded_id = self._search_regex( - (r'>\s*([\w-]+~\d{10,}~\d+\.\d+\.0\.0~[\w-]+)\s*<', - r'>\s*([\w~-]+~\d+\.\d+\.\d+\.\d+~[\w~-]+)', - r'>\s*([\w-]+~\d{10,}~(?:[a-f\d]+:){2}:~[\w-]+)\s*<', - r'>\s*([\w~-]+~[a-f0-9:]+~[\w~-]+)\s*<', - r'>\s*([\w~-]+~[a-f0-9:]+~[\w~-]+)'), webpage, - 'stream URL') - video_url = 'https://%s/%s/%s?mime=true' % (host, self._REDIR_WORD, decoded_id) - - title = self._og_search_title(webpage, default=None) or self._search_regex( - r'<span[^>]+class=["\']title["\'][^>]*>([^<]+)', webpage, - 'title', default=None) or self._html_search_meta( - 'description', webpage, 'title', fatal=True) - - entries = self._parse_html5_media_entries(page_url, webpage, video_id) - entry = entries[0] if entries else {} - subtitles = entry.get('subtitles') - - return { - 'id': video_id, - 'title': title, - 'thumbnail': entry.get('thumbnail') or self._og_search_thumbnail(webpage, default=None), - 'url': video_url, - 'ext': determine_ext(title, None) or determine_ext(url, 'mp4'), - 'subtitles': subtitles, - } - - -class VerystreamIE(OpenloadIE): - IE_NAME = 'verystream' - - _DOMAINS = r'(?:verystream\.com|woof\.tube)' - _VALID_URL = r'''(?x) - https?:// - (?P<host> - (?:www\.)? - %s - )/ - (?:stream|e)/ - (?P<id>[a-zA-Z0-9-_]+) - ''' % _DOMAINS - _EMBED_WORD = 'e' - _STREAM_WORD = 'stream' - _REDIR_WORD = 'gettoken' - _URL_IDS = ('videolink', ) - _TESTS = [{ - 'url': 'https://verystream.com/stream/c1GWQ9ngBBx/', - 'md5': 'd3e8c5628ccb9970b65fd65269886795', - 'info_dict': { - 'id': 'c1GWQ9ngBBx', - 'ext': 'mp4', - 'title': 'Big Buck Bunny.mp4', - 'thumbnail': r're:^https?://.*\.jpg$', - }, - }, { - 'url': 'https://verystream.com/e/c1GWQ9ngBBx/', - 'only_matching': True, - }] - - def _extract_decrypted_page(self, page_url, webpage, video_id): - return webpage # for Verystream, the webpage is already decrypted diff --git a/youtube_dl/extractor/orf.py b/youtube_dl/extractor/orf.py index 499be00..d54b8ac 100644 --- a/youtube_dl/extractor/orf.py +++ b/youtube_dl/extractor/orf.py @@ -6,12 +6,14 @@ import re from .common import InfoExtractor from ..compat import compat_str from ..utils import ( + clean_html, determine_ext, float_or_none, HEADRequest, int_or_none, orderedSet, remove_end, + str_or_none, strip_jsonp, unescapeHTML, unified_strdate, @@ -86,12 +88,16 @@ class ORFTVthekIE(InfoExtractor): if value: format_id_list.append(value) format_id = '-'.join(format_id_list) - if determine_ext(fd['src']) == 'm3u8': - formats.extend(self._extract_m3u8_formats( - fd['src'], video_id, 'mp4', m3u8_id=format_id)) - elif determine_ext(fd['src']) == 'f4m': + ext = determine_ext(src) + if ext == 'm3u8': + m3u8_formats = self._extract_m3u8_formats( + src, video_id, 'mp4', m3u8_id=format_id, fatal=False) + if any('/geoprotection' in f['url'] for f in m3u8_formats): + self.raise_geo_restricted() + formats.extend(m3u8_formats) + elif ext == 'f4m': formats.extend(self._extract_f4m_formats( - fd['src'], video_id, f4m_id=format_id)) + src, video_id, f4m_id=format_id, fatal=False)) else: formats.append({ 'format_id': format_id, @@ -160,44 +166,48 @@ class ORFRadioIE(InfoExtractor): show_date = mobj.group('date') show_id = mobj.group('show') - if station == 'fm4': - show_id = '4%s' % show_id - data = self._download_json( - 'http://audioapi.orf.at/%s/api/json/current/broadcast/%s/%s' % (station, show_id, show_date), - show_id - ) - - def extract_entry_dict(info, title, subtitle): - return { - 'id': info['loopStreamId'].replace('.mp3', ''), - 'url': 'http://loopstream01.apa.at/?channel=%s&id=%s' % (station, info['loopStreamId']), + 'http://audioapi.orf.at/%s/api/json/current/broadcast/%s/%s' + % (station, show_id, show_date), show_id) + + entries = [] + for info in data['streams']: + loop_stream_id = str_or_none(info.get('loopStreamId')) + if not loop_stream_id: + continue + title = str_or_none(data.get('title')) + if not title: + continue + start = int_or_none(info.get('start'), scale=1000) + end = int_or_none(info.get('end'), scale=1000) + duration = end - start if end and start else None + entries.append({ + 'id': loop_stream_id.replace('.mp3', ''), + 'url': 'http://loopstream01.apa.at/?channel=%s&id=%s' % (station, loop_stream_id), 'title': title, - 'description': subtitle, - 'duration': (info['end'] - info['start']) / 1000, - 'timestamp': info['start'] / 1000, + 'description': clean_html(data.get('subtitle')), + 'duration': duration, + 'timestamp': start, 'ext': 'mp3', - 'series': data.get('programTitle') - } - - entries = [extract_entry_dict(t, data['title'], data['subtitle']) for t in data['streams']] + 'series': data.get('programTitle'), + }) return { '_type': 'playlist', 'id': show_id, - 'title': data['title'], - 'description': data['subtitle'], - 'entries': entries + 'title': data.get('title'), + 'description': clean_html(data.get('subtitle')), + 'entries': entries, } class ORFFM4IE(ORFRadioIE): IE_NAME = 'orf:fm4' IE_DESC = 'radio FM4' - _VALID_URL = r'https?://(?P<station>fm4)\.orf\.at/player/(?P<date>[0-9]+)/(?P<show>\w+)' + _VALID_URL = r'https?://(?P<station>fm4)\.orf\.at/player/(?P<date>[0-9]+)/(?P<show>4\w+)' _TEST = { - 'url': 'http://fm4.orf.at/player/20170107/CC', + 'url': 'http://fm4.orf.at/player/20170107/4CC', 'md5': '2b0be47375432a7ef104453432a19212', 'info_dict': { 'id': '2017-01-07_2100_tl_54_7DaysSat18_31295', @@ -208,7 +218,8 @@ class ORFFM4IE(ORFRadioIE): 'timestamp': 1483819257, 'upload_date': '20170107', }, - 'skip': 'Shows from ORF radios are only available for 7 days.' + 'skip': 'Shows from ORF radios are only available for 7 days.', + 'only_matching': True, } diff --git a/youtube_dl/extractor/pandatv.py b/youtube_dl/extractor/pandatv.py deleted file mode 100644 index 4219802..0000000 --- a/youtube_dl/extractor/pandatv.py +++ /dev/null @@ -1,99 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..utils import ( - ExtractorError, - qualities, -) - - -class PandaTVIE(InfoExtractor): - IE_DESC = '熊猫TV' - _VALID_URL = r'https?://(?:www\.)?panda\.tv/(?P<id>[0-9]+)' - _TESTS = [{ - 'url': 'http://www.panda.tv/66666', - 'info_dict': { - 'id': '66666', - 'title': 're:.+', - 'uploader': '刘杀鸡', - 'ext': 'flv', - 'is_live': True, - }, - 'params': { - 'skip_download': True, - }, - 'skip': 'Live stream is offline', - }, { - 'url': 'https://www.panda.tv/66666', - 'only_matching': True, - }] - - def _real_extract(self, url): - video_id = self._match_id(url) - - config = self._download_json( - 'https://www.panda.tv/api_room_v2?roomid=%s' % video_id, video_id) - - error_code = config.get('errno', 0) - if error_code != 0: - raise ExtractorError( - '%s returned error %s: %s' - % (self.IE_NAME, error_code, config['errmsg']), - expected=True) - - data = config['data'] - video_info = data['videoinfo'] - - # 2 = live, 3 = offline - if video_info.get('status') != '2': - raise ExtractorError( - 'Live stream is offline', expected=True) - - title = data['roominfo']['name'] - uploader = data.get('hostinfo', {}).get('name') - room_key = video_info['room_key'] - stream_addr = video_info.get( - 'stream_addr', {'OD': '1', 'HD': '1', 'SD': '1'}) - - # Reverse engineered from web player swf - # (http://s6.pdim.gs/static/07153e425f581151.swf at the moment of - # writing). - plflag0, plflag1 = video_info['plflag'].split('_') - plflag0 = int(plflag0) - 1 - if plflag1 == '21': - plflag0 = 10 - plflag1 = '4' - live_panda = 'live_panda' if plflag0 < 1 else '' - - plflag_auth = self._parse_json(video_info['plflag_list'], video_id) - sign = plflag_auth['auth']['sign'] - ts = plflag_auth['auth']['time'] - rid = plflag_auth['auth']['rid'] - - quality_key = qualities(['OD', 'HD', 'SD']) - suffix = ['_small', '_mid', ''] - formats = [] - for k, v in stream_addr.items(): - if v != '1': - continue - quality = quality_key(k) - if quality <= 0: - continue - for pref, (ext, pl) in enumerate((('m3u8', '-hls'), ('flv', ''))): - formats.append({ - 'url': 'https://pl%s%s.live.panda.tv/live_panda/%s%s%s.%s?sign=%s&ts=%s&rid=%s' - % (pl, plflag1, room_key, live_panda, suffix[quality], ext, sign, ts, rid), - 'format_id': '%s-%s' % (k, ext), - 'quality': quality, - 'source_preference': pref, - }) - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': self._live_title(title), - 'uploader': uploader, - 'formats': formats, - 'is_live': True, - } diff --git a/youtube_dl/extractor/patreon.py b/youtube_dl/extractor/patreon.py index 426dd81..761a4b1 100644 --- a/youtube_dl/extractor/patreon.py +++ b/youtube_dl/extractor/patreon.py @@ -6,7 +6,11 @@ from ..utils import ( clean_html, determine_ext, int_or_none, + KNOWN_EXTENSIONS, + mimetype2ext, parse_iso8601, + str_or_none, + try_get, ) @@ -24,6 +28,7 @@ class PatreonIE(InfoExtractor): 'thumbnail': 're:^https?://.*$', 'timestamp': 1406473987, 'upload_date': '20140727', + 'uploader_id': '87145', }, }, { 'url': 'http://www.patreon.com/creation?hid=754133', @@ -90,7 +95,13 @@ class PatreonIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) post = self._download_json( - 'https://www.patreon.com/api/posts/' + video_id, video_id) + 'https://www.patreon.com/api/posts/' + video_id, video_id, query={ + 'fields[media]': 'download_url,mimetype,size_bytes', + 'fields[post]': 'comment_count,content,embed,image,like_count,post_file,published_at,title', + 'fields[user]': 'full_name,url', + 'json-api-use-default-includes': 'false', + 'include': 'media,user', + }) attributes = post['data']['attributes'] title = attributes['title'].strip() image = attributes.get('image') or {} @@ -104,33 +115,42 @@ class PatreonIE(InfoExtractor): 'comment_count': int_or_none(attributes.get('comment_count')), } - def add_file(file_data): - file_url = file_data.get('url') - if file_url: - info.update({ - 'url': file_url, - 'ext': determine_ext(file_data.get('name'), 'mp3'), - }) - for i in post.get('included', []): i_type = i.get('type') - if i_type == 'attachment': - add_file(i.get('attributes') or {}) + if i_type == 'media': + media_attributes = i.get('attributes') or {} + download_url = media_attributes.get('download_url') + ext = mimetype2ext(media_attributes.get('mimetype')) + if download_url and ext in KNOWN_EXTENSIONS: + info.update({ + 'ext': ext, + 'filesize': int_or_none(media_attributes.get('size_bytes')), + 'url': download_url, + }) elif i_type == 'user': user_attributes = i.get('attributes') if user_attributes: info.update({ 'uploader': user_attributes.get('full_name'), + 'uploader_id': str_or_none(i.get('id')), 'uploader_url': user_attributes.get('url'), }) if not info.get('url'): - add_file(attributes.get('post_file') or {}) + embed_url = try_get(attributes, lambda x: x['embed']['url']) + if embed_url: + info.update({ + '_type': 'url', + 'url': embed_url, + }) if not info.get('url'): - info.update({ - '_type': 'url', - 'url': attributes['embed']['url'], - }) + post_file = attributes['post_file'] + ext = determine_ext(post_file.get('name')) + if ext in KNOWN_EXTENSIONS: + info.update({ + 'ext': ext, + 'url': post_file['url'], + }) return info diff --git a/youtube_dl/extractor/peertube.py b/youtube_dl/extractor/peertube.py index b50543e..d3a83ea 100644 --- a/youtube_dl/extractor/peertube.py +++ b/youtube_dl/extractor/peertube.py @@ -18,81 +18,385 @@ from ..utils import ( class PeerTubeIE(InfoExtractor): _INSTANCES_RE = r'''(?: # Taken from https://instances.joinpeertube.org/instances + peertube\.rainbowswingers\.net| + tube\.stanisic\.nl| + peer\.suiri\.us| + medias\.libox\.fr| + videomensoif\.ynh\.fr| + peertube\.travelpandas\.eu| + peertube\.rachetjay\.fr| + peertube\.montecsys\.fr| + tube\.eskuero\.me| + peer\.tube| + peertube\.umeahackerspace\.se| + tube\.nx-pod\.de| + video\.monsieurbidouille\.fr| tube\.openalgeria\.org| - peertube\.pointsecu\.fr| + vid\.lelux\.fi| + video\.anormallostpod\.ovh| + tube\.crapaud-fou\.org| + peertube\.stemy\.me| + lostpod\.space| + exode\.me| + peertube\.snargol\.com| + vis\.ion\.ovh| + videosdulib\.re| + v\.mbius\.io| + videos\.judrey\.eu| + peertube\.osureplayviewer\.xyz| + peertube\.mathieufamily\.ovh| + www\.videos-libr\.es| + fightforinfo\.com| + peertube\.fediverse\.ru| + peertube\.oiseauroch\.fr| + video\.nesven\.eu| + v\.bearvideo\.win| + video\.qoto\.org| + justporn\.cc| + video\.vny\.fr| + peervideo\.club| + tube\.taker\.fr| + peertube\.chantierlibre\.org| + tube\.ipfixe\.info| + tube\.kicou\.info| + tube\.dodsorf\.as| + videobit\.cc| + video\.yukari\.moe| + videos\.elbinario\.net| + hkvideo\.live| + pt\.tux\.tf| + www\.hkvideo\.live| + FIGHTFORINFO\.com| + pt\.765racing\.com| + peertube\.gnumeria\.eu\.org| + nordenmedia\.com| + peertube\.co\.uk| + tube\.darfweb\.eu| + tube\.kalah-france\.org| + 0ch\.in| + vod\.mochi\.academy| + film\.node9\.org| + peertube\.hatthieves\.es| + video\.fitchfamily\.org| + peertube\.ddns\.net| + video\.ifuncle\.kr| + video\.fdlibre\.eu| + tube\.22decembre\.eu| + peertube\.harmoniescreatives\.com| + tube\.fabrigli\.fr| + video\.thedwyers\.co| + video\.bruitbruit\.com| + peertube\.foxfam\.club| + peer\.philoxweb\.be| + videos\.bugs\.social| + peertube\.malbert\.xyz| + peertube\.bilange\.ca| + libretube\.net| + diytelevision\.com| + peertube\.fedilab\.app| + libre\.video| + video\.mstddntfdn\.online| + us\.tv| + peertube\.sl-network\.fr| + peertube\.dynlinux\.io| + peertube\.david\.durieux\.family| + peertube\.linuxrocks\.online| + peerwatch\.xyz| + v\.kretschmann\.social| + tube\.otter\.sh| + yt\.is\.nota\.live| + tube\.dragonpsi\.xyz| + peertube\.boneheadmedia\.com| + videos\.funkwhale\.audio| + watch\.44con\.com| + peertube\.gcaillaut\.fr| + peertube\.icu| + pony\.tube| + spacepub\.space| + tube\.stbr\.io| + v\.mom-gay\.faith| + tube\.port0\.xyz| + peertube\.simounet\.net| + play\.jergefelt\.se| + peertube\.zeteo\.me| + tube\.danq\.me| + peertube\.kerenon\.com| + tube\.fab-l3\.org| + tube\.calculate\.social| + peertube\.mckillop\.org| + tube\.netzspielplatz\.de| + vod\.ksite\.de| + peertube\.laas\.fr| + tube\.govital\.net| + peertube\.stephenson\.cc| + bistule\.nohost\.me| + peertube\.kajalinifi\.de| + video\.ploud\.jp| + video\.omniatv\.com| + peertube\.ffs2play\.fr| + peertube\.leboulaire\.ovh| + peertube\.tronic-studio\.com| + peertube\.public\.cat| + peertube\.metalbanana\.net| + video\.1000i100\.fr| + peertube\.alter-nativ-voll\.de| + tube\.pasa\.tf| + tube\.worldofhauru\.xyz| + pt\.kamp\.site| + peertube\.teleassist\.fr| + videos\.mleduc\.xyz| + conf\.tube| + media\.privacyinternational\.org| + pt\.forty-two\.nl| + video\.halle-leaks\.de| + video\.grosskopfgames\.de| + peertube\.schaeferit\.de| + peertube\.jackbot\.fr| + tube\.extinctionrebellion\.fr| + peertube\.f-si\.org| + video\.subak\.ovh| + videos\.koweb\.fr| + peertube\.zergy\.net| + peertube\.roflcopter\.fr| + peertube\.floss-marketing-school\.com| + vloggers\.social| + peertube\.iriseden\.eu| + videos\.ubuntu-paris\.org| + peertube\.mastodon\.host| + armstube\.com| + peertube\.s2s\.video| + peertube\.lol| + tube\.open-plug\.eu| + open\.tube| + peertube\.ch| + peertube\.normandie-libre\.fr| + peertube\.slat\.org| + video\.lacaveatonton\.ovh| + peertube\.uno| + peertube\.servebeer\.com| + peertube\.fedi\.quebec| + tube\.h3z\.jp| + tube\.plus200\.com| + peertube\.eric\.ovh| + tube\.metadocs\.cc| + tube\.unmondemeilleur\.eu| + gouttedeau\.space| + video\.antirep\.net| + nrop\.cant\.at| + tube\.ksl-bmx\.de| + tube\.plaf\.fr| + tube\.tchncs\.de| + video\.devinberg\.com| + hitchtube\.fr| + peertube\.kosebamse\.com| + yunopeertube\.myddns\.me| + peertube\.varney\.fr| + peertube\.anon-kenkai\.com| + tube\.maiti\.info| + tubee\.fr| + videos\.dinofly\.com| + toobnix\.org| + videotape\.me| + voca\.tube| + video\.heromuster\.com| + video\.lemediatv\.fr| + video\.up\.edu\.ph| + balafon\.video| + video\.ivel\.fr| + thickrips\.cloud| + pt\.laurentkruger\.fr| + video\.monarch-pass\.net| + peertube\.artica\.center| + video\.alternanet\.fr| + indymotion\.fr| + fanvid\.stopthatimp\.net| + video\.farci\.org| + v\.lesterpig\.com| + video\.okaris\.de| + tube\.pawelko\.net| + peertube\.mablr\.org| + tube\.fede\.re| + pytu\.be| + evertron\.tv| + devtube\.dev-wiki\.de| + raptube\.antipub\.org| + video\.selea\.se| + peertube\.mygaia\.org| + video\.oh14\.de| + peertube\.livingutopia\.org| + peertube\.the-penguin\.de| + tube\.thechangebook\.org| + tube\.anjara\.eu| + pt\.pube\.tk| + video\.samedi\.pm| + mplayer\.demouliere\.eu| + widemus\.de| + peertube\.me| + peertube\.zapashcanon\.fr| + video\.latavernedejohnjohn\.fr| + peertube\.pcservice46\.fr| + peertube\.mazzonetto\.eu| + video\.irem\.univ-paris-diderot\.fr| + video\.livecchi\.cloud| + alttube\.fr| + video\.coop\.tools| + video\.cabane-libre\.org| + peertube\.openstreetmap\.fr| + videos\.alolise\.org| + irrsinn\.video| + video\.antopie\.org| + scitech\.video| + tube2\.nemsia\.org| + video\.amic37\.fr| + peertube\.freeforge\.eu| + video\.arbitrarion\.com| + video\.datsemultimedia\.com| + stoptrackingus\.tv| + peertube\.ricostrongxxx\.com| + docker\.videos\.lecygnenoir\.info| + peertube\.togart\.de| + tube\.postblue\.info| + videos\.domainepublic\.net| + peertube\.cyber-tribal\.com| + video\.gresille\.org| + peertube\.dsmouse\.net| + cinema\.yunohost\.support| + tube\.theocevaer\.fr| + repro\.video| + tube\.4aem\.com| + quaziinc\.com| + peertube\.metawurst\.space| + videos\.wakapo\.com| + video\.ploud\.fr| + video\.freeradical\.zone| + tube\.valinor\.fr| + refuznik\.video| + pt\.kircheneuenburg\.de| + peertube\.asrun\.eu| + peertube\.lagob\.fr| + videos\.side-ways\.net| + 91video\.online| + video\.valme\.io| + video\.taboulisme\.com| + videos-libr\.es| + tv\.mooh\.fr| + nuage\.acostey\.fr| + video\.monsieur-a\.fr| + peertube\.librelois\.fr| + videos\.pair2jeux\.tube| + videos\.pueseso\.club| + peer\.mathdacloud\.ovh| + media\.assassinate-you\.net| + vidcommons\.org| + ptube\.rousset\.nom\.fr| + tube\.cyano\.at| + videos\.squat\.net| + video\.iphodase\.fr| + peertube\.makotoworkshop\.org| + peertube\.serveur\.slv-valbonne\.fr| + vault\.mle\.party| + hostyour\.tv| + videos\.hack2g2\.fr| + libre\.tube| + pire\.artisanlogiciel\.net| + videos\.numerique-en-commun\.fr| + video\.netsyms\.com| + video\.die-partei\.social| + video\.writeas\.org| + peertube\.swarm\.solvingmaz\.es| + tube\.pericoloso\.ovh| + watching\.cypherpunk\.observer| + videos\.adhocmusic\.com| + tube\.rfc1149\.net| + peertube\.librelabucm\.org| + videos\.numericoop\.fr| + peertube\.koehn\.com| + peertube\.anarchmusicall\.net| + tube\.kampftoast\.de| + vid\.y-y\.li| + peertube\.xtenz\.xyz| + diode\.zone| + tube\.egf\.mn| + peertube\.nomagic\.uk| + visionon\.tv| + videos\.koumoul\.com| + video\.rastapuls\.com| + video\.mantlepro\.com| + video\.deadsuperhero\.com| + peertube\.musicstudio\.pro| + peertube\.we-keys\.fr| + artitube\.artifaille\.fr| + peertube\.ethernia\.net| + tube\.midov\.pl| + peertube\.fr| + watch\.snoot\.tube| + peertube\.donnadieu\.fr| + argos\.aquilenet\.fr| + tube\.nemsia\.org| + tube\.bruniau\.net| + videos\.darckoune\.moe| + tube\.traydent\.info| + dev\.videos\.lecygnenoir\.info| + peertube\.nayya\.org| + peertube\.live| + peertube\.mofgao\.space| + video\.lequerrec\.eu| + peertube\.amicale\.net| + aperi\.tube| + tube\.ac-lyon\.fr| + video\.lw1\.at| + www\.yiny\.org| + videos\.pofilo\.fr| + tube\.lou\.lt| + choob\.h\.etbus\.ch| + tube\.hoga\.fr| + peertube\.heberge\.fr| + video\.obermui\.de| + videos\.cloudfrancois\.fr| + betamax\.video| + video\.typica\.us| + tube\.piweb\.be| + video\.blender\.org| + peertube\.cat| + tube\.kdy\.ch| + pe\.ertu\.be| + peertube\.social| + videos\.lescommuns\.org| + tv\.datamol\.org| + videonaute\.fr| + dialup\.express| peertube\.nogafa\.org| - peertube\.pl| megatube\.lilomoino\.fr| peertube\.tamanoir\.foucry\.net| - peertube\.inapurna\.org| - peertube\.netzspielplatz\.de| - video\.deadsuperhero\.com| peertube\.devosi\.org| peertube\.1312\.media| - tube\.worldofhauru\.xyz| tube\.bootlicker\.party| skeptikon\.fr| - peertube\.geekshell\.fr| - tube\.opportunis\.me| - peertube\.peshane\.net| video\.blueline\.mg| tube\.homecomputing\.fr| - videos\.cloudfrancois\.fr| - peertube\.viviers-fibre\.net| tube\.ouahpiti\.info| video\.tedomum\.net| video\.g3l\.org| fontube\.fr| peertube\.gaialabs\.ch| - peertube\.extremely\.online| - peertube\.public-infrastructure\.eu| tube\.kher\.nl| peertube\.qtg\.fr| - tube\.22decembre\.eu| - facegirl\.me| video\.migennes\.net| - janny\.moe| tube\.p2p\.legal| - video\.atlanti\.se| troll\.tv| - peertube\.geekael\.fr| - vid\.leotindall\.com| - video\.anormallostpod\.ovh| - p-tube\.h3z\.jp| - tube\.darfweb\.eu| videos\.iut-orsay\.fr| peertube\.solidev\.net| - videos\.symphonie-of-code\.fr| - testtube\.ortg\.de| videos\.cemea\.org| - peertube\.gwendalavir\.eu| video\.passageenseine\.fr| videos\.festivalparminous\.org| peertube\.touhoppai\.moe| - peertube\.duckdns\.org| sikke\.fi| - peertube\.mastodon\.host| - firedragonvideos\.com| - vidz\.dou\.bet| - peertube\.koehn\.com| peer\.hostux\.social| share\.tube| peertube\.walkingmountains\.fr| - medias\.libox\.fr| - peertube\.moe| - peertube\.xyz| - jp\.peertube\.network| videos\.benpro\.fr| - tube\.otter\.sh| - peertube\.angristan\.xyz| peertube\.parleur\.net| - peer\.ecutsa\.fr| peertube\.heraut\.eu| - peertube\.tifox\.fr| - peertube\.maly\.io| - vod\.mochi\.academy| - exode\.me| - coste\.video| tube\.aquilenet\.fr| peertube\.gegeweb\.eu| framatube\.org| @@ -100,18 +404,11 @@ class PeerTubeIE(InfoExtractor): tube\.conferences-gesticulees\.net| peertube\.datagueule\.tv| video\.lqdn\.fr| - meilleurtube\.delire\.party| tube\.mochi\.academy| - peertube\.dav\.li| media\.zat\.im| - pytu\.be| - peertube\.valvin\.fr| - peertube\.nsa\.ovh| video\.colibris-outilslibres\.org| - video\.hispagatos\.org| tube\.svnet\.fr| peertube\.video| - videos\.lecygnenoir\.info| peertube3\.cpy\.re| peertube2\.cpy\.re| videos\.tcit\.fr| @@ -126,7 +423,7 @@ class PeerTubeIE(InfoExtractor): (?P<id>%s) ''' % (_INSTANCES_RE, _UUID_RE) _TESTS = [{ - 'url': 'https://peertube.moe/videos/watch/2790feb0-8120-4e63-9af3-c943c69f5e6c', + 'url': 'https://peertube.cpy.re/videos/watch/2790feb0-8120-4e63-9af3-c943c69f5e6c', 'md5': '80f24ff364cc9d333529506a263e7feb', 'info_dict': { 'id': '2790feb0-8120-4e63-9af3-c943c69f5e6c', diff --git a/youtube_dl/extractor/periscope.py b/youtube_dl/extractor/periscope.py index b337a56..c02e34a 100644 --- a/youtube_dl/extractor/periscope.py +++ b/youtube_dl/extractor/periscope.py @@ -17,12 +17,54 @@ class PeriscopeBaseIE(InfoExtractor): 'https://api.periscope.tv/api/v2/%s' % method, item_id, query=query) + def _parse_broadcast_data(self, broadcast, video_id): + title = broadcast['status'] + uploader = broadcast.get('user_display_name') or broadcast.get('username') + title = '%s - %s' % (uploader, title) if uploader else title + is_live = broadcast.get('state').lower() == 'running' + + thumbnails = [{ + 'url': broadcast[image], + } for image in ('image_url', 'image_url_small') if broadcast.get(image)] + + return { + 'id': broadcast.get('id') or video_id, + 'title': self._live_title(title) if is_live else title, + 'timestamp': parse_iso8601(broadcast.get('created_at')), + 'uploader': uploader, + 'uploader_id': broadcast.get('user_id') or broadcast.get('username'), + 'thumbnails': thumbnails, + 'view_count': int_or_none(broadcast.get('total_watched')), + 'tags': broadcast.get('tags'), + 'is_live': is_live, + } + + @staticmethod + def _extract_common_format_info(broadcast): + return broadcast.get('state').lower(), int_or_none(broadcast.get('width')), int_or_none(broadcast.get('height')) + + @staticmethod + def _add_width_and_height(f, width, height): + for key, val in (('width', width), ('height', height)): + if not f.get(key): + f[key] = val + + def _extract_pscp_m3u8_formats(self, m3u8_url, video_id, format_id, state, width, height, fatal=True): + m3u8_formats = self._extract_m3u8_formats( + m3u8_url, video_id, 'mp4', + entry_protocol='m3u8_native' + if state in ('ended', 'timed_out') else 'm3u8', + m3u8_id=format_id, fatal=fatal) + if len(m3u8_formats) == 1: + self._add_width_and_height(m3u8_formats[0], width, height) + return m3u8_formats + class PeriscopeIE(PeriscopeBaseIE): IE_DESC = 'Periscope' IE_NAME = 'periscope' _VALID_URL = r'https?://(?:www\.)?(?:periscope|pscp)\.tv/[^/]+/(?P<id>[^/?#]+)' - # Alive example URLs can be found here http://onperiscope.com/ + # Alive example URLs can be found here https://www.periscope.tv/ _TESTS = [{ 'url': 'https://www.periscope.tv/w/aJUQnjY3MjA3ODF8NTYxMDIyMDl2zCg2pECBgwTqRpQuQD352EMPTKQjT4uqlM3cgWFA-g==', 'md5': '65b57957972e503fcbbaeed8f4fa04ca', @@ -61,21 +103,9 @@ class PeriscopeIE(PeriscopeBaseIE): 'accessVideoPublic', {'broadcast_id': token}, token) broadcast = stream['broadcast'] - title = broadcast['status'] - - uploader = broadcast.get('user_display_name') or broadcast.get('username') - uploader_id = (broadcast.get('user_id') or broadcast.get('username')) + info = self._parse_broadcast_data(broadcast, token) - title = '%s - %s' % (uploader, title) if uploader else title state = broadcast.get('state').lower() - if state == 'running': - title = self._live_title(title) - timestamp = parse_iso8601(broadcast.get('created_at')) - - thumbnails = [{ - 'url': broadcast[image], - } for image in ('image_url', 'image_url_small') if broadcast.get(image)] - width = int_or_none(broadcast.get('width')) height = int_or_none(broadcast.get('height')) @@ -92,32 +122,20 @@ class PeriscopeIE(PeriscopeBaseIE): continue video_urls.add(video_url) if format_id != 'rtmp': - m3u8_formats = self._extract_m3u8_formats( - video_url, token, 'mp4', - entry_protocol='m3u8_native' - if state in ('ended', 'timed_out') else 'm3u8', - m3u8_id=format_id, fatal=False) - if len(m3u8_formats) == 1: - add_width_and_height(m3u8_formats[0]) + m3u8_formats = self._extract_pscp_m3u8_formats( + video_url, token, format_id, state, width, height, False) formats.extend(m3u8_formats) continue rtmp_format = { 'url': video_url, 'ext': 'flv' if format_id == 'rtmp' else 'mp4', } - add_width_and_height(rtmp_format) + self._add_width_and_height(rtmp_format) formats.append(rtmp_format) self._sort_formats(formats) - return { - 'id': broadcast.get('id') or token, - 'title': title, - 'timestamp': timestamp, - 'uploader': uploader, - 'uploader_id': uploader_id, - 'thumbnails': thumbnails, - 'formats': formats, - } + info['formats'] = formats + return info class PeriscopeUserIE(PeriscopeBaseIE): diff --git a/youtube_dl/extractor/pornhub.py b/youtube_dl/extractor/pornhub.py index 11b8cfc..b3251cc 100644 --- a/youtube_dl/extractor/pornhub.py +++ b/youtube_dl/extractor/pornhub.py @@ -17,6 +17,7 @@ from ..utils import ( determine_ext, ExtractorError, int_or_none, + NO_DEFAULT, orderedSet, remove_quotes, str_to_int, @@ -227,12 +228,13 @@ class PornHubIE(PornHubBaseIE): else: thumbnail, duration = [None] * 2 - if not video_urls: - tv_webpage = dl_webpage('tv') - + def extract_js_vars(webpage, pattern, default=NO_DEFAULT): assignments = self._search_regex( - r'(var.+?mediastring.+?)</script>', tv_webpage, - 'encoded url').split(';') + pattern, webpage, 'encoded url', default=default) + if not assignments: + return {} + + assignments = assignments.split(';') js_vars = {} @@ -254,11 +256,35 @@ class PornHubIE(PornHubBaseIE): assn = re.sub(r'var\s+', '', assn) vname, value = assn.split('=', 1) js_vars[vname] = parse_js_value(value) + return js_vars - video_url = js_vars['mediastring'] - if video_url not in video_urls_set: - video_urls.append((video_url, None)) - video_urls_set.add(video_url) + def add_video_url(video_url): + v_url = url_or_none(video_url) + if not v_url: + return + if v_url in video_urls_set: + return + video_urls.append((v_url, None)) + video_urls_set.add(v_url) + + if not video_urls: + FORMAT_PREFIXES = ('media', 'quality') + js_vars = extract_js_vars( + webpage, r'(var\s+(?:%s)_.+)' % '|'.join(FORMAT_PREFIXES), + default=None) + if js_vars: + for key, format_url in js_vars.items(): + if any(key.startswith(p) for p in FORMAT_PREFIXES): + add_video_url(format_url) + if not video_urls and re.search( + r'<[^>]+\bid=["\']lockedPlayer', webpage): + raise ExtractorError( + 'Video %s is locked' % video_id, expected=True) + + if not video_urls: + js_vars = extract_js_vars( + dl_webpage('tv'), r'(var.+?mediastring.+?)</script>') + add_video_url(js_vars['mediastring']) for mobj in re.finditer( r'<a[^>]+\bclass=["\']downloadBtn\b[^>]+\bhref=(["\'])(?P<url>(?:(?!\1).)+)\1', @@ -276,10 +302,16 @@ class PornHubIE(PornHubBaseIE): r'/(\d{6}/\d{2})/', video_url, 'upload data', default=None) if upload_date: upload_date = upload_date.replace('/', '') - if determine_ext(video_url) == 'mpd': + ext = determine_ext(video_url) + if ext == 'mpd': formats.extend(self._extract_mpd_formats( video_url, video_id, mpd_id='dash', fatal=False)) continue + elif ext == 'm3u8': + formats.extend(self._extract_m3u8_formats( + video_url, video_id, 'mp4', entry_protocol='m3u8_native', + m3u8_id='hls', fatal=False)) + continue tbr = None mobj = re.search(r'(?P<height>\d+)[pP]?_(?P<tbr>\d+)[kK]', video_url) if mobj: @@ -403,6 +435,15 @@ class PornHubUserIE(PornHubPlaylistBaseIE): class PornHubPagedPlaylistBaseIE(PornHubPlaylistBaseIE): + @staticmethod + def _has_more(webpage): + return re.search( + r'''(?x) + <li[^>]+\bclass=["\']page_next| + <link[^>]+\brel=["\']next| + <button[^>]+\bid=["\']moreDataBtn + ''', webpage) is not None + def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) host = mobj.group('host') @@ -411,13 +452,11 @@ class PornHubPagedPlaylistBaseIE(PornHubPlaylistBaseIE): page = int_or_none(self._search_regex( r'\bpage=(\d+)', url, 'page', default=None)) - page_url = self._make_page_url(url) - entries = [] for page_num in (page, ) if page is not None else itertools.count(1): try: webpage = self._download_webpage( - page_url, item_id, 'Downloading page %d' % page_num, + url, item_id, 'Downloading page %d' % page_num, query={'page': page_num}) except ExtractorError as e: if isinstance(e.cause, compat_HTTPError) and e.cause.code == 404: @@ -547,18 +586,6 @@ class PornHubPagedVideoListIE(PornHubPagedPlaylistBaseIE): if PornHubIE.suitable(url) or PornHubUserIE.suitable(url) or PornHubUserVideosUploadIE.suitable(url) else super(PornHubPagedVideoListIE, cls).suitable(url)) - def _make_page_url(self, url): - return url - - @staticmethod - def _has_more(webpage): - return re.search( - r'''(?x) - <li[^>]+\bclass=["\']page_next| - <link[^>]+\brel=["\']next| - <button[^>]+\bid=["\']moreDataBtn - ''', webpage) is not None - class PornHubUserVideosUploadIE(PornHubPagedPlaylistBaseIE): _VALID_URL = r'(?P<url>https?://(?:[^/]+\.)?(?P<host>pornhub\.(?:com|net))/(?:(?:user|channel)s|model|pornstar)/(?P<id>[^/]+)/videos/upload)' @@ -572,11 +599,3 @@ class PornHubUserVideosUploadIE(PornHubPagedPlaylistBaseIE): 'url': 'https://www.pornhub.com/model/zoe_ph/videos/upload', 'only_matching': True, }] - - def _make_page_url(self, url): - mobj = re.match(self._VALID_URL, url) - return '%s/ajax' % mobj.group('url') - - @staticmethod - def _has_more(webpage): - return True diff --git a/youtube_dl/extractor/promptfile.py b/youtube_dl/extractor/promptfile.py deleted file mode 100644 index 23ac93d..0000000 --- a/youtube_dl/extractor/promptfile.py +++ /dev/null @@ -1,70 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..utils import ( - determine_ext, - ExtractorError, - urlencode_postdata, -) - - -class PromptFileIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?promptfile\.com/l/(?P<id>[0-9A-Z\-]+)' - _TEST = { - 'url': 'http://www.promptfile.com/l/86D1CE8462-576CAAE416', - 'md5': '5a7e285a26e0d66d9a263fae91bc92ce', - 'info_dict': { - 'id': '86D1CE8462-576CAAE416', - 'ext': 'mp4', - 'title': 'oceans.mp4', - 'thumbnail': r're:^https?://.*\.jpg$', - } - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - - if re.search(r'<div.+id="not_found_msg".+>(?!We are).+</div>[^-]', webpage) is not None: - raise ExtractorError('Video %s does not exist' % video_id, - expected=True) - - chash = self._search_regex( - r'val\("([^"]*)"\s*\+\s*\$\("#chash"\)', webpage, 'chash') - fields = self._hidden_inputs(webpage) - keys = list(fields.keys()) - chash_key = keys[0] if len(keys) == 1 else next( - key for key in keys if key.startswith('cha')) - fields[chash_key] = chash + fields[chash_key] - - webpage = self._download_webpage( - url, video_id, 'Downloading video page', - data=urlencode_postdata(fields), - headers={'Content-type': 'application/x-www-form-urlencoded'}) - - video_url = self._search_regex( - (r'<a[^>]+href=(["\'])(?P<url>(?:(?!\1).)+)\1[^>]*>\s*Download File', - r'<a[^>]+href=(["\'])(?P<url>https?://(?:www\.)?promptfile\.com/file/(?:(?!\1).)+)\1'), - webpage, 'video url', group='url') - title = self._html_search_regex( - r'<span.+title="([^"]+)">', webpage, 'title') - thumbnail = self._html_search_regex( - r'<div id="player_overlay">.*button>.*?<img src="([^"]+)"', - webpage, 'thumbnail', fatal=False, flags=re.DOTALL) - - formats = [{ - 'format_id': 'sd', - 'url': video_url, - 'ext': determine_ext(title), - }] - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': title, - 'thumbnail': thumbnail, - 'formats': formats, - } diff --git a/youtube_dl/extractor/prosiebensat1.py b/youtube_dl/extractor/prosiebensat1.py index e19a470..1bc4f9b 100644 --- a/youtube_dl/extractor/prosiebensat1.py +++ b/youtube_dl/extractor/prosiebensat1.py @@ -16,7 +16,7 @@ from ..utils import ( class ProSiebenSat1BaseIE(InfoExtractor): - _GEO_COUNTRIES = ['DE'] + _GEO_BYPASS = False _ACCESS_ID = None _SUPPORTED_PROTOCOLS = 'dash:clear,hls:clear,progressive:clear' _V4_BASE_URL = 'https://vas-v4.p7s1video.net/4.0/get' @@ -39,14 +39,18 @@ class ProSiebenSat1BaseIE(InfoExtractor): formats = [] if self._ACCESS_ID: raw_ct = self._ENCRYPTION_KEY + clip_id + self._IV + self._ACCESS_ID - server_token = (self._download_json( + protocols = self._download_json( self._V4_BASE_URL + 'protocols', clip_id, 'Downloading protocols JSON', headers=self.geo_verification_headers(), query={ 'access_id': self._ACCESS_ID, 'client_token': sha1((raw_ct).encode()).hexdigest(), 'video_id': clip_id, - }, fatal=False) or {}).get('server_token') + }, fatal=False, expected_status=(403,)) or {} + error = protocols.get('error') or {} + if error.get('title') == 'Geo check failed': + self.raise_geo_restricted(countries=['AT', 'CH', 'DE']) + server_token = protocols.get('server_token') if server_token: urls = (self._download_json( self._V4_BASE_URL + 'urls', clip_id, 'Downloading urls JSON', query={ diff --git a/youtube_dl/extractor/puhutv.py b/youtube_dl/extractor/puhutv.py index 5465e8a..fb704a3 100644 --- a/youtube_dl/extractor/puhutv.py +++ b/youtube_dl/extractor/puhutv.py @@ -25,21 +25,21 @@ class PuhuTVIE(InfoExtractor): _TESTS = [{ # film 'url': 'https://puhutv.com/sut-kardesler-izle', - 'md5': 'fbd8f2d8e7681f8bcd51b592475a6ae7', + 'md5': 'a347470371d56e1585d1b2c8dab01c96', 'info_dict': { 'id': '5085', 'display_id': 'sut-kardesler', 'ext': 'mp4', 'title': 'Süt Kardeşler', - 'description': 'md5:405fd024df916ca16731114eb18e511a', + 'description': 'md5:ca09da25b7e57cbb5a9280d6e48d17aa', 'thumbnail': r're:^https?://.*\.jpg$', 'duration': 4832.44, 'creator': 'Arzu Film', - 'timestamp': 1469778212, - 'upload_date': '20160729', + 'timestamp': 1561062602, + 'upload_date': '20190620', 'release_year': 1976, 'view_count': int, - 'tags': ['Aile', 'Komedi', 'Klasikler'], + 'tags': list, }, }, { # episode, geo restricted, bypassable with --geo-verification-proxy @@ -64,9 +64,10 @@ class PuhuTVIE(InfoExtractor): display_id)['data'] video_id = compat_str(info['id']) - title = info.get('name') or info['title']['name'] + show = info.get('title') or {} + title = info.get('name') or show['name'] if info.get('display_name'): - title = '%s %s' % (title, info.get('display_name')) + title = '%s %s' % (title, info['display_name']) try: videos = self._download_json( @@ -78,17 +79,36 @@ class PuhuTVIE(InfoExtractor): self.raise_geo_restricted() raise + urls = [] formats = [] + + def add_http_from_hls(m3u8_f): + http_url = m3u8_f['url'].replace('/hls/', '/mp4/').replace('/chunklist.m3u8', '.mp4') + if http_url != m3u8_f['url']: + f = m3u8_f.copy() + f.update({ + 'format_id': f['format_id'].replace('hls', 'http'), + 'protocol': 'http', + 'url': http_url, + }) + formats.append(f) + for video in videos['data']['videos']: media_url = url_or_none(video.get('url')) - if not media_url: + if not media_url or media_url in urls: continue + urls.append(media_url) + playlist = video.get('is_playlist') - if video.get('stream_type') == 'hls' and playlist is True: - formats.extend(self._extract_m3u8_formats( + if (video.get('stream_type') == 'hls' and playlist is True) or 'playlist.m3u8' in media_url: + m3u8_formats = self._extract_m3u8_formats( media_url, video_id, 'mp4', entry_protocol='m3u8_native', - m3u8_id='hls', fatal=False)) + m3u8_id='hls', fatal=False) + for m3u8_f in m3u8_formats: + formats.append(m3u8_f) + add_http_from_hls(m3u8_f) continue + quality = int_or_none(video.get('quality')) f = { 'url': media_url, @@ -96,34 +116,29 @@ class PuhuTVIE(InfoExtractor): 'height': quality } video_format = video.get('video_format') - if video_format == 'hls' and playlist is False: + is_hls = (video_format == 'hls' or '/hls/' in media_url or '/chunklist.m3u8' in media_url) and playlist is False + if is_hls: format_id = 'hls' f['protocol'] = 'm3u8_native' elif video_format == 'mp4': format_id = 'http' - else: continue if quality: format_id += '-%sp' % quality f['format_id'] = format_id formats.append(f) + if is_hls: + add_http_from_hls(f) self._sort_formats(formats) - description = try_get( - info, lambda x: x['title']['description'], - compat_str) or info.get('description') - timestamp = unified_timestamp(info.get('created_at')) creator = try_get( - info, lambda x: x['title']['producer']['name'], compat_str) + show, lambda x: x['producer']['name'], compat_str) - duration = float_or_none( - try_get(info, lambda x: x['content']['duration_in_ms'], int), - scale=1000) - view_count = try_get(info, lambda x: x['content']['watch_count'], int) + content = info.get('content') or {} images = try_get( - info, lambda x: x['content']['images']['wide'], dict) or {} + content, lambda x: x['images']['wide'], dict) or {} thumbnails = [] for image_id, image_url in images.items(): if not isinstance(image_url, compat_str): @@ -137,14 +152,8 @@ class PuhuTVIE(InfoExtractor): }) thumbnails.append(t) - release_year = try_get(info, lambda x: x['title']['released_at'], int) - - season_number = int_or_none(info.get('season_number')) - season_id = str_or_none(info.get('season_id')) - episode_number = int_or_none(info.get('episode_number')) - tags = [] - for genre in try_get(info, lambda x: x['title']['genres'], list) or []: + for genre in show.get('genres') or []: if not isinstance(genre, dict): continue genre_name = genre.get('name') @@ -152,12 +161,11 @@ class PuhuTVIE(InfoExtractor): tags.append(genre_name) subtitles = {} - for subtitle in try_get( - info, lambda x: x['content']['subtitles'], list) or []: + for subtitle in content.get('subtitles') or []: if not isinstance(subtitle, dict): continue lang = subtitle.get('language') - sub_url = url_or_none(subtitle.get('url')) + sub_url = url_or_none(subtitle.get('url') or subtitle.get('file')) if not lang or not isinstance(lang, compat_str) or not sub_url: continue subtitles[self._SUBTITLE_LANGS.get(lang, lang)] = [{ @@ -168,15 +176,15 @@ class PuhuTVIE(InfoExtractor): 'id': video_id, 'display_id': display_id, 'title': title, - 'description': description, - 'season_id': season_id, - 'season_number': season_number, - 'episode_number': episode_number, - 'release_year': release_year, - 'timestamp': timestamp, + 'description': info.get('description') or show.get('description'), + 'season_id': str_or_none(info.get('season_id')), + 'season_number': int_or_none(info.get('season_number')), + 'episode_number': int_or_none(info.get('episode_number')), + 'release_year': int_or_none(show.get('released_at')), + 'timestamp': unified_timestamp(info.get('created_at')), 'creator': creator, - 'view_count': view_count, - 'duration': duration, + 'view_count': int_or_none(content.get('watch_count')), + 'duration': float_or_none(content.get('duration_in_ms'), 1000), 'tags': tags, 'subtitles': subtitles, 'thumbnails': thumbnails, diff --git a/youtube_dl/extractor/redtube.py b/youtube_dl/extractor/redtube.py index 10311a8..b1bde1e 100644 --- a/youtube_dl/extractor/redtube.py +++ b/youtube_dl/extractor/redtube.py @@ -6,6 +6,7 @@ from .common import InfoExtractor from ..utils import ( ExtractorError, int_or_none, + merge_dicts, str_to_int, unified_strdate, url_or_none, @@ -42,14 +43,24 @@ class RedTubeIE(InfoExtractor): webpage = self._download_webpage( 'http://www.redtube.com/%s' % video_id, video_id) - if any(s in webpage for s in ['video-deleted-info', '>This video has been removed']): - raise ExtractorError('Video %s has been removed' % video_id, expected=True) + ERRORS = ( + (('video-deleted-info', '>This video has been removed'), 'has been removed'), + (('private_video_text', '>This video is private', '>Send a friend request to its owner to be able to view it'), 'is private'), + ) - title = self._html_search_regex( - (r'<h(\d)[^>]+class="(?:video_title_text|videoTitle)[^"]*">(?P<title>(?:(?!\1).)+)</h\1>', - r'(?:videoTitle|title)\s*:\s*(["\'])(?P<title>(?:(?!\1).)+)\1',), - webpage, 'title', group='title', - default=None) or self._og_search_title(webpage) + for patterns, message in ERRORS: + if any(p in webpage for p in patterns): + raise ExtractorError( + 'Video %s %s' % (video_id, message), expected=True) + + info = self._search_json_ld(webpage, video_id, default={}) + + if not info.get('title'): + info['title'] = self._html_search_regex( + (r'<h(\d)[^>]+class="(?:video_title_text|videoTitle)[^"]*">(?P<title>(?:(?!\1).)+)</h\1>', + r'(?:videoTitle|title)\s*:\s*(["\'])(?P<title>(?:(?!\1).)+)\1',), + webpage, 'title', group='title', + default=None) or self._og_search_title(webpage) formats = [] sources = self._parse_json( @@ -88,28 +99,28 @@ class RedTubeIE(InfoExtractor): thumbnail = self._og_search_thumbnail(webpage) upload_date = unified_strdate(self._search_regex( - r'<span[^>]+>ADDED ([^<]+)<', - webpage, 'upload date', fatal=False)) + r'<span[^>]+>(?:ADDED|Published on) ([^<]+)<', + webpage, 'upload date', default=None)) duration = int_or_none(self._og_search_property( 'video:duration', webpage, default=None) or self._search_regex( r'videoDuration\s*:\s*(\d+)', webpage, 'duration', default=None)) view_count = str_to_int(self._search_regex( (r'<div[^>]*>Views</div>\s*<div[^>]*>\s*([\d,.]+)', - r'<span[^>]*>VIEWS</span>\s*</td>\s*<td>\s*([\d,.]+)'), - webpage, 'view count', fatal=False)) + r'<span[^>]*>VIEWS</span>\s*</td>\s*<td>\s*([\d,.]+)', + r'<span[^>]+\bclass=["\']video_view_count[^>]*>\s*([\d,.]+)'), + webpage, 'view count', default=None)) # No self-labeling, but they describe themselves as # "Home of Videos Porno" age_limit = 18 - return { + return merge_dicts(info, { 'id': video_id, 'ext': 'mp4', - 'title': title, 'thumbnail': thumbnail, 'upload_date': upload_date, 'duration': duration, 'view_count': view_count, 'age_limit': age_limit, 'formats': formats, - } + }) diff --git a/youtube_dl/extractor/revision3.py b/youtube_dl/extractor/revision3.py deleted file mode 100644 index 833d8a2..0000000 --- a/youtube_dl/extractor/revision3.py +++ /dev/null @@ -1,170 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..compat import compat_str -from ..utils import ( - int_or_none, - parse_iso8601, - unescapeHTML, - qualities, -) - - -class Revision3EmbedIE(InfoExtractor): - IE_NAME = 'revision3:embed' - _VALID_URL = r'(?:revision3:(?:(?P<playlist_type>[^:]+):)?|https?://(?:(?:(?:www|embed)\.)?(?:revision3|animalist)|(?:(?:api|embed)\.)?seekernetwork)\.com/player/embed\?videoId=)(?P<playlist_id>\d+)' - _TEST = { - 'url': 'http://api.seekernetwork.com/player/embed?videoId=67558', - 'md5': '83bcd157cab89ad7318dd7b8c9cf1306', - 'info_dict': { - 'id': '67558', - 'ext': 'mp4', - 'title': 'The Pros & Cons Of Zoos', - 'description': 'Zoos are often depicted as a terrible place for animals to live, but is there any truth to this?', - 'uploader_id': 'dnews', - 'uploader': 'DNews', - } - } - _API_KEY = 'ba9c741bce1b9d8e3defcc22193f3651b8867e62' - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - playlist_id = mobj.group('playlist_id') - playlist_type = mobj.group('playlist_type') or 'video_id' - video_data = self._download_json( - 'http://revision3.com/api/getPlaylist.json', playlist_id, query={ - 'api_key': self._API_KEY, - 'codecs': 'h264,vp8,theora', - playlist_type: playlist_id, - })['items'][0] - - formats = [] - for vcodec, media in video_data['media'].items(): - for quality_id, quality in media.items(): - if quality_id == 'hls': - formats.extend(self._extract_m3u8_formats( - quality['url'], playlist_id, 'mp4', - 'm3u8_native', m3u8_id='hls', fatal=False)) - else: - formats.append({ - 'url': quality['url'], - 'format_id': '%s-%s' % (vcodec, quality_id), - 'tbr': int_or_none(quality.get('bitrate')), - 'vcodec': vcodec, - }) - self._sort_formats(formats) - - return { - 'id': playlist_id, - 'title': unescapeHTML(video_data['title']), - 'description': unescapeHTML(video_data.get('summary')), - 'uploader': video_data.get('show', {}).get('name'), - 'uploader_id': video_data.get('show', {}).get('slug'), - 'duration': int_or_none(video_data.get('duration')), - 'formats': formats, - } - - -class Revision3IE(InfoExtractor): - IE_NAME = 'revision' - _VALID_URL = r'https?://(?:www\.)?(?P<domain>(?:revision3|animalist)\.com)/(?P<id>[^/]+(?:/[^/?#]+)?)' - _TESTS = [{ - 'url': 'http://www.revision3.com/technobuffalo/5-google-predictions-for-2016', - 'md5': 'd94a72d85d0a829766de4deb8daaf7df', - 'info_dict': { - 'id': '71089', - 'display_id': 'technobuffalo/5-google-predictions-for-2016', - 'ext': 'webm', - 'title': '5 Google Predictions for 2016', - 'description': 'Google had a great 2015, but it\'s already time to look ahead. Here are our five predictions for 2016.', - 'upload_date': '20151228', - 'timestamp': 1451325600, - 'duration': 187, - 'uploader': 'TechnoBuffalo', - 'uploader_id': 'technobuffalo', - } - }, { - # Show - 'url': 'http://revision3.com/variant', - 'only_matching': True, - }, { - # Tag - 'url': 'http://revision3.com/vr', - 'only_matching': True, - }] - _PAGE_DATA_TEMPLATE = 'http://www.%s/apiProxy/ddn/%s?domain=%s' - - def _real_extract(self, url): - domain, display_id = re.match(self._VALID_URL, url).groups() - site = domain.split('.')[0] - page_info = self._download_json( - self._PAGE_DATA_TEMPLATE % (domain, display_id, domain), display_id) - - page_data = page_info['data'] - page_type = page_data['type'] - if page_type in ('episode', 'embed'): - show_data = page_data['show']['data'] - page_id = compat_str(page_data['id']) - video_id = compat_str(page_data['video']['data']['id']) - - preference = qualities(['mini', 'small', 'medium', 'large']) - thumbnails = [{ - 'url': image_url, - 'id': image_id, - 'preference': preference(image_id) - } for image_id, image_url in page_data.get('images', {}).items()] - - info = { - 'id': page_id, - 'display_id': display_id, - 'title': unescapeHTML(page_data['name']), - 'description': unescapeHTML(page_data.get('summary')), - 'timestamp': parse_iso8601(page_data.get('publishTime'), ' '), - 'author': page_data.get('author'), - 'uploader': show_data.get('name'), - 'uploader_id': show_data.get('slug'), - 'thumbnails': thumbnails, - 'extractor_key': site, - } - - if page_type == 'embed': - info.update({ - '_type': 'url_transparent', - 'url': page_data['video']['data']['embed'], - }) - return info - - info.update({ - '_type': 'url_transparent', - 'url': 'revision3:%s' % video_id, - }) - return info - else: - list_data = page_info[page_type]['data'] - episodes_data = page_info['episodes']['data'] - num_episodes = page_info['meta']['totalEpisodes'] - processed_episodes = 0 - entries = [] - page_num = 1 - while True: - entries.extend([{ - '_type': 'url', - 'url': 'http://%s%s' % (domain, episode['path']), - 'id': compat_str(episode['id']), - 'ie_key': 'Revision3', - 'extractor_key': site, - } for episode in episodes_data]) - processed_episodes += len(episodes_data) - if processed_episodes == num_episodes: - break - page_num += 1 - episodes_data = self._download_json(self._PAGE_DATA_TEMPLATE % ( - domain, display_id + '/' + compat_str(page_num), domain), - display_id)['episodes']['data'] - - return self.playlist_result( - entries, compat_str(list_data['id']), - list_data.get('name'), list_data.get('summary')) diff --git a/youtube_dl/extractor/roosterteeth.py b/youtube_dl/extractor/roosterteeth.py index 8d88ee4..8883639 100644 --- a/youtube_dl/extractor/roosterteeth.py +++ b/youtube_dl/extractor/roosterteeth.py @@ -1,8 +1,6 @@ # coding: utf-8 from __future__ import unicode_literals -import re - from .common import InfoExtractor from ..compat import ( compat_HTTPError, @@ -18,7 +16,6 @@ from ..utils import ( class RoosterTeethIE(InfoExtractor): _VALID_URL = r'https?://(?:.+?\.)?roosterteeth\.com/(?:episode|watch)/(?P<id>[^/?#&]+)' - _LOGIN_URL = 'https://roosterteeth.com/login' _NETRC_MACHINE = 'roosterteeth' _TESTS = [{ 'url': 'http://roosterteeth.com/episode/million-dollars-but-season-2-million-dollars-but-the-game-announcement', @@ -53,48 +50,40 @@ class RoosterTeethIE(InfoExtractor): 'url': 'https://roosterteeth.com/watch/million-dollars-but-season-2-million-dollars-but-the-game-announcement', 'only_matching': True, }] + _EPISODE_BASE_URL = 'https://svod-be.roosterteeth.com/api/v1/episodes/' def _login(self): username, password = self._get_login_info() if username is None: return - login_page = self._download_webpage( - self._LOGIN_URL, None, - note='Downloading login page', - errnote='Unable to download login page') - - login_form = self._hidden_inputs(login_page) - - login_form.update({ - 'username': username, - 'password': password, - }) - - login_request = self._download_webpage( - self._LOGIN_URL, None, - note='Logging in', - data=urlencode_postdata(login_form), - headers={ - 'Referer': self._LOGIN_URL, - }) - - if not any(re.search(p, login_request) for p in ( - r'href=["\']https?://(?:www\.)?roosterteeth\.com/logout"', - r'>Sign Out<')): - error = self._html_search_regex( - r'(?s)<div[^>]+class=(["\']).*?\balert-danger\b.*?\1[^>]*>(?:\s*<button[^>]*>.*?</button>)?(?P<error>.+?)</div>', - login_request, 'alert', default=None, group='error') - if error: - raise ExtractorError('Unable to login: %s' % error, expected=True) - raise ExtractorError('Unable to log in') + try: + self._download_json( + 'https://auth.roosterteeth.com/oauth/token', + None, 'Logging in', data=urlencode_postdata({ + 'client_id': '4338d2b4bdc8db1239360f28e72f0d9ddb1fd01e7a38fbb07b4b1f4ba4564cc5', + 'grant_type': 'password', + 'username': username, + 'password': password, + })) + except ExtractorError as e: + msg = 'Unable to login' + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401: + resp = self._parse_json(e.cause.read().decode(), None, fatal=False) + if resp: + error = resp.get('extra_info') or resp.get('error_description') or resp.get('error') + if error: + msg += ': ' + error + self.report_warning(msg) def _real_initialize(self): + if self._get_cookies(self._EPISODE_BASE_URL).get('rt_access_token'): + return self._login() def _real_extract(self, url): display_id = self._match_id(url) - api_episode_url = 'https://svod-be.roosterteeth.com/api/v1/episodes/%s' % display_id + api_episode_url = self._EPISODE_BASE_URL + display_id try: m3u8_url = self._download_json( diff --git a/youtube_dl/extractor/safari.py b/youtube_dl/extractor/safari.py index bd9ee16..4942437 100644 --- a/youtube_dl/extractor/safari.py +++ b/youtube_dl/extractor/safari.py @@ -165,7 +165,8 @@ class SafariIE(SafariBaseIE): kaltura_session = self._download_json( '%s/player/kaltura_session/?reference_id=%s' % (self._API_BASE, reference_id), video_id, 'Downloading kaltura session JSON', - 'Unable to download kaltura session JSON', fatal=False) + 'Unable to download kaltura session JSON', fatal=False, + headers={'Accept': 'application/json'}) if kaltura_session: session = kaltura_session.get('session') if session: diff --git a/youtube_dl/extractor/scrippsnetworks.py b/youtube_dl/extractor/scrippsnetworks.py index 8b32757..b40b4c4 100644 --- a/youtube_dl/extractor/scrippsnetworks.py +++ b/youtube_dl/extractor/scrippsnetworks.py @@ -7,6 +7,7 @@ import re from .aws import AWSIE from .anvato import AnvatoIE +from .common import InfoExtractor from ..utils import ( smuggle_url, urlencode_postdata, @@ -102,3 +103,50 @@ class ScrippsNetworksWatchIE(AWSIE): 'anvato:anvato_scripps_app_web_prod_0837996dbe373629133857ae9eb72e740424d80a:%s' % mcp_id, {'geo_countries': ['US']}), AnvatoIE.ie_key(), video_id=mcp_id) + + +class ScrippsNetworksIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?(?P<site>cookingchanneltv|discovery|(?:diy|food)network|hgtv|travelchannel)\.com/videos/[0-9a-z-]+-(?P<id>\d+)' + _TESTS = [{ + 'url': 'https://www.cookingchanneltv.com/videos/the-best-of-the-best-0260338', + 'info_dict': { + 'id': '0260338', + 'ext': 'mp4', + 'title': 'The Best of the Best', + 'description': 'Catch a new episode of MasterChef Canada Tuedsay at 9/8c.', + 'timestamp': 1475678834, + 'upload_date': '20161005', + 'uploader': 'SCNI-SCND', + }, + 'add_ie': ['ThePlatform'], + }, { + 'url': 'https://www.diynetwork.com/videos/diy-barnwood-tablet-stand-0265790', + 'only_matching': True, + }, { + 'url': 'https://www.foodnetwork.com/videos/chocolate-strawberry-cake-roll-7524591', + 'only_matching': True, + }, { + 'url': 'https://www.hgtv.com/videos/cookie-decorating-101-0301929', + 'only_matching': True, + }, { + 'url': 'https://www.travelchannel.com/videos/two-climates-one-bag-5302184', + 'only_matching': True, + }, { + 'url': 'https://www.discovery.com/videos/guardians-of-the-glades-cooking-with-tom-cobb-5578368', + 'only_matching': True, + }] + _ACCOUNT_MAP = { + 'cookingchanneltv': 2433005105, + 'discovery': 2706091867, + 'diynetwork': 2433004575, + 'foodnetwork': 2433005105, + 'hgtv': 2433004575, + 'travelchannel': 2433005739, + } + _TP_TEMPL = 'https://link.theplatform.com/s/ip77QC/media/guid/%d/%s?mbr=true' + + def _real_extract(self, url): + site, guid = re.match(self._VALID_URL, url).groups() + return self.url_result(smuggle_url( + self._TP_TEMPL % (self._ACCOUNT_MAP[site], guid), + {'force_smil_url': True}), 'ThePlatform', guid) diff --git a/youtube_dl/extractor/scte.py b/youtube_dl/extractor/scte.py new file mode 100644 index 0000000..ca1de63 --- /dev/null +++ b/youtube_dl/extractor/scte.py @@ -0,0 +1,144 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + decode_packed_codes, + ExtractorError, + urlencode_postdata, +) + + +class SCTEBaseIE(InfoExtractor): + _LOGIN_URL = 'https://www.scte.org/SCTE/Sign_In.aspx' + _NETRC_MACHINE = 'scte' + + def _real_initialize(self): + self._login() + + def _login(self): + username, password = self._get_login_info() + if username is None: + return + + login_popup = self._download_webpage( + self._LOGIN_URL, None, 'Downloading login popup') + + def is_logged(webpage): + return any(re.search(p, webpage) for p in ( + r'class=["\']welcome\b', r'>Sign Out<')) + + # already logged in + if is_logged(login_popup): + return + + login_form = self._hidden_inputs(login_popup) + + login_form.update({ + 'ctl01$TemplateBody$WebPartManager1$gwpciNewContactSignInCommon$ciNewContactSignInCommon$signInUserName': username, + 'ctl01$TemplateBody$WebPartManager1$gwpciNewContactSignInCommon$ciNewContactSignInCommon$signInPassword': password, + 'ctl01$TemplateBody$WebPartManager1$gwpciNewContactSignInCommon$ciNewContactSignInCommon$RememberMe': 'on', + }) + + response = self._download_webpage( + self._LOGIN_URL, None, 'Logging in', + data=urlencode_postdata(login_form)) + + if '|pageRedirect|' not in response and not is_logged(response): + error = self._html_search_regex( + r'(?s)<[^>]+class=["\']AsiError["\'][^>]*>(.+?)</', + response, 'error message', default=None) + if error: + raise ExtractorError('Unable to login: %s' % error, expected=True) + raise ExtractorError('Unable to log in') + + +class SCTEIE(SCTEBaseIE): + _VALID_URL = r'https?://learning\.scte\.org/mod/scorm/view\.php?.*?\bid=(?P<id>\d+)' + _TESTS = [{ + 'url': 'https://learning.scte.org/mod/scorm/view.php?id=31484', + 'info_dict': { + 'title': 'Introduction to DOCSIS Engineering Professional', + 'id': '31484', + }, + 'playlist_count': 5, + 'skip': 'Requires account credentials', + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + + webpage = self._download_webpage(url, video_id) + + title = self._search_regex(r'<h1>(.+?)</h1>', webpage, 'title') + + context_id = self._search_regex(r'context-(\d+)', webpage, video_id) + content_base = 'https://learning.scte.org/pluginfile.php/%s/mod_scorm/content/8/' % context_id + context = decode_packed_codes(self._download_webpage( + '%smobile/data.js' % content_base, video_id)) + + data = self._parse_xml( + self._search_regex( + r'CreateData\(\s*"(.+?)"', context, 'data').replace(r"\'", "'"), + video_id) + + entries = [] + for asset in data.findall('.//asset'): + asset_url = asset.get('url') + if not asset_url or not asset_url.endswith('.mp4'): + continue + asset_id = self._search_regex( + r'video_([^_]+)_', asset_url, 'asset id', default=None) + if not asset_id: + continue + entries.append({ + 'id': asset_id, + 'title': title, + 'url': content_base + asset_url, + }) + + return self.playlist_result(entries, video_id, title) + + +class SCTECourseIE(SCTEBaseIE): + _VALID_URL = r'https?://learning\.scte\.org/(?:mod/sub)?course/view\.php?.*?\bid=(?P<id>\d+)' + _TESTS = [{ + 'url': 'https://learning.scte.org/mod/subcourse/view.php?id=31491', + 'only_matching': True, + }, { + 'url': 'https://learning.scte.org/course/view.php?id=3639', + 'only_matching': True, + }, { + 'url': 'https://learning.scte.org/course/view.php?id=3073', + 'only_matching': True, + }] + + def _real_extract(self, url): + course_id = self._match_id(url) + + webpage = self._download_webpage(url, course_id) + + title = self._search_regex( + r'<h1>(.+?)</h1>', webpage, 'title', default=None) + + entries = [] + for mobj in re.finditer( + r'''(?x) + <a[^>]+ + href=(["\']) + (?P<url> + https?://learning\.scte\.org/mod/ + (?P<kind>scorm|subcourse)/view\.php?(?:(?!\1).)*? + \bid=\d+ + ) + ''', + webpage): + item_url = mobj.group('url') + if item_url == url: + continue + ie = (SCTEIE.ie_key() if mobj.group('kind') == 'scorm' + else SCTECourseIE.ie_key()) + entries.append(self.url_result(item_url, ie=ie)) + + return self.playlist_result(entries, course_id, title) diff --git a/youtube_dl/extractor/seeker.py b/youtube_dl/extractor/seeker.py index 3b9c65e..7872dc8 100644 --- a/youtube_dl/extractor/seeker.py +++ b/youtube_dl/extractor/seeker.py @@ -4,34 +4,37 @@ from __future__ import unicode_literals import re from .common import InfoExtractor +from ..utils import ( + get_element_by_class, + strip_or_none, +) class SeekerIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?seeker\.com/(?P<display_id>.*)-(?P<article_id>\d+)\.html' _TESTS = [{ - # player.loadRevision3Item 'url': 'http://www.seeker.com/should-trump-be-required-to-release-his-tax-returns-1833805621.html', - 'md5': '30c1dc4030cc715cf05b423d0947ac18', + 'md5': '897d44bbe0d8986a2ead96de565a92db', 'info_dict': { - 'id': '76243', - 'ext': 'webm', + 'id': 'Elrn3gnY', + 'ext': 'mp4', 'title': 'Should Trump Be Required To Release His Tax Returns?', - 'description': 'Donald Trump has been secretive about his "big," "beautiful" tax returns. So what can we learn if he decides to release them?', - 'uploader': 'Seeker Daily', - 'uploader_id': 'seekerdaily', + 'description': 'md5:41efa8cfa8d627841045eec7b018eb45', + 'timestamp': 1490090165, + 'upload_date': '20170321', } }, { 'url': 'http://www.seeker.com/changes-expected-at-zoos-following-recent-gorilla-lion-shootings-1834116536.html', 'playlist': [ { - 'md5': '83bcd157cab89ad7318dd7b8c9cf1306', + 'md5': '0497b9f20495174be73ae136949707d2', 'info_dict': { - 'id': '67558', + 'id': 'FihYQ8AE', 'ext': 'mp4', 'title': 'The Pros & Cons Of Zoos', - 'description': 'Zoos are often depicted as a terrible place for animals to live, but is there any truth to this?', - 'uploader': 'DNews', - 'uploader_id': 'dnews', + 'description': 'md5:d88f99a8ea8e7d25e6ff77f271b1271c', + 'timestamp': 1490039133, + 'upload_date': '20170320', }, } ], @@ -45,13 +48,11 @@ class SeekerIE(InfoExtractor): def _real_extract(self, url): display_id, article_id = re.match(self._VALID_URL, url).groups() webpage = self._download_webpage(url, display_id) - mobj = re.search(r"player\.loadRevision3Item\('([^']+)'\s*,\s*(\d+)\);", webpage) - if mobj: - playlist_type, playlist_id = mobj.groups() - return self.url_result( - 'revision3:%s:%s' % (playlist_type, playlist_id), 'Revision3Embed', playlist_id) - else: - entries = [self.url_result('revision3:video_id:%s' % video_id, 'Revision3Embed', video_id) for video_id in re.findall( - r'<iframe[^>]+src=[\'"](?:https?:)?//api\.seekernetwork\.com/player/embed\?videoId=(\d+)', webpage)] - return self.playlist_result( - entries, article_id, self._og_search_title(webpage), self._og_search_description(webpage)) + entries = [] + for jwp_id in re.findall(r'data-video-id="([a-zA-Z0-9]{8})"', webpage): + entries.append(self.url_result( + 'jwplatform:' + jwp_id, 'JWPlatform', jwp_id)) + return self.playlist_result( + entries, article_id, + self._og_search_title(webpage), + strip_or_none(get_element_by_class('subtitle__text', webpage)) or self._og_search_description(webpage)) diff --git a/youtube_dl/extractor/servingsys.py b/youtube_dl/extractor/servingsys.py deleted file mode 100644 index c013d67..0000000 --- a/youtube_dl/extractor/servingsys.py +++ /dev/null @@ -1,72 +0,0 @@ -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..utils import ( - int_or_none, -) - - -class ServingSysIE(InfoExtractor): - _VALID_URL = r'https?://(?:[^.]+\.)?serving-sys\.com/BurstingPipe/adServer\.bs\?.*?&pli=(?P<id>[0-9]+)' - - _TEST = { - 'url': 'http://bs.serving-sys.com/BurstingPipe/adServer.bs?cn=is&c=23&pl=VAST&pli=5349193&PluID=0&pos=7135&ord=[timestamp]&cim=1?', - 'info_dict': { - 'id': '5349193', - 'title': 'AdAPPter_Hyundai_demo', - }, - 'playlist': [{ - 'md5': 'baed851342df6846eb8677a60a011a0f', - 'info_dict': { - 'id': '29955898', - 'ext': 'flv', - 'title': 'AdAPPter_Hyundai_demo (1)', - 'duration': 74, - 'tbr': 1378, - 'width': 640, - 'height': 400, - }, - }, { - 'md5': '979b4da2655c4bc2d81aeb915a8c5014', - 'info_dict': { - 'id': '29907998', - 'ext': 'flv', - 'title': 'AdAPPter_Hyundai_demo (2)', - 'duration': 34, - 'width': 854, - 'height': 480, - 'tbr': 516, - }, - }], - 'params': { - 'playlistend': 2, - }, - '_skip': 'Blocked in the US [sic]', - } - - def _real_extract(self, url): - pl_id = self._match_id(url) - vast_doc = self._download_xml(url, pl_id) - - title = vast_doc.find('.//AdTitle').text - media = vast_doc.find('.//MediaFile').text - info_url = self._search_regex(r'&adData=([^&]+)&', media, 'info URL') - - doc = self._download_xml(info_url, pl_id, 'Downloading video info') - entries = [{ - '_type': 'video', - 'id': a.attrib['id'], - 'title': '%s (%s)' % (title, a.attrib['assetID']), - 'url': a.attrib['URL'], - 'duration': int_or_none(a.attrib.get('length')), - 'tbr': int_or_none(a.attrib.get('bitrate')), - 'height': int_or_none(a.attrib.get('height')), - 'width': int_or_none(a.attrib.get('width')), - } for a in doc.findall('.//AdditionalAssets/asset')] - - return { - '_type': 'playlist', - 'id': pl_id, - 'title': title, - 'entries': entries, - } diff --git a/youtube_dl/extractor/shared.py b/youtube_dl/extractor/shared.py index ff575f5..02295d1 100644 --- a/youtube_dl/extractor/shared.py +++ b/youtube_dl/extractor/shared.py @@ -1,13 +1,18 @@ from __future__ import unicode_literals from .common import InfoExtractor -from ..compat import compat_b64decode +from ..compat import ( + compat_b64decode, + compat_urllib_parse_unquote_plus, +) from ..utils import ( determine_ext, ExtractorError, int_or_none, + js_to_json, KNOWN_EXTENSIONS, parse_filesize, + rot47, url_or_none, urlencode_postdata, ) @@ -112,16 +117,22 @@ class VivoIE(SharedBaseIE): webpage, 'filesize', fatal=False)) def _extract_video_url(self, webpage, video_id, url): - def decode_url(encoded_url): + def decode_url_old(encoded_url): return compat_b64decode(encoded_url).decode('utf-8') - stream_url = url_or_none(decode_url(self._search_regex( + stream_url = self._search_regex( r'data-stream\s*=\s*(["\'])(?P<url>(?:(?!\1).)+)\1', webpage, - 'stream url', default=None, group='url'))) + 'stream url', default=None, group='url') + if stream_url: + stream_url = url_or_none(decode_url_old(stream_url)) if stream_url: return stream_url - return self._parse_json( + + def decode_url(encoded_url): + return rot47(compat_urllib_parse_unquote_plus(encoded_url)) + + return decode_url(self._parse_json( self._search_regex( - r'InitializeStream\s*\(\s*(["\'])(?P<url>(?:(?!\1).)+)\1', - webpage, 'stream', group='url'), - video_id, transform_source=decode_url)[0] + r'(?s)InitializeStream\s*\(\s*({.+?})\s*\)\s*;', webpage, + 'stream'), + video_id, transform_source=js_to_json)['source']) diff --git a/youtube_dl/extractor/slideslive.py b/youtube_dl/extractor/slideslive.py index ed84322..d9ea768 100644 --- a/youtube_dl/extractor/slideslive.py +++ b/youtube_dl/extractor/slideslive.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from .common import InfoExtractor -from ..utils import ExtractorError +from ..utils import smuggle_url class SlidesLiveIE(InfoExtractor): @@ -14,9 +14,9 @@ class SlidesLiveIE(InfoExtractor): 'info_dict': { 'id': 'LMtgR8ba0b0', 'ext': 'mp4', - 'title': '38902413: external video', - 'description': '3890241320170925-9-1yd6ech.mp4', - 'uploader': 'SlidesLive Administrator', + 'title': 'GCC IA16 backend', + 'description': 'Watch full version of this video at https://slideslive.com/38902413.', + 'uploader': 'SlidesLive Videos - A', 'uploader_id': 'UC62SdArr41t_-_fX40QCLRw', 'upload_date': '20170925', } @@ -24,16 +24,38 @@ class SlidesLiveIE(InfoExtractor): # video_service_name = youtube 'url': 'https://slideslive.com/38903721/magic-a-scientific-resurrection-of-an-esoteric-legend', 'only_matching': True, + }, { + # video_service_name = url + 'url': 'https://slideslive.com/38922070/learning-transferable-skills-1', + 'only_matching': True, + }, { + # video_service_name = vimeo + 'url': 'https://slideslive.com/38921896/retrospectives-a-venue-for-selfreflection-in-ml-research-3', + 'only_matching': True, }] def _real_extract(self, url): video_id = self._match_id(url) video_data = self._download_json( - url, video_id, headers={'Accept': 'application/json'}) + 'https://ben.slideslive.com/player/' + video_id, video_id) service_name = video_data['video_service_name'].lower() - if service_name == 'youtube': - yt_video_id = video_data['video_service_id'] - return self.url_result(yt_video_id, 'Youtube', video_id=yt_video_id) + assert service_name in ('url', 'vimeo', 'youtube') + service_id = video_data['video_service_id'] + info = { + 'id': video_id, + 'thumbnail': video_data.get('thumbnail'), + 'url': service_id, + } + if service_name == 'url': + info['title'] = video_data['title'] else: - raise ExtractorError( - 'Unsupported service name: {0}'.format(service_name), expected=True) + info.update({ + '_type': 'url_transparent', + 'ie_key': service_name.capitalize(), + 'title': video_data.get('title'), + }) + if service_name == 'vimeo': + info['url'] = smuggle_url( + 'https://player.vimeo.com/video/' + service_id, + {'http_headers': {'Referer': url}}) + return info diff --git a/youtube_dl/extractor/soundcloud.py b/youtube_dl/extractor/soundcloud.py index 05538f3..a0b09f5 100644 --- a/youtube_dl/extractor/soundcloud.py +++ b/youtube_dl/extractor/soundcloud.py @@ -9,16 +9,18 @@ from .common import ( SearchInfoExtractor ) from ..compat import ( + compat_HTTPError, + compat_kwargs, compat_str, compat_urlparse, - compat_urllib_parse_urlencode, ) from ..utils import ( + error_to_compat_str, ExtractorError, float_or_none, + HEADRequest, int_or_none, KNOWN_EXTENSIONS, - merge_dicts, mimetype2ext, str_or_none, try_get, @@ -28,6 +30,30 @@ from ..utils import ( ) +class SoundcloudEmbedIE(InfoExtractor): + _VALID_URL = r'https?://(?:w|player|p)\.soundcloud\.com/player/?.*?\burl=(?P<id>.+)' + _TEST = { + # from https://www.soundi.fi/uutiset/ennakkokuuntelussa-timo-kaukolammen-station-to-station-to-station-julkaisua-juhlitaan-tanaan-g-livelabissa/ + 'url': 'https://w.soundcloud.com/player/?visual=true&url=https%3A%2F%2Fapi.soundcloud.com%2Fplaylists%2F922213810&show_artwork=true&maxwidth=640&maxheight=960&dnt=1&secret_token=s-ziYey', + 'only_matching': True, + } + + @staticmethod + def _extract_urls(webpage): + return [m.group('url') for m in re.finditer( + r'<iframe[^>]+src=(["\'])(?P<url>(?:https?://)?(?:w\.)?soundcloud\.com/player.+?)\1', + webpage)] + + def _real_extract(self, url): + query = compat_urlparse.parse_qs( + compat_urlparse.urlparse(url).query) + api_url = query['url'][0] + secret_token = query.get('secret_token') + if secret_token: + api_url = update_url_query(api_url, {'secret_token': secret_token[0]}) + return self.url_result(api_url) + + class SoundcloudIE(InfoExtractor): """Information extractor for soundcloud.com To access the media, the uid of the song and a stream token @@ -44,9 +70,8 @@ class SoundcloudIE(InfoExtractor): (?!(?:tracks|albums|sets(?:/.+?)?|reposts|likes|spotlight)/?(?:$|[?#])) (?P<title>[\w\d-]+)/? (?P<token>[^?]+?)?(?:[?].*)?$) - |(?:api\.soundcloud\.com/tracks/(?P<track_id>\d+) + |(?:api(?:-v2)?\.soundcloud\.com/tracks/(?P<track_id>\d+) (?:/?\?secret_token=(?P<secret_token>[^&]+))?) - |(?P<player>(?:w|player|p.)\.soundcloud\.com/player/?.*?url=.*) ) ''' IE_NAME = 'soundcloud' @@ -60,6 +85,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Lostin Powers - She so Heavy (SneakPreview) Adrian Ackers Blueprint 1', 'description': 'No Downloads untill we record the finished version this weekend, i was too pumped n i had to post it , earl is prolly gonna b hella p.o\'d', 'uploader': 'E.T. ExTerrestrial Music', + 'uploader_id': '1571244', 'timestamp': 1349920598, 'upload_date': '20121011', 'duration': 143.216, @@ -70,7 +96,7 @@ class SoundcloudIE(InfoExtractor): 'repost_count': int, } }, - # not streamable song + # not streamable song, preview { 'url': 'https://soundcloud.com/the-concept-band/goldrushed-mastered?in=the-concept-band/sets/the-royal-concept-ep', 'info_dict': { @@ -79,6 +105,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Goldrushed', 'description': 'From Stockholm Sweden\r\nPovel / Magnus / Filip / David\r\nwww.theroyalconcept.com', 'uploader': 'The Royal Concept', + 'uploader_id': '9615865', 'timestamp': 1337635207, 'upload_date': '20120521', 'duration': 30, @@ -103,6 +130,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Youtube - Dl Test Video \'\' Ä↭', 'description': 'test chars: \"\'/\\ä↭', 'uploader': 'jaimeMF', + 'uploader_id': '69767071', 'timestamp': 1386604920, 'upload_date': '20131209', 'duration': 9.927, @@ -123,6 +151,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Youtube - Dl Test Video \'\' Ä↭', 'description': 'test chars: \"\'/\\ä↭', 'uploader': 'jaimeMF', + 'uploader_id': '69767071', 'timestamp': 1386604920, 'upload_date': '20131209', 'duration': 9.927, @@ -143,6 +172,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Bus Brakes', 'description': 'md5:0053ca6396e8d2fd7b7e1595ef12ab66', 'uploader': 'oddsamples', + 'uploader_id': '73680509', 'timestamp': 1389232924, 'upload_date': '20140109', 'duration': 17.346, @@ -163,6 +193,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Uplifting Only 238 [No Talking] (incl. Alex Feed Guestmix) (Aug 31, 2017) [wav]', 'description': 'md5:fa20ee0fca76a3d6df8c7e57f3715366', 'uploader': 'Ori Uplift Music', + 'uploader_id': '12563093', 'timestamp': 1504206263, 'upload_date': '20170831', 'duration': 7449.096, @@ -183,6 +214,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Sideways (Prod. Mad Real)', 'description': 'md5:d41d8cd98f00b204e9800998ecf8427e', 'uploader': 'garyvee', + 'uploader_id': '2366352', 'timestamp': 1488152409, 'upload_date': '20170226', 'duration': 207.012, @@ -207,6 +239,7 @@ class SoundcloudIE(InfoExtractor): 'title': 'Mezzo Valzer', 'description': 'md5:4138d582f81866a530317bae316e8b61', 'uploader': 'Giovanni Sarani', + 'uploader_id': '3352531', 'timestamp': 1551394171, 'upload_date': '20190228', 'duration': 180.157, @@ -221,114 +254,124 @@ class SoundcloudIE(InfoExtractor): } ] - _CLIENT_ID = 'BeGVhOrGmfboy1LtiHTQF6Ejpt9ULJCI' + _API_BASE = 'https://api.soundcloud.com/' + _API_V2_BASE = 'https://api-v2.soundcloud.com/' + _BASE_URL = 'https://soundcloud.com/' + _IMAGE_REPL_RE = r'-([0-9a-z]+)\.jpg' + + _ARTWORK_MAP = { + 'mini': 16, + 'tiny': 20, + 'small': 32, + 'badge': 47, + 't67x67': 67, + 'large': 100, + 't300x300': 300, + 'crop': 400, + 't500x500': 500, + 'original': 0, + } - @staticmethod - def _extract_urls(webpage): - return [m.group('url') for m in re.finditer( - r'<iframe[^>]+src=(["\'])(?P<url>(?:https?://)?(?:w\.)?soundcloud\.com/player.+?)\1', - webpage)] + def _store_client_id(self, client_id): + self._downloader.cache.store('soundcloud', 'client_id', client_id) + + def _update_client_id(self): + webpage = self._download_webpage('https://soundcloud.com/', None) + for src in reversed(re.findall(r'<script[^>]+src="([^"]+)"', webpage)): + script = self._download_webpage(src, None, fatal=False) + if script: + client_id = self._search_regex( + r'client_id\s*:\s*"([0-9a-zA-Z]{32})"', + script, 'client id', default=None) + if client_id: + self._CLIENT_ID = client_id + self._store_client_id(client_id) + return + raise ExtractorError('Unable to extract client id') + + def _download_json(self, *args, **kwargs): + non_fatal = kwargs.get('fatal') is False + if non_fatal: + del kwargs['fatal'] + query = kwargs.get('query', {}).copy() + for _ in range(2): + query['client_id'] = self._CLIENT_ID + kwargs['query'] = query + try: + return super(SoundcloudIE, self)._download_json(*args, **compat_kwargs(kwargs)) + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401: + self._store_client_id(None) + self._update_client_id() + continue + elif non_fatal: + self._downloader.report_warning(error_to_compat_str(e)) + return False + raise + + def _real_initialize(self): + self._CLIENT_ID = self._downloader.cache.load('soundcloud', 'client_id') or 'YUKXoArFcqrlQn9tfNHvvyfnDISj04zk' @classmethod def _resolv_url(cls, url): - return 'https://api.soundcloud.com/resolve.json?url=' + url + '&client_id=' + cls._CLIENT_ID + return SoundcloudIE._API_V2_BASE + 'resolve?url=' + url - def _extract_info_dict(self, info, full_title=None, quiet=False, secret_token=None): + def _extract_info_dict(self, info, full_title=None, secret_token=None, version=2): track_id = compat_str(info['id']) title = info['title'] - name = full_title or track_id - if quiet: - self.report_extraction(name) - thumbnail = info.get('artwork_url') or info.get('user', {}).get('avatar_url') - if isinstance(thumbnail, compat_str): - thumbnail = thumbnail.replace('-large', '-t500x500') - username = try_get(info, lambda x: x['user']['username'], compat_str) - - def extract_count(key): - return int_or_none(info.get('%s_count' % key)) - - like_count = extract_count('favoritings') - if like_count is None: - like_count = extract_count('likes') - - result = { - 'id': track_id, - 'uploader': username, - 'timestamp': unified_timestamp(info.get('created_at')), - 'title': title, - 'description': info.get('description'), - 'thumbnail': thumbnail, - 'duration': float_or_none(info.get('duration'), 1000), - 'webpage_url': info.get('permalink_url'), - 'license': info.get('license'), - 'view_count': extract_count('playback'), - 'like_count': like_count, - 'comment_count': extract_count('comment'), - 'repost_count': extract_count('reposts'), - 'genre': info.get('genre'), - } + track_base_url = self._API_BASE + 'tracks/%s' % track_id format_urls = set() formats = [] query = {'client_id': self._CLIENT_ID} - if secret_token is not None: + if secret_token: query['secret_token'] = secret_token - if info.get('downloadable', False): - # We can build a direct link to the song + + if info.get('downloadable') and info.get('has_downloads_left'): format_url = update_url_query( - 'https://api.soundcloud.com/tracks/%s/download' % track_id, query) + info.get('download_url') or track_base_url + '/download', query) format_urls.add(format_url) + if version == 2: + v1_info = self._download_json( + track_base_url, track_id, query=query, fatal=False) or {} + else: + v1_info = info formats.append({ 'format_id': 'download', - 'ext': info.get('original_format', 'mp3'), + 'ext': v1_info.get('original_format') or 'mp3', + 'filesize': int_or_none(v1_info.get('original_content_size')), 'url': format_url, - 'vcodec': 'none', 'preference': 10, }) - # Old API, does not work for some tracks (e.g. - # https://soundcloud.com/giovannisarani/mezzo-valzer) - format_dict = self._download_json( - 'https://api.soundcloud.com/i1/tracks/%s/streams' % track_id, - track_id, 'Downloading track url', query=query, fatal=False) - - if format_dict: - for key, stream_url in format_dict.items(): - if stream_url in format_urls: - continue - format_urls.add(stream_url) - ext, abr = 'mp3', None - mobj = re.search(r'_([^_]+)_(\d+)_url', key) - if mobj: - ext, abr = mobj.groups() - abr = int(abr) - if key.startswith('http'): - stream_formats = [{ - 'format_id': key, - 'ext': ext, - 'url': stream_url, - }] - elif key.startswith('rtmp'): - # The url doesn't have an rtmp app, we have to extract the playpath - url, path = stream_url.split('mp3:', 1) - stream_formats = [{ - 'format_id': key, - 'url': url, - 'play_path': 'mp3:' + path, - 'ext': 'flv', - }] - elif key.startswith('hls'): - stream_formats = self._extract_m3u8_formats( - stream_url, track_id, ext, entry_protocol='m3u8_native', - m3u8_id=key, fatal=False) - else: - continue - - if abr: - for f in stream_formats: - f['abr'] = abr + def invalid_url(url): + return not url or url in format_urls - formats.extend(stream_formats) + def add_format(f, protocol, is_preview=False): + mobj = re.search(r'\.(?P<abr>\d+)\.(?P<ext>[0-9a-z]{3,4})(?=[/?])', stream_url) + if mobj: + for k, v in mobj.groupdict().items(): + if not f.get(k): + f[k] = v + format_id_list = [] + if protocol: + format_id_list.append(protocol) + for k in ('ext', 'abr'): + v = f.get(k) + if v: + format_id_list.append(v) + preview = is_preview or re.search(r'/(?:preview|playlist)/0/30/', f['url']) + if preview: + format_id_list.append('preview') + abr = f.get('abr') + if abr: + f['abr'] = int(abr) + f.update({ + 'format_id': '_'.join(format_id_list), + 'protocol': 'm3u8_native' if protocol == 'hls' else 'http', + 'preference': -10 if preview else None, + }) + formats.append(f) # New API transcodings = try_get( @@ -340,126 +383,161 @@ class SoundcloudIE(InfoExtractor): if not format_url: continue stream = self._download_json( - update_url_query(format_url, query), track_id, fatal=False) + format_url, track_id, query=query, fatal=False) if not isinstance(stream, dict): continue stream_url = url_or_none(stream.get('url')) - if not stream_url: - continue - if stream_url in format_urls: + if invalid_url(stream_url): continue format_urls.add(stream_url) - protocol = try_get(t, lambda x: x['format']['protocol'], compat_str) + stream_format = t.get('format') or {} + protocol = stream_format.get('protocol') if protocol != 'hls' and '/hls' in format_url: protocol = 'hls' ext = None preset = str_or_none(t.get('preset')) if preset: ext = preset.split('_')[0] - if ext not in KNOWN_EXTENSIONS: - mimetype = try_get( - t, lambda x: x['format']['mime_type'], compat_str) - ext = mimetype2ext(mimetype) or 'mp3' - format_id_list = [] - if protocol: - format_id_list.append(protocol) - format_id_list.append(ext) - format_id = '_'.join(format_id_list) - formats.append({ + if ext not in KNOWN_EXTENSIONS: + ext = mimetype2ext(stream_format.get('mime_type')) + add_format({ 'url': stream_url, - 'format_id': format_id, 'ext': ext, - 'protocol': 'm3u8_native' if protocol == 'hls' else 'http', - }) + }, 'http' if protocol == 'progressive' else protocol, + t.get('snipped') or '/preview/' in format_url) + + if not formats: + # Old API, does not work for some tracks (e.g. + # https://soundcloud.com/giovannisarani/mezzo-valzer) + # and might serve preview URLs (e.g. + # http://www.soundcloud.com/snbrn/ele) + format_dict = self._download_json( + track_base_url + '/streams', track_id, + 'Downloading track url', query=query, fatal=False) or {} + + for key, stream_url in format_dict.items(): + if invalid_url(stream_url): + continue + format_urls.add(stream_url) + mobj = re.search(r'(http|hls)_([^_]+)_(\d+)_url', key) + if mobj: + protocol, ext, abr = mobj.groups() + add_format({ + 'abr': abr, + 'ext': ext, + 'url': stream_url, + }, protocol) if not formats: # We fallback to the stream_url in the original info, this # cannot be always used, sometimes it can give an HTTP 404 error - formats.append({ - 'format_id': 'fallback', - 'url': update_url_query(info['stream_url'], query), - 'ext': 'mp3', - }) - self._check_formats(formats, track_id) + urlh = self._request_webpage( + HEADRequest(info.get('stream_url') or track_base_url + '/stream'), + track_id, query=query, fatal=False) + if urlh: + stream_url = urlh.geturl() + if not invalid_url(stream_url): + add_format({'url': stream_url}, 'http') for f in formats: f['vcodec'] = 'none' self._sort_formats(formats) - result['formats'] = formats - return result + user = info.get('user') or {} + + thumbnails = [] + artwork_url = info.get('artwork_url') + thumbnail = artwork_url or user.get('avatar_url') + if isinstance(thumbnail, compat_str): + if re.search(self._IMAGE_REPL_RE, thumbnail): + for image_id, size in self._ARTWORK_MAP.items(): + i = { + 'id': image_id, + 'url': re.sub(self._IMAGE_REPL_RE, '-%s.jpg' % image_id, thumbnail), + } + if image_id == 'tiny' and not artwork_url: + size = 18 + elif image_id == 'original': + i['preference'] = 10 + if size: + i.update({ + 'width': size, + 'height': size, + }) + thumbnails.append(i) + else: + thumbnails = [{'url': thumbnail}] + + def extract_count(key): + return int_or_none(info.get('%s_count' % key)) + + return { + 'id': track_id, + 'uploader': user.get('username'), + 'uploader_id': str_or_none(user.get('id')) or user.get('permalink'), + 'uploader_url': user.get('permalink_url'), + 'timestamp': unified_timestamp(info.get('created_at')), + 'title': title, + 'description': info.get('description'), + 'thumbnails': thumbnails, + 'duration': float_or_none(info.get('duration'), 1000), + 'webpage_url': info.get('permalink_url'), + 'license': info.get('license'), + 'view_count': extract_count('playback'), + 'like_count': extract_count('favoritings') or extract_count('likes'), + 'comment_count': extract_count('comment'), + 'repost_count': extract_count('reposts'), + 'genre': info.get('genre'), + 'formats': formats + } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url, flags=re.VERBOSE) - if mobj is None: - raise ExtractorError('Invalid URL: %s' % url) + mobj = re.match(self._VALID_URL, url) track_id = mobj.group('track_id') - new_info = {} - if track_id is not None: - info_json_url = 'https://api.soundcloud.com/tracks/' + track_id + '.json?client_id=' + self._CLIENT_ID + query = {} + if track_id: + info_json_url = self._API_V2_BASE + 'tracks/' + track_id full_title = track_id token = mobj.group('secret_token') if token: - info_json_url += '&secret_token=' + token - elif mobj.group('player'): - query = compat_urlparse.parse_qs(compat_urlparse.urlparse(url).query) - real_url = query['url'][0] - # If the token is in the query of the original url we have to - # manually add it - if 'secret_token' in query: - real_url += '?secret_token=' + query['secret_token'][0] - return self.url_result(real_url) + query['secret_token'] = token else: - # extract uploader (which is in the url) - uploader = mobj.group('uploader') - # extract simple title (uploader + slug of song title) - slug_title = mobj.group('title') + full_title = resolve_title = '%s/%s' % mobj.group('uploader', 'title') token = mobj.group('token') - full_title = resolve_title = '%s/%s' % (uploader, slug_title) if token: resolve_title += '/%s' % token + info_json_url = self._resolv_url(self._BASE_URL + resolve_title) - webpage = self._download_webpage(url, full_title, fatal=False) - if webpage: - entries = self._parse_json( - self._search_regex( - r'var\s+c\s*=\s*(\[.+?\])\s*,\s*o\s*=Date\b', webpage, - 'data', default='[]'), full_title, fatal=False) - if entries: - for e in entries: - if not isinstance(e, dict): - continue - if e.get('id') != 67: - continue - data = try_get(e, lambda x: x['data'][0], dict) - if data: - new_info = data - break - info_json_url = self._resolv_url( - 'https://soundcloud.com/%s' % resolve_title) - - # Contains some additional info missing from new_info + version = 2 info = self._download_json( - info_json_url, full_title, 'Downloading info JSON') + info_json_url, full_title, 'Downloading info JSON', query=query, fatal=False) + if not info: + info = self._download_json( + info_json_url.replace(self._API_V2_BASE, self._API_BASE), + full_title, 'Downloading info JSON', query=query) + version = 1 - return self._extract_info_dict( - merge_dicts(info, new_info), full_title, secret_token=token) + return self._extract_info_dict(info, full_title, token, version) class SoundcloudPlaylistBaseIE(SoundcloudIE): - @staticmethod - def _extract_id(e): - return compat_str(e['id']) if e.get('id') else None - - def _extract_track_entries(self, tracks): - return [ - self.url_result( - track['permalink_url'], SoundcloudIE.ie_key(), - video_id=self._extract_id(track)) - for track in tracks if track.get('permalink_url')] + def _extract_track_entries(self, tracks, token=None): + entries = [] + for track in tracks: + track_id = str_or_none(track.get('id')) + url = track.get('permalink_url') + if not url: + if not track_id: + continue + url = self._API_V2_BASE + 'tracks/' + track_id + if token: + url += '?secret_token=' + token + entries.append(self.url_result( + url, SoundcloudIE.ie_key(), track_id)) + return entries class SoundcloudSetIE(SoundcloudPlaylistBaseIE): @@ -480,54 +558,41 @@ class SoundcloudSetIE(SoundcloudPlaylistBaseIE): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) - # extract uploader (which is in the url) - uploader = mobj.group('uploader') - # extract simple title (uploader + slug of song title) - slug_title = mobj.group('slug_title') - full_title = '%s/sets/%s' % (uploader, slug_title) - url = 'https://soundcloud.com/%s/sets/%s' % (uploader, slug_title) - + full_title = '%s/sets/%s' % mobj.group('uploader', 'slug_title') token = mobj.group('token') if token: full_title += '/' + token - url += '/' + token - resolv_url = self._resolv_url(url) - info = self._download_json(resolv_url, full_title) + info = self._download_json(self._resolv_url( + self._BASE_URL + full_title), full_title) if 'errors' in info: msgs = (compat_str(err['error_message']) for err in info['errors']) raise ExtractorError('unable to download video webpage: %s' % ','.join(msgs)) - entries = self._extract_track_entries(info['tracks']) + entries = self._extract_track_entries(info['tracks'], token) - return { - '_type': 'playlist', - 'entries': entries, - 'id': '%s' % info['id'], - 'title': info['title'], - } + return self.playlist_result( + entries, str_or_none(info.get('id')), info.get('title')) class SoundcloudPagedPlaylistBaseIE(SoundcloudPlaylistBaseIE): - _API_V2_BASE = 'https://api-v2.soundcloud.com' - def _extract_playlist(self, base_url, playlist_id, playlist_title): COMMON_QUERY = { - 'limit': 50, - 'client_id': self._CLIENT_ID, + 'limit': 2000000000, 'linked_partitioning': '1', } query = COMMON_QUERY.copy() query['offset'] = 0 - next_href = base_url + '?' + compat_urllib_parse_urlencode(query) + next_href = base_url entries = [] for i in itertools.count(): response = self._download_json( - next_href, playlist_id, 'Downloading track page %s' % (i + 1)) + next_href, playlist_id, + 'Downloading track page %s' % (i + 1), query=query) collection = response['collection'] @@ -546,9 +611,8 @@ class SoundcloudPagedPlaylistBaseIE(SoundcloudPlaylistBaseIE): continue return self.url_result( permalink_url, - ie=SoundcloudIE.ie_key() if SoundcloudIE.suitable(permalink_url) else None, - video_id=self._extract_id(cand), - video_title=cand.get('title')) + SoundcloudIE.ie_key() if SoundcloudIE.suitable(permalink_url) else None, + str_or_none(cand.get('id')), cand.get('title')) for e in collection: entry = resolve_entry((e, e.get('track'), e.get('playlist'))) @@ -559,11 +623,10 @@ class SoundcloudPagedPlaylistBaseIE(SoundcloudPlaylistBaseIE): if not next_href: break - parsed_next_href = compat_urlparse.urlparse(response['next_href']) - qs = compat_urlparse.parse_qs(parsed_next_href.query) - qs.update(COMMON_QUERY) - next_href = compat_urlparse.urlunparse( - parsed_next_href._replace(query=compat_urllib_parse_urlencode(qs, True))) + next_href = response['next_href'] + parsed_next_href = compat_urlparse.urlparse(next_href) + query = compat_urlparse.parse_qs(parsed_next_href.query) + query.update(COMMON_QUERY) return { '_type': 'playlist', @@ -609,7 +672,7 @@ class SoundcloudUserIE(SoundcloudPagedPlaylistBaseIE): 'url': 'https://soundcloud.com/jcv246/sets', 'info_dict': { 'id': '12982173', - 'title': 'Jordi / cv (Playlists)', + 'title': 'Jordi / cv (Sets)', }, 'playlist_mincount': 2, }, { @@ -636,39 +699,29 @@ class SoundcloudUserIE(SoundcloudPagedPlaylistBaseIE): }] _BASE_URL_MAP = { - 'all': '%s/stream/users/%%s' % SoundcloudPagedPlaylistBaseIE._API_V2_BASE, - 'tracks': '%s/users/%%s/tracks' % SoundcloudPagedPlaylistBaseIE._API_V2_BASE, - 'albums': '%s/users/%%s/albums' % SoundcloudPagedPlaylistBaseIE._API_V2_BASE, - 'sets': '%s/users/%%s/playlists' % SoundcloudPagedPlaylistBaseIE._API_V2_BASE, - 'reposts': '%s/stream/users/%%s/reposts' % SoundcloudPagedPlaylistBaseIE._API_V2_BASE, - 'likes': '%s/users/%%s/likes' % SoundcloudPagedPlaylistBaseIE._API_V2_BASE, - 'spotlight': '%s/users/%%s/spotlight' % SoundcloudPagedPlaylistBaseIE._API_V2_BASE, - } - - _TITLE_MAP = { - 'all': 'All', - 'tracks': 'Tracks', - 'albums': 'Albums', - 'sets': 'Playlists', - 'reposts': 'Reposts', - 'likes': 'Likes', - 'spotlight': 'Spotlight', + 'all': 'stream/users/%s', + 'tracks': 'users/%s/tracks', + 'albums': 'users/%s/albums', + 'sets': 'users/%s/playlists', + 'reposts': 'stream/users/%s/reposts', + 'likes': 'users/%s/likes', + 'spotlight': 'users/%s/spotlight', } def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) uploader = mobj.group('user') - url = 'https://soundcloud.com/%s/' % uploader - resolv_url = self._resolv_url(url) user = self._download_json( - resolv_url, uploader, 'Downloading user info') + self._resolv_url(self._BASE_URL + uploader), + uploader, 'Downloading user info') resource = mobj.group('rsrc') or 'all' return self._extract_playlist( - self._BASE_URL_MAP[resource] % user['id'], compat_str(user['id']), - '%s (%s)' % (user['username'], self._TITLE_MAP[resource])) + self._API_V2_BASE + self._BASE_URL_MAP[resource] % user['id'], + str_or_none(user.get('id')), + '%s (%s)' % (user['username'], resource.capitalize())) class SoundcloudTrackStationIE(SoundcloudPagedPlaylistBaseIE): @@ -678,7 +731,7 @@ class SoundcloudTrackStationIE(SoundcloudPagedPlaylistBaseIE): 'url': 'https://soundcloud.com/stations/track/officialsundial/your-text', 'info_dict': { 'id': '286017854', - 'title': 'Track station: your-text', + 'title': 'Track station: your text', }, 'playlist_mincount': 47, }] @@ -686,19 +739,17 @@ class SoundcloudTrackStationIE(SoundcloudPagedPlaylistBaseIE): def _real_extract(self, url): track_name = self._match_id(url) - webpage = self._download_webpage(url, track_name) - + track = self._download_json(self._resolv_url(url), track_name) track_id = self._search_regex( - r'soundcloud:track-stations:(\d+)', webpage, 'track id') + r'soundcloud:track-stations:(\d+)', track['id'], 'track id') return self._extract_playlist( - '%s/stations/soundcloud:track-stations:%s/tracks' - % (self._API_V2_BASE, track_id), - track_id, 'Track station: %s' % track_name) + self._API_V2_BASE + 'stations/%s/tracks' % track['id'], + track_id, 'Track station: %s' % track['title']) class SoundcloudPlaylistIE(SoundcloudPlaylistBaseIE): - _VALID_URL = r'https?://api\.soundcloud\.com/playlists/(?P<id>[0-9]+)(?:/?\?secret_token=(?P<token>[^&]+?))?$' + _VALID_URL = r'https?://api(?:-v2)?\.soundcloud\.com/playlists/(?P<id>[0-9]+)(?:/?\?secret_token=(?P<token>[^&]+?))?$' IE_NAME = 'soundcloud:playlist' _TESTS = [{ 'url': 'https://api.soundcloud.com/playlists/4110309', @@ -713,29 +764,20 @@ class SoundcloudPlaylistIE(SoundcloudPlaylistBaseIE): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) playlist_id = mobj.group('id') - base_url = '%s//api.soundcloud.com/playlists/%s.json?' % (self.http_scheme(), playlist_id) - data_dict = { - 'client_id': self._CLIENT_ID, - } + query = {} token = mobj.group('token') - if token: - data_dict['secret_token'] = token + query['secret_token'] = token - data = compat_urllib_parse_urlencode(data_dict) data = self._download_json( - base_url + data, playlist_id, 'Downloading playlist') + self._API_V2_BASE + 'playlists/' + playlist_id, + playlist_id, 'Downloading playlist', query=query) - entries = self._extract_track_entries(data['tracks']) + entries = self._extract_track_entries(data['tracks'], token) - return { - '_type': 'playlist', - 'id': playlist_id, - 'title': data.get('title'), - 'description': data.get('description'), - 'entries': entries, - } + return self.playlist_result( + entries, playlist_id, data.get('title'), data.get('description')) class SoundcloudSearchIE(SearchInfoExtractor, SoundcloudIE): @@ -753,18 +795,17 @@ class SoundcloudSearchIE(SearchInfoExtractor, SoundcloudIE): _SEARCH_KEY = 'scsearch' _MAX_RESULTS_PER_PAGE = 200 _DEFAULT_RESULTS_PER_PAGE = 50 - _API_V2_BASE = 'https://api-v2.soundcloud.com' def _get_collection(self, endpoint, collection_id, **query): limit = min( query.get('limit', self._DEFAULT_RESULTS_PER_PAGE), self._MAX_RESULTS_PER_PAGE) - query['limit'] = limit - query['client_id'] = self._CLIENT_ID - query['linked_partitioning'] = '1' - query['offset'] = 0 - data = compat_urllib_parse_urlencode(query) - next_url = '{0}{1}?{2}'.format(self._API_V2_BASE, endpoint, data) + query.update({ + 'limit': limit, + 'linked_partitioning': 1, + 'offset': 0, + }) + next_url = update_url_query(self._API_V2_BASE + endpoint, query) collected_results = 0 @@ -791,5 +832,5 @@ class SoundcloudSearchIE(SearchInfoExtractor, SoundcloudIE): break def _get_n_results(self, query, n): - tracks = self._get_collection('/search/tracks', query, limit=n, q=query) + tracks = self._get_collection('search/tracks', query, limit=n, q=query) return self.playlist_result(tracks, playlist_title=query) diff --git a/youtube_dl/extractor/spankbang.py b/youtube_dl/extractor/spankbang.py index e040ada..61ca902 100644 --- a/youtube_dl/extractor/spankbang.py +++ b/youtube_dl/extractor/spankbang.py @@ -4,6 +4,7 @@ import re from .common import InfoExtractor from ..utils import ( + determine_ext, ExtractorError, merge_dicts, orderedSet, @@ -64,7 +65,7 @@ class SpankBangIE(InfoExtractor): url.replace('/%s/embed' % video_id, '/%s/video' % video_id), video_id, headers={'Cookie': 'country=US'}) - if re.search(r'<[^>]+\bid=["\']video_removed', webpage): + if re.search(r'<[^>]+\b(?:id|class)=["\']video_removed', webpage): raise ExtractorError( 'Video %s is not available' % video_id, expected=True) @@ -75,11 +76,20 @@ class SpankBangIE(InfoExtractor): if not f_url: return f = parse_resolution(format_id) - f.update({ - 'url': f_url, - 'format_id': format_id, - }) - formats.append(f) + ext = determine_ext(f_url) + if format_id.startswith('m3u8') or ext == 'm3u8': + formats.extend(self._extract_m3u8_formats( + f_url, video_id, 'mp4', entry_protocol='m3u8_native', + m3u8_id='hls', fatal=False)) + elif format_id.startswith('mpd') or ext == 'mpd': + formats.extend(self._extract_mpd_formats( + f_url, video_id, mpd_id='dash', fatal=False)) + elif ext == 'mp4' or f.get('width') or f.get('height'): + f.update({ + 'url': f_url, + 'format_id': format_id, + }) + formats.append(f) STREAM_URL_PREFIX = 'stream_url_' @@ -93,28 +103,22 @@ class SpankBangIE(InfoExtractor): r'data-streamkey\s*=\s*(["\'])(?P<value>(?:(?!\1).)+)\1', webpage, 'stream key', group='value') - sb_csrf_session = self._get_cookies( - 'https://spankbang.com')['sb_csrf_session'].value - stream = self._download_json( 'https://spankbang.com/api/videos/stream', video_id, 'Downloading stream JSON', data=urlencode_postdata({ 'id': stream_key, 'data': 0, - 'sb_csrf_session': sb_csrf_session, }), headers={ 'Referer': url, - 'X-CSRFToken': sb_csrf_session, + 'X-Requested-With': 'XMLHttpRequest', }) for format_id, format_url in stream.items(): - if format_id.startswith(STREAM_URL_PREFIX): - if format_url and isinstance(format_url, list): - format_url = format_url[0] - extract_format( - format_id[len(STREAM_URL_PREFIX):], format_url) + if format_url and isinstance(format_url, list): + format_url = format_url[0] + extract_format(format_id, format_url) - self._sort_formats(formats) + self._sort_formats(formats, field_preference=('preference', 'height', 'width', 'fps', 'tbr', 'format_id')) info = self._search_json_ld(webpage, video_id, default={}) diff --git a/youtube_dl/extractor/srmediathek.py b/youtube_dl/extractor/srmediathek.py index 28baf90..359dada 100644 --- a/youtube_dl/extractor/srmediathek.py +++ b/youtube_dl/extractor/srmediathek.py @@ -1,14 +1,14 @@ # coding: utf-8 from __future__ import unicode_literals -from .ard import ARDMediathekIE +from .ard import ARDMediathekBaseIE from ..utils import ( ExtractorError, get_element_by_attribute, ) -class SRMediathekIE(ARDMediathekIE): +class SRMediathekIE(ARDMediathekBaseIE): IE_NAME = 'sr:mediathek' IE_DESC = 'Saarländischer Rundfunk' _VALID_URL = r'https?://sr-mediathek(?:\.sr-online)?\.de/index\.php\?.*?&id=(?P<id>[0-9]+)' diff --git a/youtube_dl/extractor/streamango.py b/youtube_dl/extractor/streamango.py deleted file mode 100644 index f1e17dd..0000000 --- a/youtube_dl/extractor/streamango.py +++ /dev/null @@ -1,128 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..compat import compat_chr -from ..utils import ( - determine_ext, - ExtractorError, - int_or_none, - js_to_json, -) - - -class StreamangoIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?(?:streamango\.com|fruithosts\.net|streamcherry\.com)/(?:f|embed)/(?P<id>[^/?#&]+)' - _TESTS = [{ - 'url': 'https://streamango.com/f/clapasobsptpkdfe/20170315_150006_mp4', - 'md5': 'e992787515a182f55e38fc97588d802a', - 'info_dict': { - 'id': 'clapasobsptpkdfe', - 'ext': 'mp4', - 'title': '20170315_150006.mp4', - } - }, { - # no og:title - 'url': 'https://streamango.com/embed/foqebrpftarclpob/asdf_asd_2_mp4', - 'info_dict': { - 'id': 'foqebrpftarclpob', - 'ext': 'mp4', - 'title': 'foqebrpftarclpob', - }, - 'params': { - 'skip_download': True, - }, - 'skip': 'gone', - }, { - 'url': 'https://streamango.com/embed/clapasobsptpkdfe/20170315_150006_mp4', - 'only_matching': True, - }, { - 'url': 'https://fruithosts.net/f/mreodparcdcmspsm/w1f1_r4lph_2018_brrs_720p_latino_mp4', - 'only_matching': True, - }, { - 'url': 'https://streamcherry.com/f/clapasobsptpkdfe/', - 'only_matching': True, - }] - - def _real_extract(self, url): - def decrypt_src(encoded, val): - ALPHABET = '=/+9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA' - encoded = re.sub(r'[^A-Za-z0-9+/=]', '', encoded) - decoded = '' - sm = [None] * 4 - i = 0 - str_len = len(encoded) - while i < str_len: - for j in range(4): - sm[j % 4] = ALPHABET.index(encoded[i]) - i += 1 - char_code = ((sm[0] << 0x2) | (sm[1] >> 0x4)) ^ val - decoded += compat_chr(char_code) - if sm[2] != 0x40: - char_code = ((sm[1] & 0xf) << 0x4) | (sm[2] >> 0x2) - decoded += compat_chr(char_code) - if sm[3] != 0x40: - char_code = ((sm[2] & 0x3) << 0x6) | sm[3] - decoded += compat_chr(char_code) - return decoded - - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - - title = self._og_search_title(webpage, default=video_id) - - formats = [] - for format_ in re.findall(r'({[^}]*\bsrc\s*:\s*[^}]*})', webpage): - mobj = re.search(r'(src\s*:\s*[^(]+\(([^)]*)\)[\s,]*)', format_) - if mobj is None: - continue - - format_ = format_.replace(mobj.group(0), '') - - video = self._parse_json( - format_, video_id, transform_source=js_to_json, - fatal=False) or {} - - mobj = re.search( - r'([\'"])(?P<src>(?:(?!\1).)+)\1\s*,\s*(?P<val>\d+)', - mobj.group(1)) - if mobj is None: - continue - - src = decrypt_src(mobj.group('src'), int_or_none(mobj.group('val'))) - if not src: - continue - - ext = determine_ext(src, default_ext=None) - if video.get('type') == 'application/dash+xml' or ext == 'mpd': - formats.extend(self._extract_mpd_formats( - src, video_id, mpd_id='dash', fatal=False)) - else: - formats.append({ - 'url': src, - 'ext': ext or 'mp4', - 'width': int_or_none(video.get('width')), - 'height': int_or_none(video.get('height')), - 'tbr': int_or_none(video.get('bitrate')), - }) - - if not formats: - error = self._search_regex( - r'<p[^>]+\bclass=["\']lead[^>]+>(.+?)</p>', webpage, - 'error', default=None) - if not error and '>Sorry' in webpage: - error = 'Video %s is not available' % video_id - if error: - raise ExtractorError(error, expected=True) - - self._sort_formats(formats) - - return { - 'id': video_id, - 'url': url, - 'title': title, - 'formats': formats, - } diff --git a/youtube_dl/extractor/stretchinternet.py b/youtube_dl/extractor/stretchinternet.py index ae2ac1b..4dbead2 100644 --- a/youtube_dl/extractor/stretchinternet.py +++ b/youtube_dl/extractor/stretchinternet.py @@ -5,44 +5,28 @@ from ..utils import int_or_none class StretchInternetIE(InfoExtractor): - _VALID_URL = r'https?://portal\.stretchinternet\.com/[^/]+/portal\.htm\?.*?\beventId=(?P<id>\d+)' + _VALID_URL = r'https?://portal\.stretchinternet\.com/[^/]+/(?:portal|full)\.htm\?.*?\beventId=(?P<id>\d+)' _TEST = { - 'url': 'https://portal.stretchinternet.com/umary/portal.htm?eventId=313900&streamType=video', + 'url': 'https://portal.stretchinternet.com/umary/portal.htm?eventId=573272&streamType=video', 'info_dict': { - 'id': '313900', + 'id': '573272', 'ext': 'mp4', - 'title': 'Augustana (S.D.) Baseball vs University of Mary', - 'description': 'md5:7578478614aae3bdd4a90f578f787438', - 'timestamp': 1490468400, - 'upload_date': '20170325', + 'title': 'University of Mary Wrestling vs. Upper Iowa', + 'timestamp': 1575668361, + 'upload_date': '20191206', } } def _real_extract(self, url): video_id = self._match_id(url) - stream = self._download_json( - 'https://neo-client.stretchinternet.com/streamservice/v1/media/stream/v%s' - % video_id, video_id) - - video_url = 'https://%s' % stream['source'] - event = self._download_json( - 'https://neo-client.stretchinternet.com/portal-ws/getEvent.json', - video_id, query={ - 'clientID': 99997, - 'eventID': video_id, - 'token': 'asdf', - })['event'] - - title = event.get('title') or event['mobileTitle'] - description = event.get('customText') - timestamp = int_or_none(event.get('longtime')) + 'https://api.stretchinternet.com/trinity/event/tcg/' + video_id, + video_id)[0] return { 'id': video_id, - 'title': title, - 'description': description, - 'timestamp': timestamp, - 'url': video_url, + 'title': event['title'], + 'timestamp': int_or_none(event.get('dateCreated'), 1000), + 'url': 'https://' + event['media'][0]['url'], } diff --git a/youtube_dl/extractor/stv.py b/youtube_dl/extractor/stv.py index ccb074c..bae8b71 100644 --- a/youtube_dl/extractor/stv.py +++ b/youtube_dl/extractor/stv.py @@ -4,15 +4,10 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from ..compat import ( - compat_parse_qs, - compat_urllib_parse_urlparse -) from ..utils import ( - extract_attributes, + compat_str, float_or_none, int_or_none, - str_or_none, ) @@ -20,20 +15,20 @@ class STVPlayerIE(InfoExtractor): IE_NAME = 'stv:player' _VALID_URL = r'https?://player\.stv\.tv/(?P<type>episode|video)/(?P<id>[a-z0-9]{4})' _TEST = { - 'url': 'https://player.stv.tv/video/7srz/victoria/interview-with-the-cast-ahead-of-new-victoria/', - 'md5': '2ad867d4afd641fa14187596e0fbc91b', + 'url': 'https://player.stv.tv/video/4gwd/emmerdale/60-seconds-on-set-with-laura-norton/', + 'md5': '5adf9439c31d554f8be0707c7abe7e0a', 'info_dict': { - 'id': '6016487034001', + 'id': '5333973339001', 'ext': 'mp4', - 'upload_date': '20190321', - 'title': 'Interview with the cast ahead of new Victoria', - 'description': 'Nell Hudson and Lily Travers tell us what to expect in the new season of Victoria.', - 'timestamp': 1553179628, + 'upload_date': '20170301', + 'title': '60 seconds on set with Laura Norton', + 'description': "How many questions can Laura - a.k.a Kerry Wyatt - answer in 60 seconds? Let\'s find out!", + 'timestamp': 1488388054, 'uploader_id': '1486976045', }, 'skip': 'this resource is unavailable outside of the UK', } - _PUBLISHER_ID = '1486976045' + BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/1486976045/default_default/index.html?videoId=%s' _PTYPE_MAP = { 'episode': 'episodes', 'video': 'shortform', @@ -41,54 +36,32 @@ class STVPlayerIE(InfoExtractor): def _real_extract(self, url): ptype, video_id = re.match(self._VALID_URL, url).groups() - webpage = self._download_webpage(url, video_id) + resp = self._download_json( + 'https://player.api.stv.tv/v1/%s/%s' % (self._PTYPE_MAP[ptype], video_id), + video_id) - qs = compat_parse_qs(compat_urllib_parse_urlparse(self._search_regex( - r'itemprop="embedURL"[^>]+href="([^"]+)', - webpage, 'embed URL', default=None)).query) - publisher_id = qs.get('publisherID', [None])[0] or self._PUBLISHER_ID + result = resp['results'] + video = result['video'] + video_id = compat_str(video['id']) - player_attr = extract_attributes(self._search_regex( - r'(<[^>]+class="bcplayer"[^>]+>)', webpage, 'player', default=None)) or {} + subtitles = {} + _subtitles = result.get('_subtitles') or {} + for ext, sub_url in _subtitles.items(): + subtitles.setdefault('en', []).append({ + 'ext': 'vtt' if ext == 'webvtt' else ext, + 'url': sub_url, + }) - info = {} - duration = ref_id = series = video_id = None - api_ref_id = player_attr.get('data-player-api-refid') - if api_ref_id: - resp = self._download_json( - 'https://player.api.stv.tv/v1/%s/%s' % (self._PTYPE_MAP[ptype], api_ref_id), - api_ref_id, fatal=False) - if resp: - result = resp.get('results') or {} - video = result.get('video') or {} - video_id = str_or_none(video.get('id')) - ref_id = video.get('guid') - duration = video.get('length') - programme = result.get('programme') or {} - series = programme.get('name') or programme.get('shortName') - subtitles = {} - _subtitles = result.get('_subtitles') or {} - for ext, sub_url in _subtitles.items(): - subtitles.setdefault('en', []).append({ - 'ext': 'vtt' if ext == 'webvtt' else ext, - 'url': sub_url, - }) - info.update({ - 'description': result.get('summary'), - 'subtitles': subtitles, - 'view_count': int_or_none(result.get('views')), - }) - if not video_id: - video_id = qs.get('videoId', [None])[0] or self._search_regex( - r'<link\s+itemprop="url"\s+href="(\d+)"', - webpage, 'video id', default=None) or 'ref:' + (ref_id or player_attr['data-refid']) + programme = result.get('programme') or {} - info.update({ + return { '_type': 'url_transparent', - 'duration': float_or_none(duration or player_attr.get('data-duration'), 1000), 'id': video_id, + 'url': self.BRIGHTCOVE_URL_TEMPLATE % video_id, + 'description': result.get('summary'), + 'duration': float_or_none(video.get('length'), 1000), + 'subtitles': subtitles, + 'view_count': int_or_none(result.get('views')), + 'series': programme.get('name') or programme.get('shortName'), 'ie_key': 'BrightcoveNew', - 'series': series or player_attr.get('data-programme-name'), - 'url': 'http://players.brightcove.net/%s/default_default/index.html?videoId=%s' % (publisher_id, video_id), - }) - return info + } diff --git a/youtube_dl/extractor/teachable.py b/youtube_dl/extractor/teachable.py index c1a9dea..6b7f13b 100644 --- a/youtube_dl/extractor/teachable.py +++ b/youtube_dl/extractor/teachable.py @@ -48,6 +48,16 @@ class TeachableBaseIE(InfoExtractor): 'https://%s/sign_in' % site, None, 'Downloading %s login page' % site) + def is_logged(webpage): + return any(re.search(p, webpage) for p in ( + r'class=["\']user-signout', + r'<a[^>]+\bhref=["\']/sign_out', + r'Log\s+[Oo]ut\s*<')) + + if is_logged(login_page): + self._logged_in = True + return + login_url = compat_str(urlh.geturl()) login_form = self._hidden_inputs(login_page) @@ -78,10 +88,7 @@ class TeachableBaseIE(InfoExtractor): 'Go to https://%s/ and accept.' % (site, site), expected=True) # Successful login - if any(re.search(p, response) for p in ( - r'class=["\']user-signout', - r'<a[^>]+\bhref=["\']/sign_out', - r'>\s*Log out\s*<')): + if is_logged(response): self._logged_in = True return @@ -158,8 +165,12 @@ class TeachableIE(TeachableBaseIE): if any(re.search(p, webpage) for p in ( r'class=["\']lecture-contents-locked', r'>\s*Lecture contents locked', - r'id=["\']lecture-locked')): + r'id=["\']lecture-locked', + # https://academy.tailoredtutors.co.uk/courses/108779/lectures/1955313 + r'class=["\'](?:inner-)?lesson-locked', + r'>LESSON LOCKED<')): self.raise_login_required('Lecture contents locked') + raise ExtractorError('Unable to find video URL') title = self._og_search_title(webpage, default=None) diff --git a/youtube_dl/extractor/teachingchannel.py b/youtube_dl/extractor/teachingchannel.py index e897597..624cdb3 100644 --- a/youtube_dl/extractor/teachingchannel.py +++ b/youtube_dl/extractor/teachingchannel.py @@ -1,35 +1,33 @@ from __future__ import unicode_literals -import re - from .common import InfoExtractor -from .ooyala import OoyalaIE class TeachingChannelIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?teachingchannel\.org/videos/(?P<title>.+)' + _VALID_URL = r'https?://(?:www\.)?teachingchannel\.org/videos?/(?P<id>[^/?&#]+)' _TEST = { 'url': 'https://www.teachingchannel.org/videos/teacher-teaming-evolution', - 'md5': '3d6361864d7cac20b57c8784da17166f', 'info_dict': { - 'id': 'F3bnlzbToeI6pLEfRyrlfooIILUjz4nM', + 'id': '3swwlzkT', 'ext': 'mp4', 'title': 'A History of Teaming', 'description': 'md5:2a9033db8da81f2edffa4c99888140b3', - 'duration': 422.255, + 'duration': 422, + 'upload_date': '20170316', + 'timestamp': 1489691297, }, 'params': { 'skip_download': True, }, - 'add_ie': ['Ooyala'], + 'add_ie': ['JWPlatform'], } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - title = mobj.group('title') - webpage = self._download_webpage(url, title) - ooyala_code = self._search_regex( - r'data-embed-code=\'(.+?)\'', webpage, 'ooyala code') + display_id = self._match_id(url) + webpage = self._download_webpage(url, display_id) + mid = self._search_regex( + r'(?:data-mid=["\']|id=["\']jw-video-player-)([a-zA-Z0-9]{8})', + webpage, 'media id') - return OoyalaIE._build_url_result(ooyala_code) + return self.url_result('jwplatform:' + mid, 'JWPlatform', mid) diff --git a/youtube_dl/extractor/teamcoco.py b/youtube_dl/extractor/teamcoco.py index 7640cf0..5793b71 100644 --- a/youtube_dl/extractor/teamcoco.py +++ b/youtube_dl/extractor/teamcoco.py @@ -84,6 +84,19 @@ class TeamcocoIE(TurnerBaseIE): 'only_matching': True, } ] + _RECORD_TEMPL = '''id + title + teaser + publishOn + thumb { + preview + } + tags { + name + } + duration + turnerMediaId + turnerMediaAuthToken''' def _graphql_call(self, query_template, object_type, object_id): find_object = 'find' + object_type @@ -98,36 +111,36 @@ class TeamcocoIE(TurnerBaseIE): display_id = self._match_id(url) response = self._graphql_call('''{ - %s(slug: "%s") { + %%s(slug: "%%s") { ... on RecordSlug { record { + %s + } + } + ... on PageSlug { + child { id - title - teaser - publishOn - thumb { - preview - } - file { - url - } - tags { - name - } - duration - turnerMediaId - turnerMediaAuthToken } } ... on NotFoundSlug { status } } -}''', 'Slug', display_id) +}''' % self._RECORD_TEMPL, 'Slug', display_id) if response.get('status'): raise ExtractorError('This video is no longer available.', expected=True) - record = response['record'] + child = response.get('child') + if child: + record = self._graphql_call('''{ + %%s(id: "%%s") { + ... on Video { + %s + } + } +}''' % self._RECORD_TEMPL, 'Record', child['id']) + else: + record = response['record'] video_id = record['id'] info = { @@ -150,25 +163,21 @@ class TeamcocoIE(TurnerBaseIE): 'accessTokenType': 'jws', })) else: - d = self._download_json( + video_sources = self._download_json( 'https://teamcoco.com/_truman/d/' + video_id, - video_id, fatal=False) or {} - video_sources = d.get('meta') or {} - if not video_sources: - video_sources = self._graphql_call('''{ - %s(id: "%s") { - src - } -}''', 'RecordVideoSource', video_id) or {} + video_id)['meta']['src'] + if isinstance(video_sources, dict): + video_sources = video_sources.values() formats = [] get_quality = qualities(['low', 'sd', 'hd', 'uhd']) - for format_id, src in video_sources.get('src', {}).items(): + for src in video_sources: if not isinstance(src, dict): continue src_url = src.get('src') if not src_url: continue + format_id = src.get('label') ext = determine_ext(src_url, mimetype2ext(src.get('type'))) if format_id == 'hls' or ext == 'm3u8': # compat_urllib_parse.urljoin does not work here @@ -190,9 +199,6 @@ class TeamcocoIE(TurnerBaseIE): 'format_id': format_id, 'quality': get_quality(format_id), }) - if not formats: - formats = self._extract_m3u8_formats( - record['file']['url'], video_id, 'mp4', fatal=False) self._sort_formats(formats) info['formats'] = formats diff --git a/youtube_dl/extractor/telegraaf.py b/youtube_dl/extractor/telegraaf.py index 0f576c1..2dc0205 100644 --- a/youtube_dl/extractor/telegraaf.py +++ b/youtube_dl/extractor/telegraaf.py @@ -4,21 +4,25 @@ from __future__ import unicode_literals from .common import InfoExtractor from ..utils import ( determine_ext, - remove_end, + int_or_none, + parse_iso8601, + try_get, ) class TelegraafIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?telegraaf\.nl/tv/(?:[^/]+/)+(?P<id>\d+)/[^/]+\.html' + _VALID_URL = r'https?://(?:www\.)?telegraaf\.nl/video/(?P<id>\d+)' _TEST = { - 'url': 'http://www.telegraaf.nl/tv/nieuws/binnenland/24353229/__Tikibad_ontruimd_wegens_brand__.html', + 'url': 'https://www.telegraaf.nl/video/734366489/historisch-scheepswrak-slaat-na-100-jaar-los', 'info_dict': { - 'id': '24353229', + 'id': 'gaMItuoSeUg2', 'ext': 'mp4', - 'title': 'Tikibad ontruimd wegens brand', - 'description': 'md5:05ca046ff47b931f9b04855015e163a4', - 'thumbnail': r're:^https?://.*\.jpg$', - 'duration': 33, + 'title': 'Historisch scheepswrak slaat na 100 jaar los', + 'description': 'md5:6f53b7c4f55596722ac24d6c0ec00cfb', + 'thumbnail': r're:^https?://.*\.jpg', + 'duration': 55, + 'timestamp': 1572805527, + 'upload_date': '20191103', }, 'params': { # m3u8 download @@ -27,23 +31,30 @@ class TelegraafIE(InfoExtractor): } def _real_extract(self, url): - video_id = self._match_id(url) + article_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) + video_id = self._download_json( + 'https://www.telegraaf.nl/graphql', article_id, query={ + 'query': '''{ + article(uid: %s) { + videos { + videoId + } + } +}''' % article_id, + })['data']['article']['videos'][0]['videoId'] - player_url = self._html_search_regex( - r'<iframe[^>]+src="([^"]+")', webpage, 'player URL') - player_page = self._download_webpage( - player_url, video_id, note='Download player webpage') - playlist_url = self._search_regex( - r'playlist\s*:\s*"([^"]+)"', player_page, 'playlist URL') - playlist_data = self._download_json(playlist_url, video_id) + item = self._download_json( + 'https://content.tmgvideo.nl/playlist/item=%s/playlist.json' % video_id, + video_id)['items'][0] + title = item['title'] - item = playlist_data['items'][0] formats = [] - locations = item['locations'] + locations = item.get('locations') or {} for location in locations.get('adaptive', []): - manifest_url = location['src'] + manifest_url = location.get('src') + if not manifest_url: + continue ext = determine_ext(manifest_url) if ext == 'm3u8': formats.extend(self._extract_m3u8_formats( @@ -54,25 +65,25 @@ class TelegraafIE(InfoExtractor): else: self.report_warning('Unknown adaptive format %s' % ext) for location in locations.get('progressive', []): + src = try_get(location, lambda x: x['sources'][0]['src']) + if not src: + continue + label = location.get('label') formats.append({ - 'url': location['sources'][0]['src'], - 'width': location.get('width'), - 'height': location.get('height'), - 'format_id': 'http-%s' % location['label'], + 'url': src, + 'width': int_or_none(location.get('width')), + 'height': int_or_none(location.get('height')), + 'format_id': 'http' + ('-%s' % label if label else ''), }) self._sort_formats(formats) - title = remove_end(self._og_search_title(webpage), ' - VIDEO') - description = self._og_search_description(webpage) - duration = item.get('duration') - thumbnail = item.get('poster') - return { 'id': video_id, 'title': title, - 'description': description, + 'description': item.get('description'), 'formats': formats, - 'duration': duration, - 'thumbnail': thumbnail, + 'duration': int_or_none(item.get('duration')), + 'thumbnail': item.get('poster'), + 'timestamp': parse_iso8601(item.get('datecreated'), ' '), } diff --git a/youtube_dl/extractor/telequebec.py b/youtube_dl/extractor/telequebec.py index 6965c12..ae9f667 100644 --- a/youtube_dl/extractor/telequebec.py +++ b/youtube_dl/extractor/telequebec.py @@ -7,6 +7,7 @@ from ..utils import ( int_or_none, smuggle_url, try_get, + unified_timestamp, ) @@ -22,7 +23,13 @@ class TeleQuebecBaseIE(InfoExtractor): class TeleQuebecIE(TeleQuebecBaseIE): - _VALID_URL = r'https?://zonevideo\.telequebec\.tv/media/(?P<id>\d+)' + _VALID_URL = r'''(?x) + https?:// + (?: + zonevideo\.telequebec\.tv/media| + coucou\.telequebec\.tv/videos + )/(?P<id>\d+) + ''' _TESTS = [{ # available till 01.01.2023 'url': 'http://zonevideo.telequebec.tv/media/37578/un-petit-choc-et-puis-repart/un-chef-a-la-cabane', @@ -41,6 +48,9 @@ class TeleQuebecIE(TeleQuebecBaseIE): # no description 'url': 'http://zonevideo.telequebec.tv/media/30261', 'only_matching': True, + }, { + 'url': 'https://coucou.telequebec.tv/videos/41788/idee-de-genie/l-heure-du-bain', + 'only_matching': True, }] def _real_extract(self, url): @@ -61,6 +71,52 @@ class TeleQuebecIE(TeleQuebecBaseIE): return info +class TeleQuebecSquatIE(InfoExtractor): + _VALID_URL = r'https://squat\.telequebec\.tv/videos/(?P<id>\d+)' + _TESTS = [{ + 'url': 'https://squat.telequebec.tv/videos/9314', + 'info_dict': { + 'id': 'd59ae78112d542e793d83cc9d3a5b530', + 'ext': 'mp4', + 'title': 'Poupeflekta', + 'description': 'md5:2f0718f8d2f8fece1646ee25fb7bce75', + 'duration': 1351, + 'timestamp': 1569057600, + 'upload_date': '20190921', + 'series': 'Miraculous : Les Aventures de Ladybug et Chat Noir', + 'season': 'Saison 3', + 'season_number': 3, + 'episode_number': 57, + }, + 'params': { + 'skip_download': True, + }, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + + video = self._download_json( + 'https://squat.api.telequebec.tv/v1/videos/%s' % video_id, + video_id) + + media_id = video['sourceId'] + + return { + '_type': 'url_transparent', + 'url': 'http://zonevideo.telequebec.tv/media/%s' % media_id, + 'ie_key': TeleQuebecIE.ie_key(), + 'id': media_id, + 'title': video.get('titre'), + 'description': video.get('description'), + 'timestamp': unified_timestamp(video.get('datePublication')), + 'series': video.get('container'), + 'season': video.get('saison'), + 'season_number': int_or_none(video.get('noSaison')), + 'episode_number': int_or_none(video.get('episode')), + } + + class TeleQuebecEmissionIE(TeleQuebecBaseIE): _VALID_URL = r'''(?x) https?:// diff --git a/youtube_dl/extractor/tenplay.py b/youtube_dl/extractor/tenplay.py new file mode 100644 index 0000000..dff44a4 --- /dev/null +++ b/youtube_dl/extractor/tenplay.py @@ -0,0 +1,55 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + parse_age_limit, + parse_iso8601, + smuggle_url, +) + + +class TenPlayIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?10play\.com\.au/[^/]+/episodes/[^/]+/[^/]+/(?P<id>tpv\d{6}[a-z]{5})' + _TEST = { + 'url': 'https://10play.com.au/masterchef/episodes/season-1/masterchef-s1-ep-1/tpv190718kwzga', + 'info_dict': { + 'id': '6060533435001', + 'ext': 'mp4', + 'title': 'MasterChef - S1 Ep. 1', + 'description': 'md5:4fe7b78e28af8f2d900cd20d900ef95c', + 'age_limit': 10, + 'timestamp': 1240828200, + 'upload_date': '20090427', + 'uploader_id': '2199827728001', + }, + 'params': { + 'format': 'bestvideo', + 'skip_download': True, + } + } + BRIGHTCOVE_URL_TEMPLATE = 'https://players.brightcove.net/2199827728001/cN6vRtRQt_default/index.html?videoId=%s' + + def _real_extract(self, url): + content_id = self._match_id(url) + data = self._download_json( + 'https://10play.com.au/api/video/' + content_id, content_id) + video = data.get('video') or {} + metadata = data.get('metaData') or {} + brightcove_id = video.get('videoId') or metadata['showContentVideoId'] + brightcove_url = smuggle_url( + self.BRIGHTCOVE_URL_TEMPLATE % brightcove_id, + {'geo_countries': ['AU']}) + + return { + '_type': 'url_transparent', + 'url': brightcove_url, + 'id': content_id, + 'title': video.get('title') or metadata.get('pageContentName') or metadata.get('showContentName'), + 'description': video.get('description'), + 'age_limit': parse_age_limit(video.get('showRatingClassification') or metadata.get('showProgramClassification')), + 'series': metadata.get('showName'), + 'season': metadata.get('showContentSeason'), + 'timestamp': parse_iso8601(metadata.get('contentPublishDate') or metadata.get('pageContentPublishDate')), + 'ie_key': 'BrightcoveNew', + } diff --git a/youtube_dl/extractor/thesun.py b/youtube_dl/extractor/thesun.py index 22d0037..15d4a69 100644 --- a/youtube_dl/extractor/thesun.py +++ b/youtube_dl/extractor/thesun.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from .ooyala import OoyalaIE +from ..utils import extract_attributes class TheSunIE(InfoExtractor): @@ -16,6 +16,7 @@ class TheSunIE(InfoExtractor): }, 'playlist_count': 2, } + BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/%s/default_default/index.html?videoId=%s' def _real_extract(self, url): article_id = self._match_id(url) @@ -23,10 +24,15 @@ class TheSunIE(InfoExtractor): webpage = self._download_webpage(url, article_id) entries = [] - for ooyala_id in re.findall( - r'<[^>]+\b(?:id\s*=\s*"thesun-ooyala-player-|data-content-id\s*=\s*")([^"]+)', + for video in re.findall( + r'<video[^>]+data-video-id-pending=[^>]+>', webpage): - entries.append(OoyalaIE._build_url_result(ooyala_id)) + attrs = extract_attributes(video) + video_id = attrs['data-video-id-pending'] + account_id = attrs.get('data-account', '5067014667001') + entries.append(self.url_result( + self.BRIGHTCOVE_URL_TEMPLATE % (account_id, video_id), + 'BrightcoveNew', video_id)) return self.playlist_result( entries, article_id, self._og_search_title(webpage, fatal=False)) diff --git a/youtube_dl/extractor/trunews.py b/youtube_dl/extractor/trunews.py index b0c7caa..cca5b5c 100644 --- a/youtube_dl/extractor/trunews.py +++ b/youtube_dl/extractor/trunews.py @@ -1,21 +1,12 @@ from __future__ import unicode_literals from .common import InfoExtractor -from ..utils import ( - dict_get, - float_or_none, - int_or_none, - unified_timestamp, - update_url_query, - url_or_none, -) class TruNewsIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?trunews\.com/stream/(?P<id>[^/?#&]+)' _TEST = { 'url': 'https://www.trunews.com/stream/will-democrats-stage-a-circus-during-president-trump-s-state-of-the-union-speech', - 'md5': 'a19c024c3906ff954fac9b96ce66bb08', 'info_dict': { 'id': '5c5a21e65d3c196e1c0020cc', 'display_id': 'will-democrats-stage-a-circus-during-president-trump-s-state-of-the-union-speech', @@ -28,48 +19,16 @@ class TruNewsIE(InfoExtractor): }, 'add_ie': ['Zype'], } + _ZYPE_TEMPL = 'https://player.zype.com/embed/%s.js?api_key=X5XnahkjCwJrT_l5zUqypnaLEObotyvtUKJWWlONxDoHVjP8vqxlArLV8llxMbyt' def _real_extract(self, url): display_id = self._match_id(url) - video = self._download_json( + zype_id = self._download_json( 'https://api.zype.com/videos', display_id, query={ 'app_key': 'PUVKp9WgGUb3-JUw6EqafLx8tFVP6VKZTWbUOR-HOm__g4fNDt1bCsm_LgYf_k9H', 'per_page': 1, 'active': 'true', 'friendly_title': display_id, - })['response'][0] - - zype_id = video['_id'] - - thumbnails = [] - thumbnails_list = video.get('thumbnails') - if isinstance(thumbnails_list, list): - for thumbnail in thumbnails_list: - if not isinstance(thumbnail, dict): - continue - thumbnail_url = url_or_none(thumbnail.get('url')) - if not thumbnail_url: - continue - thumbnails.append({ - 'url': thumbnail_url, - 'width': int_or_none(thumbnail.get('width')), - 'height': int_or_none(thumbnail.get('height')), - }) - - return { - '_type': 'url_transparent', - 'url': update_url_query( - 'https://player.zype.com/embed/%s.js' % zype_id, - {'api_key': 'X5XnahkjCwJrT_l5zUqypnaLEObotyvtUKJWWlONxDoHVjP8vqxlArLV8llxMbyt'}), - 'ie_key': 'Zype', - 'id': zype_id, - 'display_id': display_id, - 'title': video.get('title'), - 'description': dict_get(video, ('description', 'ott_description', 'short_description')), - 'duration': int_or_none(video.get('duration')), - 'timestamp': unified_timestamp(video.get('published_at')), - 'average_rating': float_or_none(video.get('rating')), - 'view_count': int_or_none(video.get('request_count')), - 'thumbnails': thumbnails, - } + })['response'][0]['_id'] + return self.url_result(self._ZYPE_TEMPL % zype_id, 'Zype', zype_id) diff --git a/youtube_dl/extractor/tutv.py b/youtube_dl/extractor/tutv.py deleted file mode 100644 index 362318b..0000000 --- a/youtube_dl/extractor/tutv.py +++ /dev/null @@ -1,36 +0,0 @@ -from __future__ import unicode_literals - -from .common import InfoExtractor -from ..compat import ( - compat_b64decode, - compat_parse_qs, -) - - -class TutvIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?tu\.tv/videos/(?P<id>[^/?]+)' - _TEST = { - 'url': 'http://tu.tv/videos/robots-futbolistas', - 'md5': '0cd9e28ad270488911b0d2a72323395d', - 'info_dict': { - 'id': '2973058', - 'ext': 'mp4', - 'title': 'Robots futbolistas', - }, - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - - internal_id = self._search_regex(r'codVideo=([0-9]+)', webpage, 'internal video ID') - - data_content = self._download_webpage( - 'http://tu.tv/flvurl.php?codVideo=%s' % internal_id, video_id, 'Downloading video info') - video_url = compat_b64decode(compat_parse_qs(data_content)['kpt'][0]).decode('utf-8') - - return { - 'id': internal_id, - 'url': video_url, - 'title': self._og_search_title(webpage), - } diff --git a/youtube_dl/extractor/tv2.py b/youtube_dl/extractor/tv2.py index d5071e8..4a19b9b 100644 --- a/youtube_dl/extractor/tv2.py +++ b/youtube_dl/extractor/tv2.py @@ -4,13 +4,17 @@ from __future__ import unicode_literals import re from .common import InfoExtractor +from ..compat import compat_HTTPError from ..utils import ( determine_ext, + ExtractorError, int_or_none, float_or_none, js_to_json, parse_iso8601, remove_end, + strip_or_none, + try_get, ) @@ -20,7 +24,7 @@ class TV2IE(InfoExtractor): 'url': 'http://www.tv2.no/v/916509/', 'info_dict': { 'id': '916509', - 'ext': 'mp4', + 'ext': 'flv', 'title': 'Se Frode Gryttens hyllest av Steven Gerrard', 'description': 'TV 2 Sportens huspoet tar avskjed med Liverpools kaptein Steven Gerrard.', 'timestamp': 1431715610, @@ -29,22 +33,40 @@ class TV2IE(InfoExtractor): 'view_count': int, 'categories': list, }, - 'params': { - # m3u8 download - 'skip_download': True, - }, } + _API_DOMAIN = 'sumo.tv2.no' + _PROTOCOLS = ('HDS', 'HLS', 'DASH') + _GEO_COUNTRIES = ['NO'] def _real_extract(self, url): video_id = self._match_id(url) + api_base = 'http://%s/api/web/asset/%s' % (self._API_DOMAIN, video_id) formats = [] format_urls = [] - for protocol in ('HDS', 'HLS'): - data = self._download_json( - 'http://sumo.tv2.no/api/web/asset/%s/play.json?protocol=%s&videoFormat=SMIL+ISMUSP' % (video_id, protocol), - video_id, 'Downloading play JSON')['playback'] - for item in data['items']['item']: + for protocol in self._PROTOCOLS: + try: + data = self._download_json( + api_base + '/play.json?protocol=%s&videoFormat=SMIL+ISMUSP' % protocol, + video_id, 'Downloading play JSON')['playback'] + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401: + error = self._parse_json(e.cause.read().decode(), video_id)['error'] + error_code = error.get('code') + if error_code == 'ASSET_PLAYBACK_INVALID_GEO_LOCATION': + self.raise_geo_restricted(countries=self._GEO_COUNTRIES) + elif error_code == 'SESSION_NOT_AUTHENTICATED': + self.raise_login_required() + raise ExtractorError(error['description']) + raise + items = try_get(data, lambda x: x['items']['item']) + if not items: + continue + if not isinstance(items, list): + items = [items] + for item in items: + if not isinstance(item, dict): + continue video_url = item.get('url') if not video_url or video_url in format_urls: continue @@ -57,9 +79,13 @@ class TV2IE(InfoExtractor): formats.extend(self._extract_f4m_formats( video_url, video_id, f4m_id=format_id, fatal=False)) elif ext == 'm3u8': - formats.extend(self._extract_m3u8_formats( - video_url, video_id, 'mp4', entry_protocol='m3u8_native', - m3u8_id=format_id, fatal=False)) + if not data.get('drmProtected'): + formats.extend(self._extract_m3u8_formats( + video_url, video_id, 'mp4', entry_protocol='m3u8_native', + m3u8_id=format_id, fatal=False)) + elif ext == 'mpd': + formats.extend(self._extract_mpd_formats( + video_url, video_id, format_id, fatal=False)) elif ext == 'ism' or video_url.endswith('.ism/Manifest'): pass else: @@ -69,34 +95,30 @@ class TV2IE(InfoExtractor): 'tbr': int_or_none(item.get('bitrate')), 'filesize': int_or_none(item.get('fileSize')), }) + if not formats and data.get('drmProtected'): + raise ExtractorError('This video is DRM protected.', expected=True) self._sort_formats(formats) asset = self._download_json( - 'http://sumo.tv2.no/api/web/asset/%s.json' % video_id, - video_id, 'Downloading metadata JSON')['asset'] - + api_base + '.json', video_id, + 'Downloading metadata JSON')['asset'] title = asset['title'] - description = asset.get('description') - timestamp = parse_iso8601(asset.get('createTime')) - duration = float_or_none(asset.get('accurateDuration') or asset.get('duration')) - view_count = int_or_none(asset.get('views')) - categories = asset.get('keywords', '').split(',') thumbnails = [{ 'id': thumbnail.get('@type'), 'url': thumbnail.get('url'), - } for _, thumbnail in asset.get('imageVersions', {}).items()] + } for _, thumbnail in (asset.get('imageVersions') or {}).items()] return { 'id': video_id, 'url': video_url, 'title': title, - 'description': description, + 'description': strip_or_none(asset.get('description')), 'thumbnails': thumbnails, - 'timestamp': timestamp, - 'duration': duration, - 'view_count': view_count, - 'categories': categories, + 'timestamp': parse_iso8601(asset.get('createTime')), + 'duration': float_or_none(asset.get('accurateDuration') or asset.get('duration')), + 'view_count': int_or_none(asset.get('views')), + 'categories': asset.get('keywords', '').split(','), 'formats': formats, } @@ -108,7 +130,7 @@ class TV2ArticleIE(InfoExtractor): 'info_dict': { 'id': '6930542', 'title': 'Russen hetses etter pingvintyveri - innrømmer Ã¥ ha Ã¥pnet luken pÃ¥ buret', - 'description': 'md5:339573779d3eea3542ffe12006190954', + 'description': 'De fire siktede nekter fortsatt for Ã¥ ha stjÃ¥let pingvinbabyene, men innrømmer Ã¥ ha Ã¥pnet luken til de smÃ¥ kyllingene.', }, 'playlist_count': 2, }, { @@ -126,7 +148,7 @@ class TV2ArticleIE(InfoExtractor): if not assets: # New embed pattern - for v in re.findall(r'TV2ContentboxVideo\(({.+?})\)', webpage): + for v in re.findall(r'(?s)TV2ContentboxVideo\(({.+?})\)', webpage): video = self._parse_json( v, playlist_id, transform_source=js_to_json, fatal=False) if not video: @@ -143,3 +165,28 @@ class TV2ArticleIE(InfoExtractor): description = remove_end(self._og_search_description(webpage), ' - TV2.no') return self.playlist_result(entries, playlist_id, title, description) + + +class KatsomoIE(TV2IE): + _VALID_URL = r'https?://(?:www\.)?(?:katsomo|mtv)\.fi/(?:#!/)?(?:[^/]+/[0-9a-z-]+-\d+/[0-9a-z-]+-|[^/]+/\d+/[^/]+/)(?P<id>\d+)' + _TEST = { + 'url': 'https://www.mtv.fi/sarja/mtv-uutiset-live-33001002003/lahden-pelicans-teki-kovan-ratkaisun-ville-nieminen-pihalle-1181321', + 'info_dict': { + 'id': '1181321', + 'ext': 'mp4', + 'title': 'MTV Uutiset Live', + 'description': 'Päätöksen teki Pelicansin hallitus.', + 'timestamp': 1575116484, + 'upload_date': '20191130', + 'duration': 37.12, + 'view_count': int, + 'categories': list, + }, + 'params': { + # m3u8 download + 'skip_download': True, + }, + } + _API_DOMAIN = 'api.katsomo.fi' + _PROTOCOLS = ('HLS', 'MPD') + _GEO_COUNTRIES = ['FI'] diff --git a/youtube_dl/extractor/tv2dk.py b/youtube_dl/extractor/tv2dk.py new file mode 100644 index 0000000..611fdc0 --- /dev/null +++ b/youtube_dl/extractor/tv2dk.py @@ -0,0 +1,154 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import json +import re + +from .common import InfoExtractor +from ..utils import ( + determine_ext, + extract_attributes, + js_to_json, + url_or_none, +) + + +class TV2DKIE(InfoExtractor): + _VALID_URL = r'''(?x) + https?:// + (?:www\.)? + (?: + tvsyd| + tv2ostjylland| + tvmidtvest| + tv2fyn| + tv2east| + tv2lorry| + tv2nord + )\.dk/ + (:[^/]+/)* + (?P<id>[^/?\#&]+) + ''' + _TESTS = [{ + 'url': 'https://www.tvsyd.dk/nyheder/28-10-2019/1930/1930-28-okt-2019?autoplay=1#player', + 'info_dict': { + 'id': '0_52jmwa0p', + 'ext': 'mp4', + 'title': '19:30 - 28. okt. 2019', + 'timestamp': 1572290248, + 'upload_date': '20191028', + 'uploader_id': 'tvsyd', + 'duration': 1347, + 'view_count': int, + }, + 'params': { + 'skip_download': True, + }, + 'add_ie': ['Kaltura'], + }, { + 'url': 'https://www.tv2ostjylland.dk/artikel/minister-gaar-ind-i-sag-om-diabetes-teknologi', + 'only_matching': True, + }, { + 'url': 'https://www.tv2ostjylland.dk/nyheder/28-10-2019/22/2200-nyhederne-mandag-d-28-oktober-2019?autoplay=1#player', + 'only_matching': True, + }, { + 'url': 'https://www.tvmidtvest.dk/nyheder/27-10-2019/1930/1930-27-okt-2019', + 'only_matching': True, + }, { + 'url': 'https://www.tv2fyn.dk/artikel/fyn-kan-faa-landets-foerste-fabrik-til-groent-jetbraendstof', + 'only_matching': True, + }, { + 'url': 'https://www.tv2east.dk/artikel/gods-faar-indleveret-tonsvis-af-aebler-100-kilo-aebler-gaar-til-en-aeblebrandy', + 'only_matching': True, + }, { + 'url': 'https://www.tv2lorry.dk/koebenhavn/rasmus-paludan-evakueret-til-egen-demonstration#player', + 'only_matching': True, + }, { + 'url': 'https://www.tv2nord.dk/artikel/dybt-uacceptabelt', + 'only_matching': True, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + + webpage = self._download_webpage(url, video_id) + + entries = [] + for video_el in re.findall(r'(?s)<[^>]+\bdata-entryid\s*=[^>]*>', webpage): + video = extract_attributes(video_el) + kaltura_id = video.get('data-entryid') + if not kaltura_id: + continue + partner_id = video.get('data-partnerid') + if not partner_id: + continue + entries.append(self.url_result( + 'kaltura:%s:%s' % (partner_id, kaltura_id), 'Kaltura', + video_id=kaltura_id)) + return self.playlist_result(entries) + + +class TV2DKBornholmPlayIE(InfoExtractor): + _VALID_URL = r'https?://play\.tv2bornholm\.dk/\?.*?\bid=(?P<id>\d+)' + _TEST = { + 'url': 'http://play.tv2bornholm.dk/?area=specifikTV&id=781021', + 'info_dict': { + 'id': '781021', + 'ext': 'mp4', + 'title': '12Nyheder-27.11.19', + }, + 'params': { + 'skip_download': True, + }, + } + + def _real_extract(self, url): + video_id = self._match_id(url) + + video = self._download_json( + 'http://play.tv2bornholm.dk/controls/AJAX.aspx/specifikVideo', video_id, + data=json.dumps({ + 'playlist_id': video_id, + 'serienavn': '', + }).encode(), headers={ + 'X-Requested-With': 'XMLHttpRequest', + 'Content-Type': 'application/json; charset=UTF-8', + })['d'] + + # TODO: generalize flowplayer + title = self._search_regex( + r'title\s*:\s*(["\'])(?P<value>(?:(?!\1).)+)\1', video, 'title', + group='value') + sources = self._parse_json(self._search_regex( + r'(?s)sources:\s*(\[.+?\]),', video, 'sources'), + video_id, js_to_json) + + formats = [] + srcs = set() + for source in sources: + src = url_or_none(source.get('src')) + if not src: + continue + if src in srcs: + continue + srcs.add(src) + ext = determine_ext(src) + src_type = source.get('type') + if src_type == 'application/x-mpegurl' or ext == 'm3u8': + formats.extend(self._extract_m3u8_formats( + src, video_id, ext='mp4', entry_protocol='m3u8_native', + m3u8_id='hls', fatal=False)) + elif src_type == 'application/dash+xml' or ext == 'mpd': + formats.extend(self._extract_mpd_formats( + src, video_id, mpd_id='dash', fatal=False)) + else: + formats.append({ + 'url': src, + }) + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'formats': formats, + } diff --git a/youtube_dl/extractor/twentyfourvideo.py b/youtube_dl/extractor/twentyfourvideo.py index 1d66eea..2830c21 100644 --- a/youtube_dl/extractor/twentyfourvideo.py +++ b/youtube_dl/extractor/twentyfourvideo.py @@ -18,7 +18,7 @@ class TwentyFourVideoIE(InfoExtractor): https?:// (?P<host> (?:(?:www|porno)\.)?24video\. - (?:net|me|xxx|sexy?|tube|adult|site) + (?:net|me|xxx|sexy?|tube|adult|site|vip) )/ (?: video/(?:(?:view|xml)/)?| @@ -59,6 +59,9 @@ class TwentyFourVideoIE(InfoExtractor): }, { 'url': 'https://porno.24video.net/video/2640421-vsya-takaya-gibkaya-i-v-masle', 'only_matching': True, + }, { + 'url': 'https://www.24video.vip/video/view/1044982', + 'only_matching': True, }] def _real_extract(self, url): diff --git a/youtube_dl/extractor/twitch.py b/youtube_dl/extractor/twitch.py index 0500e33..a8c2502 100644 --- a/youtube_dl/extractor/twitch.py +++ b/youtube_dl/extractor/twitch.py @@ -17,12 +17,10 @@ from ..compat import ( from ..utils import ( clean_html, ExtractorError, - float_or_none, int_or_none, orderedSet, parse_duration, parse_iso8601, - qualities, try_get, unified_timestamp, update_url_query, @@ -248,7 +246,7 @@ class TwitchVodIE(TwitchItemBaseIE): https?:// (?: (?:(?:www|go|m)\.)?twitch\.tv/(?:[^/]+/v(?:ideo)?|videos)/| - player\.twitch\.tv/\?.*?\bvideo=v + player\.twitch\.tv/\?.*?\bvideo=v? ) (?P<id>\d+) ''' @@ -306,6 +304,9 @@ class TwitchVodIE(TwitchItemBaseIE): }, { 'url': 'https://www.twitch.tv/northernlion/video/291940395', 'only_matching': True, + }, { + 'url': 'https://player.twitch.tv/?video=480452374', + 'only_matching': True, }] def _real_extract(self, url): @@ -324,6 +325,7 @@ class TwitchVodIE(TwitchItemBaseIE): 'allow_audio_only': 'true', 'allow_spectre': 'true', 'player': 'twitchweb', + 'playlist_include_framerate': 'true', 'nauth': access_token['token'], 'nauthsig': access_token['sig'], })), @@ -341,9 +343,8 @@ class TwitchVodIE(TwitchItemBaseIE): info['subtitles'] = { 'rechat': [{ 'url': update_url_query( - 'https://rechat.twitch.tv/rechat-messages', { - 'video_id': 'v%s' % item_id, - 'start': info['timestamp'], + 'https://api.twitch.tv/v5/videos/%s/comments' % item_id, { + 'client_id': self._CLIENT_ID, }), 'ext': 'json', }], @@ -596,6 +597,7 @@ class TwitchStreamIE(TwitchBaseIE): 'allow_spectre': 'true', 'p': random.randint(1000000, 10000000), 'player': 'twitchweb', + 'playlist_include_framerate': 'true', 'segment_preference': '4', 'sig': access_token['sig'].encode('utf-8'), 'token': access_token['token'].encode('utf-8'), @@ -641,7 +643,7 @@ class TwitchStreamIE(TwitchBaseIE): class TwitchClipsIE(TwitchBaseIE): IE_NAME = 'twitch:clips' - _VALID_URL = r'https?://(?:clips\.twitch\.tv/(?:[^/]+/)*|(?:www\.)?twitch\.tv/[^/]+/clip/)(?P<id>[^/?#&]+)' + _VALID_URL = r'https?://(?:clips\.twitch\.tv/(?:embed\?.*?\bclip=|(?:[^/]+/)*)|(?:www\.)?twitch\.tv/[^/]+/clip/)(?P<id>[^/?#&]+)' _TESTS = [{ 'url': 'https://clips.twitch.tv/FaintLightGullWholeWheat', @@ -664,68 +666,89 @@ class TwitchClipsIE(TwitchBaseIE): }, { 'url': 'https://www.twitch.tv/sergeynixon/clip/StormyThankfulSproutFutureMan', 'only_matching': True, + }, { + 'url': 'https://clips.twitch.tv/embed?clip=InquisitiveBreakableYogurtJebaited', + 'only_matching': True, }] def _real_extract(self, url): video_id = self._match_id(url) - status = self._download_json( - 'https://clips.twitch.tv/api/v2/clips/%s/status' % video_id, - video_id) + clip = self._download_json( + 'https://gql.twitch.tv/gql', video_id, data=json.dumps({ + 'query': '''{ + clip(slug: "%s") { + broadcaster { + displayName + } + createdAt + curator { + displayName + id + } + durationSeconds + id + tiny: thumbnailURL(width: 86, height: 45) + small: thumbnailURL(width: 260, height: 147) + medium: thumbnailURL(width: 480, height: 272) + title + videoQualities { + frameRate + quality + sourceURL + } + viewCount + } +}''' % video_id, + }).encode(), headers={ + 'Client-ID': self._CLIENT_ID, + })['data']['clip'] + + if not clip: + raise ExtractorError( + 'This clip is no longer available', expected=True) formats = [] - - for option in status['quality_options']: + for option in clip.get('videoQualities', []): if not isinstance(option, dict): continue - source = url_or_none(option.get('source')) + source = url_or_none(option.get('sourceURL')) if not source: continue formats.append({ 'url': source, 'format_id': option.get('quality'), 'height': int_or_none(option.get('quality')), - 'fps': int_or_none(option.get('frame_rate')), + 'fps': int_or_none(option.get('frameRate')), }) - self._sort_formats(formats) - info = { + thumbnails = [] + for thumbnail_id in ('tiny', 'small', 'medium'): + thumbnail_url = clip.get(thumbnail_id) + if not thumbnail_url: + continue + thumb = { + 'id': thumbnail_id, + 'url': thumbnail_url, + } + mobj = re.search(r'-(\d+)x(\d+)\.', thumbnail_url) + if mobj: + thumb.update({ + 'height': int(mobj.group(2)), + 'width': int(mobj.group(1)), + }) + thumbnails.append(thumb) + + return { + 'id': clip.get('id') or video_id, + 'title': clip.get('title') or video_id, 'formats': formats, + 'duration': int_or_none(clip.get('durationSeconds')), + 'views': int_or_none(clip.get('viewCount')), + 'timestamp': unified_timestamp(clip.get('createdAt')), + 'thumbnails': thumbnails, + 'creator': try_get(clip, lambda x: x['broadcaster']['displayName'], compat_str), + 'uploader': try_get(clip, lambda x: x['curator']['displayName'], compat_str), + 'uploader_id': try_get(clip, lambda x: x['curator']['id'], compat_str), } - - clip = self._call_api( - 'kraken/clips/%s' % video_id, video_id, fatal=False, headers={ - 'Accept': 'application/vnd.twitchtv.v5+json', - }) - - if clip: - quality_key = qualities(('tiny', 'small', 'medium')) - thumbnails = [] - thumbnails_dict = clip.get('thumbnails') - if isinstance(thumbnails_dict, dict): - for thumbnail_id, thumbnail_url in thumbnails_dict.items(): - thumbnails.append({ - 'id': thumbnail_id, - 'url': thumbnail_url, - 'preference': quality_key(thumbnail_id), - }) - - info.update({ - 'id': clip.get('tracking_id') or video_id, - 'title': clip.get('title') or video_id, - 'duration': float_or_none(clip.get('duration')), - 'views': int_or_none(clip.get('views')), - 'timestamp': unified_timestamp(clip.get('created_at')), - 'thumbnails': thumbnails, - 'creator': try_get(clip, lambda x: x['broadcaster']['display_name'], compat_str), - 'uploader': try_get(clip, lambda x: x['curator']['display_name'], compat_str), - 'uploader_id': try_get(clip, lambda x: x['curator']['id'], compat_str), - }) - else: - info.update({ - 'title': video_id, - 'id': video_id, - }) - - return info diff --git a/youtube_dl/extractor/twitter.py b/youtube_dl/extractor/twitter.py index cebb623..0146898 100644 --- a/youtube_dl/extractor/twitter.py +++ b/youtube_dl/extractor/twitter.py @@ -4,32 +4,67 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from ..compat import compat_urlparse +from ..compat import ( + compat_HTTPError, + compat_parse_qs, + compat_urllib_parse_unquote, + compat_urllib_parse_urlparse, +) from ..utils import ( - determine_ext, dict_get, ExtractorError, float_or_none, int_or_none, - remove_end, try_get, + strip_or_none, + unified_timestamp, + update_url_query, xpath_text, ) -from .periscope import PeriscopeIE +from .periscope import ( + PeriscopeBaseIE, + PeriscopeIE, +) class TwitterBaseIE(InfoExtractor): + _API_BASE = 'https://api.twitter.com/1.1/' + _BASE_REGEX = r'https?://(?:(?:www|m(?:obile)?)\.)?twitter\.com/' + _GUEST_TOKEN = None + + def _extract_variant_formats(self, variant, video_id): + variant_url = variant.get('url') + if not variant_url: + return [] + elif '.m3u8' in variant_url: + return self._extract_m3u8_formats( + variant_url, video_id, 'mp4', 'm3u8_native', + m3u8_id='hls', fatal=False) + else: + tbr = int_or_none(dict_get(variant, ('bitrate', 'bit_rate')), 1000) or None + f = { + 'url': variant_url, + 'format_id': 'http' + ('-%d' % tbr if tbr else ''), + 'tbr': tbr, + } + self._search_dimensions_in_video_url(f, variant_url) + return [f] + def _extract_formats_from_vmap_url(self, vmap_url, video_id): vmap_data = self._download_xml(vmap_url, video_id) - video_url = xpath_text(vmap_data, './/MediaFile').strip() - if determine_ext(video_url) == 'm3u8': - return self._extract_m3u8_formats( - video_url, video_id, ext='mp4', m3u8_id='hls', - entry_protocol='m3u8_native') - return [{ - 'url': video_url, - }] + formats = [] + urls = [] + for video_variant in vmap_data.findall('.//{http://twitter.com/schema/videoVMapV2.xsd}videoVariant'): + video_variant.attrib['url'] = compat_urllib_parse_unquote( + video_variant.attrib['url']) + urls.append(video_variant.attrib['url']) + formats.extend(self._extract_variant_formats( + video_variant.attrib, video_id)) + video_url = strip_or_none(xpath_text(vmap_data, './/MediaFile')) + if video_url not in urls: + formats.extend(self._extract_variant_formats({'url': video_url}, video_id)) + return formats @staticmethod def _search_dimensions_in_video_url(a_format, video_url): @@ -40,10 +75,30 @@ class TwitterBaseIE(InfoExtractor): 'height': int(m.group('height')), }) - -class TwitterCardIE(TwitterBaseIE): + def _call_api(self, path, video_id, query={}): + headers = { + 'Authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAAPYXBAAAAAAACLXUNDekMxqa8h%2F40K4moUkGsoc%3DTYfbDKbT3jJPCEVnMYqilB28NHfOPqkca3qaAxGfsyKCs0wRbw', + } + if not self._GUEST_TOKEN: + self._GUEST_TOKEN = self._download_json( + self._API_BASE + 'guest/activate.json', video_id, + 'Downloading guest token', data=b'', + headers=headers)['guest_token'] + headers['x-guest-token'] = self._GUEST_TOKEN + try: + return self._download_json( + self._API_BASE + path, video_id, headers=headers, query=query) + except ExtractorError as e: + if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403: + raise ExtractorError(self._parse_json( + e.cause.read().decode(), + video_id)['errors'][0]['message'], expected=True) + raise + + +class TwitterCardIE(InfoExtractor): IE_NAME = 'twitter:card' - _VALID_URL = r'https?://(?:www\.)?twitter\.com/i/(?P<path>cards/tfw/v1|videos(?:/tweet)?)/(?P<id>\d+)' + _VALID_URL = TwitterBaseIE._BASE_REGEX + r'i/(?:cards/tfw/v1|videos(?:/tweet)?)/(?P<id>\d+)' _TESTS = [ { 'url': 'https://twitter.com/i/cards/tfw/v1/560070183650213889', @@ -51,19 +106,28 @@ class TwitterCardIE(TwitterBaseIE): 'info_dict': { 'id': '560070183650213889', 'ext': 'mp4', - 'title': 'Twitter web player', - 'thumbnail': r're:^https?://.*\.jpg$', + 'title': "Twitter - You can now shoot, edit and share video on Twitter. Capture life's most moving moments from your perspective.", + 'description': 'md5:18d3e24bb4f6e5007487dd546e53bd96', + 'uploader': 'Twitter', + 'uploader_id': 'Twitter', + 'thumbnail': r're:^https?://.*\.jpg', 'duration': 30.033, + 'timestamp': 1422366112, + 'upload_date': '20150127', }, }, { 'url': 'https://twitter.com/i/cards/tfw/v1/623160978427936768', - 'md5': '7ee2a553b63d1bccba97fbed97d9e1c8', + 'md5': '7137eca597f72b9abbe61e5ae0161399', 'info_dict': { 'id': '623160978427936768', 'ext': 'mp4', - 'title': 'Twitter web player', - 'thumbnail': r're:^https?://.*$', + 'title': "NASA - Fly over Pluto's icy Norgay Mountains and Sputnik Plain in this @NASANewHorizons #PlutoFlyby video.", + 'description': "Fly over Pluto's icy Norgay Mountains and Sputnik Plain in this @NASANewHorizons #PlutoFlyby video. https://t.co/BJYgOjSeGA", + 'uploader': 'NASA', + 'uploader_id': 'NASA', + 'timestamp': 1437408129, + 'upload_date': '20150720', }, }, { @@ -75,7 +139,7 @@ class TwitterCardIE(TwitterBaseIE): 'title': 'Ubuntu 11.10 Overview', 'description': 'md5:a831e97fa384863d6e26ce48d1c43376', 'upload_date': '20111013', - 'uploader': 'OMG! Ubuntu!', + 'uploader': 'OMG! UBUNTU!', 'uploader_id': 'omgubuntu', }, 'add_ie': ['Youtube'], @@ -99,190 +163,30 @@ class TwitterCardIE(TwitterBaseIE): 'info_dict': { 'id': '705235433198714880', 'ext': 'mp4', - 'title': 'Twitter web player', - 'thumbnail': r're:^https?://.*', + 'title': "Brent Yarina - Khalil Iverson's missed highlight dunk. And made highlight dunk. In one highlight.", + 'description': "Khalil Iverson's missed highlight dunk. And made highlight dunk. In one highlight. https://t.co/OrxcJ28Bns", + 'uploader': 'Brent Yarina', + 'uploader_id': 'BTNBrentYarina', + 'timestamp': 1456976204, + 'upload_date': '20160303', }, + 'skip': 'This content is no longer available.', }, { 'url': 'https://twitter.com/i/videos/752274308186120192', 'only_matching': True, }, ] - _API_BASE = 'https://api.twitter.com/1.1' - - def _parse_media_info(self, media_info, video_id): - formats = [] - for media_variant in media_info.get('variants', []): - media_url = media_variant['url'] - if media_url.endswith('.m3u8'): - formats.extend(self._extract_m3u8_formats(media_url, video_id, ext='mp4', m3u8_id='hls')) - elif media_url.endswith('.mpd'): - formats.extend(self._extract_mpd_formats(media_url, video_id, mpd_id='dash')) - else: - tbr = int_or_none(dict_get(media_variant, ('bitRate', 'bitrate')), scale=1000) - a_format = { - 'url': media_url, - 'format_id': 'http-%d' % tbr if tbr else 'http', - 'tbr': tbr, - } - # Reported bitRate may be zero - if not a_format['tbr']: - del a_format['tbr'] - - self._search_dimensions_in_video_url(a_format, media_url) - - formats.append(a_format) - return formats - - def _extract_mobile_formats(self, username, video_id): - webpage = self._download_webpage( - 'https://mobile.twitter.com/%s/status/%s' % (username, video_id), - video_id, 'Downloading mobile webpage', - headers={ - # A recent mobile UA is necessary for `gt` cookie - 'User-Agent': 'Mozilla/5.0 (Android 6.0.1; Mobile; rv:54.0) Gecko/54.0 Firefox/54.0', - }) - main_script_url = self._html_search_regex( - r'<script[^>]+src="([^"]+main\.[^"]+)"', webpage, 'main script URL') - main_script = self._download_webpage( - main_script_url, video_id, 'Downloading main script') - bearer_token = self._search_regex( - r'BEARER_TOKEN\s*:\s*"([^"]+)"', - main_script, 'bearer token') - # https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-show-id - api_data = self._download_json( - '%s/statuses/show/%s.json' % (self._API_BASE, video_id), - video_id, 'Downloading API data', - headers={ - 'Authorization': 'Bearer ' + bearer_token, - }) - media_info = try_get(api_data, lambda o: o['extended_entities']['media'][0]['video_info']) or {} - return self._parse_media_info(media_info, video_id) - def _real_extract(self, url): - path, video_id = re.search(self._VALID_URL, url).groups() - - config = None - formats = [] - duration = None - - urls = [url] - if path.startswith('cards/'): - urls.append('https://twitter.com/i/videos/' + video_id) - - for u in urls: - webpage = self._download_webpage( - u, video_id, headers={'Referer': 'https://twitter.com/'}) - - iframe_url = self._html_search_regex( - r'<iframe[^>]+src="((?:https?:)?//(?:www\.youtube\.com/embed/[^"]+|(?:www\.)?vine\.co/v/\w+/card))"', - webpage, 'video iframe', default=None) - if iframe_url: - return self.url_result(iframe_url) - - config = self._parse_json(self._html_search_regex( - r'data-(?:player-)?config="([^"]+)"', webpage, - 'data player config', default='{}'), - video_id) - - if config.get('source_type') == 'vine': - return self.url_result(config['player_url'], 'Vine') - - periscope_url = PeriscopeIE._extract_url(webpage) - if periscope_url: - return self.url_result(periscope_url, PeriscopeIE.ie_key()) - - video_url = config.get('video_url') or config.get('playlist', [{}])[0].get('source') - - if video_url: - if determine_ext(video_url) == 'm3u8': - formats.extend(self._extract_m3u8_formats(video_url, video_id, ext='mp4', m3u8_id='hls')) - else: - f = { - 'url': video_url, - } - - self._search_dimensions_in_video_url(f, video_url) - - formats.append(f) - - vmap_url = config.get('vmapUrl') or config.get('vmap_url') - if vmap_url: - formats.extend( - self._extract_formats_from_vmap_url(vmap_url, video_id)) - - media_info = None - - for entity in config.get('status', {}).get('entities', []): - if 'mediaInfo' in entity: - media_info = entity['mediaInfo'] - - if media_info: - formats.extend(self._parse_media_info(media_info, video_id)) - duration = float_or_none(media_info.get('duration', {}).get('nanos'), scale=1e9) - - username = config.get('user', {}).get('screen_name') - if username: - formats.extend(self._extract_mobile_formats(username, video_id)) - - if formats: - title = self._search_regex(r'<title>([^<]+)', webpage, 'title') - thumbnail = config.get('posterImageUrl') or config.get('image_src') - duration = float_or_none(config.get('duration'), scale=1000) or duration - break - - if not formats: - headers = { - 'Authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAAPYXBAAAAAAACLXUNDekMxqa8h%2F40K4moUkGsoc%3DTYfbDKbT3jJPCEVnMYqilB28NHfOPqkca3qaAxGfsyKCs0wRbw', - 'Referer': url, - } - ct0 = self._get_cookies(url).get('ct0') - if ct0: - headers['csrf_token'] = ct0.value - guest_token = self._download_json( - '%s/guest/activate.json' % self._API_BASE, video_id, - 'Downloading guest token', data=b'', - headers=headers)['guest_token'] - headers['x-guest-token'] = guest_token - self._set_cookie('api.twitter.com', 'gt', guest_token) - config = self._download_json( - '%s/videos/tweet/config/%s.json' % (self._API_BASE, video_id), - video_id, headers=headers) - track = config['track'] - vmap_url = track.get('vmapUrl') - if vmap_url: - formats = self._extract_formats_from_vmap_url(vmap_url, video_id) - else: - playback_url = track['playbackUrl'] - if determine_ext(playback_url) == 'm3u8': - formats = self._extract_m3u8_formats( - playback_url, video_id, 'mp4', - entry_protocol='m3u8_native', m3u8_id='hls') - else: - formats = [{ - 'url': playback_url, - }] - title = 'Twitter web player' - thumbnail = config.get('posterImage') - duration = float_or_none(track.get('durationMs'), scale=1000) - - self._remove_duplicate_formats(formats) - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': title, - 'thumbnail': thumbnail, - 'duration': duration, - 'formats': formats, - } + status_id = self._match_id(url) + return self.url_result( + 'https://twitter.com/statuses/' + status_id, + TwitterIE.ie_key(), status_id) -class TwitterIE(InfoExtractor): +class TwitterIE(TwitterBaseIE): IE_NAME = 'twitter' - _VALID_URL = r'https?://(?:www\.|m\.|mobile\.)?twitter\.com/(?:i/web|(?P[^/]+))/status/(?P\d+)' - _TEMPLATE_URL = 'https://twitter.com/%s/status/%s' - _TEMPLATE_STATUSES_URL = 'https://twitter.com/statuses/%s' + _VALID_URL = TwitterBaseIE._BASE_REGEX + r'(?:(?:i/web|[^/]+)/status|statuses)/(?P\d+)' _TESTS = [{ 'url': 'https://twitter.com/freethenipple/status/643211948184596480', @@ -291,10 +195,13 @@ class TwitterIE(InfoExtractor): 'ext': 'mp4', 'title': 'FREE THE NIPPLE - FTN supporters on Hollywood Blvd today!', 'thumbnail': r're:^https?://.*\.jpg', - 'description': 'FREE THE NIPPLE on Twitter: "FTN supporters on Hollywood Blvd today! http://t.co/c7jHH749xJ"', + 'description': 'FTN supporters on Hollywood Blvd today! http://t.co/c7jHH749xJ', 'uploader': 'FREE THE NIPPLE', 'uploader_id': 'freethenipple', 'duration': 12.922, + 'timestamp': 1442188653, + 'upload_date': '20150913', + 'age_limit': 18, }, }, { 'url': 'https://twitter.com/giphz/status/657991469417025536/photo/1', @@ -316,19 +223,23 @@ class TwitterIE(InfoExtractor): 'id': '665052190608723968', 'ext': 'mp4', 'title': 'Star Wars - A new beginning is coming December 18. Watch the official 60 second #TV spot for #StarWars: #TheForceAwakens.', - 'description': 'Star Wars on Twitter: "A new beginning is coming December 18. Watch the official 60 second #TV spot for #StarWars: #TheForceAwakens."', + 'description': 'A new beginning is coming December 18. Watch the official 60 second #TV spot for #StarWars: #TheForceAwakens. https://t.co/OkSqT2fjWJ', 'uploader_id': 'starwars', 'uploader': 'Star Wars', + 'timestamp': 1447395772, + 'upload_date': '20151113', }, }, { 'url': 'https://twitter.com/BTNBrentYarina/status/705235433198714880', 'info_dict': { 'id': '705235433198714880', 'ext': 'mp4', - 'title': 'Brent Yarina - Khalil Iverson\'s missed highlight dunk. And made highlight dunk. In one highlight.', - 'description': 'Brent Yarina on Twitter: "Khalil Iverson\'s missed highlight dunk. And made highlight dunk. In one highlight."', + 'title': "Brent Yarina - Khalil Iverson's missed highlight dunk. And made highlight dunk. In one highlight.", + 'description': "Khalil Iverson's missed highlight dunk. And made highlight dunk. In one highlight. https://t.co/OrxcJ28Bns", 'uploader_id': 'BTNBrentYarina', 'uploader': 'Brent Yarina', + 'timestamp': 1456976204, + 'upload_date': '20160303', }, 'params': { # The same video as https://twitter.com/i/videos/tweet/705235433198714880 @@ -340,12 +251,14 @@ class TwitterIE(InfoExtractor): 'info_dict': { 'id': '700207533655363584', 'ext': 'mp4', - 'title': 'JG - BEAT PROD: @suhmeduh #Damndaniel', - 'description': 'JG on Twitter: "BEAT PROD: @suhmeduh https://t.co/HBrQ4AfpvZ #Damndaniel https://t.co/byBooq2ejZ"', + 'title': 'simon vetugo - BEAT PROD: @suhmeduh #Damndaniel', + 'description': 'BEAT PROD: @suhmeduh https://t.co/HBrQ4AfpvZ #Damndaniel https://t.co/byBooq2ejZ', 'thumbnail': r're:^https?://.*\.jpg', - 'uploader': 'JG', - 'uploader_id': 'jaydingeer', + 'uploader': 'simon vetugo', + 'uploader_id': 'simonvertugo', 'duration': 30.0, + 'timestamp': 1455777459, + 'upload_date': '20160218', }, }, { 'url': 'https://twitter.com/Filmdrunk/status/713801302971588609', @@ -353,10 +266,9 @@ class TwitterIE(InfoExtractor): 'info_dict': { 'id': 'MIOxnrUteUd', 'ext': 'mp4', - 'title': 'Vince Mancini - Vine of the day', - 'description': 'Vince Mancini on Twitter: "Vine of the day https://t.co/xmTvRdqxWf"', - 'uploader': 'Vince Mancini', - 'uploader_id': 'Filmdrunk', + 'title': 'Dr.Pepperの飲み方 #japanese #バカ #ドクペ #電動ガン', + 'uploader': 'TAKUMA', + 'uploader_id': '1004126642786242560', 'timestamp': 1402826626, 'upload_date': '20140615', }, @@ -367,21 +279,22 @@ class TwitterIE(InfoExtractor): 'id': '719944021058060289', 'ext': 'mp4', 'title': 'Captain America - @King0fNerd Are you sure you made the right choice? Find out in theaters.', - 'description': 'Captain America on Twitter: "@King0fNerd Are you sure you made the right choice? Find out in theaters. https://t.co/GpgYi9xMJI"', - 'uploader_id': 'captainamerica', + 'description': '@King0fNerd Are you sure you made the right choice? Find out in theaters. https://t.co/GpgYi9xMJI', + 'uploader_id': 'CaptainAmerica', 'uploader': 'Captain America', 'duration': 3.17, + 'timestamp': 1460483005, + 'upload_date': '20160412', }, }, { 'url': 'https://twitter.com/OPP_HSD/status/779210622571536384', 'info_dict': { 'id': '1zqKVVlkqLaKB', 'ext': 'mp4', - 'title': 'Sgt Kerry Schmidt - LIVE on #Periscope: Road rage, mischief, assault, rollover and fire in one occurrence', - 'description': 'Sgt Kerry Schmidt on Twitter: "LIVE on #Periscope: Road rage, mischief, assault, rollover and fire in one occurrence https://t.co/EKrVgIXF3s"', + 'title': 'Sgt Kerry Schmidt - Ontario Provincial Police - Road rage, mischief, assault, rollover and fire in one occurrence', 'upload_date': '20160923', - 'uploader_id': 'OPP_HSD', - 'uploader': 'Sgt Kerry Schmidt', + 'uploader_id': '1PmKqpJdOJQoY', + 'uploader': 'Sgt Kerry Schmidt - Ontario Provincial Police', 'timestamp': 1474613214, }, 'add_ie': ['Periscope'], @@ -392,10 +305,12 @@ class TwitterIE(InfoExtractor): 'id': '852138619213144067', 'ext': 'mp4', 'title': 'عالم الأخبار - كلمة تاريخية بجلسة الجناسي التاريخية.. النائب خالد مؤنس العتيبي للمعارضين : اتقوا الله .. الظلم ظلمات يوم القيامة', - 'description': 'عالم الأخبار on Twitter: "كلمة تاريخية بجلسة الجناسي التاريخية.. النائب خالد مؤنس العتيبي للمعارضين : اتقوا الله .. الظلم ظلمات يوم القيامة https://t.co/xg6OhpyKfN"', + 'description': 'كلمة تاريخية بجلسة الجناسي التاريخية.. النائب خالد مؤنس العتيبي للمعارضين : اتقوا الله .. الظلم ظلمات يوم القيامة https://t.co/xg6OhpyKfN', 'uploader': 'عالم الأخبار', 'uploader_id': 'news_al3alm', 'duration': 277.4, + 'timestamp': 1492000653, + 'upload_date': '20170412', }, }, { 'url': 'https://twitter.com/i/web/status/910031516746514432', @@ -404,10 +319,12 @@ class TwitterIE(InfoExtractor): 'ext': 'mp4', 'title': 'Préfet de Guadeloupe - [Direct] #Maria Le centre se trouve actuellement au sud de Basse-Terre. Restez confinés. Réfugiez-vous dans la pièce la + sûre.', 'thumbnail': r're:^https?://.*\.jpg', - 'description': 'Préfet de Guadeloupe on Twitter: "[Direct] #Maria Le centre se trouve actuellement au sud de Basse-Terre. Restez confinés. Réfugiez-vous dans la pièce la + sûre. https://t.co/mwx01Rs4lo"', + 'description': '[Direct] #Maria Le centre se trouve actuellement au sud de Basse-Terre. Restez confinés. Réfugiez-vous dans la pièce la + sûre. https://t.co/mwx01Rs4lo', 'uploader': 'Préfet de Guadeloupe', 'uploader_id': 'Prefet971', 'duration': 47.48, + 'timestamp': 1505803395, + 'upload_date': '20170919', }, 'params': { 'skip_download': True, # requires ffmpeg @@ -420,10 +337,12 @@ class TwitterIE(InfoExtractor): 'ext': 'mp4', 'title': 're:.*?Shep is on a roll today.*?', 'thumbnail': r're:^https?://.*\.jpg', - 'description': 'md5:63b036c228772523ae1924d5f8e5ed6b', + 'description': 'md5:37b9f2ff31720cef23b2bd42ee8a0f09', 'uploader': 'Lis Power', 'uploader_id': 'LisPower1', 'duration': 111.278, + 'timestamp': 1527623489, + 'upload_date': '20180529', }, 'params': { 'skip_download': True, # requires ffmpeg @@ -435,88 +354,168 @@ class TwitterIE(InfoExtractor): 'ext': 'mp4', 'title': 'Twitter - A new is coming. Some of you got an opt-in to try it now. Check out the emoji button, quick keyboard shortcuts, upgraded trends, advanced search, and more. Let us know your thoughts!', 'thumbnail': r're:^https?://.*\.jpg', - 'description': 'md5:66d493500c013e3e2d434195746a7f78', + 'description': 'md5:6dfd341a3310fb97d80d2bf7145df976', 'uploader': 'Twitter', 'uploader_id': 'Twitter', 'duration': 61.567, + 'timestamp': 1548184644, + 'upload_date': '20190122', + }, + }, { + # not available in Periscope + 'url': 'https://twitter.com/ViviEducation/status/1136534865145286656', + 'info_dict': { + 'id': '1vOGwqejwoWxB', + 'ext': 'mp4', + 'title': 'Vivi - Vivi founder @lior_rauchy announcing our new student feedback tool live at @EduTECH_AU #EduTECH2019', + 'uploader': 'Vivi', + 'uploader_id': '1eVjYOLGkGrQL', }, + 'add_ie': ['TwitterBroadcast'], + }, { + # Twitch Clip Embed + 'url': 'https://twitter.com/GunB1g/status/1163218564784017422', + 'only_matching': True, + }, { + # promo_video_website card + 'url': 'https://twitter.com/GunB1g/status/1163218564784017422', + 'only_matching': True, }] def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - twid = mobj.group('id') - - webpage, urlh = self._download_webpage_handle( - self._TEMPLATE_STATUSES_URL % twid, twid) - - if 'twitter.com/account/suspended' in urlh.geturl(): - raise ExtractorError('Account suspended by Twitter.', expected=True) - - user_id = None - - redirect_mobj = re.match(self._VALID_URL, urlh.geturl()) - if redirect_mobj: - user_id = redirect_mobj.group('user_id') - - if not user_id: - user_id = mobj.group('user_id') - - username = remove_end(self._og_search_title(webpage), ' on Twitter') - - title = description = self._og_search_description(webpage).strip('').replace('\n', ' ').strip('“”') + twid = self._match_id(url) + status = self._call_api( + 'statuses/show/%s.json' % twid, twid, { + 'cards_platform': 'Web-12', + 'include_cards': 1, + 'include_reply_count': 1, + 'include_user_entities': 0, + 'tweet_mode': 'extended', + }) + title = description = status['full_text'].replace('\n', ' ') # strip 'https -_t.co_BJYgOjSeGA' junk from filenames title = re.sub(r'\s+(https?://[^ ]+)', '', title) + user = status.get('user') or {} + uploader = user.get('name') + if uploader: + title = '%s - %s' % (uploader, title) + uploader_id = user.get('screen_name') + + tags = [] + for hashtag in (try_get(status, lambda x: x['entities']['hashtags'], list) or []): + hashtag_text = hashtag.get('text') + if not hashtag_text: + continue + tags.append(hashtag_text) info = { - 'uploader_id': user_id, - 'uploader': username, - 'webpage_url': url, - 'description': '%s on Twitter: "%s"' % (username, description), - 'title': username + ' - ' + title, + 'id': twid, + 'title': title, + 'description': description, + 'uploader': uploader, + 'timestamp': unified_timestamp(status.get('created_at')), + 'uploader_id': uploader_id, + 'uploader_url': 'https://twitter.com/' + uploader_id if uploader_id else None, + 'like_count': int_or_none(status.get('favorite_count')), + 'repost_count': int_or_none(status.get('retweet_count')), + 'comment_count': int_or_none(status.get('reply_count')), + 'age_limit': 18 if status.get('possibly_sensitive') else 0, + 'tags': tags, } - mobj = re.search(r'''(?x) - ]+class="animated-gif"(?P[^>]+)>\s* - ]+video-src="(?P[^"]+)" - ''', webpage) - - if mobj: - more_info = mobj.group('more_info') - height = int_or_none(self._search_regex( - r'data-height="(\d+)"', more_info, 'height', fatal=False)) - width = int_or_none(self._search_regex( - r'data-width="(\d+)"', more_info, 'width', fatal=False)) - thumbnail = self._search_regex( - r'poster="([^"]+)"', more_info, 'poster', fatal=False) - info.update({ - 'id': twid, - 'url': mobj.group('url'), - 'height': height, - 'width': width, - 'thumbnail': thumbnail, - }) - return info - - twitter_card_url = None - if 'class="PlayableMedia' in webpage: - twitter_card_url = '%s//twitter.com/i/videos/tweet/%s' % (self.http_scheme(), twid) - else: - twitter_card_iframe_url = self._search_regex( - r'data-full-card-iframe-url=([\'"])(?P(?:(?!\1).)+)\1', - webpage, 'Twitter card iframe URL', default=None, group='url') - if twitter_card_iframe_url: - twitter_card_url = compat_urlparse.urljoin(url, twitter_card_iframe_url) + media = try_get(status, lambda x: x['extended_entities']['media'][0]) + if media and media.get('type') != 'photo': + video_info = media.get('video_info') or {} + + formats = [] + for variant in video_info.get('variants', []): + formats.extend(self._extract_variant_formats(variant, twid)) + self._sort_formats(formats) + + thumbnails = [] + media_url = media.get('media_url_https') or media.get('media_url') + if media_url: + def add_thumbnail(name, size): + thumbnails.append({ + 'id': name, + 'url': update_url_query(media_url, {'name': name}), + 'width': int_or_none(size.get('w') or size.get('width')), + 'height': int_or_none(size.get('h') or size.get('height')), + }) + for name, size in media.get('sizes', {}).items(): + add_thumbnail(name, size) + add_thumbnail('orig', media.get('original_info') or {}) - if twitter_card_url: info.update({ - '_type': 'url_transparent', - 'ie_key': 'TwitterCard', - 'url': twitter_card_url, + 'formats': formats, + 'thumbnails': thumbnails, + 'duration': float_or_none(video_info.get('duration_millis'), 1000), }) - return info - - raise ExtractorError('There\'s no video in this tweet.') + else: + card = status.get('card') + if card: + binding_values = card['binding_values'] + + def get_binding_value(k): + o = binding_values.get(k) or {} + return try_get(o, lambda x: x[x['type'].lower() + '_value']) + + card_name = card['name'].split(':')[-1] + if card_name in ('amplify', 'promo_video_website'): + is_amplify = card_name == 'amplify' + vmap_url = get_binding_value('amplify_url_vmap') if is_amplify else get_binding_value('player_stream_url') + content_id = get_binding_value('%s_content_id' % (card_name if is_amplify else 'player')) + formats = self._extract_formats_from_vmap_url(vmap_url, content_id or twid) + self._sort_formats(formats) + + thumbnails = [] + for suffix in ('_small', '', '_large', '_x_large', '_original'): + image = get_binding_value('player_image' + suffix) or {} + image_url = image.get('url') + if not image_url or '/player-placeholder' in image_url: + continue + thumbnails.append({ + 'id': suffix[1:] if suffix else 'medium', + 'url': image_url, + 'width': int_or_none(image.get('width')), + 'height': int_or_none(image.get('height')), + }) + + info.update({ + 'formats': formats, + 'thumbnails': thumbnails, + 'duration': int_or_none(get_binding_value( + 'content_duration_seconds')), + }) + elif card_name == 'player': + info.update({ + '_type': 'url', + 'url': get_binding_value('player_url'), + }) + elif card_name == 'periscope_broadcast': + info.update({ + '_type': 'url', + 'url': get_binding_value('url') or get_binding_value('player_url'), + 'ie_key': PeriscopeIE.ie_key(), + }) + elif card_name == 'broadcast': + info.update({ + '_type': 'url', + 'url': get_binding_value('broadcast_url'), + 'ie_key': TwitterBroadcastIE.ie_key(), + }) + else: + raise ExtractorError('Unsupported Twitter Card.') + else: + expanded_url = try_get(status, lambda x: x['entities']['urls'][0]['expanded_url']) + if not expanded_url: + raise ExtractorError("There's no video in this tweet.") + info.update({ + '_type': 'url', + 'url': expanded_url, + }) + return info class TwitterAmplifyIE(TwitterBaseIE): @@ -573,3 +572,27 @@ class TwitterAmplifyIE(TwitterBaseIE): 'formats': formats, 'thumbnails': thumbnails, } + + +class TwitterBroadcastIE(TwitterBaseIE, PeriscopeBaseIE): + IE_NAME = 'twitter:broadcast' + _VALID_URL = TwitterBaseIE._BASE_REGEX + r'i/broadcasts/(?P[0-9a-zA-Z]{13})' + + def _real_extract(self, url): + broadcast_id = self._match_id(url) + broadcast = self._call_api( + 'broadcasts/show.json', broadcast_id, + {'ids': broadcast_id})['broadcasts'][broadcast_id] + info = self._parse_broadcast_data(broadcast, broadcast_id) + media_key = broadcast['media_key'] + source = self._call_api( + 'live_video_stream/status/' + media_key, media_key)['source'] + m3u8_url = source.get('noRedirectPlaybackUrl') or source['location'] + if '/live_video_stream/geoblocked/' in m3u8_url: + self.raise_geo_restricted() + m3u8_id = compat_parse_qs(compat_urllib_parse_urlparse( + m3u8_url).query).get('type', [None])[0] + state, width, height = self._extract_common_format_info(broadcast) + info['formats'] = self._extract_pscp_m3u8_formats( + m3u8_url, broadcast_id, m3u8_id, state, width, height) + return info diff --git a/youtube_dl/extractor/ufctv.py b/youtube_dl/extractor/ufctv.py index f3eaee6..3d74ba0 100644 --- a/youtube_dl/extractor/ufctv.py +++ b/youtube_dl/extractor/ufctv.py @@ -1,73 +1,16 @@ # coding: utf-8 from __future__ import unicode_literals -from .common import InfoExtractor -from ..utils import ( - ExtractorError, - parse_duration, - parse_iso8601, - urlencode_postdata, -) +from .imggaming import ImgGamingBaseIE -class UFCTVIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?ufc\.tv/video/(?P[^/]+)' +class UFCTVIE(ImgGamingBaseIE): + _VALID_URL = ImgGamingBaseIE._VALID_URL_TEMPL % r'(?:(?:app|www)\.)?(?:ufc\.tv|(?:ufc)?fightpass\.com)|ufcfightpass\.img(?:dge|gaming)\.com' _NETRC_MACHINE = 'ufctv' - _TEST = { - 'url': 'https://www.ufc.tv/video/ufc-219-countdown-full-episode', - 'info_dict': { - 'id': '34167', - 'ext': 'mp4', - 'title': 'UFC 219 Countdown: Full Episode', - 'description': 'md5:26d4e8bf4665ae5878842d7050c3c646', - 'timestamp': 1513962360, - 'upload_date': '20171222', - }, - 'params': { - # m3u8 download - 'skip_download': True, - } - } + _REALM = 'ufc' - def _real_initialize(self): - username, password = self._get_login_info() - if username is None: - return - code = self._download_json( - 'https://www.ufc.tv/secure/authenticate', - None, 'Logging in', data=urlencode_postdata({ - 'username': username, - 'password': password, - 'format': 'json', - })).get('code') - if code and code != 'loginsuccess': - raise ExtractorError(code, expected=True) - - def _real_extract(self, url): - display_id = self._match_id(url) - video_data = self._download_json(url, display_id, query={ - 'format': 'json', - }) - video_id = str(video_data['id']) - title = video_data['name'] - m3u8_url = self._download_json( - 'https://www.ufc.tv/service/publishpoint', video_id, query={ - 'type': 'video', - 'format': 'json', - 'id': video_id, - }, headers={ - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0_1 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A402 Safari/604.1', - })['path'] - m3u8_url = m3u8_url.replace('_iphone.', '.') - formats = self._extract_m3u8_formats(m3u8_url, video_id, 'mp4') - self._sort_formats(formats) - - return { - 'id': video_id, - 'title': title, - 'description': video_data.get('description'), - 'duration': parse_duration(video_data.get('runtime')), - 'timestamp': parse_iso8601(video_data.get('releaseDate')), - 'formats': formats, - } +class UFCArabiaIE(ImgGamingBaseIE): + _VALID_URL = ImgGamingBaseIE._VALID_URL_TEMPL % r'(?:(?:app|www)\.)?ufcarabia\.(?:ae|com)' + _NETRC_MACHINE = 'ufcarabia' + _REALM = 'admufc' diff --git a/youtube_dl/extractor/vessel.py b/youtube_dl/extractor/vessel.py deleted file mode 100644 index 31eee0b..0000000 --- a/youtube_dl/extractor/vessel.py +++ /dev/null @@ -1,157 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import json -import re - -from .common import InfoExtractor -from ..utils import ( - ExtractorError, - parse_iso8601, - sanitized_Request, -) - - -class VesselIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?vessel\.com/(?:videos|embed)/(?P[0-9a-zA-Z-_]+)' - _API_URL_TEMPLATE = 'https://www.vessel.com/api/view/items/%s' - _LOGIN_URL = 'https://www.vessel.com/api/account/login' - _NETRC_MACHINE = 'vessel' - _TESTS = [{ - 'url': 'https://www.vessel.com/videos/HDN7G5UMs', - 'md5': '455cdf8beb71c6dd797fd2f3818d05c4', - 'info_dict': { - 'id': 'HDN7G5UMs', - 'ext': 'mp4', - 'title': 'Nvidia GeForce GTX Titan X - The Best Video Card on the Market?', - 'thumbnail': r're:^https?://.*\.jpg$', - 'upload_date': '20150317', - 'description': 'Did Nvidia pull out all the stops on the Titan X, or does its performance leave something to be desired?', - 'timestamp': int, - }, - }, { - 'url': 'https://www.vessel.com/embed/G4U7gUJ6a?w=615&h=346', - 'only_matching': True, - }, { - 'url': 'https://www.vessel.com/videos/F01_dsLj1', - 'only_matching': True, - }, { - 'url': 'https://www.vessel.com/videos/RRX-sir-J', - 'only_matching': True, - }] - - @staticmethod - def _extract_urls(webpage): - return [url for _, url in re.findall( - r']+src=(["\'])((?:https?:)?//(?:www\.)?vessel\.com/embed/[0-9a-zA-Z-_]+.*?)\1', - webpage)] - - @staticmethod - def make_json_request(url, data): - payload = json.dumps(data).encode('utf-8') - req = sanitized_Request(url, payload) - req.add_header('Content-Type', 'application/json; charset=utf-8') - return req - - @staticmethod - def find_assets(data, asset_type, asset_id=None): - for asset in data.get('assets', []): - if not asset.get('type') == asset_type: - continue - elif asset_id is not None and not asset.get('id') == asset_id: - continue - else: - yield asset - - def _check_access_rights(self, data): - access_info = data.get('__view', {}) - if not access_info.get('allow_access', True): - err_code = access_info.get('error_code') or '' - if err_code == 'ITEM_PAID_ONLY': - raise ExtractorError( - 'This video requires subscription.', expected=True) - else: - raise ExtractorError( - 'Access to this content is restricted. (%s said: %s)' % (self.IE_NAME, err_code), expected=True) - - def _login(self): - username, password = self._get_login_info() - if username is None: - return - self.report_login() - data = { - 'client_id': 'web', - 'type': 'password', - 'user_key': username, - 'password': password, - } - login_request = VesselIE.make_json_request(self._LOGIN_URL, data) - self._download_webpage(login_request, None, False, 'Wrong login info') - - def _real_initialize(self): - self._login() - - def _real_extract(self, url): - video_id = self._match_id(url) - - webpage = self._download_webpage(url, video_id) - data = self._parse_json(self._search_regex( - r'App\.bootstrapData\((.*?)\);', webpage, 'data'), video_id) - asset_id = data['model']['data']['id'] - - req = VesselIE.make_json_request( - self._API_URL_TEMPLATE % asset_id, {'client': 'web'}) - data = self._download_json(req, video_id) - video_asset_id = data.get('main_video_asset') - - self._check_access_rights(data) - - try: - video_asset = next( - VesselIE.find_assets(data, 'video', asset_id=video_asset_id)) - except StopIteration: - raise ExtractorError('No video assets found') - - formats = [] - for f in video_asset.get('sources', []): - location = f.get('location') - if not location: - continue - name = f.get('name') - if name == 'hls-index': - formats.extend(self._extract_m3u8_formats( - location, video_id, ext='mp4', - entry_protocol='m3u8_native', m3u8_id='m3u8', fatal=False)) - elif name == 'dash-index': - formats.extend(self._extract_mpd_formats( - location, video_id, mpd_id='dash', fatal=False)) - else: - formats.append({ - 'format_id': name, - 'tbr': f.get('bitrate'), - 'height': f.get('height'), - 'width': f.get('width'), - 'url': location, - }) - self._sort_formats(formats) - - thumbnails = [] - for im_asset in VesselIE.find_assets(data, 'image'): - thumbnails.append({ - 'url': im_asset['location'], - 'width': im_asset.get('width', 0), - 'height': im_asset.get('height', 0), - }) - - return { - 'id': video_id, - 'title': data['title'], - 'formats': formats, - 'thumbnails': thumbnails, - 'description': data.get('short_description'), - 'duration': data.get('duration'), - 'comment_count': data.get('comment_count'), - 'like_count': data.get('like_count'), - 'view_count': data.get('view_count'), - 'timestamp': parse_iso8601(data.get('released_at')), - } diff --git a/youtube_dl/extractor/vice.py b/youtube_dl/extractor/vice.py index 8fdfd74..e374995 100644 --- a/youtube_dl/extractor/vice.py +++ b/youtube_dl/extractor/vice.py @@ -1,35 +1,50 @@ # coding: utf-8 from __future__ import unicode_literals -import re -import time +import functools import hashlib import json import random +import re +import time from .adobepass import AdobePassIE -from .youtube import YoutubeIE from .common import InfoExtractor +from .youtube import YoutubeIE from ..compat import ( compat_HTTPError, compat_str, ) from ..utils import ( + clean_html, ExtractorError, int_or_none, + OnDemandPagedList, parse_age_limit, str_or_none, try_get, ) -class ViceIE(AdobePassIE): +class ViceBaseIE(InfoExtractor): + def _call_api(self, resource, resource_key, resource_id, locale, fields, args=''): + return self._download_json( + 'https://video.vice.com/api/v1/graphql', resource_id, query={ + 'query': '''{ + %s(locale: "%s", %s: "%s"%s) { + %s + } +}''' % (resource, locale, resource_key, resource_id, args, fields), + })['data'][resource] + + +class ViceIE(ViceBaseIE, AdobePassIE): IE_NAME = 'vice' - _VALID_URL = r'https?://(?:(?:video|vms)\.vice|(?:www\.)?viceland)\.com/(?P[^/]+)/(?:video/[^/]+|embed)/(?P[\da-f]+)' + _VALID_URL = r'https?://(?:(?:video|vms)\.vice|(?:www\.)?vice(?:land|tv))\.com/(?P[^/]+)/(?:video/[^/]+|embed)/(?P[\da-f]{24})' _TESTS = [{ 'url': 'https://video.vice.com/en_us/video/pet-cremator/58c69e38a55424f1227dc3f7', 'info_dict': { - 'id': '5e647f0125e145c9aef2069412c0cbde', + 'id': '58c69e38a55424f1227dc3f7', 'ext': 'mp4', 'title': '10 Questions You Always Wanted To Ask: Pet Cremator', 'description': 'md5:fe856caacf61fe0e74fab15ce2b07ca5', @@ -43,17 +58,16 @@ class ViceIE(AdobePassIE): # m3u8 download 'skip_download': True, }, - 'add_ie': ['UplynkPreplay'], }, { # geo restricted to US 'url': 'https://video.vice.com/en_us/video/the-signal-from-tolva/5816510690b70e6c5fd39a56', 'info_dict': { - 'id': '930c0ad1f47141cc955087eecaddb0e2', + 'id': '5816510690b70e6c5fd39a56', 'ext': 'mp4', - 'uploader': 'waypoint', + 'uploader': 'vice', 'title': 'The Signal From Tölva', 'description': 'md5:3927e3c79f9e8094606a2b3c5b5e55d5', - 'uploader_id': '57f7d621e05ca860fa9ccaf9', + 'uploader_id': '57a204088cb727dec794c67b', 'timestamp': 1477941983, 'upload_date': '20161031', }, @@ -61,15 +75,14 @@ class ViceIE(AdobePassIE): # m3u8 download 'skip_download': True, }, - 'add_ie': ['UplynkPreplay'], }, { 'url': 'https://video.vice.com/alps/video/ulfs-wien-beruchtigste-grafitti-crew-part-1/581b12b60a0e1f4c0fb6ea2f', 'info_dict': { 'id': '581b12b60a0e1f4c0fb6ea2f', 'ext': 'mp4', 'title': 'ULFs - Wien berüchtigste Grafitti Crew - Part 1', - 'description': '

Zwischen Hinterzimmer-Tattoos und U-Bahnschächten erzählen uns die Ulfs, wie es ist, "süchtig nach Sachbeschädigung" zu sein.

', - 'uploader': 'VICE', + 'description': 'Zwischen Hinterzimmer-Tattoos und U-Bahnschächten erzählen uns die Ulfs, wie es ist, "süchtig nach Sachbeschädigung" zu sein.', + 'uploader': 'vice', 'uploader_id': '57a204088cb727dec794c67b', 'timestamp': 1485368119, 'upload_date': '20170125', @@ -78,9 +91,7 @@ class ViceIE(AdobePassIE): 'params': { # AES-encrypted m3u8 'skip_download': True, - 'proxy': '127.0.0.1:8118', }, - 'add_ie': ['UplynkPreplay'], }, { 'url': 'https://video.vice.com/en_us/video/pizza-show-trailer/56d8c9a54d286ed92f7f30e4', 'only_matching': True, @@ -98,7 +109,7 @@ class ViceIE(AdobePassIE): @staticmethod def _extract_urls(webpage): return re.findall( - r']+\bsrc=["\']((?:https?:)?//video\.vice\.com/[^/]+/embed/[\da-f]+)', + r']+\bsrc=["\']((?:https?:)?//video\.vice\.com/[^/]+/embed/[\da-f]{24})', webpage) @staticmethod @@ -109,31 +120,16 @@ class ViceIE(AdobePassIE): def _real_extract(self, url): locale, video_id = re.match(self._VALID_URL, url).groups() - webpage = self._download_webpage( - 'https://video.vice.com/%s/embed/%s' % (locale, video_id), - video_id) - - video = self._parse_json( - self._search_regex( - r'PREFETCH_DATA\s*=\s*({.+?})\s*;\s*\n', webpage, - 'app state'), video_id)['video'] - video_id = video.get('vms_id') or video.get('id') or video_id - title = video['title'] - is_locked = video.get('locked') + video = self._call_api('videos', 'id', video_id, locale, '''body + locked + rating + thumbnail_url + title''')[0] + title = video['title'].strip() rating = video.get('rating') - thumbnail = video.get('thumbnail_url') - duration = int_or_none(video.get('duration')) - series = try_get( - video, lambda x: x['episode']['season']['show']['title'], - compat_str) - episode_number = try_get( - video, lambda x: x['episode']['episode_number']) - season_number = try_get( - video, lambda x: x['episode']['season']['season_number']) - uploader = None query = {} - if is_locked: + if video.get('locked'): resource = self._get_mvpd_resource( 'VICELAND', title, video_id, rating) query['tvetoken'] = self._extract_mvpd_auth( @@ -148,12 +144,9 @@ class ViceIE(AdobePassIE): query.update({ 'exp': exp, 'sign': hashlib.sha512(('%s:GET:%d' % (video_id, exp)).encode()).hexdigest(), - '_ad_blocked': None, - '_ad_unit': '', - '_debug': '', + 'skipadstitching': 1, 'platform': 'desktop', 'rn': random.randint(10000, 100000), - 'fbprebidtoken': '', }) try: @@ -169,85 +162,94 @@ class ViceIE(AdobePassIE): raise video_data = preplay['video'] - base = video_data['base'] - uplynk_preplay_url = preplay['preplayURL'] - episode = video_data.get('episode', {}) - channel = video_data.get('channel', {}) + formats = self._extract_m3u8_formats( + preplay['playURL'], video_id, 'mp4', 'm3u8_native') + self._sort_formats(formats) + episode = video_data.get('episode') or {} + channel = video_data.get('channel') or {} + season = video_data.get('season') or {} subtitles = {} - cc_url = preplay.get('ccURL') - if cc_url: - subtitles['en'] = [{ + for subtitle in preplay.get('subtitleURLs', []): + cc_url = subtitle.get('url') + if not cc_url: + continue + language_code = try_get(subtitle, lambda x: x['languages'][0]['language_code'], compat_str) or 'en' + subtitles.setdefault(language_code, []).append({ 'url': cc_url, - }] + }) return { - '_type': 'url_transparent', - 'url': uplynk_preplay_url, + 'formats': formats, 'id': video_id, 'title': title, - 'description': base.get('body') or base.get('display_body'), - 'thumbnail': thumbnail, - 'duration': int_or_none(video_data.get('video_duration')) or duration, + 'description': clean_html(video.get('body')), + 'thumbnail': video.get('thumbnail_url'), + 'duration': int_or_none(video_data.get('video_duration')), 'timestamp': int_or_none(video_data.get('created_at'), 1000), - 'age_limit': parse_age_limit(video_data.get('video_rating')), - 'series': video_data.get('show_title') or series, - 'episode_number': int_or_none(episode.get('episode_number') or episode_number), + 'age_limit': parse_age_limit(video_data.get('video_rating') or rating), + 'series': try_get(video_data, lambda x: x['show']['base']['display_title'], compat_str), + 'episode_number': int_or_none(episode.get('episode_number')), 'episode_id': str_or_none(episode.get('id') or video_data.get('episode_id')), - 'season_number': int_or_none(season_number), - 'season_id': str_or_none(episode.get('season_id')), - 'uploader': channel.get('base', {}).get('title') or channel.get('name') or uploader, + 'season_number': int_or_none(season.get('season_number')), + 'season_id': str_or_none(season.get('id') or video_data.get('season_id')), + 'uploader': channel.get('name'), 'uploader_id': str_or_none(channel.get('id')), 'subtitles': subtitles, - 'ie_key': 'UplynkPreplay', } -class ViceShowIE(InfoExtractor): +class ViceShowIE(ViceBaseIE): IE_NAME = 'vice:show' - _VALID_URL = r'https?://(?:.+?\.)?vice\.com/(?:[^/]+/)?show/(?P[^/?#&]+)' - - _TEST = { - 'url': 'https://munchies.vice.com/en/show/fuck-thats-delicious-2', + _VALID_URL = r'https?://(?:video\.vice|(?:www\.)?vice(?:land|tv))\.com/(?P[^/]+)/show/(?P[^/?#&]+)' + _PAGE_SIZE = 25 + _TESTS = [{ + 'url': 'https://video.vice.com/en_us/show/fck-thats-delicious', 'info_dict': { - 'id': 'fuck-thats-delicious-2', - 'title': "Fuck, That's Delicious", - 'description': 'Follow the culinary adventures of rapper Action Bronson during his ongoing world tour.', + 'id': '57a2040c8cb727dec794c901', + 'title': 'F*ck, That’s Delicious', + 'description': 'The life and eating habits of rap’s greatest bon vivant, Action Bronson.', }, - 'playlist_count': 17, - } + 'playlist_mincount': 64, + }, { + 'url': 'https://www.vicetv.com/en_us/show/fck-thats-delicious', + 'only_matching': True, + }] - def _real_extract(self, url): - show_id = self._match_id(url) - webpage = self._download_webpage(url, show_id) + def _fetch_page(self, locale, show_id, page): + videos = self._call_api('videos', 'show_id', show_id, locale, '''body + id + url''', ', page: %d, per_page: %d' % (page + 1, self._PAGE_SIZE)) + for video in videos: + yield self.url_result( + video['url'], ViceIE.ie_key(), video.get('id')) - entries = [ - self.url_result(video_url, ViceIE.ie_key()) - for video_url, _ in re.findall( - r']+class="article-title"[^>]+data-id="\d+"[^>]*>\s*]+href="(%s.*?)"' - % ViceIE._VALID_URL, webpage)] + def _real_extract(self, url): + locale, display_id = re.match(self._VALID_URL, url).groups() + show = self._call_api('shows', 'slug', display_id, locale, '''dek + id + title''')[0] + show_id = show['id'] - title = self._search_regex( - r'(.+?)', webpage, 'title', default=None) - if title: - title = re.sub(r'(.+)\s*\|\s*.+$', r'\1', title).strip() - description = self._html_search_meta( - 'description', webpage, 'description') + entries = OnDemandPagedList( + functools.partial(self._fetch_page, locale, show_id), + self._PAGE_SIZE) - return self.playlist_result(entries, show_id, title, description) + return self.playlist_result( + entries, show_id, show.get('title'), show.get('dek')) -class ViceArticleIE(InfoExtractor): +class ViceArticleIE(ViceBaseIE): IE_NAME = 'vice:article' - _VALID_URL = r'https://www\.vice\.com/[^/]+/article/(?P[^?#]+)' + _VALID_URL = r'https://(?:www\.)?vice\.com/(?P[^/]+)/article/(?:[0-9a-z]{6}/)?(?P[^?#]+)' _TESTS = [{ 'url': 'https://www.vice.com/en_us/article/on-set-with-the-woman-making-mormon-porn-in-utah', 'info_dict': { - 'id': '41eae2a47b174a1398357cec55f1f6fc', + 'id': '58dc0a3dee202d2a0ccfcbd8', 'ext': 'mp4', - 'title': 'Mormon War on Porn ', - 'description': 'md5:6394a8398506581d0346b9ab89093fef', + 'title': 'Mormon War on Porn', + 'description': 'md5:1c5d91fe25fa8aa304f9def118b92dbf', 'uploader': 'vice', 'uploader_id': '57a204088cb727dec794c67b', 'timestamp': 1491883129, @@ -258,10 +260,10 @@ class ViceArticleIE(InfoExtractor): # AES-encrypted m3u8 'skip_download': True, }, - 'add_ie': ['UplynkPreplay'], + 'add_ie': [ViceIE.ie_key()], }, { 'url': 'https://www.vice.com/en_us/article/how-to-hack-a-car', - 'md5': '7fe8ebc4fa3323efafc127b82bd821d9', + 'md5': '13010ee0bc694ea87ec40724397c2349', 'info_dict': { 'id': '3jstaBeXgAs', 'ext': 'mp4', @@ -271,15 +273,15 @@ class ViceArticleIE(InfoExtractor): 'uploader_id': 'MotherboardTV', 'upload_date': '20140529', }, - 'add_ie': ['Youtube'], + 'add_ie': [YoutubeIE.ie_key()], }, { 'url': 'https://www.vice.com/en_us/article/znm9dx/karley-sciortino-slutever-reloaded', 'md5': 'a7ecf64ee4fa19b916c16f4b56184ae2', 'info_dict': { - 'id': 'e2ed435eb67e43efb66e6ef9a6930a88', + 'id': '57f41d3556a0a80f54726060', 'ext': 'mp4', 'title': "Making The World's First Male Sex Doll", - 'description': 'md5:916078ef0e032d76343116208b6cc2c4', + 'description': 'md5:19b00b215b99961cf869c40fbe9df755', 'uploader': 'vice', 'uploader_id': '57a204088cb727dec794c67b', 'timestamp': 1476919911, @@ -288,6 +290,7 @@ class ViceArticleIE(InfoExtractor): }, 'params': { 'skip_download': True, + 'format': 'bestvideo', }, 'add_ie': [ViceIE.ie_key()], }, { @@ -299,14 +302,11 @@ class ViceArticleIE(InfoExtractor): }] def _real_extract(self, url): - display_id = self._match_id(url) - - webpage = self._download_webpage(url, display_id) + locale, display_id = re.match(self._VALID_URL, url).groups() - prefetch_data = self._parse_json(self._search_regex( - r'__APP_STATE\s*=\s*({.+?})(?:\s*\|\|\s*{}\s*)?;\s*\n', - webpage, 'app state'), display_id)['pageData'] - body = prefetch_data['body'] + article = self._call_api('articles', 'slug', display_id, locale, '''body + embed_code''')[0] + body = article['body'] def _url_res(video_url, ie_key): return { @@ -316,7 +316,7 @@ class ViceArticleIE(InfoExtractor): 'ie_key': ie_key, } - vice_url = ViceIE._extract_url(webpage) + vice_url = ViceIE._extract_url(body) if vice_url: return _url_res(vice_url, ViceIE.ie_key()) @@ -332,6 +332,6 @@ class ViceArticleIE(InfoExtractor): video_url = self._html_search_regex( r'data-video-url="([^"]+)"', - prefetch_data['embed_code'], 'video URL') + article['embed_code'], 'video URL') return _url_res(video_url, ViceIE.ie_key()) diff --git a/youtube_dl/extractor/videodetective.py b/youtube_dl/extractor/videodetective.py index a19411a..fe70db7 100644 --- a/youtube_dl/extractor/videodetective.py +++ b/youtube_dl/extractor/videodetective.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals from .common import InfoExtractor -from ..compat import compat_urlparse from .internetvideoarchive import InternetVideoArchiveIE @@ -13,7 +12,7 @@ class VideoDetectiveIE(InfoExtractor): 'info_dict': { 'id': '194487', 'ext': 'mp4', - 'title': 'KICK-ASS 2', + 'title': 'Kick-Ass 2', 'description': 'md5:c189d5b7280400630a1d3dd17eaa8d8a', }, 'params': { @@ -24,7 +23,7 @@ class VideoDetectiveIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - og_video = self._og_search_video_url(webpage) - query = compat_urlparse.urlparse(og_video).query - return self.url_result(InternetVideoArchiveIE._build_json_url(query), ie=InternetVideoArchiveIE.ie_key()) + query = 'customerid=69249&publishedid=' + video_id + return self.url_result( + InternetVideoArchiveIE._build_json_url(query), + ie=InternetVideoArchiveIE.ie_key()) diff --git a/youtube_dl/extractor/videopremium.py b/youtube_dl/extractor/videopremium.py deleted file mode 100644 index cf690d7..0000000 --- a/youtube_dl/extractor/videopremium.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import unicode_literals - -import re -import random - -from .common import InfoExtractor - - -class VideoPremiumIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?videopremium\.(?:tv|me)/(?P\w+)(?:/.*)?' - _TEST = { - 'url': 'http://videopremium.tv/4w7oadjsf156', - 'info_dict': { - 'id': '4w7oadjsf156', - 'ext': 'f4v', - 'title': 'youtube-dl_test_video____a_________-BaW_jenozKc.mp4.mp4' - }, - 'params': { - 'skip_download': True, - }, - 'skip': 'Test file has been deleted.', - } - - def _real_extract(self, url): - video_id = self._match_id(url) - webpage_url = 'http://videopremium.tv/' + video_id - webpage = self._download_webpage(webpage_url, video_id) - - if re.match(r'^]*>window\.location\s*=', webpage): - # Download again, we need a cookie - webpage = self._download_webpage( - webpage_url, video_id, - note='Downloading webpage again (with cookie)') - - video_title = self._html_search_regex( - r'\s*(.+?)\s*<', webpage, 'video title') - - return { - 'id': video_id, - 'url': 'rtmp://e%d.md.iplay.md/play' % random.randint(1, 16), - 'play_path': 'mp4:%s.f4v' % video_id, - 'page_url': 'http://videopremium.tv/' + video_id, - 'player_url': 'http://videopremium.tv/uplayer/uppod.swf', - 'ext': 'f4v', - 'title': video_title, - } diff --git a/youtube_dl/extractor/viewlift.py b/youtube_dl/extractor/viewlift.py index c43d1a1..851ad93 100644 --- a/youtube_dl/extractor/viewlift.py +++ b/youtube_dl/extractor/viewlift.py @@ -13,11 +13,12 @@ from ..utils import ( js_to_json, parse_age_limit, parse_duration, + try_get, ) class ViewLiftBaseIE(InfoExtractor): - _DOMAINS_REGEX = r'(?:snagfilms|snagxtreme|funnyforfree|kiddovid|winnersview|(?:monumental|lax)sportsnetwork|vayafilm)\.com|hoichoi\.tv' + _DOMAINS_REGEX = r'(?:(?:main\.)?snagfilms|snagxtreme|funnyforfree|kiddovid|winnersview|(?:monumental|lax)sportsnetwork|vayafilm)\.com|hoichoi\.tv' class ViewLiftEmbedIE(ViewLiftBaseIE): @@ -113,7 +114,7 @@ class ViewLiftEmbedIE(ViewLiftBaseIE): class ViewLiftIE(ViewLiftBaseIE): - _VALID_URL = r'https?://(?:www\.)?(?P%s)/(?:films/title|show|(?:news/)?videos?)/(?P[^?#]+)' % ViewLiftBaseIE._DOMAINS_REGEX + _VALID_URL = r'https?://(?:www\.)?(?P%s)(?:/(?:films/title|show|(?:news/)?videos?))?/(?P[^?#]+)' % ViewLiftBaseIE._DOMAINS_REGEX _TESTS = [{ 'url': 'http://www.snagfilms.com/films/title/lost_for_life', 'md5': '19844f897b35af219773fd63bdec2942', @@ -128,7 +129,7 @@ class ViewLiftIE(ViewLiftBaseIE): 'categories': 'mincount:3', 'age_limit': 14, 'upload_date': '20150421', - 'timestamp': 1429656819, + 'timestamp': 1429656820, } }, { 'url': 'http://www.snagfilms.com/show/the_world_cut_project/india', @@ -141,10 +142,26 @@ class ViewLiftIE(ViewLiftBaseIE): 'description': 'md5:5c168c5a8f4719c146aad2e0dfac6f5f', 'thumbnail': r're:^https?://.*\.jpg', 'duration': 979, - 'categories': 'mincount:2', 'timestamp': 1399478279, 'upload_date': '20140507', } + }, { + 'url': 'http://main.snagfilms.com/augie_alone/s_2_ep_12_love', + 'info_dict': { + 'id': '00000148-7b53-de26-a9fb-fbf306f70020', + 'display_id': 'augie_alone/s_2_ep_12_love', + 'ext': 'mp4', + 'title': 'Augie, Alone:S. 2 Ep. 12 - Love', + 'description': 'md5:db2a5c72d994f16a780c1eb353a8f403', + 'thumbnail': r're:^https?://.*\.jpg', + 'duration': 107, + }, + 'params': { + 'skip_download': True, + }, + }, { + 'url': 'http://main.snagfilms.com/films/title/the_freebie', + 'only_matching': True, }, { # Film is not playable in your area. 'url': 'http://www.snagfilms.com/films/title/inside_mecca', @@ -162,6 +179,10 @@ class ViewLiftIE(ViewLiftBaseIE): 'only_matching': True, }] + @classmethod + def suitable(cls, url): + return False if ViewLiftEmbedIE.suitable(url) else super(ViewLiftIE, cls).suitable(url) + def _real_extract(self, url): domain, display_id = re.match(self._VALID_URL, url).groups() @@ -181,7 +202,21 @@ class ViewLiftIE(ViewLiftBaseIE): gist = content_data['gist'] film_id = gist['id'] title = gist['title'] - video_assets = content_data['streamingInfo']['videoAssets'] + video_assets = try_get( + content_data, lambda x: x['streamingInfo']['videoAssets'], dict) + if not video_assets: + token = self._download_json( + 'https://prod-api.viewlift.com/identity/anonymous-token', + film_id, 'Downloading authorization token', + query={'site': 'snagfilms'})['authorizationToken'] + video_assets = self._download_json( + 'https://prod-api.viewlift.com/entitlement/video/status', + film_id, headers={ + 'Authorization': token, + 'Referer': url, + }, query={ + 'id': film_id + })['video']['streamingInfo']['videoAssets'] formats = [] mpeg_video_assets = video_assets.get('mpeg') or [] @@ -241,8 +276,9 @@ class ViewLiftIE(ViewLiftBaseIE): if category.get('title')] break else: - title = self._search_regex( - r'itemprop="title">([^<]+)<', webpage, 'title') + title = self._html_search_regex( + (r'itemprop="title">([^<]+)<', + r'(?s)itemprop="title">(.+?)(.+?)', webpage, 'description', default=None) or self._og_search_description(webpage) diff --git a/youtube_dl/extractor/viewster.py b/youtube_dl/extractor/viewster.py deleted file mode 100644 index 6e31847..0000000 --- a/youtube_dl/extractor/viewster.py +++ /dev/null @@ -1,217 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..compat import ( - compat_HTTPError, - compat_urllib_parse_unquote, -) -from ..utils import ( - determine_ext, - ExtractorError, - int_or_none, - parse_iso8601, - sanitized_Request, - HEADRequest, - url_basename, -) - - -class ViewsterIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?viewster\.com/(?:serie|movie)/(?P\d+-\d+-\d+)' - _TESTS = [{ - # movie, Type=Movie - 'url': 'http://www.viewster.com/movie/1140-11855-000/the-listening-project/', - 'md5': 'e642d1b27fcf3a4ffa79f194f5adde36', - 'info_dict': { - 'id': '1140-11855-000', - 'ext': 'mp4', - 'title': 'The listening Project', - 'description': 'md5:bac720244afd1a8ea279864e67baa071', - 'timestamp': 1214870400, - 'upload_date': '20080701', - 'duration': 4680, - }, - }, { - # series episode, Type=Episode - 'url': 'http://www.viewster.com/serie/1284-19427-001/the-world-and-a-wall/', - 'md5': '9243079a8531809efe1b089db102c069', - 'info_dict': { - 'id': '1284-19427-001', - 'ext': 'mp4', - 'title': 'The World and a Wall', - 'description': 'md5:24814cf74d3453fdf5bfef9716d073e3', - 'timestamp': 1428192000, - 'upload_date': '20150405', - 'duration': 1500, - }, - }, { - # serie, Type=Serie - 'url': 'http://www.viewster.com/serie/1303-19426-000/', - 'info_dict': { - 'id': '1303-19426-000', - 'title': 'Is It Wrong to Try to Pick up Girls in a Dungeon?', - 'description': 'md5:eeda9bef25b0d524b3a29a97804c2f11', - }, - 'playlist_count': 13, - }, { - # unfinished serie, no Type - 'url': 'http://www.viewster.com/serie/1284-19427-000/baby-steps-season-2/', - 'info_dict': { - 'id': '1284-19427-000', - 'title': 'Baby Steps—Season 2', - 'description': 'md5:e7097a8fc97151e25f085c9eb7a1cdb1', - }, - 'playlist_mincount': 16, - }, { - # geo restricted series - 'url': 'https://www.viewster.com/serie/1280-18794-002/', - 'only_matching': True, - }, { - # geo restricted video - 'url': 'https://www.viewster.com/serie/1280-18794-002/what-is-extraterritoriality-lawo/', - 'only_matching': True, - }] - - _ACCEPT_HEADER = 'application/json, text/javascript, */*; q=0.01' - - def _download_json(self, url, video_id, note='Downloading JSON metadata', fatal=True, query={}): - request = sanitized_Request(url) - request.add_header('Accept', self._ACCEPT_HEADER) - request.add_header('Auth-token', self._AUTH_TOKEN) - return super(ViewsterIE, self)._download_json(request, video_id, note, fatal=fatal, query=query) - - def _real_extract(self, url): - video_id = self._match_id(url) - # Get 'api_token' cookie - self._request_webpage( - HEADRequest('http://www.viewster.com/'), - video_id, headers=self.geo_verification_headers()) - cookies = self._get_cookies('http://www.viewster.com/') - self._AUTH_TOKEN = compat_urllib_parse_unquote(cookies['api_token'].value) - - info = self._download_json( - 'https://public-api.viewster.com/search/%s' % video_id, - video_id, 'Downloading entry JSON') - - entry_id = info.get('Id') or info['id'] - - # unfinished serie has no Type - if info.get('Type') in ('Serie', None): - try: - episodes = self._download_json( - 'https://public-api.viewster.com/series/%s/episodes' % entry_id, - video_id, 'Downloading series JSON') - except ExtractorError as e: - if isinstance(e.cause, compat_HTTPError) and e.cause.code == 404: - self.raise_geo_restricted() - else: - raise - entries = [ - self.url_result( - 'http://www.viewster.com/movie/%s' % episode['OriginId'], 'Viewster') - for episode in episodes] - title = (info.get('Title') or info['Synopsis']['Title']).strip() - description = info.get('Synopsis', {}).get('Detailed') - return self.playlist_result(entries, video_id, title, description) - - formats = [] - for language_set in info.get('LanguageSets', []): - manifest_url = None - m3u8_formats = [] - audio = language_set.get('Audio') or '' - subtitle = language_set.get('Subtitle') or '' - base_format_id = audio - if subtitle: - base_format_id += '-%s' % subtitle - - def concat(suffix, sep='-'): - return (base_format_id + '%s%s' % (sep, suffix)) if base_format_id else suffix - - medias = self._download_json( - 'https://public-api.viewster.com/movies/%s/videos' % entry_id, - video_id, fatal=False, query={ - 'mediaTypes': ['application/f4m+xml', 'application/x-mpegURL', 'video/mp4'], - 'language': audio, - 'subtitle': subtitle, - }) - if not medias: - continue - for media in medias: - video_url = media.get('Uri') - if not video_url: - continue - ext = determine_ext(video_url) - if ext == 'f4m': - manifest_url = video_url - video_url += '&' if '?' in video_url else '?' - video_url += 'hdcore=3.2.0&plugin=flowplayer-3.2.0.1' - formats.extend(self._extract_f4m_formats( - video_url, video_id, f4m_id=concat('hds'))) - elif ext == 'm3u8': - manifest_url = video_url - m3u8_formats = self._extract_m3u8_formats( - video_url, video_id, 'mp4', m3u8_id=concat('hls'), - fatal=False) # m3u8 sometimes fail - if m3u8_formats: - formats.extend(m3u8_formats) - else: - qualities_basename = self._search_regex( - r'/([^/]+)\.csmil/', - manifest_url, 'qualities basename', default=None) - if not qualities_basename: - continue - QUALITIES_RE = r'((,\d+k)+,?)' - qualities = self._search_regex( - QUALITIES_RE, qualities_basename, - 'qualities', default=None) - if not qualities: - continue - qualities = list(map(lambda q: int(q[:-1]), qualities.strip(',').split(','))) - qualities.sort() - http_template = re.sub(QUALITIES_RE, r'%dk', qualities_basename) - http_url_basename = url_basename(video_url) - if m3u8_formats: - self._sort_formats(m3u8_formats) - m3u8_formats = list(filter( - lambda f: f.get('vcodec') != 'none', m3u8_formats)) - if len(qualities) == len(m3u8_formats): - for q, m3u8_format in zip(qualities, m3u8_formats): - f = m3u8_format.copy() - f.update({ - 'url': video_url.replace(http_url_basename, http_template % q), - 'format_id': f['format_id'].replace('hls', 'http'), - 'protocol': 'http', - }) - formats.append(f) - else: - for q in qualities: - formats.append({ - 'url': video_url.replace(http_url_basename, http_template % q), - 'ext': 'mp4', - 'format_id': 'http-%d' % q, - 'tbr': q, - }) - - if not formats and not info.get('VODSettings'): - self.raise_geo_restricted() - - self._sort_formats(formats) - - synopsis = info.get('Synopsis') or {} - # Prefer title outside synopsis since it's less messy - title = (info.get('Title') or synopsis['Title']).strip() - description = synopsis.get('Detailed') or (info.get('Synopsis') or {}).get('Short') - duration = int_or_none(info.get('Duration')) - timestamp = parse_iso8601(info.get('ReleaseDate')) - - return { - 'id': video_id, - 'title': title, - 'description': description, - 'timestamp': timestamp, - 'duration': duration, - 'formats': formats, - } diff --git a/youtube_dl/extractor/vimeo.py b/youtube_dl/extractor/vimeo.py index ddf375c..baa46d5 100644 --- a/youtube_dl/extractor/vimeo.py +++ b/youtube_dl/extractor/vimeo.py @@ -15,19 +15,20 @@ from ..compat import ( compat_urlparse, ) from ..utils import ( + clean_html, determine_ext, + dict_get, ExtractorError, js_to_json, int_or_none, merge_dicts, - NO_DEFAULT, OnDemandPagedList, parse_filesize, - qualities, RegexNotFoundError, sanitized_Request, smuggle_url, std_headers, + str_or_none, try_get, unified_timestamp, unsmuggle_url, @@ -211,6 +212,7 @@ class VimeoBaseInfoExtractor(InfoExtractor): video_uploader_url = owner.get('url') return { + 'id': str_or_none(video_data.get('id')) or video_id, 'title': self._live_title(video_title) if is_live else video_title, 'uploader': owner.get('name'), 'uploader_id': video_uploader_url.split('/')[-1] if video_uploader_url else None, @@ -258,11 +260,11 @@ class VimeoIE(VimeoBaseInfoExtractor): (?: (?: www| - (?Pplayer) + player ) \. )? - vimeo(?Ppro)?\.com/ + vimeo(?:pro)?\.com/ (?!(?:channels|album|showcase)/[^/?#]+/?(?:$|[?#])|[^/]+/review/|ondemand/) (?:.*?/)? (?: @@ -284,7 +286,7 @@ class VimeoIE(VimeoBaseInfoExtractor): 'id': '56015672', 'ext': 'mp4', 'title': "youtube-dl test video - \u2605 \" ' \u5e78 / \\ \u00e4 \u21ad \U0001d550", - 'description': 'md5:509a9ad5c9bf97c60faee9203aca4479', + 'description': 'md5:2d3305bad981a06ff79f027f19865021', 'timestamp': 1355990239, 'upload_date': '20121220', 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/user7108434', @@ -293,6 +295,9 @@ class VimeoIE(VimeoBaseInfoExtractor): 'duration': 10, 'license': 'by-sa', }, + 'params': { + 'format': 'best[protocol=https]', + }, }, { 'url': 'http://vimeopro.com/openstreetmapus/state-of-the-map-us-2013/video/68093876', @@ -305,8 +310,13 @@ class VimeoIE(VimeoBaseInfoExtractor): 'uploader_id': 'openstreetmapus', 'uploader': 'OpenStreetMap US', 'title': 'Andy Allan - Putting the Carto into OpenStreetMap Cartography', - 'description': 'md5:fd69a7b8d8c34a4e1d2ec2e4afd6ec30', + 'description': 'md5:2c362968038d4499f4d79f88458590c1', 'duration': 1595, + 'upload_date': '20130610', + 'timestamp': 1370893156, + }, + 'params': { + 'format': 'best[protocol=https]', }, }, { @@ -323,6 +333,10 @@ class VimeoIE(VimeoBaseInfoExtractor): 'duration': 3610, 'description': None, }, + 'params': { + 'format': 'best[protocol=https]', + }, + 'expected_warnings': ['Unable to download JSON metadata'], }, { 'url': 'http://vimeo.com/68375962', @@ -341,6 +355,7 @@ class VimeoIE(VimeoBaseInfoExtractor): 'description': 'md5:dca3ea23adb29ee387127bc4ddfce63f', }, 'params': { + 'format': 'best[protocol=https]', 'videopassword': 'youtube-dl', }, }, @@ -441,10 +456,14 @@ class VimeoIE(VimeoBaseInfoExtractor): 'uploader': '10Ft Films', 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/tenfootfilms', 'uploader_id': 'tenfootfilms', + 'description': 'md5:0fa704e05b04f91f40b7f3ca2e801384', + 'upload_date': '20130830', + 'timestamp': 1377853339, }, 'params': { 'skip_download': True, }, + 'expected_warnings': ['Unable to download JSON metadata'], }, { 'url': 'http://player.vimeo.com/video/68375962', @@ -459,6 +478,7 @@ class VimeoIE(VimeoBaseInfoExtractor): 'duration': 10, }, 'params': { + 'format': 'best[protocol=https]', 'videopassword': 'youtube-dl', }, }, @@ -523,7 +543,7 @@ class VimeoIE(VimeoBaseInfoExtractor): def _verify_player_video_password(self, url, video_id, headers): password = self._downloader.params.get('videopassword') if password is None: - raise ExtractorError('This video is protected by a password, use the --video-password option') + raise ExtractorError('This video is protected by a password, use the --video-password option', expected=True) data = urlencode_postdata({ 'password': base64.b64encode(password.encode()), }) @@ -552,28 +572,26 @@ class VimeoIE(VimeoBaseInfoExtractor): r'vimeo\.com/channels/([^/]+)', url, 'channel id', default=None) # Extract ID from URL - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') + video_id = self._match_id(url) orig_url = url - if mobj.group('pro'): + is_pro = 'vimeopro.com/' in url + is_player = '://player.vimeo.com/video/' in url + if is_pro: # some videos require portfolio_id to be present in player url # https://github.com/ytdl-org/youtube-dl/issues/20070 url = self._extract_url(url, self._download_webpage(url, video_id)) - elif mobj.group('player'): + if not url: + url = 'https://vimeo.com/' + video_id + elif is_player: url = 'https://player.vimeo.com/video/' + video_id elif any(p in url for p in ('play_redirect_hls', 'moogaloop.swf')): url = 'https://vimeo.com/' + video_id - # Retrieve video webpage to extract further information - request = sanitized_Request(url, headers=headers) try: - webpage, urlh = self._download_webpage_handle(request, video_id) + # Retrieve video webpage to extract further information + webpage, urlh = self._download_webpage_handle( + url, video_id, headers=headers) redirect_url = compat_str(urlh.geturl()) - # Some URLs redirect to ondemand can't be extracted with - # this extractor right away thus should be passed through - # ondemand extractor (e.g. https://vimeo.com/73445910) - if VimeoOndemandIE.suitable(redirect_url): - return self.url_result(redirect_url, VimeoOndemandIE.ie_key()) except ExtractorError as ee: if isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 403: errmsg = ee.cause.read() @@ -600,6 +618,7 @@ class VimeoIE(VimeoBaseInfoExtractor): cc_license = None timestamp = None + video_description = None # Extract the config JSON try: @@ -611,17 +630,17 @@ class VimeoIE(VimeoBaseInfoExtractor): # Sometimes new react-based page is served instead of old one that require # different config URL extraction approach (see # https://github.com/ytdl-org/youtube-dl/pull/7209) - vimeo_clip_page_config = self._search_regex( - r'vimeo\.clip_page_config\s*=\s*({.+?});', webpage, - 'vimeo clip page config') - page_config = self._parse_json(vimeo_clip_page_config, video_id) + page_config = self._parse_json(self._search_regex( + r'vimeo\.(?:clip|vod_title)_page_config\s*=\s*({.+?});', + webpage, 'page config'), video_id) config_url = page_config['player']['config_url'] cc_license = page_config.get('cc_license') timestamp = try_get( page_config, lambda x: x['clip']['uploaded_on'], compat_str) - config_json = self._download_webpage(config_url, video_id) - config = json.loads(config_json) + video_description = clean_html(dict_get( + page_config, ('description', 'description_html_escaped'))) + config = self._download_json(config_url, video_id) except RegexNotFoundError: # For pro videos or player.vimeo.com urls # We try to find out to which variable is assigned the config dic @@ -675,14 +694,14 @@ class VimeoIE(VimeoBaseInfoExtractor): {'force_feature_id': True}), 'Vimeo') # Extract video description - - video_description = self._html_search_regex( - r'(?s)]*>(.*?)', - webpage, 'description', default=None) + if not video_description: + video_description = self._html_search_regex( + r'(?s)]*>(.*?)', + webpage, 'description', default=None) if not video_description: video_description = self._html_search_meta( 'description', webpage, default=None) - if not video_description and mobj.group('pro'): + if not video_description and is_pro: orig_webpage = self._download_webpage( orig_url, video_id, note='Downloading webpage for description', @@ -690,7 +709,7 @@ class VimeoIE(VimeoBaseInfoExtractor): if orig_webpage: video_description = self._html_search_meta( 'description', orig_webpage, default=None) - if not video_description and not mobj.group('player'): + if not video_description and not is_player: self._downloader.report_warning('Cannot find video description') # Extract upload date @@ -730,7 +749,6 @@ class VimeoIE(VimeoBaseInfoExtractor): channel_url = 'https://vimeo.com/channels/%s' % channel_id if channel_id else None info_dict = { - 'id': video_id, 'formats': formats, 'timestamp': unified_timestamp(timestamp), 'description': video_description, @@ -748,9 +766,9 @@ class VimeoIE(VimeoBaseInfoExtractor): return info_dict -class VimeoOndemandIE(VimeoBaseInfoExtractor): +class VimeoOndemandIE(VimeoIE): IE_NAME = 'vimeo:ondemand' - _VALID_URL = r'https?://(?:www\.)?vimeo\.com/ondemand/(?P[^/?#&]+)' + _VALID_URL = r'https?://(?:www\.)?vimeo\.com/ondemand/([^/]+/)?(?P[^/?#&]+)' _TESTS = [{ # ondemand video not available via https://vimeo.com/id 'url': 'https://vimeo.com/ondemand/20704', @@ -762,24 +780,32 @@ class VimeoOndemandIE(VimeoBaseInfoExtractor): 'uploader': 'גם סרטים', 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/gumfilms', 'uploader_id': 'gumfilms', + 'description': 'md5:4c027c965e439de4baab621e48b60791', + 'upload_date': '20140906', + 'timestamp': 1410032453, }, 'params': { 'format': 'best[protocol=https]', }, + 'expected_warnings': ['Unable to download JSON metadata'], }, { # requires Referer to be passed along with og:video:url 'url': 'https://vimeo.com/ondemand/36938/126682985', 'info_dict': { - 'id': '126682985', + 'id': '126584684', 'ext': 'mp4', 'title': 'Rävlock, rätt läte på rätt plats', 'uploader': 'Lindroth & Norin', - 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/user14430847', - 'uploader_id': 'user14430847', + 'uploader_url': r're:https?://(?:www\.)?vimeo\.com/lindrothnorin', + 'uploader_id': 'lindrothnorin', + 'description': 'md5:c3c46a90529612c8279fb6af803fc0df', + 'upload_date': '20150502', + 'timestamp': 1430586422, }, 'params': { 'skip_download': True, }, + 'expected_warnings': ['Unable to download JSON metadata'], }, { 'url': 'https://vimeo.com/ondemand/nazmaalik', 'only_matching': True, @@ -791,16 +817,6 @@ class VimeoOndemandIE(VimeoBaseInfoExtractor): 'only_matching': True, }] - def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - return self.url_result( - # Some videos require Referer to be passed along with og:video:url - # similarly to generic vimeo embeds (e.g. - # https://vimeo.com/ondemand/36938/126682985). - VimeoIE._smuggle_referrer(self._og_search_video_url(webpage), url), - VimeoIE.ie_key()) - class VimeoChannelIE(VimeoBaseInfoExtractor): IE_NAME = 'vimeo:channel' @@ -816,6 +832,7 @@ class VimeoChannelIE(VimeoBaseInfoExtractor): }, 'playlist_mincount': 25, }] + _BASE_URL_TEMPL = 'https://vimeo.com/channels/%s' def _page_url(self, base_url, pagenum): return '%s/videos/page:%d/' % (base_url, pagenum) @@ -887,14 +904,13 @@ class VimeoChannelIE(VimeoBaseInfoExtractor): return self.playlist_result(title_and_entries, list_id, list_title) def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - channel_id = mobj.group('id') - return self._extract_videos(channel_id, 'https://vimeo.com/channels/%s' % channel_id) + channel_id = self._match_id(url) + return self._extract_videos(channel_id, self._BASE_URL_TEMPL % channel_id) class VimeoUserIE(VimeoChannelIE): IE_NAME = 'vimeo:user' - _VALID_URL = r'https://vimeo\.com/(?!(?:[0-9]+|watchlater)(?:$|[?#/]))(?P[^/]+)(?:/videos|[#?]|$)' + _VALID_URL = r'https://vimeo\.com/(?!(?:[0-9]+|watchlater)(?:$|[?#/]))(?P[^/]+)(?:/videos|[#?]|$)' _TITLE_RE = r']+?class="user">([^<>]+?)
' _TESTS = [{ 'url': 'https://vimeo.com/nkistudio/videos', @@ -904,11 +920,7 @@ class VimeoUserIE(VimeoChannelIE): }, 'playlist_mincount': 66, }] - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - name = mobj.group('name') - return self._extract_videos(name, 'https://vimeo.com/%s' % name) + _BASE_URL_TEMPL = 'https://vimeo.com/%s' class VimeoAlbumIE(VimeoChannelIE): @@ -939,7 +951,7 @@ class VimeoAlbumIE(VimeoChannelIE): def _fetch_page(self, album_id, authorizaion, hashed_pass, page): api_page = page + 1 query = { - 'fields': 'link', + 'fields': 'link,uri', 'page': api_page, 'per_page': self._PAGE_SIZE, } @@ -954,7 +966,9 @@ class VimeoAlbumIE(VimeoChannelIE): link = video.get('link') if not link: continue - yield self.url_result(link, VimeoIE.ie_key(), VimeoIE._match_id(link)) + uri = video.get('uri') + video_id = self._search_regex(r'/videos/(\d+)', uri, 'video_id', default=None) if uri else None + yield self.url_result(link, VimeoIE.ie_key(), video_id) def _real_extract(self, url): album_id = self._match_id(url) @@ -968,25 +982,18 @@ class VimeoAlbumIE(VimeoChannelIE): r'\s*(.+?)(?:\s+on Vimeo)?', webpage, 'title', fatal=False)) -class VimeoGroupsIE(VimeoAlbumIE): +class VimeoGroupsIE(VimeoChannelIE): IE_NAME = 'vimeo:group' - _VALID_URL = r'https://vimeo\.com/groups/(?P[^/]+)(?:/(?!videos?/\d+)|$)' + _VALID_URL = r'https://vimeo\.com/groups/(?P[^/]+)(?:/(?!videos?/\d+)|$)' _TESTS = [{ - 'url': 'https://vimeo.com/groups/rolexawards', + 'url': 'https://vimeo.com/groups/kattykay', 'info_dict': { - 'id': 'rolexawards', - 'title': 'Rolex Awards for Enterprise', + 'id': 'kattykay', + 'title': 'Katty Kay', }, - 'playlist_mincount': 73, + 'playlist_mincount': 27, }] - - def _extract_list_title(self, webpage): - return self._og_search_title(webpage, fatal=False) - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - name = mobj.group('name') - return self._extract_videos(name, 'https://vimeo.com/groups/%s' % name) + _BASE_URL_TEMPL = 'https://vimeo.com/groups/%s' class VimeoReviewIE(VimeoBaseInfoExtractor): @@ -1002,7 +1009,9 @@ class VimeoReviewIE(VimeoBaseInfoExtractor): 'title': "DICK HARDWICK 'Comedian'", 'uploader': 'Richard Hardwick', 'uploader_id': 'user21297594', - } + 'description': "Comedian Dick Hardwick's five minute demo filmed in front of a live theater audience.\nEdit by Doug Mattocks", + }, + 'expected_warnings': ['Unable to download JSON metadata'], }, { 'note': 'video player needs Referer', 'url': 'https://vimeo.com/user22258446/review/91613211/13f927e053', @@ -1015,7 +1024,8 @@ class VimeoReviewIE(VimeoBaseInfoExtractor): 'duration': 2773, 'thumbnail': r're:^https?://.*\.jpg$', 'uploader_id': 'user22258446', - } + }, + 'skip': 'video gone', }, { 'note': 'Password protected', 'url': 'https://vimeo.com/user37284429/review/138823582/c4d865efde', @@ -1035,33 +1045,20 @@ class VimeoReviewIE(VimeoBaseInfoExtractor): def _real_initialize(self): self._login() - def _get_config_url(self, webpage_url, video_id, video_password_verified=False): - webpage = self._download_webpage(webpage_url, video_id) - config_url = self._html_search_regex( - r'data-config-url=(["\'])(?P(?:(?!\1).)+)\1', webpage, - 'config URL', default=None, group='url') - if not config_url: - data = self._parse_json(self._search_regex( - r'window\s*=\s*_extend\(window,\s*({.+?})\);', webpage, 'data', - default=NO_DEFAULT if video_password_verified else '{}'), video_id) - config = data.get('vimeo_esi', {}).get('config', {}) - config_url = config.get('configUrl') or try_get(config, lambda x: x['clipData']['configUrl']) - if config_url is None: - self._verify_video_password(webpage_url, video_id, webpage) - config_url = self._get_config_url( - webpage_url, video_id, video_password_verified=True) - return config_url - def _real_extract(self, url): page_url, video_id = re.match(self._VALID_URL, url).groups() - config_url = self._get_config_url(url, video_id) + clip_data = self._download_json( + page_url.replace('/review/', '/review/data/'), + video_id)['clipData'] + config_url = clip_data['configUrl'] config = self._download_json(config_url, video_id) info_dict = self._parse_config(config, video_id) - source_format = self._extract_original_format(page_url, video_id) + source_format = self._extract_original_format( + page_url + '/action', video_id) if source_format: info_dict['formats'].append(source_format) self._vimeo_sort_formats(info_dict['formats']) - info_dict['id'] = video_id + info_dict['description'] = clean_html(clip_data.get('description')) return info_dict @@ -1115,94 +1112,17 @@ class VimeoLikesIE(VimeoChannelIE): return self._extract_videos(user_id, 'https://vimeo.com/%s/likes' % user_id) -class VHXEmbedIE(InfoExtractor): +class VHXEmbedIE(VimeoBaseInfoExtractor): IE_NAME = 'vhx:embed' _VALID_URL = r'https?://embed\.vhx\.tv/videos/(?P\d+)' - def _call_api(self, video_id, access_token, path='', query=None): - return self._download_json( - 'https://api.vhx.tv/videos/' + video_id + path, video_id, headers={ - 'Authorization': 'Bearer ' + access_token, - }, query=query) - def _real_extract(self, url): video_id = self._match_id(url) webpage = self._download_webpage(url, video_id) - credentials = self._parse_json(self._search_regex( - r'(?s)credentials\s*:\s*({.+?}),', webpage, - 'config'), video_id, js_to_json) - access_token = credentials['access_token'] - - query = {} - for k, v in credentials.items(): - if k in ('authorization', 'authUserToken', 'ticket') and v and v != 'undefined': - if k == 'authUserToken': - query['auth_user_token'] = v - else: - query[k] = v - files = self._call_api(video_id, access_token, '/files', query) - - formats = [] - for f in files: - href = try_get(f, lambda x: x['_links']['source']['href']) - if not href: - continue - method = f.get('method') - if method == 'hls': - formats.extend(self._extract_m3u8_formats( - href, video_id, 'mp4', 'm3u8_native', - m3u8_id='hls', fatal=False)) - elif method == 'dash': - formats.extend(self._extract_mpd_formats( - href, video_id, mpd_id='dash', fatal=False)) - else: - fmt = { - 'filesize': int_or_none(try_get(f, lambda x: x['size']['bytes'])), - 'format_id': 'http', - 'preference': 1, - 'url': href, - 'vcodec': f.get('codec'), - } - quality = f.get('quality') - if quality: - fmt.update({ - 'format_id': 'http-' + quality, - 'height': int_or_none(self._search_regex(r'(\d+)p', quality, 'height', default=None)), - }) - formats.append(fmt) - self._sort_formats(formats) - - video_data = self._call_api(video_id, access_token) - title = video_data.get('title') or video_data['name'] - - subtitles = {} - for subtitle in try_get(video_data, lambda x: x['tracks']['subtitles'], list) or []: - lang = subtitle.get('srclang') or subtitle.get('label') - for _link in subtitle.get('_links', {}).values(): - href = _link.get('href') - if not href: - continue - subtitles.setdefault(lang, []).append({ - 'url': href, - }) - - q = qualities(['small', 'medium', 'large', 'source']) - thumbnails = [] - for thumbnail_id, thumbnail_url in video_data.get('thumbnail', {}).items(): - thumbnails.append({ - 'id': thumbnail_id, - 'url': thumbnail_url, - 'preference': q(thumbnail_id), - }) - - return { - 'id': video_id, - 'title': title, - 'description': video_data.get('description'), - 'duration': int_or_none(try_get(video_data, lambda x: x['duration']['seconds'])), - 'formats': formats, - 'subtitles': subtitles, - 'thumbnails': thumbnails, - 'timestamp': unified_timestamp(video_data.get('created_at')), - 'view_count': int_or_none(video_data.get('plays_count')), - } + config_url = self._parse_json(self._search_regex( + r'window\.OTTData\s*=\s*({.+})', webpage, + 'ott data'), video_id, js_to_json)['config_url'] + config = self._download_json(config_url, video_id) + info = self._parse_config(config, video_id) + self._vimeo_sort_formats(info['formats']) + return info diff --git a/youtube_dl/extractor/vk.py b/youtube_dl/extractor/vk.py index 8b6dc0e..00ec006 100644 --- a/youtube_dl/extractor/vk.py +++ b/youtube_dl/extractor/vk.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import collections +import functools import re from .common import InfoExtractor @@ -11,8 +12,8 @@ from ..utils import ( ExtractorError, get_element_by_class, int_or_none, + OnDemandPagedList, orderedSet, - remove_start, str_or_none, str_to_int, unescapeHTML, @@ -21,6 +22,7 @@ from ..utils import ( urlencode_postdata, ) from .dailymotion import DailymotionIE +from .odnoklassniki import OdnoklassnikiIE from .pladform import PladformIE from .vimeo import VimeoIE from .youtube import YoutubeIE @@ -60,6 +62,18 @@ class VKBaseIE(InfoExtractor): def _real_initialize(self): self._login() + def _download_payload(self, path, video_id, data, fatal=True): + data['al'] = 1 + code, payload = self._download_json( + 'https://vk.com/%s.php' % path, video_id, + data=urlencode_postdata(data), fatal=fatal, + headers={'X-Requested-With': 'XMLHttpRequest'})['payload'] + if code == '3': + self.raise_login_required() + elif code == '8': + raise ExtractorError(clean_html(payload[0][1:-1]), expected=True) + return payload + class VKIE(VKBaseIE): IE_NAME = 'vk' @@ -96,7 +110,6 @@ class VKIE(VKBaseIE): }, { 'url': 'http://vk.com/video205387401_165548505', - 'md5': '6c0aeb2e90396ba97035b9cbde548700', 'info_dict': { 'id': '205387401_165548505', 'ext': 'mp4', @@ -110,18 +123,18 @@ class VKIE(VKBaseIE): }, { 'note': 'Embedded video', - 'url': 'http://vk.com/video_ext.php?oid=32194266&id=162925554&hash=7d8c2e0d5e05aeaa&hd=1', - 'md5': 'c7ce8f1f87bec05b3de07fdeafe21a0a', + 'url': 'https://vk.com/video_ext.php?oid=-77521&id=162222515&hash=87b046504ccd8bfa', + 'md5': '7babad3b85ea2e91948005b1b8b0cb84', 'info_dict': { - 'id': '32194266_162925554', + 'id': '-77521_162222515', 'ext': 'mp4', - 'uploader': 'Vladimir Gavrin', - 'title': 'Lin Dan', - 'duration': 101, - 'upload_date': '20120730', - 'view_count': int, + 'uploader': 're:(?:Noize MC|Alexander Ilyashenko).*', + 'title': 'ProtivoGunz - Хуёвая песня', + 'duration': 195, + 'upload_date': '20120212', + 'timestamp': 1329049880, + 'uploader_id': '-77521', }, - 'skip': 'This video has been removed from public access.', }, { # VIDEO NOW REMOVED @@ -138,18 +151,19 @@ class VKIE(VKBaseIE): 'upload_date': '20121218', 'view_count': int, }, - 'skip': 'Requires vk account credentials', + 'skip': 'Removed', }, { 'url': 'http://vk.com/hd_kino_mania?z=video-43215063_168067957%2F15c66b9b533119788d', - 'md5': '4d7a5ef8cf114dfa09577e57b2993202', 'info_dict': { 'id': '-43215063_168067957', 'ext': 'mp4', - 'uploader': 'Киномания - лучшее из мира кино', + 'uploader': 'Bro Mazter', 'title': ' ', 'duration': 7291, 'upload_date': '20140328', + 'uploader_id': '223413403', + 'timestamp': 1396018030, }, 'skip': 'Requires vk account credentials', }, @@ -165,7 +179,7 @@ class VKIE(VKBaseIE): 'upload_date': '20140626', 'view_count': int, }, - 'skip': 'Only works from Russia', + 'skip': 'Removed', }, { # video (removed?) only available with list id @@ -204,8 +218,7 @@ class VKIE(VKBaseIE): 'id': 'k3lz2cmXyRuJQSjGHUv', 'ext': 'mp4', 'title': 'md5:d52606645c20b0ddbb21655adaa4f56f', - # TODO: fix test by fixing dailymotion description extraction - 'description': 'md5:c651358f03c56f1150b555c26d90a0fd', + 'description': 'md5:424b8e88cc873217f520e582ba28bb36', 'uploader': 'AniLibria.Tv', 'upload_date': '20160914', 'uploader_id': 'x1p5vl5', @@ -247,6 +260,9 @@ class VKIE(VKBaseIE): 'uploader_id': '-387766', 'timestamp': 1475137527, }, + 'params': { + 'skip_download': True, + }, }, { # live stream, hls and rtmp links, most likely already finished live @@ -288,80 +304,94 @@ class VKIE(VKBaseIE): mobj = re.match(self._VALID_URL, url) video_id = mobj.group('videoid') + mv_data = {} if video_id: - info_url = 'https://vk.com/al_video.php?act=show_inline&al=1&video=' + video_id + data = { + 'act': 'show_inline', + 'video': video_id, + } # Some videos (removed?) can only be downloaded with list id specified list_id = mobj.group('list_id') if list_id: - info_url += '&list=%s' % list_id + data['list'] = list_id + + payload = self._download_payload('al_video', video_id, data) + info_page = payload[1] + opts = payload[-1] + mv_data = opts.get('mvData') or {} + player = opts.get('player') or {} else: - info_url = 'http://vk.com/video_ext.php?' + mobj.group('embed_query') video_id = '%s_%s' % (mobj.group('oid'), mobj.group('id')) - info_page = self._download_webpage(info_url, video_id) + info_page = self._download_webpage( + 'http://vk.com/video_ext.php?' + mobj.group('embed_query'), video_id) - error_message = self._html_search_regex( - [r'(?s)]+class="video_layer_message"[^>]*>(.+?)', - r'(?s)]+id="video_ext_msg"[^>]*>(.+?)'], - info_page, 'error message', default=None) - if error_message: - raise ExtractorError(error_message, expected=True) + error_message = self._html_search_regex( + [r'(?s)]+class="video_layer_message"[^>]*>(.+?)', + r'(?s)]+id="video_ext_msg"[^>]*>(.+?)'], + info_page, 'error message', default=None) + if error_message: + raise ExtractorError(error_message, expected=True) - if re.search(r'/login\.php\?.*\bact=security_check', info_page): - raise ExtractorError( - 'You are trying to log in from an unusual location. You should confirm ownership at vk.com to log in with this IP.', - expected=True) + if re.search(r'/login\.php\?.*\bact=security_check', info_page): + raise ExtractorError( + 'You are trying to log in from an unusual location. You should confirm ownership at vk.com to log in with this IP.', + expected=True) - ERROR_COPYRIGHT = 'Video %s has been removed from public access due to rightholder complaint.' + ERROR_COPYRIGHT = 'Video %s has been removed from public access due to rightholder complaint.' - ERRORS = { - r'>Видеозапись .*? была изъята из публичного доступа в связи с обращением правообладателя.<': - ERROR_COPYRIGHT, + ERRORS = { + r'>Видеозапись .*? была изъята из публичного доступа в связи с обращением правообладателя.<': + ERROR_COPYRIGHT, - r'>The video .*? was removed from public access by request of the copyright holder.<': - ERROR_COPYRIGHT, + r'>The video .*? was removed from public access by request of the copyright holder.<': + ERROR_COPYRIGHT, - r'Please log in or <': - 'Video %s is only available for registered users, ' - 'use --username and --password options to provide account credentials.', + r'Please log in or <': + 'Video %s is only available for registered users, ' + 'use --username and --password options to provide account credentials.', - r'Unknown error': - 'Video %s does not exist.', + r'Unknown error': + 'Video %s does not exist.', - r'Видео временно недоступно': - 'Video %s is temporarily unavailable.', + r'Видео временно недоступно': + 'Video %s is temporarily unavailable.', - r'Access denied': - 'Access denied to video %s.', + r'Access denied': + 'Access denied to video %s.', - r'Видеозапись недоступна, так как её автор был заблокирован.': - 'Video %s is no longer available, because its author has been blocked.', + r'Видеозапись недоступна, так как её автор был заблокирован.': + 'Video %s is no longer available, because its author has been blocked.', - r'This video is no longer available, because its author has been blocked.': - 'Video %s is no longer available, because its author has been blocked.', + r'This video is no longer available, because its author has been blocked.': + 'Video %s is no longer available, because its author has been blocked.', - r'This video is no longer available, because it has been deleted.': - 'Video %s is no longer available, because it has been deleted.', + r'This video is no longer available, because it has been deleted.': + 'Video %s is no longer available, because it has been deleted.', - r'The video .+? is not available in your region.': - 'Video %s is not available in your region.', - } + r'The video .+? is not available in your region.': + 'Video %s is not available in your region.', + } + + for error_re, error_msg in ERRORS.items(): + if re.search(error_re, info_page): + raise ExtractorError(error_msg % video_id, expected=True) - for error_re, error_msg in ERRORS.items(): - if re.search(error_re, info_page): - raise ExtractorError(error_msg % video_id, expected=True) + player = self._parse_json(self._search_regex( + r'var\s+playerParams\s*=\s*({.+?})\s*;\s*\n', + info_page, 'player params'), video_id) youtube_url = YoutubeIE._extract_url(info_page) if youtube_url: - return self.url_result(youtube_url, ie=YoutubeIE.ie_key()) + return self.url_result(youtube_url, YoutubeIE.ie_key()) vimeo_url = VimeoIE._extract_url(url, info_page) if vimeo_url is not None: - return self.url_result(vimeo_url) + return self.url_result(vimeo_url, VimeoIE.ie_key()) pladform_url = PladformIE._extract_url(info_page) if pladform_url: - return self.url_result(pladform_url) + return self.url_result(pladform_url, PladformIE.ie_key()) m_rutube = re.search( r'\ssrc="((?:https?:)?//rutube\.ru\\?/(?:video|play)\\?/embed(?:.*?))\\?"', info_page) @@ -374,6 +404,10 @@ class VKIE(VKBaseIE): if dailymotion_urls: return self.url_result(dailymotion_urls[0], DailymotionIE.ie_key()) + odnoklassniki_url = OdnoklassnikiIE._extract_url(info_page) + if odnoklassniki_url: + return self.url_result(odnoklassniki_url, OdnoklassnikiIE.ie_key()) + m_opts = re.search(r'(?s)var\s+opts\s*=\s*({.+?});', info_page) if m_opts: m_opts_url = re.search(r"url\s*:\s*'((?!/\b)[^']+)", m_opts.group(1)) @@ -383,38 +417,7 @@ class VKIE(VKBaseIE): opts_url = 'http:' + opts_url return self.url_result(opts_url) - # vars does not look to be served anymore since 24.10.2016 - data = self._parse_json( - self._search_regex( - r'var\s+vars\s*=\s*({.+?});', info_page, 'vars', default='{}'), - video_id, fatal=False) - - # is served instead - if not data: - data = self._parse_json( - self._search_regex( - [r'\s*({.+?})\s*', r'\s*({.+})'], - info_page, 'json', default='{}'), - video_id) - if data: - data = data['player']['params'][0] - - if not data: - data = self._parse_json( - self._search_regex( - r'var\s+playerParams\s*=\s*({.+?})\s*;\s*\n', info_page, - 'player params', default='{}'), - video_id) - if data: - data = data['params'][0] - - #

C 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 GBe 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�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