From f46044c66663049e286c20ee015db99d47d9dd8a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rog=C3=A9rio=20Brito?= Date: Sun, 1 Mar 2015 02:04:05 -0300 Subject: [PATCH] Imported Upstream version 2015.02.28 --- Makefile | 5 +- README.md | 67 +++-- README.txt | 77 +++-- devscripts/check-porn.py | 8 +- docs/supportedsites.md | 34 ++- test/helper.py | 16 +- test/parameters.json | 5 +- test/swftests/ArrayAccess.swf | Bin 610 -> 610 bytes test/swftests/ClassCall.swf | Bin 581 -> 583 bytes test/swftests/ClassConstruction.swf | Bin 552 -> 555 bytes test/swftests/ConstArrayAccess.swf | Bin 625 -> 628 bytes test/swftests/ConstantInt.swf | Bin 517 -> 520 bytes test/swftests/DictCall.swf | Bin 546 -> 546 bytes test/swftests/EqualsOperator.swf | Bin 510 -> 512 bytes test/swftests/LocalVars.swf | Bin 516 -> 519 bytes test/swftests/MemberAssignment.swf | Bin 557 -> 559 bytes test/swftests/NeOperator.swf | Bin 536 -> 537 bytes test/swftests/PrivateCall.swf | Bin 596 -> 595 bytes test/swftests/PrivateVoidCall.swf | Bin 599 -> 601 bytes test/swftests/StaticAssignment.swf | Bin 517 -> 518 bytes test/swftests/StaticRetrieval.swf | Bin 517 -> 519 bytes test/swftests/StringBasics.swf | Bin 522 -> 521 bytes test/swftests/StringCharCodeAt.swf | Bin 553 -> 554 bytes test/swftests/StringConversion.swf | Bin 529 -> 531 bytes test/test_YoutubeDL.py | 90 ++++++ test/test_jsinterp.py | 11 + test/test_subtitles.py | 309 ++++++++++----------- test/test_swfinterp.py | 4 +- test/test_utils.py | 39 +++ test/test_youtube_signature.py | 11 +- youtube-dl | Bin 773892 -> 811194 bytes youtube-dl.1 | 76 +++-- youtube-dl.bash-completion | 2 +- youtube-dl.fish | 10 +- youtube-dl.zsh | 2 +- youtube_dl/YoutubeDL.py | 244 ++++++++++------ youtube_dl/__init__.py | 35 ++- youtube_dl/aes.py | 4 +- youtube_dl/downloader/__init__.py | 3 + youtube_dl/downloader/common.py | 97 ++++--- youtube_dl/downloader/external.py | 2 +- youtube_dl/downloader/f4m.py | 173 ++++++++---- youtube_dl/downloader/hls.py | 7 +- youtube_dl/downloader/http.py | 25 +- youtube_dl/downloader/rtmp.py | 23 +- youtube_dl/extractor/__init__.py | 46 ++- youtube_dl/extractor/adobetv.py | 7 +- youtube_dl/extractor/adultswim.py | 2 + youtube_dl/extractor/aftenposten.py | 103 +++++++ youtube_dl/extractor/airmozilla.py | 74 +++++ youtube_dl/extractor/aparat.py | 7 +- youtube_dl/extractor/appletrailers.py | 12 +- youtube_dl/extractor/atresplayer.py | 19 +- youtube_dl/extractor/bambuser.py | 2 +- youtube_dl/extractor/bandcamp.py | 37 ++- youtube_dl/extractor/bbccouk.py | 35 ++- youtube_dl/extractor/beeg.py | 2 +- youtube_dl/extractor/blinkx.py | 49 ++-- youtube_dl/extractor/bliptv.py | 34 +-- youtube_dl/extractor/bloomberg.py | 6 +- youtube_dl/extractor/brightcove.py | 3 +- youtube_dl/extractor/buzzfeed.py | 5 +- youtube_dl/extractor/camdemy.py | 153 ++++++++++ youtube_dl/extractor/canalplus.py | 13 +- youtube_dl/extractor/cbs.py | 5 +- youtube_dl/extractor/cbssports.py | 30 ++ youtube_dl/extractor/ccc.py | 99 +++++++ youtube_dl/extractor/ceskatelevize.py | 30 +- youtube_dl/extractor/chirbit.py | 84 ++++++ youtube_dl/extractor/comedycentral.py | 3 + youtube_dl/extractor/common.py | 169 ++++++++--- youtube_dl/extractor/commonmistakes.py | 19 +- youtube_dl/extractor/crunchyroll.py | 66 ++--- youtube_dl/extractor/dailymotion.py | 11 +- youtube_dl/extractor/dctp.py | 4 + youtube_dl/extractor/defense.py | 5 +- youtube_dl/extractor/dotsub.py | 44 +-- youtube_dl/extractor/drtuber.py | 5 +- youtube_dl/extractor/drtv.py | 13 +- youtube_dl/extractor/embedly.py | 16 ++ youtube_dl/extractor/eporner.py | 7 +- youtube_dl/extractor/escapist.py | 125 ++++++--- youtube_dl/extractor/facebook.py | 18 +- youtube_dl/extractor/firstpost.py | 10 +- youtube_dl/extractor/firsttv.py | 59 ++-- youtube_dl/extractor/fivemin.py | 1 + youtube_dl/extractor/gamekings.py | 58 ++-- youtube_dl/extractor/gamestar.py | 4 +- youtube_dl/extractor/gdcvault.py | 11 +- youtube_dl/extractor/generic.py | 82 +++++- youtube_dl/extractor/goshgay.py | 4 +- youtube_dl/extractor/history.py | 31 +++ youtube_dl/extractor/ign.py | 3 + youtube_dl/extractor/imgur.py | 97 +++++++ youtube_dl/extractor/izlesene.py | 5 +- youtube_dl/extractor/kaltura.py | 138 +++++++++ youtube_dl/extractor/laola1tv.py | 45 +-- youtube_dl/extractor/letv.py | 190 +++++++++++++ youtube_dl/extractor/livestream.py | 4 +- youtube_dl/extractor/lynda.py | 71 +++-- youtube_dl/extractor/mit.py | 9 - youtube_dl/extractor/mitele.py | 4 +- youtube_dl/extractor/mpora.py | 6 +- youtube_dl/extractor/mtv.py | 26 +- youtube_dl/extractor/musicvault.py | 27 +- youtube_dl/extractor/nationalgeographic.py | 38 +++ youtube_dl/extractor/nbc.py | 33 ++- youtube_dl/extractor/netzkino.py | 3 + youtube_dl/extractor/npo.py | 97 ++++++- youtube_dl/extractor/nrk.py | 23 +- youtube_dl/extractor/ntvru.py | 97 +++---- youtube_dl/extractor/odnoklassniki.py | 85 ++++++ youtube_dl/extractor/patreon.py | 39 ++- youtube_dl/extractor/pornhd.py | 19 +- youtube_dl/extractor/pornhub.py | 32 ++- youtube_dl/extractor/puls4.py | 88 ++++++ youtube_dl/extractor/r7.py | 88 ++++++ youtube_dl/extractor/radiode.py | 15 +- youtube_dl/extractor/rai.py | 22 +- youtube_dl/extractor/rtlnl.py | 63 ++++- youtube_dl/extractor/rtlnow.py | 24 +- youtube_dl/extractor/rtp.py | 42 ++- youtube_dl/extractor/rtve.py | 27 +- youtube_dl/extractor/sandia.py | 117 ++++++++ youtube_dl/extractor/sockshare.py | 5 +- youtube_dl/extractor/soulanime.py | 80 ------ youtube_dl/extractor/soundgasm.py | 24 ++ youtube_dl/extractor/streamcz.py | 23 +- youtube_dl/extractor/subtitles.py | 99 ------- youtube_dl/extractor/sunporno.py | 2 +- youtube_dl/extractor/svtplay.py | 82 ++++++ youtube_dl/extractor/teamcoco.py | 62 +++-- youtube_dl/extractor/ted.py | 50 +++- youtube_dl/extractor/telecinco.py | 9 +- youtube_dl/extractor/theonion.py | 17 +- youtube_dl/extractor/theplatform.py | 64 +++-- youtube_dl/extractor/trilulilu.py | 51 ++-- youtube_dl/extractor/tv4.py | 100 +++++++ youtube_dl/extractor/tvigle.py | 22 +- youtube_dl/extractor/twitch.py | 17 +- youtube_dl/extractor/videolecturesnet.py | 34 ++- youtube_dl/extractor/viki.py | 17 +- youtube_dl/extractor/vimeo.py | 93 +++++-- youtube_dl/extractor/vk.py | 3 + youtube_dl/extractor/walla.py | 15 +- youtube_dl/extractor/wdr.py | 30 ++ youtube_dl/extractor/webofstories.py | 22 +- youtube_dl/extractor/wsj.py | 4 +- youtube_dl/extractor/xtube.py | 2 +- youtube_dl/extractor/yahoo.py | 1 - youtube_dl/extractor/yam.py | 81 ++++++ youtube_dl/extractor/youtube.py | 88 +++--- youtube_dl/extractor/zapiks.py | 110 ++++++++ youtube_dl/jsinterp.py | 5 +- youtube_dl/options.py | 76 +++-- youtube_dl/postprocessor/__init__.py | 2 + youtube_dl/postprocessor/ffmpeg.py | 167 ++++++++--- youtube_dl/utils.py | 152 ++++++++-- youtube_dl/version.py | 2 +- 159 files changed, 4648 insertions(+), 1541 deletions(-) create mode 100644 youtube_dl/extractor/aftenposten.py create mode 100644 youtube_dl/extractor/airmozilla.py create mode 100644 youtube_dl/extractor/camdemy.py create mode 100644 youtube_dl/extractor/cbssports.py create mode 100644 youtube_dl/extractor/ccc.py create mode 100644 youtube_dl/extractor/chirbit.py create mode 100644 youtube_dl/extractor/embedly.py create mode 100644 youtube_dl/extractor/history.py create mode 100644 youtube_dl/extractor/imgur.py create mode 100644 youtube_dl/extractor/kaltura.py create mode 100644 youtube_dl/extractor/letv.py create mode 100644 youtube_dl/extractor/nationalgeographic.py create mode 100644 youtube_dl/extractor/odnoklassniki.py create mode 100644 youtube_dl/extractor/puls4.py create mode 100644 youtube_dl/extractor/r7.py create mode 100644 youtube_dl/extractor/sandia.py delete mode 100644 youtube_dl/extractor/soulanime.py delete mode 100644 youtube_dl/extractor/subtitles.py create mode 100644 youtube_dl/extractor/svtplay.py create mode 100644 youtube_dl/extractor/tv4.py create mode 100644 youtube_dl/extractor/yam.py create mode 100644 youtube_dl/extractor/zapiks.py diff --git a/Makefile b/Makefile index 0636fc4..c6c7627 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ all: youtube-dl README.md CONTRIBUTING.md README.txt youtube-dl.1 youtube-dl.bash-completion youtube-dl.zsh youtube-dl.fish supportedsites clean: - rm -rf youtube-dl.1.temp.md youtube-dl.1 youtube-dl.bash-completion README.txt MANIFEST build/ dist/ .coverage cover/ youtube-dl.tar.gz youtube-dl.zsh youtube-dl.fish *.dump *.part *.info.json *.mp4 *.flv *.mp3 CONTRIBUTING.md.tmp youtube-dl youtube-dl.exe + rm -rf youtube-dl.1.temp.md youtube-dl.1 youtube-dl.bash-completion README.txt MANIFEST build/ dist/ .coverage cover/ youtube-dl.tar.gz youtube-dl.zsh youtube-dl.fish *.dump *.part *.info.json *.mp4 *.flv *.mp3 *.avi CONTRIBUTING.md.tmp youtube-dl youtube-dl.exe + find -name "*.pyc" -delete PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin @@ -43,7 +44,7 @@ test: ot: offlinetest offlinetest: codetest - nosetests --verbose test --exclude test_download --exclude test_age_restriction --exclude test_subtitles --exclude test_write_annotations --exclude test_youtube_lists + nosetests --verbose test --exclude test_download.py --exclude test_age_restriction.py --exclude test_subtitles.py --exclude test_write_annotations.py --exclude test_youtube_lists.py tar: youtube-dl.tar.gz diff --git a/README.md b/README.md index 06dea40..04f664c 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ which means you can modify it, redistribute it or use it however you like. on Windows) --flat-playlist Do not extract the videos of a playlist, only list them. + --no-color Do not emit color codes in output. ## Network Options: --proxy URL Use the specified HTTP/HTTPS proxy. Pass in @@ -119,8 +120,27 @@ which means you can modify it, redistribute it or use it however you like. COUNT views --max-views COUNT Do not download any videos with more than COUNT views + --match-filter FILTER (Experimental) Generic video filter. + Specify any key (see help for -o for a list + of available keys) to match if the key is + present, !key to check if the key is not + present,key > NUMBER (like "comment_count > + 12", also works with >=, <, <=, !=, =) to + compare against a number, and & to require + multiple matches. Values which are not + known are excluded unless you put a + question mark (?) after the operator.For + example, to only match videos that have + been liked more than 100 times and disliked + less than 50 times (or the dislike + functionality is not available at the given + service), but who also have a description, + use --match-filter "like_count > 100 & + dislike_count 10M]"). This works for - filesize, height, width, tbr, abr, vbr, and - fps and the comparisons <, <=, >, >=, =, != - . Formats for which the value is not known - are excluded unless you put a question mark - (?) after the operator. You can combine - format filters, so -f "[height <=? - 720][tbr>500]" selects up to 720p videos - (or videos where the height is not known) - with a bitrate of at least 500 KBit/s. By - default, youtube-dl will pick the best - quality. Use commas to download multiple - audio formats, such as -f + filesize, height, width, tbr, abr, vbr, + asr, and fps and the comparisons <, <=, >, + >=, =, != and for ext, acodec, vcodec, + container, and protocol and the comparisons + =, != . Formats for which the value is not + known are excluded unless you put a + question mark (?) after the operator. You + can combine format filters, so -f "[height + <=? 720][tbr>500]" selects up to 720p + videos (or videos where the height is not + known) with a bitrate of at least 500 + KBit/s. By default, youtube-dl will pick + the best quality. Use commas to download + multiple audio formats, such as -f 136/137/mp4/bestvideo,140/m4a/bestaudio. You can merge the video and audio of two formats into a single file using -f NUMBER (like "comment_count > + 12", also works with >=, <, <=, !=, =) to + compare against a number, and & to require + multiple matches. Values which are not + known are excluded unless you put a + question mark (?) after the operator.For + example, to only match videos that have + been liked more than 100 times and disliked + less than 50 times (or the dislike + functionality is not available at the given + service), but who also have a description, + use --match-filter "like_count > 100 & + dislike_count 10M]"). This works for - filesize, height, width, tbr, abr, vbr, and - fps and the comparisons <, <=, >, >=, =, != - . Formats for which the value is not known - are excluded unless you put a question mark - (?) after the operator. You can combine - format filters, so -f "[height <=? - 720][tbr>500]" selects up to 720p videos - (or videos where the height is not known) - with a bitrate of at least 500 KBit/s. By - default, youtube-dl will pick the best - quality. Use commas to download multiple - audio formats, such as -f + filesize, height, width, tbr, abr, vbr, + asr, and fps and the comparisons <, <=, >, + >=, =, != and for ext, acodec, vcodec, + container, and protocol and the comparisons + =, != . Formats for which the value is not + known are excluded unless you put a + question mark (?) after the operator. You + can combine format filters, so -f "[height + <=? 720][tbr>500]" selects up to 720p + videos (or videos where the height is not + known) with a bitrate of at least 500 + KBit/s. By default, youtube-dl will pick + the best quality. Use commas to download + multiple audio formats, such as -f 136/137/mp4/bestvideo,140/m4a/bestaudio. You can merge the video and audio of two formats into a single file using -f zu#RA`dI&33yX z9F6=S=5*SK^XqlH1Poa2WBsOGCouuH~_4*0bb5EgZk%cAFb4?bqh{ZfNTg{dL zd2ZKFvWRk7_B=ujJDOfbsR&gJ@db5pD1DjZ5Y&k;~v~s zj*gCYSFqS&Oz5lulzfyIF^sVabxia-IRtzv|T z(2zhQ@x(Lhp)_GkYBOtg58mSMhx1Kks49;H3#&xkm|62p@bz~;=7)2?@=?6GL?{lS w`uy;lxCy7ks+u4?2EijD1U@&j80-;ikGz1ZV=Uy_njGEoK<|qB4^bfVv>34_rvLx| literal 610 zcmV-o0-gOsS5ppk0{{Sc+Fg;&Zqq;%h3|OAc2XorRRjfuWS~+uBz97Ylqj_bgaAS+ z5^PY}bZn0kQ~${xlXL|ecn>7R6R>BGSR_S)JuBXUMVWC+6R`Yu&z$@D_|6o_Pk^%@ z0oD-=Rxbg->$NWkpqF`m_vv70OrtQ)yQ12zk2z1fra75Rnv>0Dl8ww(r_(X5w%Kks zgrkuk#GFnWaekw2mw*Aw-7H9Xki>?psgo3ZyIwz`dhRJSEwZpgdalVr7O|M;W~BA4 z{OkCu$@P%Nqk@i@eSfE1JFUx%lrwwC9AoRI(Y9J!$0?-PGyfa*i6ZvThC%HY?!i6f z=;&y71&a;V#6`6CyHFnQet&xLSZw&$m424dgTCvsJcrNcJ3L#4$ICg^=MC=m(1nJClL+eYbR4&OtAlK(`;MTZPO`&kO#3AvUtSDl?!N{sG!0{ zRHZo(27AQXBhTUL7z??!CP%kC&^x0311#k95{YLnmH+?% diff --git a/test/swftests/ClassCall.swf b/test/swftests/ClassCall.swf index b24fadb1294d3dfed94ddfcb00e7e32c5f326790..5902cd3c1a00799a9db7951a80d20d096a56a88c 100644 GIT binary patch literal 583 zcmV-N0=WG{S5ppl0{{Sc+Fg;)iqlXO#?Sqe#C9>v&_O!LK+r-rwn?gjEp2dUt^dFQ zS27^XZF1YjNt2M=*t*i!5L}EKU&Fm_I)X3YN_>fWlg>09FA2$a&hPtja_<7@Z-AYz z096Eoy#oOFQ2BuXy0JU%yc!Jk#moH!a&b78-=Op)$5n3uCob^(%8=hSjuW zkn42DVLW5PW>MsO4$I<0vsyXk~8BZ@;eb>vKA8I_y2Em=gAj(jhf^4Ly;vml(WKT%XO#)&x- z;dSDwmi2uWOj0)C_T!g%Z=>@Wnc()2k96zdUA<*m57uL3)vod1ZeLd90opLw{X@FY z$E(%qq)g-qtMaDmmlMd>r@yy9zmO;Xz1)}EnDm+N!?*pOtjG(-F`IDK1~$C$|6q literal 581 zcmV-L0=oS}S5ppk0{{Sc+Fg;&Zqq;%h41{>CRtRiQlV6+k|iQ#Lt-bTi$sY2pBW2cQ%Mz-v8?{|)`XBI&J0PK7N zs3I8d9RR@R$`u0W#g5y3GaTuQnI9xwsrvP)5K-4K=JR=Te$))(iP7qGI)>Rc+UEQ>Q1jbs|y7jyQJH(Z}3)1Fa)nMZiS=hlf6j=4Va`9goJpA`O_ zULzUo6oXn@zsWLp(++1w6o*b~%b8pmm7BLMSwxhMeJ`2v*h+(oAe^s1QB*U=jyV(I zUE;Qu^?ephQa0h%)7N=#qw^V=;MRzb_2Wl++iV@Lr^t#u!xr@nw`9A#I@5_q3z>V3Aw_q2V8CwG41){V8 z)zk3@Zj17%kUyAL4>r9fOKPod(V=b{*mTCcK)H{qM1iUbnuf53h=!;}6b(svPs@iw zuvr+PEd>~p5(W&Elqe`jK|leidjt{rz?e!+G134bLdnv6CbI}8w6Zkc)0Y&!(BIcJ zr?x**@bf&ID(cc)z5of5!b7D+DJ{+GUzas>DM{rHsY)YxurxWG6Z4$Bg~KVneMg5= TDv_N^Hg&P3Po(+>$Q9{iEN&iz diff --git a/test/swftests/ClassConstruction.swf b/test/swftests/ClassConstruction.swf index ea74c2df1e779f6ac1d9e7ba997500035668ea2d..a551d79841b49b06f008ea998a3264b4e5a3e1ca 100644 GIT binary patch literal 555 zcmV+`0@VFOS5ppO0{{Sc+GSDQiqk+8K9iXw?t-#Qmr|95pbNdR`Kb!Fbc0K4{R0KB zWI@_oOKM=qm^QZkcqp>lMqa^Rk>aZOMk@hXCEK9SzZ}MzrIlW%bvb$Ed+mVb; z{xK1B-bwPiZMQZUvE0kTRD?V+s+vxCAr9N^GgsfcFindrsx5ubViAj3B67~fDk5lVLz29QZTu`u-}mv1U{2r2k=ZJV(m5XS%j literal 552 zcmV+@0@wXRS5ppN0{{Sc+GSD8Zqq;%z2h0%ZKa|{MNt4%vP7k9h#!G25~UVZLU>6a zu|h>io!FDu)b?2R7>5=73LE}_HG5VO5U&qFX^};>rSDlRVlhiZZaJnSjeM^^ zi+cp0OD-(+0& zDm7ppE|;e} zSPoc|FVVi9LcMmkzQ21Z2mWhkC~q+z@+23TJgIbnAGezlkq=BW8Z!s>z^pV|fWt&I zHU!%1$p_{MJm&oF258d!(CJHv#57FQCTd|7S{i6NQgnoMM0Bj`NZ0CE2sW3Z;B5sI zAb6VqksP&w5tf^x5CnuMNCSj0!3+DTM3I8Y?!tagUJ&>~ejma!X@L+?wS~QS4w8b` qY;proB@f?Q*bL6FeTLt{L7-fIql17*N^`%8xOr!fW%nPY<>@{GfC1$I diff --git a/test/swftests/ConstArrayAccess.swf b/test/swftests/ConstArrayAccess.swf index 1acf40a0fdbd69259ec88aaed151f2fdf513659f..d0a17693a1cb71cd018bb5f5cb7282e0e875eea3 100644 GIT binary patch literal 628 zcmV-)0*n1aS5pp@0{{Sc+GSErZ__{!o!#|El2S-jJ_-maK&4!o*iH+gQECwy0tf*T zNC@>%bz`q%Q^$_%4M|V%L%49^Z}0=SqzC>0C$5}0ma&^QrL4TN=FNL=XJ>W-%1?lc zUjbGKbe66Iz{ln91fZ3;Uh{RQTbT^PC~ac2RrRGDHVtDu9@od~^*HGp*5>A>VK$6L zqlS!HdJsuIsYU7Cs+}8jMCv5LPzG^S$ztA%M{=uLow>Tssp)W(gt?{b7$Ot{5y{lB z>J}QgPScB%0hcx(4#U9VnVm7IrGD(}kNF2t^Fp5bEn`m1G%}E(u-k6j6P0c#CY6m! zd#=yf$CQlh&I`5AT$5+&x)TqKVG_F|2W#@sDi@!XWER6wFAP#&B=#uUkK*z15py)- zIEmmg{+DrrW%-at{SogA`|-;>cN*t4aw+Vt=vAx-Yn6s+-8(KLLtDnVZqE=Lpbee! zFV=!>dUSNOQ(`z_4Y#6w*@1lh{&VN^bDa2LX*-Tm*-jFE&~_Y=rtt0Z3rye#Ucv{$ zf-=;BQhYGLf=HIn3$$0g_rj6HBNNIKHP0vm9z=Abp{#FM*6mqu=Y4IzSvMM{dEe-b zf=~vL7K*4Z{lZnU!ccknxrjBjd6OyjrSJ?0etl6_l7yJM#{-RvFX;aF`BkP`f&Y3&+&IFX-0E^!M zRta>LZvnvPm7fHlmGs@_n@-o541+LjVzg87q>P)UIUbK|HUhG8+1hKBz`RYC^WK|_o9*9sZ?gJedpXX9wk9;*>_A4h@l8&YSwFY zH0nD|H%f+F+B}W}-{F~^IjN>zRYE(WMIp@)a)68^RuC|^oO-z zm!6!Q?3EY}Si`MoU-uwi4;R0Gc!2{yF6~BPD%(lIkJ^qS(iDDNdx;7Bz)kp2)L{u~ zKqsn^Ux>{1 z*&>t`DWCxX{HYotglXsng=Iz%rI=7L&yLMtJ z53&!^X)BljO~9Dveio%FlESVro5?~Qbvl=+fqxa67Fpax20rC6Pq=Ssh2KZXQbiykr-=JC9i&j_5{MdsL)i?i~km#_dVWEBm2+yzw{cwWJmY zn?b#;XR_Me^JPNQOa_IoXPWD%#=LE*Bhq3PM|sFIuMp=#mg^Q9w$}I=XG;F7_{-Jx zn2ANf7TkOKvZ-C+W=5vCH{mneeSF{UJMN?P7&SYh|NZStMlaBVar+k@!HKb2tbKaDRRYxIu#1O-TbO+nudAC67E79dSDm;7T`#zYg=0L z)$Bd@6{<+WB0&z&A#Uj=7BVb^EkrEbvXDudW(YP18F#9l2+OA^h!_;mOK0gN+07`>j(>?(;xKGNu{6DpOCC@ssfSDy4_wxs>xa7dj29Spi!(ak>! z#j38zA9UO%V9IkZi&7OyVb_=~WTDPFo$FNJy9rH;EN&uwkMfu&T&SG(dwm_`d!s;R z2~#dh(>U^29Y?Ef9!l@3WFL4ph*=(v=~h^KRHS0=p8Ima?ODt#`>}n#^*8E`q!#O^YpCYrKpzCI40Y}y8v&xL9GHy*>pSg+TY`&cj7 z)R&l_FQGY;qpxpY=!O5>pGc7_Ce(#c@crnUu4x*Aj3vAeZRmkv09b${p>FMH%~y-} z+*7C`35x`|i;i(iH?fdmA#5RH;g*F=(lkS`J;=a&2IxqGm7pi41$1wfiT%y zIq%3rBP7qXSeHm^<;=-*Z9s^$%$2jc0A0cw;yWvc!yG$v{08oahNjzxb+g?!J<<3N H1KrTeNGb>U diff --git a/test/swftests/DictCall.swf b/test/swftests/DictCall.swf index be3e096648a3820da47bf308e4c7ef214412e186..4d3e48edbba3fa876b3bd20b8a92fbf66424b72d 100644 GIT binary patch literal 546 zcmV+-0^R*XS5pok0{{Sc+Feo0Zqq;%z2h0%NhF|E5fmgOqb{-`87BoqqSPX42p}Yo zV1v5q#2zQ6e#stVcg2sefDOOF8nH=#ffam37&~cP7-<&w+;h%-6+nIgT>l2Jk6^NU z2LL|p{X_tx#BqmjCsU&c{4gEL=%~FAA|6tj=Xp0j>_*9)_6CCiHT$&R??^@`Jr4yd zI$?Uywkm@OPwm8ug%^cJ8M9fGiKBLVP1~%F?kZ_j$lWkl%$7a5(y9_)m6R57HuJr7!4oSB&%!8Qm#EQ_V<()6=wHSqR_1*c z&NDXW*0a}DZW~uUGQq7WpBcR;4~)Lqd$ew&L`U?$ZEp~HKno^2zwro;mDOr>(!%n> zn*2ojdIHsp)q~HkgQvrz}vWpSINUDKI5+-X+;>aaa6G+3*LfS;H#*1y=ACW$dJJVWe5ybI&>VRRH+~aPup`E`rJS zJplN;^AiD#Qr8>4olK1)45Dl(qr>)Gh-66VVzKBh_PcR9qrJgkK+Qhw_dAl&$<89d zicXY0Y+IGVglA6bC&G^-ql}py=i;#4Uc0)^#x%*(pt5uw$^#zqNMy9v?MWlo8G3OV zGGVbK34Di@cC_eZ^Vm6Euur_>1uUD7XiY3N!WRLz#%^qLV;bQNijJ_3h>p~z zhMEmT%7O?fP(Or~rUDW{WE&%dkyHbbBuwzqd@gZC!KAe`FFf_a)6QQ2CZqq;zo%K2~RH(EHLgj#Dsg-geSv#~6iBgL~8bC-? z;)HtY#@-~RYp=1_*qrzgE?l^9;|KTv4)_~5@fTs&DRtYGR+@S9-kaH-63jmUo8JI- z5KOio0Kn(YF9a}7gZb#~WNMcYkF$}=4!cV!lMx|BQS^()eUUDRI~)#)Ga!ROPceGg zr&!Xm7iYU&uQr&l%umBah9b6gPG=&Qhu!XlYv5m+CV9$h%fKg$vxvnqBW~YSMu9(? zi!`Frqe;R;pK3c&_Ohk$&kOpI_2!&r%Q0z)S|dZrnRgV38MCLHmG-`U)aYyWnxe@; zGpKjvnN+L$zKBSYiXivZOmk&bi?2$wMUu~Wm@QfAn|R|b7Qqyoo-;Y z;kLSF`|Byxr+sJl%WJjq-y6pta>}!lgr#~Q_<8S#Dys_2QyMWBwxC}NzUpo+XfgaFt;&67#Su46I5j4%6Xv) zD!f%WduY%2{u01I$ZWMMr+NjdidBm5Rt|$R?403u@Nj7;xYN-+Zan6xg8l)3o79|W CO91x( literal 510 zcmV?!6*`W zLZwHujK=}hcBHn8xd_fG`hnRIr^S3s)DlX z@5(c&Ry%=6NS2GR4Ae}KvTDRvCE6k@eI6HcmV0G-mWpcCVvTA}kTWX9b;f^8*EvmR zC7m(v=yg-O%$pghWZsnd*8W3l;P&@dQ)qBZZhZCyqW0&(Wa}>;!!u*KT%K%Twcxh8 zX8ZFAH0QVV{oO0I@LwB8=OyLEamI2z5B#|MO_fyzqMRnI4_n|sBkw#Ff-{@1R`_tqw9e2zQX#K`pashhTk>fo~gNsKDID2w`NH2ux6si5Kp3O;F*j zg}aCLjIS>M41~;9d*Lo#f~sPb;yVkM!6|l6@msh*Hx%6M>K->9^F%@a0K?YRpS{2O AssI20 diff --git a/test/swftests/LocalVars.swf b/test/swftests/LocalVars.swf index 3216aee070d49ec43db239152ccf069b0ce821d1..3aaa2f7ebaad9d53e827e0cf0a5fd4e5dac1591d 100644 GIT binary patch literal 519 zcmV+i0{HzyS5pr00ssJb+FemWZ__Xs{T#ckw!_#Mpm9Kov_mCCo1}n5t1e=q6c7j` z4hZcu*KymhB#vT-loKcZ1&8gzZ{WrqE~Ol}bK+kVI~~oyk|n?Qz4!dt-wenvfUQpe zdk6+Q*8$-D?l%O`&w_F9$n}K(`ji% zOTJ4KowX9V-}K9X0hcTbQx%HDHkgh?t`3^b^VEQ?L(@Eq%E*8@JmN7=lytndr-K64 z8;dNa%BN`>g^ZdwXV#Ka!A=VLmbb^6J@K!b&jh2n_b16d7(8;CSejTn!G5Q1tU3vXCp=>yrp2w`Lq1O)Vn;JN$A2m*dd+=} J{s3w()qTDC2@3!K literal 516 zcmV+f0{i_#S5pq~0ssJb+FemWZ__Xs{T#ckw!_%8fyMzT5)zdVZIZ$ct-6SbQa~V( zI3P4Ga~-!0OX4VYNICIWwhR9Ni5vHwN;z=n#J?zZI+}qcOMdTr@AG!;3k1;5f^qNlU}(?cD3Lvl4x3Y@(w^fKMbR$qw?#H_yl%JaxE-g{X=z1E zeoPddwGw%|>6ZZmE?E|)Din!rFdd0p9X6YnsR3Jurg;{XkpXjf#ABW)>3D5V2L-G* z7FkS{Pt!CC88vavtR<&{ofh;1Z;c}=r+udq8jlK9#Qmc{jJQ3F_{@G_A65QRy^j{5&~LM6tS}VvUAnoGS6J;xA|F z5ltpJopAs0%d)n{Wsg*Gf5=Dn!9BaVuvB!z2U$Vz_Siy&|fDOOF2e3(4@Bys&i!kFfO(`Q=ntSd!XU@!>0{soJ{SDv% zVX%7$03Y{$AV4qk{O;Sq(3(bJoOfk)Qkw{oc5S;X%SL(JNV2ir>U27Gvu(HAb;+pb zA7a6#^*BGOIhDbH=WZ6HB1mFO)ohd$;-pr)boJaT)3nIK%F=Uf9`cCCBDY(OmNfF* zuAgKP6Anw$FmRc&v#0fZlDOw3yWn*{Wcj3LuZc<{0ugej?$v|@`yF6IBv$7Nd9H4 zFx3xPJTBOnJ5OI%y{o#)$OLzWd}OsA-m}`x)`MjXh4$_9_FHh~1O z*ty9!-i+RJSKtMX(Wem$VsZx$2yB?BnMh2eCh8^{CYmO0s1$(e0CmE0vs$Q;O${ia zs;47p1_A*zcL}178bx^rL_*1|`K)3Sx;<;o9>XW?*U$OTz~=xOBGnCv`czg#)2Mz+ xR&z!rG8^jfMZ$DNdI8c%ml`5T9L`AdjJ$)p6HUVVdn((1uk%QPe*qkr;?7_~4nP0^ literal 557 zcmV+|0@D3MS5pp00{{Sc+GSBqZ__{!o$;>iwuh3cfXV^M5{F!HoCJDElv;#_078Jo z36)FN_Bt{3m+VawPViIU!av~5om0YrAHa!!5q6!XDP?6#J8#~5GdnW_`Ws;PE5HH5 zVDAn9eBA$m0KFmzyKe?VYnH@m*_F{zeJn)Yb)4yR+L%6QWW~s7bvhlV*>>7(TQcnO zLn_$JPRo0Bw=x*;(l4T1L|JO7n0eVm9M$U=u7Q7Pnoo+jvJ8BO$2{SwD4kZLC5-~V z8)ikqgv;_gj(n!Rf!F%IDWyI$o^%l zF_n*5I-0N%cb~kfa+h({BNN;ma?d)vZ?&7P!&Mgw>^awleSygRxiF~xAw4+OmdoYI z4v`BshM{@bWM5=(nyyYB1s%hN%NGvg}Y--!ngKSZ~sl_kp%w&=WOFFjF=FC diff --git a/test/swftests/NeOperator.swf b/test/swftests/NeOperator.swf index 9cbc3e3d7147661e662836d143336970f39be922..62a97cf9e4ecc109c445b4b4907c40ae356c0d95 100644 GIT binary patch literal 537 zcmV+!0_OcgS5pok0{{Sc+FeoIY7;>i{pKeL&4o=#ka{65G!Q5zvl|smNEb_ERD>41 zl3sPPJ4v?PKXzx`cqRB8Ug(Xl;REz0z32-Ff^QLLHZ_S3EPUsD=bZUwzd6vK0QbHF z>?0WNJph1D^=kw$NZd*P-Ed^g13ygr3LUj(QpSD8@;vY4PdZUDWmd1(V`i6iyKSXt zryoPf=j|{(XxT-;P^3=c#nOvHLt{RUGI`W$-KDzDIyBA_zld}lCVUZyP^Qf4SSrYM z`jaRLxU_j3`<}yf9Gkb(S>#;h{DWvue4fq*Y$Mbj=}BMM$8Izh#>f|Q*}dEi$$V`fgg=us-;+%Bs>rn)Sv@}m3X1tQkKug zm%@=W;9f}XqkRIU3c?jcDu`B4i56EN*c^n(4hF0Wx|xvf1%(XBOGIZvB!y#$m;;z=l6y%^o)CqCbFy#9xFNrzC-qEZuYNIcM(p&Vl{}c<=>a zAHitv5deIwe@6hr#F-8*Mq^_h_+dIw=(y!d84noC^SqNEcA{j)y8V8inLXC)wUwfs zeh4L>x5M;F%PIm!BDE7QmR=MZ8uLk%$>Ub*KGm_;p>dY@MWkah;fp|oGG*OPR|Prt zU>YR>mlls>-?O=nWAk?EM)pn4-;4It=czkn8=>|{Px`_-aiWPZ#=e*v&y16ezfi9v zTI_5FwYHwgwYy_S0gIE!$!s;#R7Dl$ZHtbGvx)Deu1Ksbya}Uxb;X9&8aokOM*k}Q za=P#HaF+3zuwI-My)`ao)WUyM&%}8w5~#}P@E}~c@ESY-9KwMY;KW;$UH8LjSGMf=&u{*o@yvn#1-SVg zpoL(xb{7CXum3~6kBb#G8pl~%cD$0X=19FP0~{AwA<&dzISPwm3drQ`kuvOKIMrhET`*8 zBi|bYX+CAbWmy(S9#eMKyiCa}O(Hj}%bV)o4xl>Wy{)gWwB-{jGWblYQb3_otalbXCB$k~)TunJv8H-SWn zxUq!l`;(8{6U}`gr`(g9C^nX|T~=&6gF1(^fCgpa(J6}({SImo4O+Seuwo!=AYveD z5Y5mG14*T^QniSnKImGEF==4HKuLpwjx{7lL!bdN)(9fNQl%tRS9ijZ#N{RslbrbSW`v%l_EoWkd1}S h;gHyeuP}Izx_nU{{har?50{{Sc+Fg;&Zqq;z$7j83y9pAsDndn7B}-Jwg~U#vheWAG)eycU ziZ~!tgw&0_PD~x!ve!*G!5i=lTzCV{+!2Rx-~~AG7G>7`aN3nEd;asAzh^viV1EH_ zegoJbFj%__0H4->5`cc@2ff#Wp*5dIao)pdw=t12?b-HhHfzluw32LWx4Yf0?R4x; zr-?)}{}@X?Z^rq(hFcm8MDAr_D#IkURLn<7A$J>%b64NHG);>vDlL7_7Lk~WSmt)S z)kY)V>jgzoBcJ_%%Rg9Mj zE|aUog{JZmkH-Zc3-|HMGItr5J#s1Bp%_^^_pOf8-Z|?+iGBOp&puahe=ZDG|It3| zYp18DhjoezHt=S~*Fz}Jm+tp>FL2?%>aVi!1l{&|6v2<%Z&1Svf{af^8&;vE=sM6a zmN%AA<6!hbc(Q&VamamKM83I{ZSj1&-K%n18nB>VeMO_QKfTPa&4P#tnD)-+nvKm$f=3=B;tI2r*Rh`B}y#fPRb)R;zAfDp>)!g+!Y zM5FB1!gy0LH;&j2A>@k}N3g|l5lN>_o2)KFJN#+4!yJ?Q4b i5pYDEBl;G$Cfdb2*_tp!R@c=4%YXY3#{U7R=S6pfzl&F5pj3lPe$B4jQHGqWbRk~ zl3pSb_NzwSE7xSw-S(1+m1c=wc-T{bQKk8+MMk8>C<^m2&)gzDjg#5(6O}3%FXK!k z*NF>Fo<}S`DcA{jpS>y1F6**KCb)aZN2c@Sf!VR0$ICXP+P7Bz_PK%sbYZaePwm5j za&~rh)KGE4IxebzKZ5eP-`e^18YjMJyv@QXroB%>|A0ji{M-ys#}|T(O}GPV(3XxH zpoX!aQ{--~c=X}u6Zb@8DDcV$IF|h03ejfyuG6c|l{BD15qosP!dSmewx|YMh6YeK zh++`cAk-k5q3VWKGYE=}TG=*%>QTf{I4#6m&%=fEl0xsjaI-1!5q8HC0Fr z2vMoJu%BZhL3w>)f7D)S@KyWsduYIJ{RPGmLN$G1FJ1y-YUQBvV7b-g)<9;cOGv+F nF)%^ByRbPNQ~Q{HfbFq*u_xPO4Ux?ad7;$_JVot4ElKpzup}#x literal 599 zcmV-d0;v5%S5pqE0{{Sc+Fg;&Zqq;%h3|OAb`m6@YK4kWg(WIwLt-b;MWfVEHIzSz zAQlJ}A$4Mp8&k)&>~RxT@G5M0gRa@L3JYF<6>m}QIBng=@3g<_#6-k0w>#|) z2KinuNU{l+E>F`a^tg(%XRUmkc*j$IB3ePj^KsvJnSjJsM37Zq9W2_6ovU%WNr~3$H{c@iAq(BmkBPD z>%@ho&LbWl75qrJ&)$@0mvz}Am%`l_BWvrS)pa^si!PMdx0inQxq|a^VQ~8&?ZcjS zc6N5qpg3Ry7c;&eK>3_LIsNz=2R?7S&B7B*d!K~<9*-jUxfY;~F9aE%hz{I_wsPD6 z8pe{HAa`rYV+=>1g(n+Bi8tQEspR*Uh&InRJH6^$O9K`ZvBxGnjEy^Fo$0V{>Hu|< zXeOa1VJ6W{YM6S>Bq%m&W!nU*M>}7aHDz@T6`j=?7@9!3@C?P1vlzz&JvfZp@weOF)cP4yFzkTU~8UWQK-ah8)>hSpmM8EOwg0Zj^@;N99o+x` diff --git a/test/swftests/StaticAssignment.swf b/test/swftests/StaticAssignment.swf index 0a74f9e568e80b0e225b0378a446b93618e04294..b7186233d56b6e3d049d5eb6cda6aded82112f16 100644 GIT binary patch literal 518 zcmV+h0{Q(zS5poI0{{Sc+GUYJZ__Xo$Dd<25j{Ys0U8ISNIUdG>!ceJt-6SbQb0%` z!3FJr>N;*4mN-%3Eak)(;lhP)f#A-i`wE=+7R64-I)2|FWU=24>VT0bcphacN~LRRHcd-))NWs-hWs)#EAzOH3^^6CNQ6`c^}D_f3i)7` z<_S{)%d$A)%*4@Ur&y%?v|?wXGmBZV7}70hJStML2#&*aD%^1_mhPc@y!F@g1~G8B z9W=P|OlI6&o+dQQ)3D@vrkRea%~vfZA}gnHR4haul=4)j)#i$=Y8ajirqX|jznbaC zOwLO-7s1n4b?>sSXJkqQV=;C8M-SYd=Re$xVbmeL_O~w-y}$rQt>1VEPptKNebU5w z!?ym2{pAGe^W$Lu^Gm()^X6Nne+@q_ifAs)0^s}YZyL}&nB^=HKD3}~EDqpEs@8Sh zem(slxI$+nVUfgl(H;idL6(ECgNTC~4zh{yBZOdkkcDqpU;$V}cc8I@5yHqK2uzI$ zUU|<9Wnt1>dGE)9dx9*QMQVODkIW zN2%DdCG!VOzX}+MoM&OG!bG|TvuRSO<7V?RHQ-mFX^}-$WWcG2L@cDrX{X)MK>_d2 zk}PJ*XK5ORoS8VfY~_oDpOx%fv}O^@7X!K#8jlK9B>Z8JOocm+#L|7_4!8bFy^$Dk zux-@8_DyEoZJxw5&61$tx~G|rs?66dCL%4SQJ618<`?ozCgtXdEo(G96HF!lD*ke& z9x*vD*j)H0FRR)Wu6krj_+v43j~=>RuXD8N!jJ=cW7wCB-k%Sn#&0};C)RqsKCNTD zU|U~ee?Eok{5bjg?uB0XMg5J^li|ZW59iX%AHLuDrUkkNvy8=}0}W^!ivu{6s&P|q zznXp!T%mIkvryuFbb!HjkmVrkAmX5!gKT2_2qD-WWZ@kPEC7q>3e)I-WI~>4IYOjnue{ZB&~>aKzP<7UOt3e>Z{hyJ()8Uu^VEMod#uSn HW2V?Xb;$(S diff --git a/test/swftests/StaticRetrieval.swf b/test/swftests/StaticRetrieval.swf index 5f0014b72f6434606310234eb25a716efa54a52a..b8326f13d0fc7be7f7da3ff803d9f461ee289b21 100644 GIT binary patch literal 519 zcmV+i0{HzyS5poI0{{Sc+Feo2Zqq;zp7lDm=%GKfLgj#Dsg-geSv#dt6QvdvArv8j zR4%BeY}V_<)PJ(qaX9fJT)6NWeE=?g22LD!hp_9Ex@4u5cE0((Z)SFup#K8c{sC}^ zV6^uX0KV@3L;%Cg^9NU>v9*lCI3LL9yge5p9S~BMWw$)(CfSTQ{eGX=J<{uSB%_mm zi3MGD;{2%X)&?Valy%w8+BR(qn{&JmRs)iPLqYk;evp zl0{UwG)=>RQDsM#oqV3Ko02Yg#}8>fACiWsG$IfocQ3qT%B^w8m(~mGqS4pvHARuV zrcw97m{h5|EQv^(C0@Z~PrkIO#SbOQA}yw2kk5JM7V%A-loISUCwsX2}L!m>m@!NNZT%Zf1-QRc!ue8-_b-jh< zh7Eaj1C^%Dha0pV5drunS$KFaZa#*x8^P zAEuu<6KJ7FG>GvNbcn$)k!B)nBHctS6B&A45kYg1h97C50cbiP1g$-c5JsAgK*d@PD;)(b=H1D^l@ literal 517 zcmV+g0{ZJ;Zg7RB(69r`E|!tLJo2)?FxYNH#wE9+CTVVYK%L58A$q~> zOO|@>RL(?yA_q8z^J8=_B?##)qjIVbAURluc(-ymOt3S-U*P#%lknkzDz`b>8;Sh| Hm1@=(=Ue?| diff --git a/test/swftests/StringBasics.swf b/test/swftests/StringBasics.swf index f4839316ff1cb9ac823a902acd129f6f1acdd158..733ebba9dd6794690b4d318aad4b6596008c4d80 100644 GIT binary patch literal 521 zcmV+k0`~nwS5pr90ssJb+Fg;)Zqq;z#%H}7n^p)K6`^uKveZK^O>CziktnqYgaASU z2`;FouGi~7)LvWm8ix}v!i5Vj!GQ-rNa4T>aN;e(+9^%SN|tuM`OP=8o&}KK05`q> z93Yr=?*PEZ{qG21Qux96^=xh~(nOSF6`k}VDf6*q)pb3nj|W*1TFz)Rvh1NX9QGB_ zFFy!L7kyD4_T1KB#!FVjxr{SmHZk?GN}lw37p^|LG|j6bX)S$b@r0*b$kK8KjxzGu zILL~WN|)w&5;NM^S&M!dW$e7B?|DB+XcfPPoX`<^zhRQwecUjZ)6dR@DVLzR>HSiUsY1+5EL}!4(!38!LI?1g}lDa z>aVSYYZgJ>eph5x$KMFz5!-41^6t4Ae1@LE5GWHV0{VM*~e=NEai7kwy>@ zP&a~?_EV)Rg6u5qBmLLUpz{nsLx^PXV^Z&Z{cpFDY?7fG`aGo Lhf4ShOE=aR66XP6 literal 522 zcmV+l0`>hvS5pr80ssJb+Fg;sZqq;zhG)HwO)CVAicmQqS>ljOlXX&hNR(O>LI5Fw zfD0;@uGj0>)LvWm8iy0l!i6{B#DO~!QaJDeoVf4|Vb>{5%1V}Y{`uygSVsZZ%t(JY91?dx27|65 zy5)Nz>AWk-I~}hvnDCMnaW3ObI69_&R>`AI=iD`57p8etB#mXj2v2y*g)B+G*H=aX z8--bsQt8n=Phv*39hrB_C}U?eeaE|DLd$4O)}XGDu}rvk9ArLsrU{=rcb(&PeM7Gh z4F~H%y^Uv5UEO0@O7bELDyC)%l~q%`S)wiS%1`1l;)PdpNDmvrd!)HzIB5r1+l6zC`JBRzu!0jKdrqJS;{P(lZ6}3MPCOg0J7#`3 zs|8!?Gp&y&(40RnKEHXY7XE$vl`LX0yHCrQmGJe(7nM{xgau7`A9kRp@hgC1A+K(- z)^qCzh5Jb9iZHhp?!NW&N7#A{U?60+tcAOH0xFGFh_5eP4yV{X#joLZWGK14tD9VU M(>*2p1wEnGzS4~MZU6uP diff --git a/test/swftests/StringCharCodeAt.swf b/test/swftests/StringCharCodeAt.swf index 7e5b5bcf9cceccac26c0cbbea650d2f308a707c7..163707589a9b80514fa52aedc687e6ad084a5700 100644 GIT binary patch literal 554 zcmV+_0@eLPS5po-0{{Sc+GSD8Zqq;%z2kB0HVa7Ag31EPsFkv5GIk1xM5#rT5Q>mM zq8rpz$Mz&P^-K1+4l90y1+d^Z_y9J^f*)YTnjZ*bC&ZYli4EEL|B#L>ypAE&MeWK<1ICjD)kN#!+ z#frX9!)ZpR%zXB$>}~2YBjwB-GfOj`9BCchc(jU9pnY;<+G|8C(1cOr7w*GQS}vF8 zbu2clh)-5NpF?@BP7gl56dPaE&v@d6)1ga~VdSs@hi`ko1wr&+lF)z|(13O!*#_)| zym6DSytdvko67<9LQF0D!FrO_6bEO=q@(MPiIsUi_rkip5zBYcKHgG6QIVt~tRh)O zH5G5kWk>|oK@#4UKoS>u2P1@$BqNYP++;l0pBDrP%X@SENcpiiMB^GdbiORcHTZN2 sAR#2zl({~C0fLD|iEqz!1{YYrz;EHcD+&0{Zt>oK<9I5-Ke%)0z@?B6QUCw| literal 553 zcmV+^0@nRQS5po+0{{Sc+GSD8Zqq;%z2kA>HVa7Ag31EPh)UTs87HNc5~UVVLI5Fw zL^oC0bUdEKrhdsDj`M#2pPJ+G-1rsA~GSi9P6V;ZHgS6JGNaF6>u5D96w+S15o zy-67RRG2i1JeSejj?9{g6SAv}zT?e_M-!({N@A`NuJE`yutSUMV~@}DNBW@D7wi=! zC);IE^V)CHT-{=!Pog-qQzkP_q*WolF3ByT)biZK;jx(pS3#Jqo+#0r!(vWF_%Gux zmiIjxOjA1L=98C2Z&Mc;so>_ATl(>#-Z9$8s}wodCpU(@M&$lX7}bB_J`9!Ra(Pk1 za=}&ksnt&xP@I$VuWw$+g)eGnB6fr6(4p}#wD~~5x4qwzAbT*0sn6R`hgL4x2J8l+ zev@B)WxeH0s6KTAOfB|cJ;-v1gR>*jF^m&prLHI3pvE?0^)A}STN+d~q-Y3hNYzk9 z!&_<*5QIYGhd-rP8>{#YEKaRnXNpBLi_e0&C= rAf#5Rb7TG-BooUL-<}&BF0pZm&*8qKNchff{@#D%cr3v`_f6@nk8BYt diff --git a/test/swftests/StringConversion.swf b/test/swftests/StringConversion.swf index 3f584927257873385ec941905ec6cb89a7847310..e4d458cb9ced0b9c6445aeee6407ee6f6b35bbf7 100644 GIT binary patch literal 531 zcmV+u0_^=mS5poW0{{Sc+GUZ!ZqqOr$3Mqz0y{vb0U8ISNJHv{Hc0`AR$aujQb0&d zf(x32G&gaYu*8lMXDKI6dkZdHcnuz4m+rs|aN;eBosM-3OOgEjzu*7w&+#0{FMwO$ z0k#p0H}3<$m#s4dFe<`m_-;J0=UK|jp{jN}v6T7Haq7D6)sK6km^t2HFmT+y)9-f` z(Jeo7N#|W&?sWVnV9d&(NOGA7ZtI#(MJ0DTor}~kxD3s!B5fkWz+oxN7?-8v^*j|6 z2E#}c8I?ZG^E3&lj&tVSG8VycO;1=iN@*F7oHeLDGLb3s_d+pc_9SI<`-#1`_BZqj z(QvpP)W32~s@=UnWKLd)unN>nk&0@}S1mdsucm2I#;ouwe#}L^I%2JACMXz{;$Pyg zru!-7vx?4`|Ke@ayR4fTsbv0yO>OVlBfIZv+8+ZT#@Kp)2K-*^Q3#&Wql z+`#IEP4yA;+aWaT^kC=f8};Jn8}DV2@Y%lLC#)z{2>iHnrU2E0sGu41pbb53xdAxg zvVEO552l}3AW23OZmybU%J@vi_#WEEU|Gnp5VjDpP|HH5g)GvHfMC6lfo~dMs14b~ z2w`Lp1O(KM;D!5A0|q9y7w*T_!(h@vr$5gl^A&)B5NVkUckvn&gjIchBca`~zy~-nzsR2#o*$ literal 529 zcmV+s0`C1oS5poV0{{Sc+GUYJZ__XshCjz?0y{vb0U8ISNFen>o1|lhR$aujQb0%` z!37P0<|a-Pme`TwEak+BAHs!yz?nN-x&wcJ6aS*v=~&0G6v^NFJ@4z!@f^%w0N1_% zY$F(N-Ufh=Ti+4DNJR1Q<#^)E^Nf{4Rqb^WDT|@&)^**hcY0jRTz@baxL)7w_q&Sd zmLHfT^DZmzc7i5gOv_NDg-khfbWNtbl6#%bS!xuXhZdE{n#d@0X-0F(Wa;`nUj;?s zFy1UrQ>iq&3w}0ai92m>x@^AyI z2e#B_TAvT0S>?O0Z=R_KKizmGMapIeoSjfnsu1{gO&iP+HwVO%4GX8 zZ@rklr=c`+k}_-6v@*(OGQqddHU`^9hK;a|OdGXqWZB3zn-LJK7c%fw0}Qn>H!(sO z872Y~)Xu~U@3969Y+he@Z(H}mNeg}Yc^X?!01Sl8mbLH}PeDOgl~_R(j<9!xU&Ecm TQ1Z)81VoU diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py index 678b9f7..055e425 100644 --- a/test/test_YoutubeDL.py +++ b/test/test_YoutubeDL.py @@ -13,6 +13,7 @@ import copy from test.helper import FakeYDL, assertRegexpMatches from youtube_dl import YoutubeDL from youtube_dl.extractor import YoutubeIE +from youtube_dl.postprocessor.common import PostProcessor class YDL(FakeYDL): @@ -336,6 +337,65 @@ class TestFormatSelection(unittest.TestCase): downloaded = ydl.downloaded_info_dicts[0] self.assertEqual(downloaded['format_id'], 'G') + def test_subtitles(self): + def s_formats(lang, autocaption=False): + return [{ + 'ext': ext, + 'url': 'http://localhost/video.%s.%s' % (lang, ext), + '_auto': autocaption, + } for ext in ['vtt', 'srt', 'ass']] + subtitles = dict((l, s_formats(l)) for l in ['en', 'fr', 'es']) + auto_captions = dict((l, s_formats(l, True)) for l in ['it', 'pt', 'es']) + info_dict = { + 'id': 'test', + 'title': 'Test', + 'url': 'http://localhost/video.mp4', + 'subtitles': subtitles, + 'automatic_captions': auto_captions, + 'extractor': 'TEST', + } + + def get_info(params={}): + params.setdefault('simulate', True) + ydl = YDL(params) + ydl.report_warning = lambda *args, **kargs: None + return ydl.process_video_result(info_dict, download=False) + + result = get_info() + self.assertFalse(result.get('requested_subtitles')) + self.assertEqual(result['subtitles'], subtitles) + self.assertEqual(result['automatic_captions'], auto_captions) + + result = get_info({'writesubtitles': True}) + subs = result['requested_subtitles'] + self.assertTrue(subs) + self.assertEqual(set(subs.keys()), set(['en'])) + self.assertTrue(subs['en'].get('data') is None) + self.assertEqual(subs['en']['ext'], 'ass') + + result = get_info({'writesubtitles': True, 'subtitlesformat': 'foo/srt'}) + subs = result['requested_subtitles'] + self.assertEqual(subs['en']['ext'], 'srt') + + result = get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']}) + subs = result['requested_subtitles'] + self.assertTrue(subs) + self.assertEqual(set(subs.keys()), set(['es', 'fr'])) + + result = get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']}) + subs = result['requested_subtitles'] + self.assertTrue(subs) + self.assertEqual(set(subs.keys()), set(['es', 'pt'])) + self.assertFalse(subs['es']['_auto']) + self.assertTrue(subs['pt']['_auto']) + + result = get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']}) + subs = result['requested_subtitles'] + self.assertTrue(subs) + self.assertEqual(set(subs.keys()), set(['es', 'pt'])) + self.assertTrue(subs['es']['_auto']) + self.assertTrue(subs['pt']['_auto']) + def test_add_extra_info(self): test_dict = { 'extractor': 'Foo', @@ -370,5 +430,35 @@ class TestFormatSelection(unittest.TestCase): 'vbr': 10, }), '^\s*10k$') + def test_postprocessors(self): + filename = 'post-processor-testfile.mp4' + audiofile = filename + '.mp3' + + class SimplePP(PostProcessor): + def run(self, info): + with open(audiofile, 'wt') as f: + f.write('EXAMPLE') + info['filepath'] + return False, info + + def run_pp(params): + with open(filename, 'wt') as f: + f.write('EXAMPLE') + ydl = YoutubeDL(params) + ydl.add_post_processor(SimplePP()) + ydl.post_process(filename, {'filepath': filename}) + + run_pp({'keepvideo': True}) + self.assertTrue(os.path.exists(filename), '%s doesn\'t exist' % filename) + self.assertTrue(os.path.exists(audiofile), '%s doesn\'t exist' % audiofile) + os.unlink(filename) + os.unlink(audiofile) + + run_pp({'keepvideo': False}) + self.assertFalse(os.path.exists(filename), '%s exists' % filename) + self.assertTrue(os.path.exists(audiofile), '%s doesn\'t exist' % audiofile) + os.unlink(audiofile) + + if __name__ == '__main__': unittest.main() diff --git a/test/test_jsinterp.py b/test/test_jsinterp.py index b91b8c4..fc73e5d 100644 --- a/test/test_jsinterp.py +++ b/test/test_jsinterp.py @@ -70,6 +70,8 @@ class TestJSInterpreter(unittest.TestCase): self.assertEqual(jsi.call_function('f'), -11) def test_comments(self): + 'Skipping: Not yet fully implemented' + return jsi = JSInterpreter(''' function x() { var x = /* 1 + */ 2; @@ -80,6 +82,15 @@ class TestJSInterpreter(unittest.TestCase): ''') self.assertEqual(jsi.call_function('x'), 52) + jsi = JSInterpreter(''' + function f() { + var x = "/*"; + var y = 1 /* comment */ + 2; + return y; + } + ''') + self.assertEqual(jsi.call_function('f'), 3) + def test_precedence(self): jsi = JSInterpreter(''' function x() { diff --git a/test/test_subtitles.py b/test/test_subtitles.py index 6336dd3..3f2d8a2 100644 --- a/test/test_subtitles.py +++ b/test/test_subtitles.py @@ -18,6 +18,14 @@ from youtube_dl.extractor import ( VimeoIE, WallaIE, CeskaTelevizeIE, + LyndaIE, + NPOIE, + ComedyCentralIE, + NRKTVIE, + RaiIE, + VikiIE, + ThePlatformIE, + RTVEALaCartaIE, ) @@ -27,42 +35,38 @@ class BaseTestSubtitles(unittest.TestCase): def setUp(self): self.DL = FakeYDL() - self.ie = self.IE(self.DL) + self.ie = self.IE() + self.DL.add_info_extractor(self.ie) def getInfoDict(self): - info_dict = self.ie.extract(self.url) + info_dict = self.DL.extract_info(self.url, download=False) return info_dict def getSubtitles(self): info_dict = self.getInfoDict() - return info_dict['subtitles'] + subtitles = info_dict['requested_subtitles'] + if not subtitles: + return subtitles + for sub_info in subtitles.values(): + if sub_info.get('data') is None: + uf = self.DL.urlopen(sub_info['url']) + sub_info['data'] = uf.read().decode('utf-8') + return dict((l, sub_info['data']) for l, sub_info in subtitles.items()) class TestYoutubeSubtitles(BaseTestSubtitles): url = 'QRS8MkLhQmM' IE = YoutubeIE - def test_youtube_no_writesubtitles(self): - self.DL.params['writesubtitles'] = False - subtitles = self.getSubtitles() - self.assertEqual(subtitles, None) - - def test_youtube_subtitles(self): - self.DL.params['writesubtitles'] = True - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['en']), '4cd9278a35ba2305f47354ee13472260') - - def test_youtube_subtitles_lang(self): - self.DL.params['writesubtitles'] = True - self.DL.params['subtitleslangs'] = ['it'] - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['it']), '164a51f16f260476a05b50fe4c2f161d') - def test_youtube_allsubtitles(self): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() self.assertEqual(len(subtitles.keys()), 13) + self.assertEqual(md5(subtitles['en']), '4cd9278a35ba2305f47354ee13472260') + self.assertEqual(md5(subtitles['it']), '164a51f16f260476a05b50fe4c2f161d') + for lang in ['it', 'fr', 'de']: + self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) def test_youtube_subtitles_sbv_format(self): self.DL.params['writesubtitles'] = True @@ -76,12 +80,6 @@ class TestYoutubeSubtitles(BaseTestSubtitles): subtitles = self.getSubtitles() self.assertEqual(md5(subtitles['en']), '3cb210999d3e021bd6c7f0ea751eab06') - def test_youtube_list_subtitles(self): - self.DL.expect_warning('Video doesn\'t have automatic captions') - self.DL.params['listsubtitles'] = True - info_dict = self.getInfoDict() - self.assertEqual(info_dict, None) - def test_youtube_automatic_captions(self): self.url = '8YoUxe5ncPo' self.DL.params['writeautomaticsub'] = True @@ -103,55 +101,22 @@ class TestYoutubeSubtitles(BaseTestSubtitles): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() - self.assertEqual(len(subtitles), 0) - - def test_youtube_multiple_langs(self): - self.url = 'QRS8MkLhQmM' - self.DL.params['writesubtitles'] = True - langs = ['it', 'fr', 'de'] - self.DL.params['subtitleslangs'] = langs - subtitles = self.getSubtitles() - for lang in langs: - self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) + self.assertFalse(subtitles) class TestDailymotionSubtitles(BaseTestSubtitles): url = 'http://www.dailymotion.com/video/xczg00' IE = DailymotionIE - def test_no_writesubtitles(self): - subtitles = self.getSubtitles() - self.assertEqual(subtitles, None) - - def test_subtitles(self): - self.DL.params['writesubtitles'] = True - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['en']), '976553874490cba125086bbfea3ff76f') - - def test_subtitles_lang(self): - self.DL.params['writesubtitles'] = True - self.DL.params['subtitleslangs'] = ['fr'] - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['fr']), '594564ec7d588942e384e920e5341792') - def test_allsubtitles(self): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() - self.assertEqual(len(subtitles.keys()), 5) - - def test_list_subtitles(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['listsubtitles'] = True - info_dict = self.getInfoDict() - self.assertEqual(info_dict, None) - - def test_automatic_captions(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['writeautomaticsub'] = True - self.DL.params['subtitleslang'] = ['en'] - subtitles = self.getSubtitles() - self.assertTrue(len(subtitles.keys()) == 0) + self.assertTrue(len(subtitles.keys()) >= 6) + self.assertEqual(md5(subtitles['en']), '976553874490cba125086bbfea3ff76f') + self.assertEqual(md5(subtitles['fr']), '594564ec7d588942e384e920e5341792') + for lang in ['es', 'fr', 'de']: + self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) def test_nosubtitles(self): self.DL.expect_warning('video doesn\'t have subtitles') @@ -159,61 +124,21 @@ class TestDailymotionSubtitles(BaseTestSubtitles): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() - self.assertEqual(len(subtitles), 0) - - def test_multiple_langs(self): - self.DL.params['writesubtitles'] = True - langs = ['es', 'fr', 'de'] - self.DL.params['subtitleslangs'] = langs - subtitles = self.getSubtitles() - for lang in langs: - self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) + self.assertFalse(subtitles) class TestTedSubtitles(BaseTestSubtitles): url = 'http://www.ted.com/talks/dan_dennett_on_our_consciousness.html' IE = TEDIE - def test_no_writesubtitles(self): - subtitles = self.getSubtitles() - self.assertEqual(subtitles, None) - - def test_subtitles(self): - self.DL.params['writesubtitles'] = True - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['en']), '4262c1665ff928a2dada178f62cb8d14') - - def test_subtitles_lang(self): - self.DL.params['writesubtitles'] = True - self.DL.params['subtitleslangs'] = ['fr'] - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['fr']), '66a63f7f42c97a50f8c0e90bc7797bb5') - def test_allsubtitles(self): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() self.assertTrue(len(subtitles.keys()) >= 28) - - def test_list_subtitles(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['listsubtitles'] = True - info_dict = self.getInfoDict() - self.assertEqual(info_dict, None) - - def test_automatic_captions(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['writeautomaticsub'] = True - self.DL.params['subtitleslang'] = ['en'] - subtitles = self.getSubtitles() - self.assertTrue(len(subtitles.keys()) == 0) - - def test_multiple_langs(self): - self.DL.params['writesubtitles'] = True - langs = ['es', 'fr', 'de'] - self.DL.params['subtitleslangs'] = langs - subtitles = self.getSubtitles() - for lang in langs: + self.assertEqual(md5(subtitles['en']), '4262c1665ff928a2dada178f62cb8d14') + self.assertEqual(md5(subtitles['fr']), '66a63f7f42c97a50f8c0e90bc7797bb5') + for lang in ['es', 'fr', 'de']: self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) @@ -221,14 +146,7 @@ class TestBlipTVSubtitles(BaseTestSubtitles): url = 'http://blip.tv/a/a-6603250' IE = BlipTVIE - def test_list_subtitles(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['listsubtitles'] = True - info_dict = self.getInfoDict() - self.assertEqual(info_dict, None) - def test_allsubtitles(self): - self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() @@ -240,39 +158,13 @@ class TestVimeoSubtitles(BaseTestSubtitles): url = 'http://vimeo.com/76979871' IE = VimeoIE - def test_no_writesubtitles(self): - subtitles = self.getSubtitles() - self.assertEqual(subtitles, None) - - def test_subtitles(self): - self.DL.params['writesubtitles'] = True - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['en']), '26399116d23ae3cf2c087cea94bc43b4') - - def test_subtitles_lang(self): - self.DL.params['writesubtitles'] = True - self.DL.params['subtitleslangs'] = ['fr'] - subtitles = self.getSubtitles() - self.assertEqual(md5(subtitles['fr']), 'b6191146a6c5d3a452244d853fde6dc8') - def test_allsubtitles(self): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() self.assertEqual(set(subtitles.keys()), set(['de', 'en', 'es', 'fr'])) - - def test_list_subtitles(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['listsubtitles'] = True - info_dict = self.getInfoDict() - self.assertEqual(info_dict, None) - - def test_automatic_captions(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['writeautomaticsub'] = True - self.DL.params['subtitleslang'] = ['en'] - subtitles = self.getSubtitles() - self.assertTrue(len(subtitles.keys()) == 0) + self.assertEqual(md5(subtitles['en']), '8062383cf4dec168fc40a088aa6d5888') + self.assertEqual(md5(subtitles['fr']), 'b6191146a6c5d3a452244d853fde6dc8') def test_nosubtitles(self): self.DL.expect_warning('video doesn\'t have subtitles') @@ -280,27 +172,13 @@ class TestVimeoSubtitles(BaseTestSubtitles): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() - self.assertEqual(len(subtitles), 0) - - def test_multiple_langs(self): - self.DL.params['writesubtitles'] = True - langs = ['es', 'fr', 'de'] - self.DL.params['subtitleslangs'] = langs - subtitles = self.getSubtitles() - for lang in langs: - self.assertTrue(subtitles.get(lang) is not None, 'Subtitles for \'%s\' not extracted' % lang) + self.assertFalse(subtitles) class TestWallaSubtitles(BaseTestSubtitles): url = 'http://vod.walla.co.il/movie/2705958/the-yes-men' IE = WallaIE - def test_list_subtitles(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['listsubtitles'] = True - info_dict = self.getInfoDict() - self.assertEqual(info_dict, None) - def test_allsubtitles(self): self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writesubtitles'] = True @@ -315,26 +193,20 @@ class TestWallaSubtitles(BaseTestSubtitles): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() - self.assertEqual(len(subtitles), 0) + self.assertFalse(subtitles) class TestCeskaTelevizeSubtitles(BaseTestSubtitles): url = 'http://www.ceskatelevize.cz/ivysilani/10600540290-u6-uzasny-svet-techniky' IE = CeskaTelevizeIE - def test_list_subtitles(self): - self.DL.expect_warning('Automatic Captions not supported by this server') - self.DL.params['listsubtitles'] = True - info_dict = self.getInfoDict() - self.assertEqual(info_dict, None) - def test_allsubtitles(self): self.DL.expect_warning('Automatic Captions not supported by this server') self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() self.assertEqual(set(subtitles.keys()), set(['cs'])) - self.assertEqual(md5(subtitles['cs']), '9bf52d9549533c32c427e264bf0847d4') + self.assertTrue(len(subtitles['cs']) > 20000) def test_nosubtitles(self): self.DL.expect_warning('video doesn\'t have subtitles') @@ -342,7 +214,110 @@ class TestCeskaTelevizeSubtitles(BaseTestSubtitles): self.DL.params['writesubtitles'] = True self.DL.params['allsubtitles'] = True subtitles = self.getSubtitles() - self.assertEqual(len(subtitles), 0) + self.assertFalse(subtitles) + + +class TestLyndaSubtitles(BaseTestSubtitles): + url = 'http://www.lynda.com/Bootstrap-tutorials/Using-exercise-files/110885/114408-4.html' + IE = LyndaIE + + def test_allsubtitles(self): + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['en'])) + self.assertEqual(md5(subtitles['en']), '09bbe67222259bed60deaa26997d73a7') + + +class TestNPOSubtitles(BaseTestSubtitles): + url = 'http://www.npo.nl/nos-journaal/28-08-2014/POW_00722860' + IE = NPOIE + + def test_allsubtitles(self): + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['nl'])) + self.assertEqual(md5(subtitles['nl']), 'fc6435027572b63fb4ab143abd5ad3f4') + + +class TestMTVSubtitles(BaseTestSubtitles): + url = 'http://www.cc.com/video-clips/kllhuv/stand-up-greg-fitzsimmons--uncensored---too-good-of-a-mother' + IE = ComedyCentralIE + + def getInfoDict(self): + return super(TestMTVSubtitles, self).getInfoDict()['entries'][0] + + def test_allsubtitles(self): + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['en'])) + self.assertEqual(md5(subtitles['en']), 'b9f6ca22a6acf597ec76f61749765e65') + + +class TestNRKSubtitles(BaseTestSubtitles): + url = 'http://tv.nrk.no/serie/ikke-gjoer-dette-hjemme/DMPV73000411/sesong-2/episode-1' + IE = NRKTVIE + + def test_allsubtitles(self): + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['no'])) + self.assertEqual(md5(subtitles['no']), '1d221e6458c95c5494dcd38e6a1f129a') + + +class TestRaiSubtitles(BaseTestSubtitles): + url = 'http://www.rai.tv/dl/RaiTV/programmi/media/ContentItem-cb27157f-9dd0-4aee-b788-b1f67643a391.html' + IE = RaiIE + + def test_allsubtitles(self): + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['it'])) + self.assertEqual(md5(subtitles['it']), 'b1d90a98755126b61e667567a1f6680a') + + +class TestVikiSubtitles(BaseTestSubtitles): + url = 'http://www.viki.com/videos/1060846v-punch-episode-18' + IE = VikiIE + + def test_allsubtitles(self): + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['en'])) + self.assertEqual(md5(subtitles['en']), '53cb083a5914b2d84ef1ab67b880d18a') + + +class TestThePlatformSubtitles(BaseTestSubtitles): + # from http://www.3playmedia.com/services-features/tools/integrations/theplatform/ + # (see http://theplatform.com/about/partners/type/subtitles-closed-captioning/) + url = 'theplatform:JFUjUE1_ehvq' + IE = ThePlatformIE + + def test_allsubtitles(self): + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['en'])) + self.assertEqual(md5(subtitles['en']), '97e7670cbae3c4d26ae8bcc7fdd78d4b') + + +class TestRtveSubtitles(BaseTestSubtitles): + url = 'http://www.rtve.es/alacarta/videos/los-misterios-de-laura/misterios-laura-capitulo-32-misterio-del-numero-17-2-parte/2428621/' + IE = RTVEALaCartaIE + + def test_allsubtitles(self): + print('Skipping, only available from Spain') + return + self.DL.params['writesubtitles'] = True + self.DL.params['allsubtitles'] = True + subtitles = self.getSubtitles() + self.assertEqual(set(subtitles.keys()), set(['es'])) + self.assertEqual(md5(subtitles['es']), '69e70cae2d40574fb7316f31d6eb7fca') if __name__ == '__main__': diff --git a/test/test_swfinterp.py b/test/test_swfinterp.py index 9f18055..f1e8998 100644 --- a/test/test_swfinterp.py +++ b/test/test_swfinterp.py @@ -34,8 +34,8 @@ def _make_testfunc(testfile): def test_func(self): as_file = os.path.join(TEST_DIR, testfile) swf_file = os.path.join(TEST_DIR, test_id + '.swf') - if ((not os.path.exists(swf_file)) - or os.path.getmtime(swf_file) < os.path.getmtime(as_file)): + if ((not os.path.exists(swf_file)) or + os.path.getmtime(swf_file) < os.path.getmtime(as_file)): # Recompile try: subprocess.check_call([ diff --git a/test/test_utils.py b/test/test_utils.py index 80c765b..3fba8ae 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -53,6 +53,7 @@ from youtube_dl.utils import ( version_tuple, xpath_with_ns, render_table, + match_str, ) @@ -84,6 +85,8 @@ class TestUtil(unittest.TestCase): self.assertEqual( sanitize_filename('New World record at 0:12:34'), 'New World record at 0_12_34') + self.assertEqual(sanitize_filename('--gasdgf'), '_-gasdgf') + self.assertEqual(sanitize_filename('--gasdgf', is_id=True), '--gasdgf') forbidden = '"\0\\/' for fc in forbidden: @@ -243,6 +246,7 @@ class TestUtil(unittest.TestCase): self.assertEqual(parse_duration('2.5 hours'), 9000) self.assertEqual(parse_duration('02:03:04'), 7384) self.assertEqual(parse_duration('01:02:03:04'), 93784) + self.assertEqual(parse_duration('1 hour 3 minutes'), 3780) def test_fix_xml_ampersands(self): self.assertEqual( @@ -369,6 +373,10 @@ class TestUtil(unittest.TestCase): "playlist":[{"controls":{"all":null}}] }''') + inp = '"SAND Number: SAND 2013-7800P\\nPresenter: Tom Russo\\nHabanero Software Training - Xyce Software\\nXyce, Sandia\\u0027s"' + json_code = js_to_json(inp) + self.assertEqual(json.loads(json_code), json.loads(inp)) + def test_js_to_json_edgecases(self): on = js_to_json("{abc_def:'1\\'\\\\2\\\\\\'3\"4'}") self.assertEqual(json.loads(on), {"abc_def": "1'\\2\\'3\"4"}) @@ -459,6 +467,37 @@ ffmpeg version 2.4.4 Copyright (c) 2000-2014 the FFmpeg ...'''), '2.4.4') '123 4\n' '9999 51') + def test_match_str(self): + self.assertRaises(ValueError, match_str, 'xy>foobar', {}) + self.assertFalse(match_str('xy', {'x': 1200})) + self.assertTrue(match_str('!xy', {'x': 1200})) + self.assertTrue(match_str('x', {'x': 1200})) + self.assertFalse(match_str('!x', {'x': 1200})) + self.assertTrue(match_str('x', {'x': 0})) + self.assertFalse(match_str('x>0', {'x': 0})) + self.assertFalse(match_str('x>0', {})) + self.assertTrue(match_str('x>?0', {})) + self.assertTrue(match_str('x>1K', {'x': 1200})) + self.assertFalse(match_str('x>2K', {'x': 1200})) + self.assertTrue(match_str('x>=1200 & x < 1300', {'x': 1200})) + self.assertFalse(match_str('x>=1100 & x < 1200', {'x': 1200})) + self.assertFalse(match_str('y=a212', {'y': 'foobar42'})) + self.assertTrue(match_str('y=foobar42', {'y': 'foobar42'})) + self.assertFalse(match_str('y!=foobar42', {'y': 'foobar42'})) + self.assertTrue(match_str('y!=foobar2', {'y': 'foobar42'})) + self.assertFalse(match_str( + 'like_count > 100 & dislike_count 100 & dislike_count 100 & dislike_count 100 & dislike_count E(J@>F$r3jhHG=mP)% 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
_LqjiSdf6!IjKv&4zJ0 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�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 delta 292227 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 z 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 z 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�DNvknpUgySh2vmkON>|-z(4wpcZwQs0*^{WZ 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 HP0-~3?`Yk3 diff --git a/youtube-dl.1 b/youtube-dl.1 index bddd991..65d4fc3 100644 --- a/youtube-dl.1 +++ b/youtube-dl.1 @@ -50,6 +50,7 @@ redistribute it or use it however you like. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ on\ Windows) \-\-flat\-playlist\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Do\ not\ extract\ the\ videos\ of\ a\ playlist, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ only\ list\ them. +\-\-no\-color\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Do\ not\ emit\ color\ codes\ in\ output. \f[] .fi .SS Network Options: @@ -100,8 +101,27 @@ redistribute it or use it however you like. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ COUNT\ views \-\-max\-views\ COUNT\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Do\ not\ download\ any\ videos\ with\ more\ than \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ COUNT\ views +\-\-match\-filter\ FILTER\ \ \ \ \ \ \ \ \ \ \ \ (Experimental)\ Generic\ video\ filter. +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Specify\ any\ key\ (see\ help\ for\ \-o\ for\ a\ list +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ of\ available\ keys)\ to\ match\ if\ the\ key\ is +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ present,\ !key\ to\ check\ if\ the\ key\ is\ not +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ present,key\ >\ NUMBER\ (like\ "comment_count\ > +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 12",\ also\ works\ with\ >=,\ <,\ <=,\ !=,\ =)\ to +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ compare\ against\ a\ number,\ and\ &\ to\ require +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ multiple\ matches.\ Values\ which\ are\ not +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ known\ are\ excluded\ unless\ you\ put\ a +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ question\ mark\ (?)\ after\ the\ operator.For +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ example,\ to\ only\ match\ videos\ that\ have +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ been\ liked\ more\ than\ 100\ times\ and\ disliked +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ less\ than\ 50\ times\ (or\ the\ dislike +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ functionality\ is\ not\ available\ at\ the\ given +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ service),\ but\ who\ also\ have\ a\ description, +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ use\ \ \-\-match\-filter\ "like_count\ >\ 100\ & +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ dislike_count\ 10M]").\ \ This\ works\ for -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ filesize,\ height,\ width,\ tbr,\ abr,\ vbr,\ and -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fps\ and\ the\ comparisons\ <,\ <=,\ >,\ >=,\ =,\ != -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .\ Formats\ for\ which\ the\ value\ is\ not\ known -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ are\ excluded\ unless\ you\ put\ a\ question\ mark -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (?)\ after\ the\ operator.\ You\ can\ combine -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ format\ filters,\ so\ \ \-f\ "[height\ <=? -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 720][tbr>500]"\ selects\ up\ to\ 720p\ videos -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (or\ videos\ where\ the\ height\ is\ not\ known) -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ with\ a\ bitrate\ of\ at\ least\ 500\ KBit/s.\ By -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ default,\ youtube\-dl\ will\ pick\ the\ best -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ quality.\ Use\ commas\ to\ download\ multiple -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ audio\ formats,\ such\ as\ \-f +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ filesize,\ height,\ width,\ tbr,\ abr,\ vbr, +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ asr,\ and\ fps\ and\ the\ comparisons\ <,\ <=,\ >, +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ >=,\ =,\ !=\ and\ for\ ext,\ acodec,\ vcodec, +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ container,\ and\ protocol\ and\ the\ comparisons +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =,\ !=\ .\ Formats\ for\ which\ the\ value\ is\ not +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ known\ are\ excluded\ unless\ you\ put\ a +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ question\ mark\ (?)\ after\ the\ operator.\ You +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ can\ combine\ format\ filters,\ so\ \ \-f\ "[height +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ <=?\ 720][tbr>500]"\ selects\ up\ to\ 720p +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ videos\ (or\ videos\ where\ the\ height\ is\ not +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ known)\ with\ a\ bitrate\ of\ at\ least\ 500 +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ KBit/s.\ By\ default,\ youtube\-dl\ will\ pick +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ the\ best\ quality.\ Use\ commas\ to\ download +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ multiple\ audio\ formats,\ such\ as\ \-f \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 136/137/mp4/bestvideo,140/m4a/bestaudio. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ You\ can\ merge\ the\ video\ and\ audio\ of\ two \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ formats\ into\ a\ single\ file\ using\ \-f\ NUMBER (like "comment_count > 12", also works with >=, <, <=, !=, =) to compare against a number, and & to require multiple matches. Values which are not known are excluded unless you put a question mark (?) after the operator.For example, to only match videos that have been liked more than 100 times and disliked less than 50 times (or the dislike functionality is not available at the given service), but who also have a description, use --match-filter "like_count > 100 & dislike_count 10M]"). This works for filesize, height, width, tbr, abr, vbr, and fps and the comparisons <, <=, >, >=, =, != . Formats for which the value is not known are excluded unless you put a question mark (?) after the operator. You can combine format filters, so -f "[height <=? 720][tbr>500]" selects up to 720p videos (or videos where the height is not known) with a bitrate of at least 500 KBit/s. By default, youtube-dl will pick the best quality. Use commas to download multiple audio formats, such as -f 136/137/mp4/bestvideo,140/m4a/bestaudio. You can merge the video and audio of two formats into a single file using -f + (requires ffmpeg or avconv), for example -f bestvideo+bestaudio.' +complete --command youtube-dl --long-option format --short-option f --description 'video format code, specify the order of preference using slashes, as in -f 22/17/18 . Instead of format codes, you can select by extension for the extensions aac, m4a, mp3, mp4, ogg, wav, webm. You can also use the special names "best", "bestvideo", "bestaudio", "worst". You can filter the video results by putting a condition in brackets, as in -f "best[height=720]" (or -f "[filesize>10M]"). This works for filesize, height, width, tbr, abr, vbr, asr, and fps and the comparisons <, <=, >, >=, =, != and for ext, acodec, vcodec, container, and protocol and the comparisons =, != . Formats for which the value is not known are excluded unless you put a question mark (?) after the operator. You can combine format filters, so -f "[height <=? 720][tbr>500]" selects up to 720p videos (or videos where the height is not known) with a bitrate of at least 500 KBit/s. By default, youtube-dl will pick the best quality. Use commas to download multiple audio formats, such as -f 136/137/mp4/bestvideo,140/m4a/bestaudio. You can merge the video and audio of two formats into a single file using -f + (requires ffmpeg or avconv), for example -f bestvideo+bestaudio.' complete --command youtube-dl --long-option all-formats --description 'download all available video formats' complete --command youtube-dl --long-option prefer-free-formats --description 'prefer free video formats unless a specific one is requested' complete --command youtube-dl --long-option max-quality --description 'highest quality format to download' @@ -109,7 +113,7 @@ complete --command youtube-dl --long-option write-sub --description 'write subti complete --command youtube-dl --long-option write-auto-sub --description 'write automatic subtitle file (youtube only)' complete --command youtube-dl --long-option all-subs --description 'downloads all the available subtitles of the video' complete --command youtube-dl --long-option list-subs --description 'lists all available subtitles for the video' -complete --command youtube-dl --long-option sub-format --description 'subtitle format (default=srt) ([sbv/vtt] youtube only)' +complete --command youtube-dl --long-option sub-format --description 'subtitle format, accepts formats preference, for example: "ass/srt/best"' complete --command youtube-dl --long-option sub-lang --description 'languages of the subtitles to download (optional) separated by commas, use IETF language tags like '"'"'en,pt'"'"'' complete --command youtube-dl --long-option username --short-option u --description 'login with this account ID' complete --command youtube-dl --long-option password --short-option p --description 'account password. If this option is left out, youtube-dl will ask interactively.' @@ -129,7 +133,9 @@ complete --command youtube-dl --long-option xattrs --description 'write metadata complete --command youtube-dl --long-option fixup --description 'Automatically correct known faults of the file. One of never (do nothing), warn (only emit a warning), detect_or_warn(the default; fix file if we can, warn otherwise)' complete --command youtube-dl --long-option prefer-avconv --description 'Prefer avconv over ffmpeg for running the postprocessors (default)' complete --command youtube-dl --long-option prefer-ffmpeg --description 'Prefer ffmpeg over avconv for running the postprocessors' +complete --command youtube-dl --long-option ffmpeg-location --description 'Location of the ffmpeg/avconv binary; either the path to the binary or its containing directory.' complete --command youtube-dl --long-option exec --description 'Execute a command on the file after downloading, similar to find'"'"'s -exec syntax. Example: --exec '"'"'adb push {} /sdcard/Music/ && rm {}'"'"'' +complete --command youtube-dl --long-option convert-subtitles --description 'Convert the subtitles to other format (currently supported: srt|ass|vtt)' complete --command youtube-dl --arguments ":ytfavorites :ytrecommended :ytsubscriptions :ytwatchlater :ythistory" diff --git a/youtube-dl.zsh b/youtube-dl.zsh index 71d1423..5071f16 100644 --- a/youtube-dl.zsh +++ b/youtube-dl.zsh @@ -19,7 +19,7 @@ __youtube_dl() { elif [[ ${prev} == "--recode-video" ]]; then _arguments '*: :(mp4 flv ogg webm mkv)' else - _arguments '*: :(--help --version --update --ignore-errors --abort-on-error --dump-user-agent --list-extractors --extractor-descriptions --default-search --ignore-config --flat-playlist --proxy --socket-timeout --source-address --force-ipv4 --force-ipv6 --playlist-start --playlist-end --playlist-items --match-title --reject-title --max-downloads --min-filesize --max-filesize --date --datebefore --dateafter --min-views --max-views --no-playlist --age-limit --download-archive --include-ads --rate-limit --retries --buffer-size --no-resize-buffer --test --playlist-reverse --xattr-set-filesize --external-downloader --batch-file --id --output --autonumber-size --restrict-filenames --auto-number --title --literal --no-overwrites --continue --no-continue --no-part --no-mtime --write-description --write-info-json --write-annotations --load-info --cookies --cache-dir --no-cache-dir --rm-cache-dir --write-thumbnail --write-all-thumbnails --list-thumbnails --quiet --no-warnings --simulate --skip-download --get-url --get-title --get-id --get-thumbnail --get-description --get-duration --get-filename --get-format --dump-json --dump-single-json --print-json --newline --no-progress --console-title --verbose --dump-intermediate-pages --write-pages --youtube-print-sig-code --print-traffic --call-home --no-call-home --encoding --no-check-certificate --prefer-insecure --user-agent --referer --add-header --bidi-workaround --sleep-interval --format --all-formats --prefer-free-formats --max-quality --list-formats --youtube-include-dash-manifest --youtube-skip-dash-manifest --merge-output-format --write-sub --write-auto-sub --all-subs --list-subs --sub-format --sub-lang --username --password --twofactor --netrc --video-password --extract-audio --audio-format --audio-quality --recode-video --keep-video --no-post-overwrites --embed-subs --embed-thumbnail --add-metadata --xattrs --fixup --prefer-avconv --prefer-ffmpeg --exec)' + _arguments '*: :(--help --version --update --ignore-errors --abort-on-error --dump-user-agent --list-extractors --extractor-descriptions --default-search --ignore-config --flat-playlist --no-color --proxy --socket-timeout --source-address --force-ipv4 --force-ipv6 --playlist-start --playlist-end --playlist-items --match-title --reject-title --max-downloads --min-filesize --max-filesize --date --datebefore --dateafter --min-views --max-views --match-filter --no-playlist --yes-playlist --age-limit --download-archive --include-ads --rate-limit --retries --buffer-size --no-resize-buffer --test --playlist-reverse --xattr-set-filesize --hls-prefer-native --external-downloader --batch-file --id --output --autonumber-size --restrict-filenames --auto-number --title --literal --no-overwrites --continue --no-continue --no-part --no-mtime --write-description --write-info-json --write-annotations --load-info --cookies --cache-dir --no-cache-dir --rm-cache-dir --write-thumbnail --write-all-thumbnails --list-thumbnails --quiet --no-warnings --simulate --skip-download --get-url --get-title --get-id --get-thumbnail --get-description --get-duration --get-filename --get-format --dump-json --dump-single-json --print-json --newline --no-progress --console-title --verbose --dump-intermediate-pages --write-pages --youtube-print-sig-code --print-traffic --call-home --no-call-home --encoding --no-check-certificate --prefer-insecure --user-agent --referer --add-header --bidi-workaround --sleep-interval --format --all-formats --prefer-free-formats --max-quality --list-formats --youtube-include-dash-manifest --youtube-skip-dash-manifest --merge-output-format --write-sub --write-auto-sub --all-subs --list-subs --sub-format --sub-lang --username --password --twofactor --netrc --video-password --extract-audio --audio-format --audio-quality --recode-video --keep-video --no-post-overwrites --embed-subs --embed-thumbnail --add-metadata --xattrs --fixup --prefer-avconv --prefer-ffmpeg --ffmpeg-location --exec --convert-subtitles)' fi ;; esac diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 9605f8f..74e4261 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -154,7 +154,7 @@ class YoutubeDL(object): allsubtitles: Downloads all the subtitles of the video (requires writesubtitles or writeautomaticsub) listsubtitles: Lists all available subtitles for the video - subtitlesformat: Subtitle format [srt/sbv/vtt] (default=srt) + subtitlesformat: The format code for subtitles subtitleslangs: List of languages of the subtitles to download keepvideo: Keep the video file after post-processing daterange: A DateRange object, download only if the upload_date is in the range. @@ -199,18 +199,25 @@ class YoutubeDL(object): postprocessor. progress_hooks: A list of functions that get called on download progress, with a dictionary with the entries - * status: One of "downloading" and "finished". + * status: One of "downloading", "error", or "finished". Check this first and ignore unknown values. - If status is one of "downloading" or "finished", the + If status is one of "downloading", or "finished", the following properties may also be present: * filename: The final filename (always present) + * tmpfilename: The filename we're currently writing to * downloaded_bytes: Bytes on disk * total_bytes: Size of the whole file, None if unknown - * tmpfilename: The filename we're currently writing to + * total_bytes_estimate: Guess of the eventual file size, + None if unavailable. + * elapsed: The number of seconds since download started. * eta: The estimated time in seconds, None if unknown * speed: The download speed in bytes/second, None if unknown + * fragment_index: The counter of the currently + downloaded video fragment. + * fragment_count: The number of fragments (= individual + files that will be merged) Progress hooks are guaranteed to be called at least once (with status "finished") if the download is successful. @@ -225,10 +232,19 @@ class YoutubeDL(object): call_home: Boolean, true iff we are allowed to contact the youtube-dl servers for debugging. sleep_interval: Number of seconds to sleep before each download. - external_downloader: Executable of the external downloader to call. listformats: Print an overview of available video formats and exit. list_thumbnails: Print a table of all thumbnails and exit. - + match_filter: A function that gets called with the info_dict of + every video. + If it returns a message, the video is ignored. + If it returns None, the video is downloaded. + match_filter_func in utils.py is one example for this. + no_color: Do not emit color codes in output. + + The following options determine which downloader is picked: + external_downloader: Executable of the external downloader to call. + None or unset for standard (built-in) downloader. + hls_prefer_native: Use the native HLS downloader instead of ffmpeg/avconv. The following parameters are not used by YoutubeDL itself, they are used by the FileDownloader: @@ -292,8 +308,8 @@ class YoutubeDL(object): raise if (sys.version_info >= (3,) and sys.platform != 'win32' and - sys.getfilesystemencoding() in ['ascii', 'ANSI_X3.4-1968'] - and not params.get('restrictfilenames', False)): + sys.getfilesystemencoding() in ['ascii', 'ANSI_X3.4-1968'] and + not params.get('restrictfilenames', False)): # On Python 3, the Unicode filesystem API will throw errors (#1474) self.report_warning( 'Assuming --restrict-filenames since file system encoding ' @@ -485,7 +501,7 @@ class YoutubeDL(object): else: if self.params.get('no_warnings'): return - if self._err_file.isatty() and os.name != 'nt': + if not self.params.get('no_color') and self._err_file.isatty() and os.name != 'nt': _msg_header = '\033[0;33mWARNING:\033[0m' else: _msg_header = 'WARNING:' @@ -497,7 +513,7 @@ class YoutubeDL(object): Do the same as trouble, but prefixes the message with 'ERROR:', colored in red if stderr is a tty file. ''' - if self._err_file.isatty() and os.name != 'nt': + if not self.params.get('no_color') and self._err_file.isatty() and os.name != 'nt': _msg_header = '\033[0;31mERROR:\033[0m' else: _msg_header = 'ERROR:' @@ -554,7 +570,7 @@ class YoutubeDL(object): self.report_error('Error in output template: ' + str(err) + ' (encoding: ' + repr(preferredencoding()) + ')') return None - def _match_entry(self, info_dict): + def _match_entry(self, info_dict, incomplete): """ Returns None iff the file should be downloaded """ video_title = info_dict.get('title', info_dict.get('id', 'video')) @@ -583,9 +599,17 @@ class YoutubeDL(object): if max_views is not None and view_count > max_views: return 'Skipping %s, because it has exceeded the maximum view count (%d/%d)' % (video_title, view_count, max_views) if age_restricted(info_dict.get('age_limit'), self.params.get('age_limit')): - return 'Skipping "%s" because it is age restricted' % title + return 'Skipping "%s" because it is age restricted' % video_title if self.in_download_archive(info_dict): return '%s has already been recorded in archive' % video_title + + if not incomplete: + match_filter = self.params.get('match_filter') + if match_filter is not None: + ret = match_filter(info_dict) + if ret is not None: + return ret + return None @staticmethod @@ -779,7 +803,7 @@ class YoutubeDL(object): 'extractor_key': ie_result['extractor_key'], } - reason = self._match_entry(entry) + reason = self._match_entry(entry, incomplete=True) if reason is not None: self.to_screen('[download] ' + reason) continue @@ -826,26 +850,43 @@ class YoutubeDL(object): '!=': operator.ne, } operator_rex = re.compile(r'''(?x)\s*\[ - (?Pwidth|height|tbr|abr|vbr|filesize|fps) + (?Pwidth|height|tbr|abr|vbr|asr|filesize|fps) \s*(?P%s)(?P\s*\?)?\s* (?P[0-9.]+(?:[kKmMgGtTpPeEzZyY]i?[Bb]?)?) \]$ ''' % '|'.join(map(re.escape, OPERATORS.keys()))) m = operator_rex.search(format_spec) + if m: + try: + comparison_value = int(m.group('value')) + except ValueError: + comparison_value = parse_filesize(m.group('value')) + if comparison_value is None: + comparison_value = parse_filesize(m.group('value') + 'B') + if comparison_value is None: + raise ValueError( + 'Invalid value %r in format specification %r' % ( + m.group('value'), format_spec)) + op = OPERATORS[m.group('op')] + if not m: - raise ValueError('Invalid format specification %r' % format_spec) + STR_OPERATORS = { + '=': operator.eq, + '!=': operator.ne, + } + str_operator_rex = re.compile(r'''(?x)\s*\[ + \s*(?Pext|acodec|vcodec|container|protocol) + \s*(?P%s)(?P\s*\?)? + \s*(?P[a-zA-Z0-9_-]+) + \s*\]$ + ''' % '|'.join(map(re.escape, STR_OPERATORS.keys()))) + m = str_operator_rex.search(format_spec) + if m: + comparison_value = m.group('value') + op = STR_OPERATORS[m.group('op')] - try: - comparison_value = int(m.group('value')) - except ValueError: - comparison_value = parse_filesize(m.group('value')) - if comparison_value is None: - comparison_value = parse_filesize(m.group('value') + 'B') - if comparison_value is None: - raise ValueError( - 'Invalid value %r in format specification %r' % ( - m.group('value'), format_spec)) - op = OPERATORS[m.group('op')] + if not m: + raise ValueError('Invalid format specification %r' % format_spec) def _filter(f): actual_value = f.get(m.group('key')) @@ -920,27 +961,9 @@ class YoutubeDL(object): return res def _calc_cookies(self, info_dict): - class _PseudoRequest(object): - def __init__(self, url): - self.url = url - self.headers = {} - self.unverifiable = False - - def add_unredirected_header(self, k, v): - self.headers[k] = v - - def get_full_url(self): - return self.url - - def is_unverifiable(self): - return self.unverifiable - - def has_header(self, h): - return h in self.headers - - pr = _PseudoRequest(info_dict['url']) + pr = compat_urllib_request.Request(info_dict['url']) self.cookiejar.add_cookie_header(pr) - return pr.headers.get('Cookie') + return pr.get_header('Cookie') def process_video_result(self, info_dict, download=True): assert info_dict.get('_type', 'video') == 'video' @@ -985,6 +1008,15 @@ class YoutubeDL(object): info_dict['timestamp']) info_dict['upload_date'] = upload_date.strftime('%Y%m%d') + if self.params.get('listsubtitles', False): + if 'automatic_captions' in info_dict: + self.list_subtitles(info_dict['id'], info_dict.get('automatic_captions'), 'automatic captions') + self.list_subtitles(info_dict['id'], info_dict.get('subtitles'), 'subtitles') + return + info_dict['requested_subtitles'] = self.process_subtitles( + info_dict['id'], info_dict.get('subtitles'), + info_dict.get('automatic_captions')) + # This extractors handle format selection themselves if info_dict['extractor'] in ['Youku']: if download: @@ -1113,6 +1145,55 @@ class YoutubeDL(object): info_dict.update(formats_to_download[-1]) return info_dict + def process_subtitles(self, video_id, normal_subtitles, automatic_captions): + """Select the requested subtitles and their format""" + available_subs = {} + if normal_subtitles and self.params.get('writesubtitles'): + available_subs.update(normal_subtitles) + if automatic_captions and self.params.get('writeautomaticsub'): + for lang, cap_info in automatic_captions.items(): + if lang not in available_subs: + available_subs[lang] = cap_info + + if (not self.params.get('writesubtitles') and not + self.params.get('writeautomaticsub') or not + available_subs): + return None + + if self.params.get('allsubtitles', False): + requested_langs = available_subs.keys() + else: + if self.params.get('subtitleslangs', False): + requested_langs = self.params.get('subtitleslangs') + elif 'en' in available_subs: + requested_langs = ['en'] + else: + requested_langs = [list(available_subs.keys())[0]] + + formats_query = self.params.get('subtitlesformat', 'best') + formats_preference = formats_query.split('/') if formats_query else [] + subs = {} + for lang in requested_langs: + formats = available_subs.get(lang) + if formats is None: + self.report_warning('%s subtitles not available for %s' % (lang, video_id)) + continue + for ext in formats_preference: + if ext == 'best': + f = formats[-1] + break + matches = list(filter(lambda f: f['ext'] == ext, formats)) + if matches: + f = matches[-1] + break + else: + f = formats[-1] + self.report_warning( + 'No subtitle format found matching "%s" for language %s, ' + 'using %s' % (formats_query, lang, f['ext'])) + subs[lang] = f + return subs + def process_info(self, info_dict): """Process a single resolved IE result.""" @@ -1133,7 +1214,7 @@ class YoutubeDL(object): if 'format' not in info_dict: info_dict['format'] = info_dict['ext'] - reason = self._match_entry(info_dict) + reason = self._match_entry(info_dict, incomplete=False) if reason is not None: self.to_screen('[download] ' + reason) return @@ -1215,15 +1296,23 @@ class YoutubeDL(object): subtitles_are_requested = any([self.params.get('writesubtitles', False), self.params.get('writeautomaticsub')]) - if subtitles_are_requested and 'subtitles' in info_dict and info_dict['subtitles']: + if subtitles_are_requested and info_dict.get('requested_subtitles'): # subtitles download errors are already managed as troubles in relevant IE # that way it will silently go on when used with unsupporting IE - subtitles = info_dict['subtitles'] - sub_format = self.params.get('subtitlesformat', 'srt') - for sub_lang in subtitles.keys(): - sub = subtitles[sub_lang] - if sub is None: - continue + subtitles = info_dict['requested_subtitles'] + ie = self.get_info_extractor(info_dict['extractor_key']) + for sub_lang, sub_info in subtitles.items(): + sub_format = sub_info['ext'] + if sub_info.get('data') is not None: + sub_data = sub_info['data'] + else: + try: + sub_data = ie._download_webpage( + sub_info['url'], info_dict['id'], note=False) + except ExtractorError as err: + self.report_warning('Unable to download subtitle for "%s": %s' % + (sub_lang, compat_str(err.cause))) + continue try: sub_filename = subtitles_filename(filename, sub_lang, sub_format) if self.params.get('nooverwrites', False) and os.path.exists(encodeFilename(sub_filename)): @@ -1231,7 +1320,7 @@ class YoutubeDL(object): else: self.to_screen('[info] Writing video subtitles to: ' + sub_filename) with io.open(encodeFilename(sub_filename), 'w', encoding='utf-8') as subfile: - subfile.write(sub) + subfile.write(sub_data) except (OSError, IOError): self.report_error('Cannot write subtitles file ' + sub_filename) return @@ -1264,7 +1353,7 @@ class YoutubeDL(object): downloaded = [] success = True merger = FFmpegMergerPP(self, not self.params.get('keepvideo')) - if not merger._executable: + if not merger.available: postprocessors = [] self.report_warning('You have requested multiple ' 'formats but ffmpeg or avconv are not installed.' @@ -1343,8 +1432,8 @@ class YoutubeDL(object): """Download a given list of URLs.""" outtmpl = self.params.get('outtmpl', DEFAULT_OUTTMPL) if (len(url_list) > 1 and - '%' not in outtmpl - and self.params.get('max_downloads') != 1): + '%' not in outtmpl and + self.params.get('max_downloads') != 1): raise SameFileError(outtmpl) for url in url_list: @@ -1511,30 +1600,18 @@ class YoutubeDL(object): return res def list_formats(self, info_dict): - def line(format, idlen=20): - return (('%-' + compat_str(idlen + 1) + 's%-10s%-12s%s') % ( - format['format_id'], - format['ext'], - self.format_resolution(format), - self._format_note(format), - )) - formats = info_dict.get('formats', [info_dict]) - idlen = max(len('format code'), - max(len(f['format_id']) for f in formats)) - formats_s = [ - line(f, idlen) for f in formats + table = [ + [f['format_id'], f['ext'], self.format_resolution(f), self._format_note(f)] + for f in formats if f.get('preference') is None or f['preference'] >= -1000] if len(formats) > 1: - formats_s[0] += (' ' if self._format_note(formats[0]) else '') + '(worst)' - formats_s[-1] += (' ' if self._format_note(formats[-1]) else '') + '(best)' + table[-1][-1] += (' ' if table[-1][-1] else '') + '(best)' - header_line = line({ - 'format_id': 'format code', 'ext': 'extension', - 'resolution': 'resolution', 'format_note': 'note'}, idlen=idlen) + header_line = ['format code', 'extension', 'resolution', 'note'] self.to_screen( - '[info] Available formats for %s:\n%s\n%s' % - (info_dict['id'], header_line, '\n'.join(formats_s))) + '[info] Available formats for %s:\n%s' % + (info_dict['id'], render_table(header_line, table))) def list_thumbnails(self, info_dict): thumbnails = info_dict.get('thumbnails') @@ -1553,6 +1630,17 @@ class YoutubeDL(object): ['ID', 'width', 'height', 'URL'], [[t['id'], t.get('width', 'unknown'), t.get('height', 'unknown'), t['url']] for t in thumbnails])) + def list_subtitles(self, video_id, subtitles, name='subtitles'): + if not subtitles: + self.to_screen('%s has no %s' % (video_id, name)) + return + self.to_screen( + 'Available %s for %s:' % (name, video_id)) + self.to_screen(render_table( + ['Language', 'formats'], + [[lang, ', '.join(f['ext'] for f in reversed(formats))] + for lang, formats in subtitles.items()])) + def urlopen(self, req): """ Start an HTTP download """ @@ -1614,7 +1702,7 @@ class YoutubeDL(object): self._write_string('[debug] Python version %s - %s\n' % ( platform.python_version(), platform_name())) - exe_versions = FFmpegPostProcessor.get_versions() + exe_versions = FFmpegPostProcessor.get_versions(self) exe_versions['rtmpdump'] = rtmpdump_version() exe_str = ', '.join( '%s %s' % (exe, v) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index e90679f..49f3826 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -23,9 +23,10 @@ from .compat import ( ) from .utils import ( DateRange, - DEFAULT_OUTTMPL, decodeOption, + DEFAULT_OUTTMPL, DownloadError, + match_filter_func, MaxDownloadsReached, preferredencoding, read_batch_urls, @@ -169,6 +170,9 @@ def _real_main(argv=None): if opts.recodevideo is not None: if opts.recodevideo not in ['mp4', 'flv', 'webm', 'ogg', 'mkv']: parser.error('invalid video recode format specified') + if opts.convertsubtitles is not None: + if opts.convertsubtitles not in ['srt', 'vtt', 'ass']: + parser.error('invalid subtitle format specified') if opts.date is not None: date = DateRange.day(opts.date) @@ -188,14 +192,14 @@ def _real_main(argv=None): # In Python 2, sys.argv is a bytestring (also note http://bugs.python.org/issue2128 for Windows systems) if opts.outtmpl is not None: opts.outtmpl = opts.outtmpl.decode(preferredencoding()) - outtmpl = ((opts.outtmpl is not None and opts.outtmpl) - or (opts.format == '-1' and opts.usetitle and '%(title)s-%(id)s-%(format)s.%(ext)s') - or (opts.format == '-1' and '%(id)s-%(format)s.%(ext)s') - or (opts.usetitle and opts.autonumber and '%(autonumber)s-%(title)s-%(id)s.%(ext)s') - or (opts.usetitle and '%(title)s-%(id)s.%(ext)s') - or (opts.useid and '%(id)s.%(ext)s') - or (opts.autonumber and '%(autonumber)s-%(id)s.%(ext)s') - or DEFAULT_OUTTMPL) + outtmpl = ((opts.outtmpl is not None and opts.outtmpl) or + (opts.format == '-1' and opts.usetitle and '%(title)s-%(id)s-%(format)s.%(ext)s') or + (opts.format == '-1' and '%(id)s-%(format)s.%(ext)s') or + (opts.usetitle and opts.autonumber and '%(autonumber)s-%(title)s-%(id)s.%(ext)s') or + (opts.usetitle and '%(title)s-%(id)s.%(ext)s') or + (opts.useid and '%(id)s.%(ext)s') or + (opts.autonumber and '%(autonumber)s-%(id)s.%(ext)s') or + DEFAULT_OUTTMPL) if not os.path.splitext(outtmpl)[1] and opts.extractaudio: parser.error('Cannot download a video and extract audio into the same' ' file! Use "{0}.%(ext)s" instead of "{0}" as the output' @@ -222,10 +226,14 @@ def _real_main(argv=None): 'key': 'FFmpegVideoConvertor', 'preferedformat': opts.recodevideo, }) + if opts.convertsubtitles: + postprocessors.append({ + 'key': 'FFmpegSubtitlesConvertor', + 'format': opts.convertsubtitles, + }) if opts.embedsubtitles: postprocessors.append({ 'key': 'FFmpegEmbedSubtitle', - 'subtitlesformat': opts.subtitlesformat, }) if opts.xattrs: postprocessors.append({'key': 'XAttrMetadata'}) @@ -247,6 +255,9 @@ def _real_main(argv=None): xattr # Confuse flake8 except ImportError: parser.error('setting filesize xattr requested but python-xattr is not available') + match_filter = ( + None if opts.match_filter is None + else match_filter_func(opts.match_filter)) ydl_opts = { 'usenetrc': opts.usenetrc, @@ -344,6 +355,10 @@ def _real_main(argv=None): 'list_thumbnails': opts.list_thumbnails, 'playlist_items': opts.playlist_items, 'xattr_set_filesize': opts.xattr_set_filesize, + 'match_filter': match_filter, + 'no_color': opts.no_color, + 'ffmpeg_location': opts.ffmpeg_location, + 'hls_prefer_native': opts.hls_prefer_native, } with YoutubeDL(ydl_opts) as ydl: diff --git a/youtube_dl/aes.py b/youtube_dl/aes.py index 5efd0f8..07224d5 100644 --- a/youtube_dl/aes.py +++ b/youtube_dl/aes.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -__all__ = ['aes_encrypt', 'key_expansion', 'aes_ctr_decrypt', 'aes_cbc_decrypt', 'aes_decrypt_text'] - import base64 from math import ceil @@ -329,3 +327,5 @@ def inc(data): data[i] = data[i] + 1 break return data + +__all__ = ['aes_encrypt', 'key_expansion', 'aes_ctr_decrypt', 'aes_cbc_decrypt', 'aes_decrypt_text'] diff --git a/youtube_dl/downloader/__init__.py b/youtube_dl/downloader/__init__.py index eff1122..9fb66e2 100644 --- a/youtube_dl/downloader/__init__.py +++ b/youtube_dl/downloader/__init__.py @@ -34,6 +34,9 @@ def get_suitable_downloader(info_dict, params={}): if ed.supports(info_dict): return ed + if protocol == 'm3u8' and params.get('hls_prefer_native'): + return NativeHlsFD + return PROTOCOL_MAP.get(protocol, HttpFD) diff --git a/youtube_dl/downloader/common.py b/youtube_dl/downloader/common.py index 7bb3a94..3ae9002 100644 --- a/youtube_dl/downloader/common.py +++ b/youtube_dl/downloader/common.py @@ -1,4 +1,4 @@ -from __future__ import unicode_literals +from __future__ import division, unicode_literals import os import re @@ -54,6 +54,7 @@ class FileDownloader(object): self.ydl = ydl self._progress_hooks = [] self.params = params + self.add_progress_hook(self.report_progress) @staticmethod def format_seconds(seconds): @@ -226,42 +227,64 @@ class FileDownloader(object): self.to_screen(clear_line + fullmsg, skip_eol=not is_last_line) self.to_console_title('youtube-dl ' + msg) - def report_progress(self, percent, data_len_str, speed, eta): - """Report download progress.""" - if self.params.get('noprogress', False): + def report_progress(self, s): + if s['status'] == 'finished': + if self.params.get('noprogress', False): + self.to_screen('[download] Download completed') + else: + s['_total_bytes_str'] = format_bytes(s['total_bytes']) + if s.get('elapsed') is not None: + s['_elapsed_str'] = self.format_seconds(s['elapsed']) + msg_template = '100%% of %(_total_bytes_str)s in %(_elapsed_str)s' + else: + msg_template = '100%% of %(_total_bytes_str)s' + self._report_progress_status( + msg_template % s, is_last_line=True) + + if self.params.get('noprogress'): return - if eta is not None: - eta_str = self.format_eta(eta) - else: - eta_str = 'Unknown ETA' - if percent is not None: - percent_str = self.format_percent(percent) + + if s['status'] != 'downloading': + return + + if s.get('eta') is not None: + s['_eta_str'] = self.format_eta(s['eta']) else: - percent_str = 'Unknown %' - speed_str = self.format_speed(speed) + s['_eta_str'] = 'Unknown ETA' - msg = ('%s of %s at %s ETA %s' % - (percent_str, data_len_str, speed_str, eta_str)) - self._report_progress_status(msg) + if s.get('total_bytes') and s.get('downloaded_bytes') is not None: + s['_percent_str'] = self.format_percent(100 * s['downloaded_bytes'] / s['total_bytes']) + elif s.get('total_bytes_estimate') and s.get('downloaded_bytes') is not None: + s['_percent_str'] = self.format_percent(100 * s['downloaded_bytes'] / s['total_bytes_estimate']) + else: + if s.get('downloaded_bytes') == 0: + s['_percent_str'] = self.format_percent(0) + else: + s['_percent_str'] = 'Unknown %' - def report_progress_live_stream(self, downloaded_data_len, speed, elapsed): - if self.params.get('noprogress', False): - return - downloaded_str = format_bytes(downloaded_data_len) - speed_str = self.format_speed(speed) - elapsed_str = FileDownloader.format_seconds(elapsed) - msg = '%s at %s (%s)' % (downloaded_str, speed_str, elapsed_str) - self._report_progress_status(msg) - - def report_finish(self, data_len_str, tot_time): - """Report download finished.""" - if self.params.get('noprogress', False): - self.to_screen('[download] Download completed') + if s.get('speed') is not None: + s['_speed_str'] = self.format_speed(s['speed']) + else: + s['_speed_str'] = 'Unknown speed' + + if s.get('total_bytes') is not None: + s['_total_bytes_str'] = format_bytes(s['total_bytes']) + msg_template = '%(_percent_str)s of %(_total_bytes_str)s at %(_speed_str)s ETA %(_eta_str)s' + elif s.get('total_bytes_estimate') is not None: + s['_total_bytes_estimate_str'] = format_bytes(s['total_bytes_estimate']) + msg_template = '%(_percent_str)s of ~%(_total_bytes_estimate_str)s at %(_speed_str)s ETA %(_eta_str)s' else: - self._report_progress_status( - ('100%% of %s in %s' % - (data_len_str, self.format_seconds(tot_time))), - is_last_line=True) + if s.get('downloaded_bytes') is not None: + s['_downloaded_bytes_str'] = format_bytes(s['downloaded_bytes']) + if s.get('elapsed'): + s['_elapsed_str'] = self.format_seconds(s['elapsed']) + msg_template = '%(_downloaded_bytes_str)s at %(_speed_str)s (%(_elapsed_str)s)' + else: + msg_template = '%(_downloaded_bytes_str)s at %(_speed_str)s' + else: + msg_template = '%(_percent_str)s % at %(_speed_str)s ETA %(_eta_str)s' + + self._report_progress_status(msg_template % s) def report_resuming_byte(self, resume_len): """Report attempt to resume at given byte.""" @@ -288,14 +311,14 @@ class FileDownloader(object): """ nooverwrites_and_exists = ( - self.params.get('nooverwrites', False) - and os.path.exists(encodeFilename(filename)) + self.params.get('nooverwrites', False) and + os.path.exists(encodeFilename(filename)) ) continuedl_and_exists = ( - self.params.get('continuedl', False) - and os.path.isfile(encodeFilename(filename)) - and not self.params.get('nopart', False) + self.params.get('continuedl', False) and + os.path.isfile(encodeFilename(filename)) and + not self.params.get('nopart', False) ) # Check file already present diff --git a/youtube_dl/downloader/external.py b/youtube_dl/downloader/external.py index ff031d2..51c41c7 100644 --- a/youtube_dl/downloader/external.py +++ b/youtube_dl/downloader/external.py @@ -75,7 +75,7 @@ class ExternalFD(FileDownloader): class CurlFD(ExternalFD): def _make_cmd(self, tmpfilename, info_dict): - cmd = [self.exe, '-o', tmpfilename] + cmd = [self.exe, '--location', '-o', tmpfilename] for key, val in info_dict['http_headers'].items(): cmd += ['--header', '%s: %s' % (key, val)] cmd += self._source_address('--interface') diff --git a/youtube_dl/downloader/f4m.py b/youtube_dl/downloader/f4m.py index 0e7a1c2..3dc796f 100644 --- a/youtube_dl/downloader/f4m.py +++ b/youtube_dl/downloader/f4m.py @@ -1,4 +1,4 @@ -from __future__ import unicode_literals +from __future__ import division, unicode_literals import base64 import io @@ -11,11 +11,11 @@ from .common import FileDownloader from .http import HttpFD from ..compat import ( compat_urlparse, + compat_urllib_error, ) from ..utils import ( struct_pack, struct_unpack, - format_bytes, encodeFilename, sanitize_open, xpath_text, @@ -122,7 +122,8 @@ class FlvReader(io.BytesIO): self.read_unsigned_int() # BootstrapinfoVersion # Profile,Live,Update,Reserved - self.read(1) + flags = self.read_unsigned_char() + live = flags & 0x20 != 0 # time scale self.read_unsigned_int() # CurrentMediaTime @@ -161,6 +162,7 @@ class FlvReader(io.BytesIO): return { 'segments': segments, 'fragments': fragments, + 'live': live, } def read_bootstrap_info(self): @@ -183,6 +185,10 @@ def build_fragments_list(boot_info): for segment, fragments_count in segment_run_table['segment_run']: for _ in range(fragments_count): res.append((segment, next(fragments_counter))) + + if boot_info['live']: + res = res[-2:] + return res @@ -247,22 +253,43 @@ class F4mFD(FileDownloader): self.report_error('Unsupported DRM') return media + def _get_bootstrap_from_url(self, bootstrap_url): + bootstrap = self.ydl.urlopen(bootstrap_url).read() + return read_bootstrap_info(bootstrap) + + def _update_live_fragments(self, bootstrap_url, latest_fragment): + fragments_list = [] + retries = 30 + while (not fragments_list) and (retries > 0): + boot_info = self._get_bootstrap_from_url(bootstrap_url) + fragments_list = build_fragments_list(boot_info) + fragments_list = [f for f in fragments_list if f[1] > latest_fragment] + if not fragments_list: + # Retry after a while + time.sleep(5.0) + retries -= 1 + + if not fragments_list: + self.report_error('Failed to update fragments') + + return fragments_list + + def _parse_bootstrap_node(self, node, base_url): + if node.text is None: + bootstrap_url = compat_urlparse.urljoin( + base_url, node.attrib['url']) + boot_info = self._get_bootstrap_from_url(bootstrap_url) + else: + bootstrap_url = None + bootstrap = base64.b64decode(node.text) + boot_info = read_bootstrap_info(bootstrap) + return (boot_info, bootstrap_url) + def real_download(self, filename, info_dict): man_url = info_dict['url'] requested_bitrate = info_dict.get('tbr') self.to_screen('[download] Downloading f4m manifest') manifest = self.ydl.urlopen(man_url).read() - self.report_destination(filename) - http_dl = HttpQuietDownloader( - self.ydl, - { - 'continuedl': True, - 'quiet': True, - 'noprogress': True, - 'ratelimit': self.params.get('ratelimit', None), - 'test': self.params.get('test', False), - } - ) doc = etree.fromstring(manifest) formats = [(int(f.attrib.get('bitrate', -1)), f) @@ -277,18 +304,13 @@ class F4mFD(FileDownloader): base_url = compat_urlparse.urljoin(man_url, media.attrib['url']) bootstrap_node = doc.find(_add_ns('bootstrapInfo')) - if bootstrap_node.text is None: - bootstrap_url = compat_urlparse.urljoin( - base_url, bootstrap_node.attrib['url']) - bootstrap = self.ydl.urlopen(bootstrap_url).read() - else: - bootstrap = base64.b64decode(bootstrap_node.text) + boot_info, bootstrap_url = self._parse_bootstrap_node(bootstrap_node, base_url) + live = boot_info['live'] metadata_node = media.find(_add_ns('metadata')) if metadata_node is not None: metadata = base64.b64decode(metadata_node.text) else: metadata = None - boot_info = read_bootstrap_info(bootstrap) fragments_list = build_fragments_list(boot_info) if self.params.get('test', False): @@ -298,64 +320,112 @@ class F4mFD(FileDownloader): # For some akamai manifests we'll need to add a query to the fragment url akamai_pv = xpath_text(doc, _add_ns('pv-2.0')) + self.report_destination(filename) + http_dl = HttpQuietDownloader( + self.ydl, + { + 'continuedl': True, + 'quiet': True, + 'noprogress': True, + 'ratelimit': self.params.get('ratelimit', None), + 'test': self.params.get('test', False), + } + ) tmpfilename = self.temp_name(filename) (dest_stream, tmpfilename) = sanitize_open(tmpfilename, 'wb') + write_flv_header(dest_stream) - write_metadata_tag(dest_stream, metadata) + if not live: + write_metadata_tag(dest_stream, metadata) # This dict stores the download progress, it's updated by the progress # hook state = { + 'status': 'downloading', 'downloaded_bytes': 0, - 'frag_counter': 0, + 'frag_index': 0, + 'frag_count': total_frags, + 'filename': filename, + 'tmpfilename': tmpfilename, } start = time.time() - def frag_progress_hook(status): - frag_total_bytes = status.get('total_bytes', 0) - estimated_size = (state['downloaded_bytes'] + - (total_frags - state['frag_counter']) * frag_total_bytes) - if status['status'] == 'finished': + def frag_progress_hook(s): + if s['status'] not in ('downloading', 'finished'): + return + + frag_total_bytes = s.get('total_bytes', 0) + if s['status'] == 'finished': state['downloaded_bytes'] += frag_total_bytes - state['frag_counter'] += 1 - progress = self.calc_percent(state['frag_counter'], total_frags) - byte_counter = state['downloaded_bytes'] + state['frag_index'] += 1 + + estimated_size = ( + (state['downloaded_bytes'] + frag_total_bytes) / + (state['frag_index'] + 1) * total_frags) + time_now = time.time() + state['total_bytes_estimate'] = estimated_size + state['elapsed'] = time_now - start + + if s['status'] == 'finished': + progress = self.calc_percent(state['frag_index'], total_frags) else: - frag_downloaded_bytes = status['downloaded_bytes'] - byte_counter = state['downloaded_bytes'] + frag_downloaded_bytes + frag_downloaded_bytes = s['downloaded_bytes'] frag_progress = self.calc_percent(frag_downloaded_bytes, frag_total_bytes) - progress = self.calc_percent(state['frag_counter'], total_frags) + progress = self.calc_percent(state['frag_index'], total_frags) progress += frag_progress / float(total_frags) - eta = self.calc_eta(start, time.time(), estimated_size, byte_counter) - self.report_progress(progress, format_bytes(estimated_size), - status.get('speed'), eta) + state['eta'] = self.calc_eta( + start, time_now, estimated_size, state['downloaded_bytes'] + frag_downloaded_bytes) + state['speed'] = s.get('speed') + self._hook_progress(state) + http_dl.add_progress_hook(frag_progress_hook) frags_filenames = [] - for (seg_i, frag_i) in fragments_list: + while fragments_list: + seg_i, frag_i = fragments_list.pop(0) name = 'Seg%d-Frag%d' % (seg_i, frag_i) url = base_url + name if akamai_pv: url += '?' + akamai_pv.strip(';') frag_filename = '%s-%s' % (tmpfilename, name) - success = http_dl.download(frag_filename, {'url': url}) - if not success: - return False - with open(frag_filename, 'rb') as down: - down_data = down.read() - reader = FlvReader(down_data) - while True: - _, box_type, box_data = reader.read_box_info() - if box_type == b'mdat': - dest_stream.write(box_data) - break - frags_filenames.append(frag_filename) + try: + success = http_dl.download(frag_filename, {'url': url}) + if not success: + return False + with open(frag_filename, 'rb') as down: + down_data = down.read() + reader = FlvReader(down_data) + while True: + _, box_type, box_data = reader.read_box_info() + if box_type == b'mdat': + dest_stream.write(box_data) + break + if live: + os.remove(frag_filename) + else: + frags_filenames.append(frag_filename) + except (compat_urllib_error.HTTPError, ) as err: + if live and (err.code == 404 or err.code == 410): + # We didn't keep up with the live window. Continue + # with the next available fragment. + msg = 'Fragment %d unavailable' % frag_i + self.report_warning(msg) + fragments_list = [] + else: + raise + + if not fragments_list and live and bootstrap_url: + fragments_list = self._update_live_fragments(bootstrap_url, frag_i) + total_frags += len(fragments_list) + if fragments_list and (fragments_list[0][1] > frag_i + 1): + msg = 'Missed %d fragments' % (fragments_list[0][1] - (frag_i + 1)) + self.report_warning(msg) dest_stream.close() - self.report_finish(format_bytes(state['downloaded_bytes']), time.time() - start) + elapsed = time.time() - start self.try_rename(tmpfilename, filename) for frag_file in frags_filenames: os.remove(frag_file) @@ -366,6 +436,7 @@ class F4mFD(FileDownloader): 'total_bytes': fsize, 'filename': filename, 'status': 'finished', + 'elapsed': elapsed, }) return True diff --git a/youtube_dl/downloader/hls.py b/youtube_dl/downloader/hls.py index e527ee4..8be4f42 100644 --- a/youtube_dl/downloader/hls.py +++ b/youtube_dl/downloader/hls.py @@ -23,15 +23,14 @@ class HlsFD(FileDownloader): tmpfilename = self.temp_name(filename) ffpp = FFmpegPostProcessor(downloader=self) - program = ffpp._executable - if program is None: + if not ffpp.available: self.report_error('m3u8 download detected but ffmpeg or avconv could not be found. Please install one.') return False ffpp.check_version() args = [ encodeArgument(opt) - for opt in (program, '-y', '-i', url, '-f', 'mp4', '-c', 'copy', '-bsf:a', 'aac_adtstoasc')] + for opt in (ffpp.executable, '-y', '-i', url, '-f', 'mp4', '-c', 'copy', '-bsf:a', 'aac_adtstoasc')] args.append(encodeFilename(tmpfilename, True)) retval = subprocess.call(args) @@ -48,7 +47,7 @@ class HlsFD(FileDownloader): return True else: self.to_stderr('\n') - self.report_error('%s exited with code %d' % (program, retval)) + self.report_error('%s exited with code %d' % (ffpp.basename, retval)) return False diff --git a/youtube_dl/downloader/http.py b/youtube_dl/downloader/http.py index 49170cf..2e3dac8 100644 --- a/youtube_dl/downloader/http.py +++ b/youtube_dl/downloader/http.py @@ -1,11 +1,10 @@ from __future__ import unicode_literals +import errno import os +import socket import time -from socket import error as SocketError -import errno - from .common import FileDownloader from ..compat import ( compat_urllib_request, @@ -15,7 +14,6 @@ from ..utils import ( ContentTooShortError, encodeFilename, sanitize_open, - format_bytes, ) @@ -102,7 +100,7 @@ class HttpFD(FileDownloader): resume_len = 0 open_mode = 'wb' break - except SocketError as e: + except socket.error as e: if e.errno != errno.ECONNRESET: # Connection reset is no problem, just retry raise @@ -137,7 +135,6 @@ class HttpFD(FileDownloader): self.to_screen('\r[download] File is larger than max-filesize (%s bytes > %s bytes). Aborting.' % (data_len, max_data_len)) return False - data_len_str = format_bytes(data_len) byte_counter = 0 + resume_len block_size = self.params.get('buffersize', 1024) start = time.time() @@ -196,20 +193,19 @@ class HttpFD(FileDownloader): # Progress message speed = self.calc_speed(start, now, byte_counter - resume_len) if data_len is None: - eta = percent = None + eta = None else: - percent = self.calc_percent(byte_counter, data_len) eta = self.calc_eta(start, time.time(), data_len - resume_len, byte_counter - resume_len) - self.report_progress(percent, data_len_str, speed, eta) self._hook_progress({ + 'status': 'downloading', 'downloaded_bytes': byte_counter, 'total_bytes': data_len, 'tmpfilename': tmpfilename, 'filename': filename, - 'status': 'downloading', 'eta': eta, 'speed': speed, + 'elapsed': now - start, }) if is_test and byte_counter == data_len: @@ -221,7 +217,13 @@ class HttpFD(FileDownloader): return False if tmpfilename != '-': stream.close() - self.report_finish(data_len_str, (time.time() - start)) + + self._hook_progress({ + 'downloaded_bytes': byte_counter, + 'total_bytes': data_len, + 'tmpfilename': tmpfilename, + 'status': 'error', + }) if data_len is not None and byte_counter != data_len: raise ContentTooShortError(byte_counter, int(data_len)) self.try_rename(tmpfilename, filename) @@ -235,6 +237,7 @@ class HttpFD(FileDownloader): 'total_bytes': byte_counter, 'filename': filename, 'status': 'finished', + 'elapsed': time.time() - start, }) return True diff --git a/youtube_dl/downloader/rtmp.py b/youtube_dl/downloader/rtmp.py index f7eeb6f..89e98ae 100644 --- a/youtube_dl/downloader/rtmp.py +++ b/youtube_dl/downloader/rtmp.py @@ -11,7 +11,6 @@ from ..compat import compat_str from ..utils import ( check_executable, encodeFilename, - format_bytes, get_exe_version, ) @@ -51,23 +50,23 @@ class RtmpFD(FileDownloader): if not resume_percent: resume_percent = percent resume_downloaded_data_len = downloaded_data_len - eta = self.calc_eta(start, time.time(), 100 - resume_percent, percent - resume_percent) - speed = self.calc_speed(start, time.time(), downloaded_data_len - resume_downloaded_data_len) + time_now = time.time() + eta = self.calc_eta(start, time_now, 100 - resume_percent, percent - resume_percent) + speed = self.calc_speed(start, time_now, downloaded_data_len - resume_downloaded_data_len) data_len = None if percent > 0: data_len = int(downloaded_data_len * 100 / percent) - data_len_str = '~' + format_bytes(data_len) - self.report_progress(percent, data_len_str, speed, eta) - cursor_in_new_line = False self._hook_progress({ + 'status': 'downloading', 'downloaded_bytes': downloaded_data_len, - 'total_bytes': data_len, + 'total_bytes_estimate': data_len, 'tmpfilename': tmpfilename, 'filename': filename, - 'status': 'downloading', 'eta': eta, + 'elapsed': time_now - start, 'speed': speed, }) + cursor_in_new_line = False else: # no percent for live streams mobj = re.search(r'([0-9]+\.[0-9]{3}) kB / [0-9]+\.[0-9]{2} sec', line) @@ -75,15 +74,15 @@ class RtmpFD(FileDownloader): downloaded_data_len = int(float(mobj.group(1)) * 1024) time_now = time.time() speed = self.calc_speed(start, time_now, downloaded_data_len) - self.report_progress_live_stream(downloaded_data_len, speed, time_now - start) - cursor_in_new_line = False self._hook_progress({ 'downloaded_bytes': downloaded_data_len, 'tmpfilename': tmpfilename, 'filename': filename, 'status': 'downloading', + 'elapsed': time_now - start, 'speed': speed, }) + cursor_in_new_line = False elif self.params.get('verbose', False): if not cursor_in_new_line: self.to_screen('') @@ -120,7 +119,9 @@ class RtmpFD(FileDownloader): # Download using rtmpdump. rtmpdump returns exit code 2 when # the connection was interrumpted and resuming appears to be # possible. This is part of rtmpdump's normal usage, AFAIK. - basic_args = ['rtmpdump', '--verbose', '-r', url, '-o', tmpfilename] + basic_args = [ + 'rtmpdump', '--verbose', '-r', url, + '-o', encodeFilename(tmpfilename, True)] if player_url is not None: basic_args += ['--swfVfy', player_url] if page_url is not None: diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 047f700..ffcc7d9 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -6,7 +6,9 @@ from .academicearth import AcademicEarthCourseIE from .addanime import AddAnimeIE from .adobetv import AdobeTVIE from .adultswim import AdultSwimIE +from .aftenposten import AftenpostenIE from .aftonbladet import AftonbladetIE +from .airmozilla import AirMozillaIE from .aljazeera import AlJazeeraIE from .alphaporno import AlphaPornoIE from .anitube import AnitubeIE @@ -48,14 +50,24 @@ from .brightcove import BrightcoveIE from .buzzfeed import BuzzFeedIE from .byutv import BYUtvIE from .c56 import C56IE +from .camdemy import ( + CamdemyIE, + CamdemyFolderIE +) from .canal13cl import Canal13clIE from .canalplus import CanalplusIE from .canalc2 import Canalc2IE from .cbs import CBSIE from .cbsnews import CBSNewsIE +from .cbssports import CBSSportsIE +from .ccc import CCCIE from .ceskatelevize import CeskaTelevizeIE from .channel9 import Channel9IE from .chilloutzone import ChilloutzoneIE +from .chirbit import ( + ChirbitIE, + ChirbitProfileIE, +) from .cinchcast import CinchcastIE from .clipfish import ClipfishIE from .cliphunter import CliphunterIE @@ -73,7 +85,7 @@ from .collegehumor import CollegeHumorIE from .collegerama import CollegeRamaIE from .comedycentral import ComedyCentralIE, ComedyCentralShowsIE from .comcarcoff import ComCarCoffIE -from .commonmistakes import CommonMistakesIE +from .commonmistakes import CommonMistakesIE, UnicodeBOMIE from .condenast import CondeNastIE from .cracked import CrackedIE from .criterion import CriterionIE @@ -115,6 +127,7 @@ from .ellentv import ( EllenTVClipsIE, ) from .elpais import ElPaisIE +from .embedly import EmbedlyIE from .empflix import EMPFlixIE from .engadget import EngadgetIE from .eporner import EpornerIE @@ -183,6 +196,7 @@ from .hellporno import HellPornoIE from .helsinki import HelsinkiIE from .hentaistigma import HentaiStigmaIE from .historicfilms import HistoricFilmsIE +from .history import HistoryIE from .hitbox import HitboxIE, HitboxLiveIE from .hornbunny import HornBunnyIE from .hostingbulk import HostingBulkIE @@ -197,6 +211,7 @@ from .imdb import ( ImdbIE, ImdbListIE ) +from .imgur import ImgurIE from .ina import InaIE from .infoq import InfoQIE from .instagram import InstagramIE, InstagramUserIE @@ -212,6 +227,7 @@ from .jeuxvideo import JeuxVideoIE from .jove import JoveIE from .jukebox import JukeboxIE from .jpopsukitv import JpopsukiIE +from .kaltura import KalturaIE from .kankan import KankanIE from .karaoketv import KaraoketvIE from .keezmovies import KeezMoviesIE @@ -223,6 +239,11 @@ from .krasview import KrasViewIE from .ku6 import Ku6IE from .la7 import LA7IE from .laola1tv import Laola1TvIE +from .letv import ( + LetvIE, + LetvTvIE, + LetvPlaylistIE +) from .lifenews import LifeNewsIE from .liveleak import LiveLeakIE from .livestream import ( @@ -275,6 +296,7 @@ from .myspace import MySpaceIE, MySpaceAlbumIE from .myspass import MySpassIE from .myvideo import MyVideoIE from .myvidster import MyVidsterIE +from .nationalgeographic import NationalGeographicIE from .naver import NaverIE from .nba import NBAIE from .nbc import ( @@ -312,6 +334,8 @@ from .nowvideo import NowVideoIE from .npo import ( NPOIE, NPOLiveIE, + NPORadioIE, + NPORadioFragmentIE, TegenlichtVproIE, ) from .nrk import ( @@ -322,6 +346,7 @@ from .ntvde import NTVDeIE from .ntvru import NTVRuIE from .nytimes import NYTimesIE from .nuvid import NuvidIE +from .odnoklassniki import OdnoklassnikiIE from .oktoberfesttv import OktoberfestTVIE from .ooyala import OoyalaIE from .openfilm import OpenFilmIE @@ -341,13 +366,18 @@ from .playfm import PlayFMIE from .playvid import PlayvidIE from .podomatic import PodomaticIE from .pornhd import PornHdIE -from .pornhub import PornHubIE +from .pornhub import ( + PornHubIE, + PornHubPlaylistIE, +) from .pornotube import PornotubeIE from .pornoxo import PornoXOIE from .promptfile import PromptFileIE from .prosiebensat1 import ProSiebenSat1IE +from .puls4 import Puls4IE from .pyvideo import PyvideoIE from .quickvid import QuickVidIE +from .r7 import R7IE from .radiode import RadioDeIE from .radiobremen import RadioBremenIE from .radiofrance import RadioFranceIE @@ -362,7 +392,7 @@ from .rottentomatoes import RottenTomatoesIE from .roxwel import RoxwelIE from .rtbf import RTBFIE from .rte import RteIE -from .rtlnl import RtlXlIE +from .rtlnl import RtlNlIE from .rtlnow import RTLnowIE from .rtl2 import RTL2IE from .rtp import RTPIE @@ -377,6 +407,7 @@ from .rutube import ( RutubePersonIE, ) from .rutv import RUTVIE +from .sandia import SandiaIE from .sapo import SapoIE from .savefrom import SaveFromIE from .sbs import SBSIE @@ -407,7 +438,10 @@ from .soundcloud import ( SoundcloudUserIE, SoundcloudPlaylistIE ) -from .soundgasm import SoundgasmIE +from .soundgasm import ( + SoundgasmIE, + SoundgasmProfileIE +) from .southpark import ( SouthParkIE, SouthparkDeIE, @@ -427,6 +461,7 @@ from .streamcloud import StreamcloudIE from .streamcz import StreamCZIE from .streetvoice import StreetVoiceIE from .sunporno import SunPornoIE +from .svtplay import SVTPlayIE from .swrmediathek import SWRMediathekIE from .syfy import SyfyIE from .sztvhu import SztvHuIE @@ -472,6 +507,7 @@ from .tumblr import TumblrIE from .tunein import TuneInIE from .turbo import TurboIE from .tutv import TutvIE +from .tv4 import TV4IE from .tvigle import TvigleIE from .tvp import TvpIE, TvpSeriesIE from .tvplay import TVPlayIE @@ -569,6 +605,7 @@ from .yahoo import ( YahooIE, YahooSearchIE, ) +from .yam import YamIE from .yesjapan import YesJapanIE from .ynet import YnetIE from .youjizz import YouJizzIE @@ -592,6 +629,7 @@ from .youtube import ( YoutubeUserIE, YoutubeWatchLaterIE, ) +from .zapiks import ZapiksIE from .zdf import ZDFIE, ZDFChannelIE from .zingmp3 import ( ZingMp3SongIE, diff --git a/youtube_dl/extractor/adobetv.py b/youtube_dl/extractor/adobetv.py index 28e07f8..97d1285 100644 --- a/youtube_dl/extractor/adobetv.py +++ b/youtube_dl/extractor/adobetv.py @@ -28,7 +28,6 @@ class AdobeTVIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) player = self._parse_json( @@ -44,8 +43,10 @@ class AdobeTVIE(InfoExtractor): self._html_search_meta('datepublished', webpage, 'upload date')) duration = parse_duration( - self._html_search_meta('duration', webpage, 'duration') - or self._search_regex(r'Runtime:\s*(\d{2}:\d{2}:\d{2})', webpage, 'duration')) + self._html_search_meta('duration', webpage, 'duration') or + self._search_regex( + r'Runtime:\s*(\d{2}:\d{2}:\d{2})', + webpage, 'duration', fatal=False)) view_count = str_to_int(self._search_regex( r'

', diff --git a/youtube_dl/extractor/adultswim.py b/youtube_dl/extractor/adultswim.py index 502a9c2..34b8b01 100644 --- a/youtube_dl/extractor/adultswim.py +++ b/youtube_dl/extractor/adultswim.py @@ -38,6 +38,7 @@ class AdultSwimIE(InfoExtractor): }, ], 'info_dict': { + 'id': 'rQxZvXQ4ROaSOqq-or2Mow', 'title': 'Rick and Morty - Pilot', 'description': "Rick moves in with his daughter's family and establishes himself as a bad influence on his grandson, Morty. " } @@ -55,6 +56,7 @@ class AdultSwimIE(InfoExtractor): } ], 'info_dict': { + 'id': '-t8CamQlQ2aYZ49ItZCFog', 'title': 'American Dad - Putting Francine Out of Business', 'description': 'Stan hatches a plan to get Francine out of the real estate business.Watch more American Dad on [adult swim].' }, diff --git a/youtube_dl/extractor/aftenposten.py b/youtube_dl/extractor/aftenposten.py new file mode 100644 index 0000000..2b257ed --- /dev/null +++ b/youtube_dl/extractor/aftenposten.py @@ -0,0 +1,103 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + int_or_none, + parse_iso8601, + xpath_with_ns, + xpath_text, + find_xpath_attr, +) + + +class AftenpostenIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?aftenposten\.no/webtv/([^/]+/)*(?P[^/]+)-\d+\.html' + + _TEST = { + 'url': 'http://www.aftenposten.no/webtv/serier-og-programmer/sweatshopenglish/TRAILER-SWEATSHOP---I-cant-take-any-more-7800835.html?paging=§ion=webtv_serierogprogrammer_sweatshop_sweatshopenglish', + 'md5': 'fd828cd29774a729bf4d4425fe192972', + 'info_dict': { + 'id': '21039', + 'ext': 'mov', + 'title': 'TRAILER: "Sweatshop" - I can´t take any more', + 'description': 'md5:21891f2b0dd7ec2f78d84a50e54f8238', + 'timestamp': 1416927969, + 'upload_date': '20141125', + } + } + + def _real_extract(self, url): + display_id = self._match_id(url) + + webpage = self._download_webpage(url, display_id) + + video_id = self._html_search_regex( + r'data-xs-id="(\d+)"', webpage, 'video id') + + data = self._download_xml( + 'http://frontend.xstream.dk/ap/feed/video/?platform=web&id=%s' % video_id, video_id) + + NS_MAP = { + 'atom': 'http://www.w3.org/2005/Atom', + 'xt': 'http://xstream.dk/', + 'media': 'http://search.yahoo.com/mrss/', + } + + entry = data.find(xpath_with_ns('./atom:entry', NS_MAP)) + + title = xpath_text( + entry, xpath_with_ns('./atom:title', NS_MAP), 'title') + description = xpath_text( + entry, xpath_with_ns('./atom:summary', NS_MAP), 'description') + timestamp = parse_iso8601(xpath_text( + entry, xpath_with_ns('./atom:published', NS_MAP), 'upload date')) + + formats = [] + media_group = entry.find(xpath_with_ns('./media:group', NS_MAP)) + for media_content in media_group.findall(xpath_with_ns('./media:content', NS_MAP)): + media_url = media_content.get('url') + if not media_url: + continue + tbr = int_or_none(media_content.get('bitrate')) + mobj = re.search(r'^(?Prtmp://[^/]+/(?P[^/]+))/(?P.+)$', media_url) + if mobj: + formats.append({ + 'url': mobj.group('url'), + 'play_path': 'mp4:%s' % mobj.group('playpath'), + 'app': mobj.group('app'), + 'ext': 'flv', + 'tbr': tbr, + 'format_id': 'rtmp-%d' % tbr, + }) + else: + formats.append({ + 'url': media_url, + 'tbr': tbr, + }) + self._sort_formats(formats) + + link = find_xpath_attr( + entry, xpath_with_ns('./atom:link', NS_MAP), 'rel', 'original') + if link is not None: + formats.append({ + 'url': link.get('href'), + 'format_id': link.get('rel'), + }) + + thumbnails = [{ + 'url': splash.get('url'), + 'width': int_or_none(splash.get('width')), + 'height': int_or_none(splash.get('height')), + } for splash in media_group.findall(xpath_with_ns('./xt:splash', NS_MAP))] + + return { + 'id': video_id, + 'title': title, + 'description': description, + 'timestamp': timestamp, + 'formats': formats, + 'thumbnails': thumbnails, + } diff --git a/youtube_dl/extractor/airmozilla.py b/youtube_dl/extractor/airmozilla.py new file mode 100644 index 0000000..611ad1e --- /dev/null +++ b/youtube_dl/extractor/airmozilla.py @@ -0,0 +1,74 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + int_or_none, + parse_duration, + parse_iso8601, +) + + +class AirMozillaIE(InfoExtractor): + _VALID_URL = r'https?://air\.mozilla\.org/(?P[0-9a-z-]+)/?' + _TEST = { + 'url': 'https://air.mozilla.org/privacy-lab-a-meetup-for-privacy-minded-people-in-san-francisco/', + 'md5': '2e3e7486ba5d180e829d453875b9b8bf', + 'info_dict': { + 'id': '6x4q2w', + 'ext': 'mp4', + 'title': 'Privacy Lab - a meetup for privacy minded people in San Francisco', + 'thumbnail': 're:https://\w+\.cloudfront\.net/6x4q2w/poster\.jpg\?t=\d+', + 'description': 'Brings together privacy professionals and others interested in privacy at for-profits, non-profits, and NGOs in an effort to contribute to the state of the ecosystem...', + 'timestamp': 1422487800, + 'upload_date': '20150128', + 'location': 'SFO Commons', + 'duration': 3780, + 'view_count': int, + 'categories': ['Main'], + } + } + + def _real_extract(self, url): + display_id = self._match_id(url) + webpage = self._download_webpage(url, display_id) + video_id = self._html_search_regex(r'//vid.ly/(.*?)/embed', webpage, 'id') + + embed_script = self._download_webpage('https://vid.ly/{0}/embed'.format(video_id), video_id) + jwconfig = self._search_regex(r'\svar jwconfig = (\{.*?\});\s', embed_script, 'metadata') + metadata = self._parse_json(jwconfig, video_id) + + formats = [{ + 'url': source['file'], + 'ext': source['type'], + 'format_id': self._search_regex(r'&format=(.*)$', source['file'], 'video format'), + 'format': source['label'], + 'height': int(source['label'].rstrip('p')), + } for source in metadata['playlist'][0]['sources']] + self._sort_formats(formats) + + view_count = int_or_none(self._html_search_regex( + r'Views since archived: ([0-9]+)', + webpage, 'view count', fatal=False)) + timestamp = parse_iso8601(self._html_search_regex( + r'', webpage), + } diff --git a/youtube_dl/extractor/aparat.py b/youtube_dl/extractor/aparat.py index 1500633..6342978 100644 --- a/youtube_dl/extractor/aparat.py +++ b/youtube_dl/extractor/aparat.py @@ -20,6 +20,7 @@ class AparatIE(InfoExtractor): 'id': 'wP8On', 'ext': 'mp4', 'title': 'تیم گلکسی 11 - زومیت', + 'age_limit': 0, }, # 'skip': 'Extremely unreliable', } @@ -34,7 +35,8 @@ class AparatIE(InfoExtractor): video_id + '/vt/frame') webpage = self._download_webpage(embed_url, video_id) - video_urls = re.findall(r'fileList\[[0-9]+\]\s*=\s*"([^"]+)"', webpage) + video_urls = [video_url.replace('\\/', '/') for video_url in re.findall( + r'(?:fileList\[[0-9]+\]\s*=|"file"\s*:)\s*"([^"]+)"', webpage)] for i, video_url in enumerate(video_urls): req = HEADRequest(video_url) res = self._request_webpage( @@ -46,7 +48,7 @@ class AparatIE(InfoExtractor): title = self._search_regex(r'\s+title:\s*"([^"]+)"', webpage, 'title') thumbnail = self._search_regex( - r'\s+image:\s*"([^"]+)"', webpage, 'thumbnail', fatal=False) + r'image:\s*"([^"]+)"', webpage, 'thumbnail', fatal=False) return { 'id': video_id, @@ -54,4 +56,5 @@ class AparatIE(InfoExtractor): 'url': video_url, 'ext': 'mp4', 'thumbnail': thumbnail, + 'age_limit': self._family_friendly_search(webpage), } diff --git a/youtube_dl/extractor/appletrailers.py b/youtube_dl/extractor/appletrailers.py index 287f71e..576f03b 100644 --- a/youtube_dl/extractor/appletrailers.py +++ b/youtube_dl/extractor/appletrailers.py @@ -11,9 +11,12 @@ from ..utils import ( class AppleTrailersIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?trailers\.apple\.com/trailers/(?P[^/]+)/(?P[^/]+)' - _TEST = { + _VALID_URL = r'https?://(?:www\.)?trailers\.apple\.com/(?:trailers|ca)/(?P[^/]+)/(?P[^/]+)' + _TESTS = [{ "url": "http://trailers.apple.com/trailers/wb/manofsteel/", + 'info_dict': { + 'id': 'manofsteel', + }, "playlist": [ { "md5": "d97a8e575432dbcb81b7c3acb741f8a8", @@ -60,7 +63,10 @@ class AppleTrailersIE(InfoExtractor): }, }, ] - } + }, { + 'url': 'http://trailers.apple.com/ca/metropole/autrui/', + 'only_matching': True, + }] _JSON_RE = r'iTunes.playURL\((.*?)\);' diff --git a/youtube_dl/extractor/atresplayer.py b/youtube_dl/extractor/atresplayer.py index f016368..7669e0e 100644 --- a/youtube_dl/extractor/atresplayer.py +++ b/youtube_dl/extractor/atresplayer.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import time import hmac -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..compat import ( compat_str, compat_urllib_parse, @@ -17,7 +17,7 @@ from ..utils import ( ) -class AtresPlayerIE(SubtitlesInfoExtractor): +class AtresPlayerIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?atresplayer\.com/television/[^/]+/[^/]+/[^/]+/(?P.+?)_\d+\.html' _TESTS = [ { @@ -144,13 +144,12 @@ class AtresPlayerIE(SubtitlesInfoExtractor): thumbnail = xpath_text(episode, './media/asset/files/background', 'thumbnail') subtitles = {} - subtitle = xpath_text(episode, './media/asset/files/subtitle', 'subtitle') - if subtitle: - subtitles['es'] = subtitle - - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return + subtitle_url = xpath_text(episode, './media/asset/files/subtitle', 'subtitle') + if subtitle_url: + subtitles['es'] = [{ + 'ext': 'srt', + 'url': subtitle_url, + }] return { 'id': video_id, @@ -159,5 +158,5 @@ class AtresPlayerIE(SubtitlesInfoExtractor): 'thumbnail': thumbnail, 'duration': duration, 'formats': formats, - 'subtitles': self.extract_subtitles(video_id, subtitles), + 'subtitles': subtitles, } diff --git a/youtube_dl/extractor/bambuser.py b/youtube_dl/extractor/bambuser.py index 98e1443..c193e66 100644 --- a/youtube_dl/extractor/bambuser.py +++ b/youtube_dl/extractor/bambuser.py @@ -50,7 +50,7 @@ class BambuserIE(InfoExtractor): 'duration': int(info['length']), 'view_count': int(info['views_total']), 'uploader': info['username'], - 'uploader_id': info['uid'], + 'uploader_id': info['owner']['uid'], } diff --git a/youtube_dl/extractor/bandcamp.py b/youtube_dl/extractor/bandcamp.py index aea0263..8692949 100644 --- a/youtube_dl/extractor/bandcamp.py +++ b/youtube_dl/extractor/bandcamp.py @@ -72,26 +72,29 @@ class BandcampIE(InfoExtractor): download_link = m_download.group(1) video_id = self._search_regex( - r'var TralbumData = {.*?id: (?P\d+),?$', - webpage, 'video id', flags=re.MULTILINE | re.DOTALL) + r'(?ms)var TralbumData = {.*?id: (?P\d+),?$', + webpage, 'video id') download_webpage = self._download_webpage(download_link, video_id, 'Downloading free downloads page') # We get the dictionary of the track from some javascript code - info = re.search(r'items: (.*?),$', download_webpage, re.MULTILINE).group(1) - info = json.loads(info)[0] + all_info = self._parse_json(self._search_regex( + r'(?sm)items: (.*?),$', download_webpage, 'items'), video_id) + info = all_info[0] # We pick mp3-320 for now, until format selection can be easily implemented. mp3_info = info['downloads']['mp3-320'] # If we try to use this url it says the link has expired initial_url = mp3_info['url'] - re_url = r'(?Phttp://(.*?)\.bandcamp\.com)/download/track\?enc=mp3-320&fsig=(?P.*?)&id=(?P.*?)&ts=(?P.*)$' - m_url = re.match(re_url, initial_url) + m_url = re.match( + r'(?Phttp://(.*?)\.bandcamp\.com)/download/track\?enc=mp3-320&fsig=(?P.*?)&id=(?P.*?)&ts=(?P.*)$', + initial_url) # We build the url we will use to get the final track url # This url is build in Bandcamp in the script download_bunde_*.js request_url = '%s/statdownload/track?enc=mp3-320&fsig=%s&id=%s&ts=%s&.rand=665028774616&.vrs=1' % (m_url.group('server'), m_url.group('fsig'), video_id, m_url.group('ts')) final_url_webpage = self._download_webpage(request_url, video_id, 'Requesting download url') # If we could correctly generate the .rand field the url would be # in the "download_url" key - final_url = re.search(r'"retry_url":"(.*?)"', final_url_webpage).group(1) + final_url = self._search_regex( + r'"retry_url":"(.*?)"', final_url_webpage, 'final video URL') return { 'id': video_id, @@ -106,7 +109,7 @@ class BandcampIE(InfoExtractor): class BandcampAlbumIE(InfoExtractor): IE_NAME = 'Bandcamp:album' - _VALID_URL = r'https?://(?:(?P[^.]+)\.)?bandcamp\.com(?:/album/(?P[^?#]+)|/?(?:$|[?#]))' + _VALID_URL = r'https?://(?:(?P<subdomain>[^.]+)\.)?bandcamp\.com(?:/album/(?P<album_id>[^?#]+)|/?(?:$|[?#]))' _TESTS = [{ 'url': 'http://blazo.bandcamp.com/album/jazz-format-mixtape-vol-1', @@ -130,31 +133,37 @@ class BandcampAlbumIE(InfoExtractor): ], 'info_dict': { 'title': 'Jazz Format Mixtape vol.1', + 'id': 'jazz-format-mixtape-vol-1', + 'uploader_id': 'blazo', }, 'params': { 'playlistend': 2 }, - 'skip': 'Bandcamp imposes download limits. See test_playlists:test_bandcamp_album for the playlist test' + 'skip': 'Bandcamp imposes download limits.' }, { 'url': 'http://nightbringer.bandcamp.com/album/hierophany-of-the-open-grave', 'info_dict': { 'title': 'Hierophany of the Open Grave', + 'uploader_id': 'nightbringer', + 'id': 'hierophany-of-the-open-grave', }, 'playlist_mincount': 9, }, { 'url': 'http://dotscale.bandcamp.com', 'info_dict': { 'title': 'Loom', + 'id': 'dotscale', + 'uploader_id': 'dotscale', }, 'playlist_mincount': 7, }] def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) - playlist_id = mobj.group('subdomain') - title = mobj.group('title') - display_id = title or playlist_id - webpage = self._download_webpage(url, display_id) + uploader_id = mobj.group('subdomain') + album_id = mobj.group('album_id') + playlist_id = album_id or uploader_id + webpage = self._download_webpage(url, playlist_id) tracks_paths = re.findall(r'<a href="(.*?)" itemprop="url">', webpage) if not tracks_paths: raise ExtractorError('The page doesn\'t contain any tracks') @@ -165,8 +174,8 @@ class BandcampAlbumIE(InfoExtractor): r'album_title\s*:\s*"(.*?)"', webpage, 'title', fatal=False) return { '_type': 'playlist', + 'uploader_id': uploader_id, 'id': playlist_id, - 'display_id': display_id, 'title': title, 'entries': entries, } diff --git a/youtube_dl/extractor/bbccouk.py b/youtube_dl/extractor/bbccouk.py index 126c882..abc34a5 100644 --- a/youtube_dl/extractor/bbccouk.py +++ b/youtube_dl/extractor/bbccouk.py @@ -2,12 +2,12 @@ from __future__ import unicode_literals import xml.etree.ElementTree -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..utils import ExtractorError from ..compat import compat_HTTPError -class BBCCoUkIE(SubtitlesInfoExtractor): +class BBCCoUkIE(InfoExtractor): IE_NAME = 'bbc.co.uk' IE_DESC = 'BBC iPlayer' _VALID_URL = r'https?://(?:www\.)?bbc\.co\.uk/(?:(?:(?:programmes|iplayer(?:/[^/]+)?/(?:episode|playlist))/)|music/clips[/#])(?P<id>[\da-z]{8})' @@ -215,17 +215,32 @@ class BBCCoUkIE(SubtitlesInfoExtractor): formats.extend(conn_formats) return formats - def _extract_captions(self, media, programme_id): + def _get_subtitles(self, media, programme_id): subtitles = {} for connection in self._extract_connections(media): captions = self._download_xml(connection.get('href'), programme_id, 'Downloading captions') lang = captions.get('{http://www.w3.org/XML/1998/namespace}lang', 'en') ps = captions.findall('./{0}body/{0}div/{0}p'.format('{http://www.w3.org/2006/10/ttaf1}')) srt = '' + + def _extract_text(p): + if p.text is not None: + stripped_text = p.text.strip() + if stripped_text: + return stripped_text + return ' '.join(span.text.strip() for span in p.findall('{http://www.w3.org/2006/10/ttaf1}span')) for pos, p in enumerate(ps): - srt += '%s\r\n%s --> %s\r\n%s\r\n\r\n' % (str(pos), p.get('begin'), p.get('end'), - p.text.strip() if p.text is not None else '') - subtitles[lang] = srt + srt += '%s\r\n%s --> %s\r\n%s\r\n\r\n' % (str(pos), p.get('begin'), p.get('end'), _extract_text(p)) + subtitles[lang] = [ + { + 'url': connection.get('href'), + 'ext': 'ttml', + }, + { + 'data': srt, + 'ext': 'srt', + }, + ] return subtitles def _download_media_selector(self, programme_id): @@ -249,7 +264,7 @@ class BBCCoUkIE(SubtitlesInfoExtractor): elif kind == 'video': formats.extend(self._extract_video(media, programme_id)) elif kind == 'captions': - subtitles = self._extract_captions(media, programme_id) + subtitles = self.extract_subtitles(media, programme_id) return formats, subtitles @@ -273,7 +288,7 @@ class BBCCoUkIE(SubtitlesInfoExtractor): formats, subtitles = self._download_media_selector(programme_id) return programme_id, title, description, duration, formats, subtitles except ExtractorError as ee: - if not isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 404: + if not (isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 404): raise # fallback to legacy playlist @@ -324,10 +339,6 @@ class BBCCoUkIE(SubtitlesInfoExtractor): else: programme_id, title, description, duration, formats, subtitles = self._download_playlist(group_id) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(programme_id, subtitles) - return - self._sort_formats(formats) return { diff --git a/youtube_dl/extractor/beeg.py b/youtube_dl/extractor/beeg.py index 4e79fea..b38057f 100644 --- a/youtube_dl/extractor/beeg.py +++ b/youtube_dl/extractor/beeg.py @@ -9,7 +9,7 @@ class BeegIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?beeg\.com/(?P<id>\d+)' _TEST = { 'url': 'http://beeg.com/5416503', - 'md5': '634526ae978711f6b748fe0dd6c11f57', + 'md5': '1bff67111adb785c51d1b42959ec10e5', 'info_dict': { 'id': '5416503', 'ext': 'mp4', diff --git a/youtube_dl/extractor/blinkx.py b/youtube_dl/extractor/blinkx.py index 3e461e7..3b8eabe 100644 --- a/youtube_dl/extractor/blinkx.py +++ b/youtube_dl/extractor/blinkx.py @@ -1,40 +1,35 @@ from __future__ import unicode_literals import json -import re from .common import InfoExtractor -from ..utils import remove_start +from ..utils import ( + remove_start, + int_or_none, +) class BlinkxIE(InfoExtractor): - _VALID_URL = r'^(?:https?://(?:www\.)blinkx\.com/#?ce/|blinkx:)(?P<id>[^?]+)' + _VALID_URL = r'(?:https?://(?:www\.)blinkx\.com/#?ce/|blinkx:)(?P<id>[^?]+)' IE_NAME = 'blinkx' _TEST = { - 'url': 'http://www.blinkx.com/ce/8aQUy7GVFYgFzpKhT0oqsilwOGFRVXk3R1ZGWWdGenBLaFQwb3FzaWx3OGFRVXk3R1ZGWWdGenB', - 'md5': '2e9a07364af40163a908edbf10bb2492', + 'url': 'http://www.blinkx.com/ce/Da0Gw3xc5ucpNduzLuDDlv4WC9PuI4fDi1-t6Y3LyfdY2SZS5Urbvn-UPJvrvbo8LTKTc67Wu2rPKSQDJyZeeORCR8bYkhs8lI7eqddznH2ofh5WEEdjYXnoRtj7ByQwt7atMErmXIeYKPsSDuMAAqJDlQZ-3Ff4HJVeH_s3Gh8oQ', + 'md5': '337cf7a344663ec79bf93a526a2e06c7', 'info_dict': { - 'id': '8aQUy7GV', + 'id': 'Da0Gw3xc', 'ext': 'mp4', - 'title': 'Police Car Rolls Away', - 'uploader': 'stupidvideos.com', - 'upload_date': '20131215', - 'timestamp': 1387068000, - 'description': 'A police car gently rolls away from a fight. Maybe it felt weird being around a confrontation and just had to get out of there!', - 'duration': 14.886, - 'thumbnails': [{ - 'width': 100, - 'height': 76, - 'resolution': '100x76', - 'url': 'http://cdn.blinkx.com/stream/b/41/StupidVideos/20131215/1873969261/1873969261_tn_0.jpg', - }], + 'title': 'No Daily Show for John Oliver; HBO Show Renewed - IGN News', + 'uploader': 'IGN News', + 'upload_date': '20150217', + 'timestamp': 1424215740, + 'description': 'HBO has renewed Last Week Tonight With John Oliver for two more seasons.', + 'duration': 47.743333, }, } - def _real_extract(self, rl): - m = re.match(self._VALID_URL, rl) - video_id = m.group('id') + def _real_extract(self, url): + video_id = self._match_id(url) display_id = video_id[:8] api_url = ('https://apib4.blinkx.com/api.php?action=play_video&' + @@ -60,18 +55,20 @@ class BlinkxIE(InfoExtractor): elif m['type'] in ('flv', 'mp4'): vcodec = remove_start(m['vcodec'], 'ff') acodec = remove_start(m['acodec'], 'ff') - tbr = (int(m['vbr']) + int(m['abr'])) // 1000 + vbr = int_or_none(m.get('vbr') or m.get('vbitrate'), 1000) + abr = int_or_none(m.get('abr') or m.get('abitrate'), 1000) + tbr = vbr + abr if vbr and abr else None format_id = '%s-%sk-%s' % (vcodec, tbr, m['w']) formats.append({ 'format_id': format_id, 'url': m['link'], 'vcodec': vcodec, 'acodec': acodec, - 'abr': int(m['abr']) // 1000, - 'vbr': int(m['vbr']) // 1000, + 'abr': abr, + 'vbr': vbr, 'tbr': tbr, - 'width': int(m['w']), - 'height': int(m['h']), + 'width': int_or_none(m.get('w')), + 'height': int_or_none(m.get('h')), }) self._sort_formats(formats) diff --git a/youtube_dl/extractor/bliptv.py b/youtube_dl/extractor/bliptv.py index 436cc51..8c7ba4b 100644 --- a/youtube_dl/extractor/bliptv.py +++ b/youtube_dl/extractor/bliptv.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from .subtitles import SubtitlesInfoExtractor from ..compat import ( compat_str, @@ -18,7 +17,7 @@ from ..utils import ( ) -class BlipTVIE(SubtitlesInfoExtractor): +class BlipTVIE(InfoExtractor): _VALID_URL = r'https?://(?:\w+\.)?blip\.tv/(?:(?:.+-|rss/flash/)(?P<id>\d+)|((?:play/|api\.swf#)(?P<lookup_id>[\da-zA-Z+_]+)))' _TESTS = [ @@ -143,7 +142,7 @@ class BlipTVIE(SubtitlesInfoExtractor): categories = [category.text for category in item.findall('category')] formats = [] - subtitles = {} + subtitles_urls = {} media_group = item.find(media('group')) for media_content in media_group.findall(media('content')): @@ -161,7 +160,7 @@ class BlipTVIE(SubtitlesInfoExtractor): } lang = role.rpartition('-')[-1].strip().lower() langcode = LANGS.get(lang, lang) - subtitles[langcode] = url + subtitles_urls[langcode] = url elif media_type.startswith('video/'): formats.append({ 'url': real_url, @@ -175,11 +174,7 @@ class BlipTVIE(SubtitlesInfoExtractor): }) self._sort_formats(formats) - # subtitles - video_subtitles = self.extract_subtitles(video_id, subtitles) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return + subtitles = self.extract_subtitles(video_id, subtitles_urls) return { 'id': video_id, @@ -192,15 +187,22 @@ class BlipTVIE(SubtitlesInfoExtractor): 'thumbnail': thumbnail, 'categories': categories, 'formats': formats, - 'subtitles': video_subtitles, + 'subtitles': subtitles, } - def _download_subtitle_url(self, sub_lang, url): - # For some weird reason, blip.tv serves a video instead of subtitles - # when we request with a common UA - req = compat_urllib_request.Request(url) - req.add_header('User-Agent', 'youtube-dl') - return self._download_webpage(req, None, note=False) + def _get_subtitles(self, video_id, subtitles_urls): + subtitles = {} + for lang, url in subtitles_urls.items(): + # For some weird reason, blip.tv serves a video instead of subtitles + # when we request with a common UA + req = compat_urllib_request.Request(url) + req.add_header('User-Agent', 'youtube-dl') + subtitles[lang] = [{ + # The extension is 'srt' but it's actually an 'ass' file + 'ext': 'ass', + 'data': self._download_webpage(req, None, note=False), + }] + return subtitles class BlipTVUserIE(InfoExtractor): diff --git a/youtube_dl/extractor/bloomberg.py b/youtube_dl/extractor/bloomberg.py index c51a97c..4a88ccd 100644 --- a/youtube_dl/extractor/bloomberg.py +++ b/youtube_dl/extractor/bloomberg.py @@ -6,7 +6,7 @@ from .common import InfoExtractor class BloombergIE(InfoExtractor): - _VALID_URL = r'https?://www\.bloomberg\.com/video/(?P<name>.+?)\.html' + _VALID_URL = r'https?://www\.bloomberg\.com/video/(?P<id>.+?)\.html' _TEST = { 'url': 'http://www.bloomberg.com/video/shah-s-presentation-on-foreign-exchange-strategies-qurhIVlJSB6hzkVi229d8g.html', @@ -20,9 +20,9 @@ class BloombergIE(InfoExtractor): } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - name = mobj.group('name') + name = self._match_id(url) webpage = self._download_webpage(url, name) + f4m_url = self._search_regex( r'<source src="(https?://[^"]+\.f4m.*?)"', webpage, 'f4m url') diff --git a/youtube_dl/extractor/brightcove.py b/youtube_dl/extractor/brightcove.py index ea0969d..0733bec 100644 --- a/youtube_dl/extractor/brightcove.py +++ b/youtube_dl/extractor/brightcove.py @@ -95,6 +95,7 @@ class BrightcoveIE(InfoExtractor): 'url': 'http://c.brightcove.com/services/viewer/htmlFederated?playerID=3550052898001&playerKey=AQ%7E%7E%2CAAABmA9XpXk%7E%2C-Kp7jNgisre1fG5OdqpAFUTcs0lP_ZoL', 'info_dict': { 'title': 'Sealife', + 'id': '3550319591001', }, 'playlist_mincount': 7, }, @@ -247,7 +248,7 @@ class BrightcoveIE(InfoExtractor): playlist_info = json_data['videoList'] videos = [self._extract_video_info(video_info) for video_info in playlist_info['mediaCollectionDTO']['videoDTOs']] - return self.playlist_result(videos, playlist_id=playlist_info['id'], + return self.playlist_result(videos, playlist_id='%s' % playlist_info['id'], playlist_title=playlist_info['mediaCollectionDTO']['displayName']) def _extract_video_info(self, video_info): diff --git a/youtube_dl/extractor/buzzfeed.py b/youtube_dl/extractor/buzzfeed.py index a5d2af1..df503ec 100644 --- a/youtube_dl/extractor/buzzfeed.py +++ b/youtube_dl/extractor/buzzfeed.py @@ -33,6 +33,7 @@ class BuzzFeedIE(InfoExtractor): 'skip_download': True, # Got enough YouTube download tests }, 'info_dict': { + 'id': 'look-at-this-cute-dog-omg', 'description': 're:Munchkin the Teddy Bear is back ?!', 'title': 'You Need To Stop What You\'re Doing And Watching This Dog Walk On A Treadmill', }, @@ -42,8 +43,8 @@ class BuzzFeedIE(InfoExtractor): 'ext': 'mp4', 'upload_date': '20141124', 'uploader_id': 'CindysMunchkin', - 'description': 're:© 2014 Munchkin the Shih Tzu', - 'uploader': 'Munchkin the Shih Tzu', + 'description': 're:© 2014 Munchkin the', + 'uploader': 're:^Munchkin the', 'title': 're:Munchkin the Teddy Bear gets her exercise', }, }] diff --git a/youtube_dl/extractor/camdemy.py b/youtube_dl/extractor/camdemy.py new file mode 100644 index 0000000..897f3a1 --- /dev/null +++ b/youtube_dl/extractor/camdemy.py @@ -0,0 +1,153 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import datetime +import re + +from .common import InfoExtractor +from ..compat import ( + compat_urllib_parse, + compat_urlparse, +) +from ..utils import ( + parse_iso8601, + str_to_int, +) + + +class CamdemyIE(InfoExtractor): + _VALID_URL = r'http://(?:www\.)?camdemy\.com/media/(?P<id>\d+)' + _TESTS = [{ + # single file + 'url': 'http://www.camdemy.com/media/5181/', + 'md5': '5a5562b6a98b37873119102e052e311b', + 'info_dict': { + 'id': '5181', + 'ext': 'mp4', + 'title': 'Ch1-1 Introduction, Signals (02-23-2012)', + 'thumbnail': 're:^https?://.*\.jpg$', + 'description': '', + 'creator': 'ss11spring', + 'upload_date': '20130114', + 'timestamp': 1358154556, + 'view_count': int, + } + }, { + # With non-empty description + 'url': 'http://www.camdemy.com/media/13885', + 'md5': '4576a3bb2581f86c61044822adbd1249', + 'info_dict': { + 'id': '13885', + 'ext': 'mp4', + 'title': 'EverCam + Camdemy QuickStart', + 'thumbnail': 're:^https?://.*\.jpg$', + 'description': 'md5:050b62f71ed62928f8a35f1a41e186c9', + 'creator': 'evercam', + 'upload_date': '20140620', + 'timestamp': 1403271569, + } + }, { + # External source + 'url': 'http://www.camdemy.com/media/14842', + 'md5': '50e1c3c3aa233d3d7b7daa2fa10b1cf7', + 'info_dict': { + 'id': '2vsYQzNIsJo', + 'ext': 'mp4', + 'upload_date': '20130211', + 'uploader': 'Hun Kim', + 'description': 'Excel 2013 Tutorial for Beginners - How to add Password Protection', + 'uploader_id': 'hunkimtutorials', + 'title': 'Excel 2013 Tutorial - How to add Password Protection', + } + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + page = self._download_webpage(url, video_id) + + src_from = self._html_search_regex( + r"<div class='srcFrom'>Source: <a title='([^']+)'", page, + 'external source', default=None) + if src_from: + return self.url_result(src_from) + + oembed_obj = self._download_json( + 'http://www.camdemy.com/oembed/?format=json&url=' + url, video_id) + + thumb_url = oembed_obj['thumbnail_url'] + video_folder = compat_urlparse.urljoin(thumb_url, 'video/') + file_list_doc = self._download_xml( + compat_urlparse.urljoin(video_folder, 'fileList.xml'), + video_id, 'Filelist XML') + file_name = file_list_doc.find('./video/item/fileName').text + video_url = compat_urlparse.urljoin(video_folder, file_name) + + timestamp = parse_iso8601(self._html_search_regex( + r"<div class='title'>Posted\s*:</div>\s*<div class='value'>([^<>]+)<", + page, 'creation time', fatal=False), + delimiter=' ', timezone=datetime.timedelta(hours=8)) + view_count = str_to_int(self._html_search_regex( + r"<div class='title'>Views\s*:</div>\s*<div class='value'>([^<>]+)<", + page, 'view count', fatal=False)) + + return { + 'id': video_id, + 'url': video_url, + 'title': oembed_obj['title'], + 'thumbnail': thumb_url, + 'description': self._html_search_meta('description', page), + 'creator': oembed_obj['author_name'], + 'duration': oembed_obj['duration'], + 'timestamp': timestamp, + 'view_count': view_count, + } + + +class CamdemyFolderIE(InfoExtractor): + _VALID_URL = r'http://www.camdemy.com/folder/(?P<id>\d+)' + _TESTS = [{ + # links with trailing slash + 'url': 'http://www.camdemy.com/folder/450', + 'info_dict': { + 'id': '450', + 'title': '信號與系統 2012 & 2011 (Signals and Systems)', + }, + 'playlist_mincount': 145 + }, { + # links without trailing slash + # and multi-page + 'url': 'http://www.camdemy.com/folder/853', + 'info_dict': { + 'id': '853', + 'title': '科學計算 - 使用 Matlab' + }, + 'playlist_mincount': 20 + }, { + # with displayMode parameter. For testing the codes to add parameters + 'url': 'http://www.camdemy.com/folder/853/?displayMode=defaultOrderByOrg', + 'info_dict': { + 'id': '853', + 'title': '科學計算 - 使用 Matlab' + }, + 'playlist_mincount': 20 + }] + + def _real_extract(self, url): + folder_id = self._match_id(url) + + # Add displayMode=list so that all links are displayed in a single page + parsed_url = list(compat_urlparse.urlparse(url)) + query = dict(compat_urlparse.parse_qsl(parsed_url[4])) + query.update({'displayMode': 'list'}) + parsed_url[4] = compat_urllib_parse.urlencode(query) + final_url = compat_urlparse.urlunparse(parsed_url) + + page = self._download_webpage(final_url, folder_id) + matches = re.findall(r"href='(/media/\d+/?)'", page) + + entries = [self.url_result('http://www.camdemy.com' + media_path) + for media_path in matches] + + folder_title = self._html_search_meta('keywords', page) + + return self.playlist_result(entries, folder_id, folder_title) diff --git a/youtube_dl/extractor/canalplus.py b/youtube_dl/extractor/canalplus.py index 11d18d7..1b14471 100644 --- a/youtube_dl/extractor/canalplus.py +++ b/youtube_dl/extractor/canalplus.py @@ -15,12 +15,13 @@ from ..utils import ( class CanalplusIE(InfoExtractor): IE_DESC = 'canalplus.fr, piwiplus.fr and d8.tv' - _VALID_URL = r'https?://(?:www\.(?P<site>canalplus\.fr|piwiplus\.fr|d8\.tv)/.*?/(?P<path>.*)|player\.canalplus\.fr/#/(?P<id>[0-9]+))' + _VALID_URL = r'https?://(?:www\.(?P<site>canalplus\.fr|piwiplus\.fr|d8\.tv|itele\.fr)/.*?/(?P<path>.*)|player\.canalplus\.fr/#/(?P<id>[0-9]+))' _VIDEO_INFO_TEMPLATE = 'http://service.canal-plus.com/video/rest/getVideosLiees/%s/%s' _SITE_ID_MAP = { 'canalplus.fr': 'cplus', 'piwiplus.fr': 'teletoon', 'd8.tv': 'd8', + 'itele.fr': 'itele', } _TESTS = [{ @@ -53,6 +54,16 @@ class CanalplusIE(InfoExtractor): 'upload_date': '20131108', }, 'skip': 'videos get deleted after a while', + }, { + 'url': 'http://www.itele.fr/france/video/aubervilliers-un-lycee-en-colere-111559', + 'md5': '65aa83ad62fe107ce29e564bb8712580', + 'info_dict': { + 'id': '1213714', + 'ext': 'flv', + 'title': 'Aubervilliers : un lycée en colère - Le 11/02/2015 à 06h45', + 'description': 'md5:8216206ec53426ea6321321f3b3c16db', + 'upload_date': '20150211', + }, }] def _real_extract(self, url): diff --git a/youtube_dl/extractor/cbs.py b/youtube_dl/extractor/cbs.py index e43756e..1ceb9d8 100644 --- a/youtube_dl/extractor/cbs.py +++ b/youtube_dl/extractor/cbs.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -import re - from .common import InfoExtractor @@ -39,8 +37,7 @@ class CBSIE(InfoExtractor): }] def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') + video_id = self._match_id(url) webpage = self._download_webpage(url, video_id) real_id = self._search_regex( r"video\.settings\.pid\s*=\s*'([^']+)';", diff --git a/youtube_dl/extractor/cbssports.py b/youtube_dl/extractor/cbssports.py new file mode 100644 index 0000000..ae47e74 --- /dev/null +++ b/youtube_dl/extractor/cbssports.py @@ -0,0 +1,30 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor + + +class CBSSportsIE(InfoExtractor): + _VALID_URL = r'http://www\.cbssports\.com/video/player/(?P<section>[^/]+)/(?P<id>[^/]+)' + + _TEST = { + 'url': 'http://www.cbssports.com/video/player/tennis/318462531970/0/us-open-flashbacks-1990s', + 'info_dict': { + 'id': '_d5_GbO8p1sT', + 'ext': 'flv', + 'title': 'US Open flashbacks: 1990s', + 'description': 'Bill Macatee relives the best moments in US Open history from the 1990s.', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + section = mobj.group('section') + video_id = mobj.group('id') + all_videos = self._download_json( + 'http://www.cbssports.com/data/video/player/getVideos/%s?as=json' % section, + video_id) + # The json file contains the info of all the videos in the section + video_info = next(v for v in all_videos if v['pcid'] == video_id) + return self.url_result('theplatform:%s' % video_info['pid'], 'ThePlatform') diff --git a/youtube_dl/extractor/ccc.py b/youtube_dl/extractor/ccc.py new file mode 100644 index 0000000..2a5d4be --- /dev/null +++ b/youtube_dl/extractor/ccc.py @@ -0,0 +1,99 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + int_or_none, + qualities, + unified_strdate, +) + + +class CCCIE(InfoExtractor): + IE_NAME = 'media.ccc.de' + _VALID_URL = r'https?://(?:www\.)?media\.ccc\.de/[^?#]+/[^?#/]*?_(?P<id>[0-9]{8,})._[^?#/]*\.html' + + _TEST = { + 'url': 'http://media.ccc.de/browse/congress/2013/30C3_-_5443_-_en_-_saal_g_-_201312281830_-_introduction_to_processor_design_-_byterazor.html#video', + 'md5': '205a365d0d57c0b1e43a12c9ffe8f9be', + 'info_dict': { + 'id': '20131228183', + 'ext': 'mp4', + 'title': 'Introduction to Processor Design', + 'description': 'md5:5ddbf8c734800267f2cee4eab187bc1b', + 'thumbnail': 're:^https?://.*\.jpg$', + 'view_count': int, + 'upload_date': '20131229', + } + } + + def _real_extract(self, url): + video_id = self._match_id(url) + webpage = self._download_webpage(url, video_id) + + if self._downloader.params.get('prefer_free_formats'): + preference = qualities(['mp3', 'opus', 'mp4-lq', 'webm-lq', 'h264-sd', 'mp4-sd', 'webm-sd', 'mp4', 'webm', 'mp4-hd', 'h264-hd', 'webm-hd']) + else: + preference = qualities(['opus', 'mp3', 'webm-lq', 'mp4-lq', 'webm-sd', 'h264-sd', 'mp4-sd', 'webm', 'mp4', 'webm-hd', 'mp4-hd', 'h264-hd']) + + title = self._html_search_regex( + r'(?s)<h1>(.*?)</h1>', webpage, 'title') + description = self._html_search_regex( + r"(?s)<p class='description'>(.*?)</p>", + webpage, 'description', fatal=False) + upload_date = unified_strdate(self._html_search_regex( + r"(?s)<span class='[^']*fa-calendar-o'></span>(.*?)</li>", + webpage, 'upload date', fatal=False)) + view_count = int_or_none(self._html_search_regex( + r"(?s)<span class='[^']*fa-eye'></span>(.*?)</li>", + webpage, 'view count', fatal=False)) + + matches = re.finditer(r'''(?xs) + <(?:span|div)\s+class='label\s+filetype'>(?P<format>.*?)</(?:span|div)>\s* + <a\s+href='(?P<http_url>[^']+)'>\s* + (?: + .*? + <a\s+href='(?P<torrent_url>[^']+\.torrent)' + )?''', webpage) + formats = [] + for m in matches: + format = m.group('format') + format_id = self._search_regex( + r'.*/([a-z0-9_-]+)/[^/]*$', + m.group('http_url'), 'format id', default=None) + vcodec = 'h264' if 'h264' in format_id else ( + 'none' if format_id in ('mp3', 'opus') else None + ) + formats.append({ + 'format_id': format_id, + 'format': format, + 'url': m.group('http_url'), + 'vcodec': vcodec, + 'preference': preference(format_id), + }) + + if m.group('torrent_url'): + formats.append({ + 'format_id': 'torrent-%s' % (format if format_id is None else format_id), + 'format': '%s (torrent)' % format, + 'proto': 'torrent', + 'format_note': '(unsupported; will just download the .torrent file)', + 'vcodec': vcodec, + 'preference': -100 + preference(format_id), + 'url': m.group('torrent_url'), + }) + self._sort_formats(formats) + + thumbnail = self._html_search_regex( + r"<video.*?poster='([^']+)'", webpage, 'thumbnail', fatal=False) + + return { + 'id': video_id, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + 'view_count': view_count, + 'upload_date': upload_date, + 'formats': formats, + } diff --git a/youtube_dl/extractor/ceskatelevize.py b/youtube_dl/extractor/ceskatelevize.py index f70e090..65f6be6 100644 --- a/youtube_dl/extractor/ceskatelevize.py +++ b/youtube_dl/extractor/ceskatelevize.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import re -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..compat import ( compat_urllib_request, compat_urllib_parse, @@ -15,7 +15,7 @@ from ..utils import ( ) -class CeskaTelevizeIE(SubtitlesInfoExtractor): +class CeskaTelevizeIE(InfoExtractor): _VALID_URL = r'https?://www\.ceskatelevize\.cz/(porady|ivysilani)/(.+/)?(?P<id>[^?#]+)' _TESTS = [ @@ -107,13 +107,7 @@ class CeskaTelevizeIE(SubtitlesInfoExtractor): subtitles = {} subs = item.get('subtitles') if subs: - subtitles['cs'] = subs[0]['url'] - - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return - - subtitles = self._fix_subtitles(self.extract_subtitles(video_id, subtitles)) + subtitles = self.extract_subtitles(episode_id, subs) return { 'id': episode_id, @@ -125,11 +119,20 @@ class CeskaTelevizeIE(SubtitlesInfoExtractor): 'subtitles': subtitles, } + def _get_subtitles(self, episode_id, subs): + original_subtitles = self._download_webpage( + subs[0]['url'], episode_id, 'Downloading subtitles') + srt_subs = self._fix_subtitles(original_subtitles) + return { + 'cs': [{ + 'ext': 'srt', + 'data': srt_subs, + }] + } + @staticmethod def _fix_subtitles(subtitles): """ Convert millisecond-based subtitles to SRT """ - if subtitles is None: - return subtitles # subtitles not requested def _msectotimecode(msec): """ Helper utility to convert milliseconds to timecode """ @@ -149,7 +152,4 @@ class CeskaTelevizeIE(SubtitlesInfoExtractor): else: yield line - fixed_subtitles = {} - for k, v in subtitles.items(): - fixed_subtitles[k] = "\r\n".join(_fix_subtitle(v)) - return fixed_subtitles + return "\r\n".join(_fix_subtitle(subtitles)) diff --git a/youtube_dl/extractor/chirbit.py b/youtube_dl/extractor/chirbit.py new file mode 100644 index 0000000..b1eeaf1 --- /dev/null +++ b/youtube_dl/extractor/chirbit.py @@ -0,0 +1,84 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + parse_duration, + int_or_none, +) + + +class ChirbitIE(InfoExtractor): + IE_NAME = 'chirbit' + _VALID_URL = r'https?://(?:www\.)?chirb\.it/(?:(?:wp|pl)/|fb_chirbit_player\.swf\?key=)?(?P<id>[\da-zA-Z]+)' + _TESTS = [{ + 'url': 'http://chirb.it/PrIPv5', + 'md5': '9847b0dad6ac3e074568bf2cfb197de8', + 'info_dict': { + 'id': 'PrIPv5', + 'ext': 'mp3', + 'title': 'Фасадстрой', + 'duration': 52, + 'view_count': int, + 'comment_count': int, + } + }, { + 'url': 'https://chirb.it/fb_chirbit_player.swf?key=PrIPv5', + 'only_matching': True, + }] + + def _real_extract(self, url): + audio_id = self._match_id(url) + + webpage = self._download_webpage( + 'http://chirb.it/%s' % audio_id, audio_id) + + audio_url = self._search_regex( + r'"setFile"\s*,\s*"([^"]+)"', webpage, 'audio url') + + title = self._search_regex( + r'itemprop="name">([^<]+)', webpage, 'title') + duration = parse_duration(self._html_search_meta( + 'duration', webpage, 'duration', fatal=False)) + view_count = int_or_none(self._search_regex( + r'itemprop="playCount"\s*>(\d+)', webpage, + 'listen count', fatal=False)) + comment_count = int_or_none(self._search_regex( + r'>(\d+) Comments?:', webpage, + 'comment count', fatal=False)) + + return { + 'id': audio_id, + 'url': audio_url, + 'title': title, + 'duration': duration, + 'view_count': view_count, + 'comment_count': comment_count, + } + + +class ChirbitProfileIE(InfoExtractor): + IE_NAME = 'chirbit:profile' + _VALID_URL = r'https?://(?:www\.)?chirbit.com/(?:rss/)?(?P<id>[^/]+)' + _TEST = { + 'url': 'http://chirbit.com/ScarletBeauty', + 'info_dict': { + 'id': 'ScarletBeauty', + 'title': 'Chirbits by ScarletBeauty', + }, + 'playlist_mincount': 3, + } + + def _real_extract(self, url): + profile_id = self._match_id(url) + + rss = self._download_xml( + 'http://chirbit.com/rss/%s' % profile_id, profile_id) + + entries = [ + self.url_result(audio_url.text, 'Chirbit') + for audio_url in rss.findall('./channel/item/link')] + + title = rss.find('./channel/title').text + + return self.playlist_result(entries, profile_id, title) diff --git a/youtube_dl/extractor/comedycentral.py b/youtube_dl/extractor/comedycentral.py index b245389..e5edcc8 100644 --- a/youtube_dl/extractor/comedycentral.py +++ b/youtube_dl/extractor/comedycentral.py @@ -250,6 +250,8 @@ class ComedyCentralShowsIE(MTVServicesInfoExtractor): }) self._sort_formats(formats) + subtitles = self._extract_subtitles(cdoc, guid) + virtual_id = show_name + ' ' + epTitle + ' part ' + compat_str(part_num + 1) entries.append({ 'id': guid, @@ -260,6 +262,7 @@ class ComedyCentralShowsIE(MTVServicesInfoExtractor): 'duration': duration, 'thumbnail': thumbnail, 'description': description, + 'subtitles': subtitles, }) return { diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index df1a441..7977fa8 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -27,7 +27,6 @@ from ..utils import ( compiled_regex_type, ExtractorError, float_or_none, - HEADRequest, int_or_none, RegexNotFoundError, sanitize_filename, @@ -151,12 +150,19 @@ class InfoExtractor(object): If not explicitly set, calculated from timestamp. uploader_id: Nickname or id of the video uploader. location: Physical location where the video was filmed. - subtitles: The subtitle file contents as a dictionary in the format - {language: subtitles}. + subtitles: The available subtitles as a dictionary in the format + {language: subformats}. "subformats" is a list sorted from + lower to higher preference, each element is a dictionary + with the "ext" entry and one of: + * "data": The subtitles file contents + * "url": A url pointing to the subtitles file + automatic_captions: Like 'subtitles', used by the YoutubeIE for + automatically generated captions duration: Length of the video in seconds, as an integer. view_count: How many users have watched the video on the platform. like_count: Number of positive ratings of the video dislike_count: Number of negative ratings of the video + average_rating: Average rating give by users, the scale used depends on the webpage comment_count: Number of comments on the video comments: A list of comments, each with one or more of the following properties (all but one of text or html optional): @@ -264,8 +270,15 @@ class InfoExtractor(object): def extract(self, url): """Extracts URL information and returns it in list of dicts.""" - self.initialize() - return self._real_extract(url) + try: + self.initialize() + return self._real_extract(url) + except ExtractorError: + raise + except compat_http_client.IncompleteRead as e: + raise ExtractorError('A network error has occured.', cause=e, expected=True) + except (KeyError, StopIteration) as e: + raise ExtractorError('An extractor error has occured.', cause=e) def set_downloader(self, downloader): """Sets the downloader for this IE.""" @@ -384,6 +397,16 @@ class InfoExtractor(object): if blocked_iframe: msg += ' Visit %s for more details' % blocked_iframe raise ExtractorError(msg, expected=True) + if '<title>The URL you requested has been blocked' in content[:512]: + msg = ( + 'Access to this webpage has been blocked by Indian censorship. ' + 'Use a VPN or proxy server (with --proxy) to route around it.') + block_msg = self._html_search_regex( + r'

(.*?)

', + content, 'block message', default=None) + if block_msg: + msg += ' (Message: "%s")' % block_msg.replace('\n', ' ') + raise ExtractorError(msg, expected=True) return content @@ -507,7 +530,7 @@ class InfoExtractor(object): if mobj: break - if os.name != 'nt' and sys.stderr.isatty(): + if not self._downloader.params.get('no_color') and os.name != 'nt' and sys.stderr.isatty(): _name = '\033[0;34m%s\033[0m' % name else: _name = name @@ -656,6 +679,21 @@ class InfoExtractor(object): } return RATING_TABLE.get(rating.lower(), None) + def _family_friendly_search(self, html): + # See http://schema.org/VideoObject + family_friendly = self._html_search_meta('isFamilyFriendly', html) + + if not family_friendly: + return None + + RATING_TABLE = { + '1': 0, + 'true': 0, + '0': 18, + 'false': 18, + } + return RATING_TABLE.get(family_friendly.lower(), None) + def _twitter_search_player(self, html): return self._html_search_meta('twitter:player', html, 'twitter card player') @@ -706,14 +744,14 @@ class InfoExtractor(object): f.get('language_preference') if f.get('language_preference') is not None else -1, f.get('quality') if f.get('quality') is not None else -1, f.get('tbr') if f.get('tbr') is not None else -1, + f.get('filesize') if f.get('filesize') is not None else -1, f.get('vbr') if f.get('vbr') is not None else -1, - ext_preference, f.get('height') if f.get('height') is not None else -1, f.get('width') if f.get('width') is not None else -1, + ext_preference, f.get('abr') if f.get('abr') is not None else -1, audio_ext_preference, f.get('fps') if f.get('fps') is not None else -1, - f.get('filesize') if f.get('filesize') is not None else -1, f.get('filesize_approx') if f.get('filesize_approx') is not None else -1, f.get('source_preference') if f.get('source_preference') is not None else -1, f.get('format_id'), @@ -730,9 +768,7 @@ class InfoExtractor(object): def _is_valid_url(self, url, video_id, item='video'): try: - self._request_webpage( - HEADRequest(url), video_id, - 'Checking %s URL' % item) + self._request_webpage(url, video_id, 'Checking %s URL' % item) return True except ExtractorError as e: if isinstance(e.cause, compat_HTTPError): @@ -778,8 +814,8 @@ class InfoExtractor(object): media_nodes = manifest.findall('{http://ns.adobe.com/f4m/2.0}media') for i, media_el in enumerate(media_nodes): if manifest_version == '2.0': - manifest_url = ('/'.join(manifest_url.split('/')[:-1]) + '/' - + (media_el.attrib.get('href') or media_el.attrib.get('url'))) + manifest_url = ('/'.join(manifest_url.split('/')[:-1]) + '/' + + (media_el.attrib.get('href') or media_el.attrib.get('url'))) tbr = int_or_none(media_el.attrib.get('bitrate')) formats.append({ 'format_id': '-'.join(filter(None, [f4m_id, 'f4m-%d' % (i if tbr is None else tbr)])), @@ -803,7 +839,7 @@ class InfoExtractor(object): 'url': m3u8_url, 'ext': ext, 'protocol': 'm3u8', - 'preference': -1, + 'preference': preference - 1 if preference else -1, 'resolution': 'multiple', 'format_note': 'Quality selection URL', }] @@ -818,6 +854,7 @@ class InfoExtractor(object): note='Downloading m3u8 information', errnote='Failed to download m3u8 information') last_info = None + last_media = None kv_rex = re.compile( r'(?P[a-zA-Z_-]+)=(?P"[^"]+"|[^",]+)(?:,|$)') for line in m3u8_doc.splitlines(): @@ -828,6 +865,13 @@ class InfoExtractor(object): if v.startswith('"'): v = v[1:-1] last_info[m.group('key')] = v + elif line.startswith('#EXT-X-MEDIA:'): + last_media = {} + for m in kv_rex.finditer(line): + v = m.group('val') + if v.startswith('"'): + v = v[1:-1] + last_media[m.group('key')] = v elif line.startswith('#') or not line.strip(): continue else: @@ -856,6 +900,9 @@ class InfoExtractor(object): width_str, height_str = resolution.split('x') f['width'] = int(width_str) f['height'] = int(height_str) + if last_media is not None: + f['m3u8_media'] = last_media + last_media = None formats.append(f) last_info = {} self._sort_formats(formats) @@ -874,39 +921,57 @@ class InfoExtractor(object): formats = [] rtmp_count = 0 - for video in smil.findall('./body/switch/video'): - src = video.get('src') - if not src: - continue - bitrate = int_or_none(video.get('system-bitrate') or video.get('systemBitrate'), 1000) - width = int_or_none(video.get('width')) - height = int_or_none(video.get('height')) - proto = video.get('proto') - if not proto: - if base: - if base.startswith('rtmp'): - proto = 'rtmp' - elif base.startswith('http'): - proto = 'http' - ext = video.get('ext') - if proto == 'm3u8': - formats.extend(self._extract_m3u8_formats(src, video_id, ext)) - elif proto == 'rtmp': - rtmp_count += 1 - streamer = video.get('streamer') or base - formats.append({ - 'url': streamer, - 'play_path': src, - 'ext': 'flv', - 'format_id': 'rtmp-%d' % (rtmp_count if bitrate is None else bitrate), - 'tbr': bitrate, - 'width': width, - 'height': height, - }) + if smil.findall('./body/seq/video'): + video = smil.findall('./body/seq/video')[0] + fmts, rtmp_count = self._parse_smil_video(video, video_id, base, rtmp_count) + formats.extend(fmts) + else: + for video in smil.findall('./body/switch/video'): + fmts, rtmp_count = self._parse_smil_video(video, video_id, base, rtmp_count) + formats.extend(fmts) + self._sort_formats(formats) return formats + def _parse_smil_video(self, video, video_id, base, rtmp_count): + src = video.get('src') + if not src: + return ([], rtmp_count) + bitrate = int_or_none(video.get('system-bitrate') or video.get('systemBitrate'), 1000) + width = int_or_none(video.get('width')) + height = int_or_none(video.get('height')) + proto = video.get('proto') + if not proto: + if base: + if base.startswith('rtmp'): + proto = 'rtmp' + elif base.startswith('http'): + proto = 'http' + ext = video.get('ext') + if proto == 'm3u8': + return (self._extract_m3u8_formats(src, video_id, ext), rtmp_count) + elif proto == 'rtmp': + rtmp_count += 1 + streamer = video.get('streamer') or base + return ([{ + 'url': streamer, + 'play_path': src, + 'ext': 'flv', + 'format_id': 'rtmp-%d' % (rtmp_count if bitrate is None else bitrate), + 'tbr': bitrate, + 'width': width, + 'height': height, + }], rtmp_count) + elif proto.startswith('http'): + return ([{ + 'url': base + src, + 'ext': ext or 'flv', + 'tbr': bitrate, + 'width': width, + 'height': height, + }], rtmp_count) + def _live_title(self, name): """ Generate the title for a live video """ now = datetime.datetime.now() @@ -970,6 +1035,24 @@ class InfoExtractor(object): any_restricted = any_restricted or is_restricted return not any_restricted + def extract_subtitles(self, *args, **kwargs): + if (self._downloader.params.get('writesubtitles', False) or + self._downloader.params.get('listsubtitles')): + return self._get_subtitles(*args, **kwargs) + return {} + + def _get_subtitles(self, *args, **kwargs): + raise NotImplementedError("This method must be implemented by subclasses") + + def extract_automatic_captions(self, *args, **kwargs): + if (self._downloader.params.get('writeautomaticsub', False) or + self._downloader.params.get('listsubtitles')): + return self._get_automatic_captions(*args, **kwargs) + return {} + + def _get_automatic_captions(self, *args, **kwargs): + raise NotImplementedError("This method must be implemented by subclasses") + class SearchInfoExtractor(InfoExtractor): """ diff --git a/youtube_dl/extractor/commonmistakes.py b/youtube_dl/extractor/commonmistakes.py index 75c0690..2f86e23 100644 --- a/youtube_dl/extractor/commonmistakes.py +++ b/youtube_dl/extractor/commonmistakes.py @@ -24,6 +24,23 @@ class CommonMistakesIE(InfoExtractor): 'That doesn\'t make any sense. ' 'Simply remove the parameter in your command or configuration.' ) % url - if self._downloader.params.get('verbose'): + if not self._downloader.params.get('verbose'): msg += ' Add -v to the command line to see what arguments and configuration youtube-dl got.' raise ExtractorError(msg, expected=True) + + +class UnicodeBOMIE(InfoExtractor): + IE_DESC = False + _VALID_URL = r'(?P\ufeff)(?P.*)$' + + _TESTS = [{ + 'url': '\ufeffhttp://www.youtube.com/watch?v=BaW_jenozKc', + 'only_matching': True, + }] + + def _real_extract(self, url): + real_url = self._match_id(url) + self.report_warning( + 'Your URL starts with a Byte Order Mark (BOM). ' + 'Removing the BOM and looking for "%s" ...' % real_url) + return self.url_result(real_url) diff --git a/youtube_dl/extractor/crunchyroll.py b/youtube_dl/extractor/crunchyroll.py index 1680f53..f1da7d0 100644 --- a/youtube_dl/extractor/crunchyroll.py +++ b/youtube_dl/extractor/crunchyroll.py @@ -9,7 +9,7 @@ import xml.etree.ElementTree from hashlib import sha1 from math import pow, sqrt, floor -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..compat import ( compat_urllib_parse, compat_urllib_request, @@ -25,10 +25,9 @@ from ..aes import ( aes_cbc_decrypt, inc, ) -from .common import InfoExtractor -class CrunchyrollIE(SubtitlesInfoExtractor): +class CrunchyrollIE(InfoExtractor): _VALID_URL = r'https?://(?:(?Pwww|m)\.)?(?Pcrunchyroll\.(?:com|fr)/(?:[^/]*/[^/?&]*?|media/\?id=)(?P[0-9]+))(?:[/?&]|$)' _TESTS = [{ 'url': 'http://www.crunchyroll.com/wanna-be-the-strongest-in-the-world/episode-1-an-idol-wrestler-is-born-645513', @@ -187,6 +186,38 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text return output + def _get_subtitles(self, video_id, webpage): + subtitles = {} + for sub_id, sub_name in re.findall(r'\?ssid=([0-9]+)" title="([^"]+)', webpage): + sub_page = self._download_webpage( + 'http://www.crunchyroll.com/xml/?req=RpcApiSubtitle_GetXml&subtitle_script_id=' + sub_id, + video_id, note='Downloading subtitles for ' + sub_name) + id = self._search_regex(r'id=\'([0-9]+)', sub_page, 'subtitle_id', fatal=False) + iv = self._search_regex(r'([^<]+)', sub_page, 'subtitle_iv', fatal=False) + data = self._search_regex(r'([^<]+)', sub_page, 'subtitle_data', fatal=False) + if not id or not iv or not data: + continue + id = int(id) + iv = base64.b64decode(iv) + data = base64.b64decode(data) + + subtitle = self._decrypt_subtitles(data, iv, id).decode('utf-8') + lang_code = self._search_regex(r'lang_code=["\']([^"\']+)', subtitle, 'subtitle_lang_code', fatal=False) + if not lang_code: + continue + sub_root = xml.etree.ElementTree.fromstring(subtitle) + subtitles[lang_code] = [ + { + 'ext': 'srt', + 'data': self._convert_subtitles_to_srt(sub_root), + }, + { + 'ext': 'ass', + 'data': self._convert_subtitles_to_ass(sub_root), + }, + ] + return subtitles + def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) video_id = mobj.group('video_id') @@ -249,34 +280,7 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text 'format_id': video_format, }) - subtitles = {} - sub_format = self._downloader.params.get('subtitlesformat', 'srt') - for sub_id, sub_name in re.findall(r'\?ssid=([0-9]+)" title="([^"]+)', webpage): - sub_page = self._download_webpage( - 'http://www.crunchyroll.com/xml/?req=RpcApiSubtitle_GetXml&subtitle_script_id=' + sub_id, - video_id, note='Downloading subtitles for ' + sub_name) - id = self._search_regex(r'id=\'([0-9]+)', sub_page, 'subtitle_id', fatal=False) - iv = self._search_regex(r'([^<]+)', sub_page, 'subtitle_iv', fatal=False) - data = self._search_regex(r'([^<]+)', sub_page, 'subtitle_data', fatal=False) - if not id or not iv or not data: - continue - id = int(id) - iv = base64.b64decode(iv) - data = base64.b64decode(data) - - subtitle = self._decrypt_subtitles(data, iv, id).decode('utf-8') - lang_code = self._search_regex(r'lang_code=["\']([^"\']+)', subtitle, 'subtitle_lang_code', fatal=False) - if not lang_code: - continue - sub_root = xml.etree.ElementTree.fromstring(subtitle) - if sub_format == 'ass': - subtitles[lang_code] = self._convert_subtitles_to_ass(sub_root) - else: - subtitles[lang_code] = self._convert_subtitles_to_srt(sub_root) - - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return + subtitles = self.extract_subtitles(video_id, webpage) return { 'id': video_id, diff --git a/youtube_dl/extractor/dailymotion.py b/youtube_dl/extractor/dailymotion.py index cf5841a..42b20a4 100644 --- a/youtube_dl/extractor/dailymotion.py +++ b/youtube_dl/extractor/dailymotion.py @@ -6,7 +6,6 @@ import json import itertools from .common import InfoExtractor -from .subtitles import SubtitlesInfoExtractor from ..compat import ( compat_str, @@ -31,7 +30,7 @@ class DailymotionBaseInfoExtractor(InfoExtractor): return request -class DailymotionIE(DailymotionBaseInfoExtractor, SubtitlesInfoExtractor): +class DailymotionIE(DailymotionBaseInfoExtractor): """Information Extractor for Dailymotion""" _VALID_URL = r'(?i)(?:https?://)?(?:(www|touch)\.)?dailymotion\.[a-z]{2,3}/(?:(embed|#)/)?video/(?P[^/?_]+)' @@ -143,9 +142,6 @@ class DailymotionIE(DailymotionBaseInfoExtractor, SubtitlesInfoExtractor): # subtitles video_subtitles = self.extract_subtitles(video_id, webpage) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, webpage) - return view_count = str_to_int(self._search_regex( r'video_views_count[^>]+>\s+([\d\.,]+)', @@ -169,7 +165,7 @@ class DailymotionIE(DailymotionBaseInfoExtractor, SubtitlesInfoExtractor): 'view_count': view_count, } - def _get_available_subtitles(self, video_id, webpage): + 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, @@ -179,7 +175,7 @@ class DailymotionIE(DailymotionBaseInfoExtractor, SubtitlesInfoExtractor): return {} info = json.loads(sub_list) if (info['total'] > 0): - sub_lang_list = dict((l['language'], l['url']) for l in info['list']) + 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 {} @@ -194,6 +190,7 @@ class DailymotionPlaylistIE(DailymotionBaseInfoExtractor): 'url': 'http://www.dailymotion.com/playlist/xv4bw_nqtv_sport/1#video=xl8v3q', 'info_dict': { 'title': 'SPORT', + 'id': 'xv4bw_nqtv_sport', }, 'playlist_mincount': 20, }] diff --git a/youtube_dl/extractor/dctp.py b/youtube_dl/extractor/dctp.py index 6ed3543..aa2c09e 100644 --- a/youtube_dl/extractor/dctp.py +++ b/youtube_dl/extractor/dctp.py @@ -14,6 +14,10 @@ class DctpTvIE(InfoExtractor): 'display_id': 'videoinstallation-fuer-eine-kaufhausfassade', 'ext': 'flv', 'title': 'Videoinstallation für eine Kaufhausfassade' + }, + 'params': { + # rtmp download + 'skip_download': True, } } diff --git a/youtube_dl/extractor/defense.py b/youtube_dl/extractor/defense.py index 2b90bf4..98e3aed 100644 --- a/youtube_dl/extractor/defense.py +++ b/youtube_dl/extractor/defense.py @@ -25,8 +25,9 @@ class DefenseGouvFrIE(InfoExtractor): r"flashvars.pvg_id=\"(\d+)\";", webpage, 'ID') - json_url = ('http://static.videos.gouv.fr/brightcovehub/export/json/' - + video_id) + json_url = ( + 'http://static.videos.gouv.fr/brightcovehub/export/json/%s' % + video_id) info = self._download_json(json_url, title, 'Downloading JSON config') video_url = info['renditions'][0]['url'] diff --git a/youtube_dl/extractor/dotsub.py b/youtube_dl/extractor/dotsub.py index 638bb33..f51d88a 100644 --- a/youtube_dl/extractor/dotsub.py +++ b/youtube_dl/extractor/dotsub.py @@ -1,13 +1,14 @@ from __future__ import unicode_literals -import re -import time - from .common import InfoExtractor +from ..utils import ( + float_or_none, + int_or_none, +) class DotsubIE(InfoExtractor): - _VALID_URL = r'http://(?:www\.)?dotsub\.com/view/(?P[^/]+)' + _VALID_URL = r'https?://(?:www\.)?dotsub\.com/view/(?P[^/]+)' _TEST = { 'url': 'http://dotsub.com/view/aed3b8b2-1889-4df5-ae63-ad85f5572f27', 'md5': '0914d4d69605090f623b7ac329fea66e', @@ -15,28 +16,37 @@ class DotsubIE(InfoExtractor): 'id': 'aed3b8b2-1889-4df5-ae63-ad85f5572f27', 'ext': 'flv', 'title': 'Pyramids of Waste (2010), AKA The Lightbulb Conspiracy - Planned obsolescence documentary', + 'description': 'md5:699a0f7f50aeec6042cb3b1db2d0d074', + 'thumbnail': 're:^https?://dotsub.com/media/aed3b8b2-1889-4df5-ae63-ad85f5572f27/p', + 'duration': 3169, 'uploader': '4v4l0n42', - 'description': 'Pyramids of Waste (2010) also known as "The lightbulb conspiracy" is a documentary about how our economic system based on consumerism and planned obsolescence is breaking our planet down.\r\n\r\nSolutions to this can be found at:\r\nhttp://robotswillstealyourjob.com\r\nhttp://www.federicopistono.org\r\n\r\nhttp://opensourceecology.org\r\nhttp://thezeitgeistmovement.com', - 'thumbnail': 'http://dotsub.com/media/aed3b8b2-1889-4df5-ae63-ad85f5572f27/p', + 'timestamp': 1292248482.625, 'upload_date': '20101213', + 'view_count': int, } } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') - info_url = "https://dotsub.com/api/media/%s/metadata" % video_id - info = self._download_json(info_url, video_id) - date = time.gmtime(info['dateCreated'] / 1000) # The timestamp is in miliseconds + video_id = self._match_id(url) + + info = self._download_json( + 'https://dotsub.com/api/media/%s/metadata' % video_id, video_id) + video_url = info.get('mediaURI') + + if not video_url: + webpage = self._download_webpage(url, video_id) + video_url = self._search_regex( + r'"file"\s*:\s*\'([^\']+)', webpage, 'video url') return { 'id': video_id, - 'url': info['mediaURI'], + 'url': video_url, 'ext': 'flv', 'title': info['title'], - 'thumbnail': info['screenshotURI'], - 'description': info['description'], - 'uploader': info['user'], - 'view_count': info['numberOfViews'], - 'upload_date': '%04i%02i%02i' % (date.tm_year, date.tm_mon, date.tm_mday), + 'description': info.get('description'), + 'thumbnail': info.get('screenshotURI'), + 'duration': int_or_none(info.get('duration'), 1000), + 'uploader': info.get('user'), + 'timestamp': float_or_none(info.get('dateCreated'), 1000), + 'view_count': int_or_none(info.get('numberOfViews')), } diff --git a/youtube_dl/extractor/drtuber.py b/youtube_dl/extractor/drtuber.py index ca274df..37c5c18 100644 --- a/youtube_dl/extractor/drtuber.py +++ b/youtube_dl/extractor/drtuber.py @@ -15,7 +15,7 @@ class DrTuberIE(InfoExtractor): 'id': '1740434', 'display_id': 'hot-perky-blonde-naked-golf', 'ext': 'mp4', - 'title': 'Hot Perky Blonde Naked Golf', + 'title': 'hot perky blonde naked golf', 'like_count': int, 'dislike_count': int, 'comment_count': int, @@ -36,7 +36,8 @@ class DrTuberIE(InfoExtractor): r'([^<]+)\s*-\s*Free', webpage, 'title') + [r'class="hd_title" style="[^"]+">([^<]+)', r'([^<]+) - \d+'], + webpage, 'title') thumbnail = self._html_search_regex( r'poster="([^"]+)"', diff --git a/youtube_dl/extractor/drtv.py b/youtube_dl/extractor/drtv.py index d5df18d..8257e35 100644 --- a/youtube_dl/extractor/drtv.py +++ b/youtube_dl/extractor/drtv.py @@ -1,11 +1,10 @@ from __future__ import unicode_literals -from .subtitles import SubtitlesInfoExtractor -from .common import ExtractorError +from .common import InfoExtractor, ExtractorError from ..utils import parse_iso8601 -class DRTVIE(SubtitlesInfoExtractor): +class DRTVIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?dr\.dk/tv/se/(?:[^/]+/)*(?P<id>[\da-z-]+)(?:[/#?]|$)' _TEST = { @@ -76,7 +75,7 @@ class DRTVIE(SubtitlesInfoExtractor): } for subs in subtitles_list: lang = subs['Language'] - subtitles[LANGS.get(lang, lang)] = subs['Uri'] + subtitles[LANGS.get(lang, lang)] = [{'url': subs['Uri'], 'ext': 'vtt'}] if not formats and restricted_to_denmark: raise ExtractorError( @@ -84,10 +83,6 @@ class DRTVIE(SubtitlesInfoExtractor): self._sort_formats(formats) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return - return { 'id': video_id, 'title': title, @@ -96,5 +91,5 @@ class DRTVIE(SubtitlesInfoExtractor): 'timestamp': timestamp, 'duration': duration, 'formats': formats, - 'subtitles': self.extract_subtitles(video_id, subtitles), + 'subtitles': subtitles, } diff --git a/youtube_dl/extractor/embedly.py b/youtube_dl/extractor/embedly.py new file mode 100644 index 0000000..1cdb11e --- /dev/null +++ b/youtube_dl/extractor/embedly.py @@ -0,0 +1,16 @@ +# encoding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..compat import compat_urllib_parse_unquote + + +class EmbedlyIE(InfoExtractor): + _VALID_URL = r'https?://(?:www|cdn\.)?embedly\.com/widgets/media\.html\?(?:[^#]*?&)?url=(?P<id>[^#&]+)' + _TESTS = [{ + 'url': 'https://cdn.embedly.com/widgets/media.html?src=http%3A%2F%2Fwww.youtube.com%2Fembed%2Fvideoseries%3Flist%3DUUGLim4T2loE5rwCMdpCIPVg&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DSU4fj_aEMVw%26list%3DUUGLim4T2loE5rwCMdpCIPVg&image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FSU4fj_aEMVw%2Fhqdefault.jpg&key=8ee8a2e6a8cc47aab1a5ee67f9a178e0&type=text%2Fhtml&schema=youtube&autoplay=1', + 'only_matching': True, + }] + + def _real_extract(self, url): + return self.url_result(compat_urllib_parse_unquote(self._match_id(url))) diff --git a/youtube_dl/extractor/eporner.py b/youtube_dl/extractor/eporner.py index 4de8d4b..e006921 100644 --- a/youtube_dl/extractor/eporner.py +++ b/youtube_dl/extractor/eporner.py @@ -35,10 +35,7 @@ class EpornerIE(InfoExtractor): title = self._html_search_regex( r'<title>(.*?) - EPORNER', webpage, 'title') - redirect_code = self._html_search_regex( - r'<script type="text/javascript" src="/config5/%s/([a-f\d]+)/">' % video_id, - webpage, 'redirect_code') - redirect_url = 'http://www.eporner.com/config5/%s/%s' % (video_id, redirect_code) + redirect_url = 'http://www.eporner.com/config5/%s' % video_id player_code = self._download_webpage( redirect_url, display_id, note='Downloading player config') @@ -69,5 +66,5 @@ class EpornerIE(InfoExtractor): 'duration': duration, 'view_count': view_count, 'formats': formats, - 'age_limit': self._rta_search(webpage), + 'age_limit': 18, } diff --git a/youtube_dl/extractor/escapist.py b/youtube_dl/extractor/escapist.py index e240cb8..e47f3e2 100644 --- a/youtube_dl/extractor/escapist.py +++ b/youtube_dl/extractor/escapist.py @@ -1,18 +1,20 @@ from __future__ import unicode_literals -import re - from .common import InfoExtractor from ..compat import ( compat_urllib_parse, + compat_urllib_request, ) from ..utils import ( ExtractorError, + js_to_json, + parse_duration, ) class EscapistIE(InfoExtractor): - _VALID_URL = r'^https?://?(www\.)?escapistmagazine\.com/videos/view/(?P<showname>[^/]+)/(?P<id>[0-9]+)-' + _VALID_URL = r'https?://?(www\.)?escapistmagazine\.com/videos/view/[^/?#]+/(?P<id>[0-9]+)-[^/?#]*(?:$|[?#])' + _USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko' _TEST = { 'url': 'http://www.escapistmagazine.com/videos/view/the-escapist-presents/6618-Breaking-Down-Baldurs-Gate', 'md5': 'ab3a706c681efca53f0a35f1415cf0d1', @@ -20,64 +22,107 @@ class EscapistIE(InfoExtractor): 'id': '6618', 'ext': 'mp4', 'description': "Baldur's Gate: Original, Modded or Enhanced Edition? I'll break down what you can expect from the new Baldur's Gate: Enhanced Edition.", - 'uploader': 'the-escapist-presents', + 'uploader_id': 'the-escapist-presents', + 'uploader': 'The Escapist Presents', 'title': "Breaking Down Baldur's Gate", + 'thumbnail': 're:^https?://.*\.jpg$', + 'duration': 264, } } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - showName = mobj.group('showname') - video_id = mobj.group('id') - - self.report_extraction(video_id) - webpage = self._download_webpage(url, video_id) - - videoDesc = self._html_search_regex( - r'<meta name="description" content="([^"]*)"', - webpage, 'description', fatal=False) - - playerUrl = self._og_search_video_url(webpage, name='player URL') - - title = self._html_search_regex( - r'<meta name="title" content="([^"]*)"', - webpage, 'title').split(' : ')[-1] - - configUrl = self._search_regex('config=(.*)$', playerUrl, 'config URL') - configUrl = compat_urllib_parse.unquote(configUrl) + video_id = self._match_id(url) + webpage_req = compat_urllib_request.Request(url) + webpage_req.add_header('User-Agent', self._USER_AGENT) + webpage = self._download_webpage(webpage_req, video_id) + + uploader_id = self._html_search_regex( + r"<h1\s+class='headline'>\s*<a\s+href='/videos/view/(.*?)'", + webpage, 'uploader ID', fatal=False) + uploader = self._html_search_regex( + r"<h1\s+class='headline'>(.*?)</a>", + webpage, 'uploader', fatal=False) + description = self._html_search_meta('description', webpage) + duration = parse_duration(self._html_search_meta('duration', webpage)) + + raw_title = self._html_search_meta('title', webpage, fatal=True) + title = raw_title.partition(' : ')[2] + + config_url = compat_urllib_parse.unquote(self._html_search_regex( + r'''(?x) + (?: + <param\s+name="flashvars".*?\s+value="config=| + flashvars="config= + ) + (https?://[^"&]+) + ''', + webpage, 'config URL')) formats = [] + ad_formats = [] - def _add_format(name, cfgurl, quality): + def _add_format(name, cfg_url, quality): + cfg_req = compat_urllib_request.Request(cfg_url) + cfg_req.add_header('User-Agent', self._USER_AGENT) config = self._download_json( - cfgurl, video_id, + cfg_req, video_id, 'Downloading ' + name + ' configuration', 'Unable to download ' + name + ' configuration', - transform_source=lambda s: s.replace("'", '"')) + transform_source=js_to_json) playlist = config['playlist'] - formats.append({ - 'url': playlist[1]['url'], - 'format_id': name, - 'quality': quality, - }) - - _add_format('normal', configUrl, quality=0) - hq_url = (configUrl + - ('&hq=1' if '?' in configUrl else configUrl + '?hq=1')) + for p in playlist: + if p.get('eventCategory') == 'Video': + ar = formats + elif p.get('eventCategory') == 'Video Postroll': + ar = ad_formats + else: + continue + + ar.append({ + 'url': p['url'], + 'format_id': name, + 'quality': quality, + 'http_headers': { + 'User-Agent': self._USER_AGENT, + }, + }) + + _add_format('normal', config_url, quality=0) + hq_url = (config_url + + ('&hq=1' if '?' in config_url else config_url + '?hq=1')) try: _add_format('hq', hq_url, quality=1) except ExtractorError: pass # That's fine, we'll just use normal quality - self._sort_formats(formats) - return { + if '/escapist/sales-marketing/' in formats[-1]['url']: + raise ExtractorError('This IP address has been blocked by The Escapist', expected=True) + + res = { 'id': video_id, 'formats': formats, - 'uploader': showName, + 'uploader': uploader, + 'uploader_id': uploader_id, 'title': title, 'thumbnail': self._og_search_thumbnail(webpage), - 'description': videoDesc, - 'player_url': playerUrl, + 'description': description, + 'duration': duration, } + + if self._downloader.params.get('include_ads') and ad_formats: + self._sort_formats(ad_formats) + ad_res = { + 'id': '%s-ad' % video_id, + 'title': '%s (Postroll)' % title, + 'formats': ad_formats, + } + return { + '_type': 'playlist', + 'entries': [res, ad_res], + 'title': title, + 'id': video_id, + } + + return res diff --git a/youtube_dl/extractor/facebook.py b/youtube_dl/extractor/facebook.py index 1ad4e77..f0e5753 100644 --- a/youtube_dl/extractor/facebook.py +++ b/youtube_dl/extractor/facebook.py @@ -126,11 +126,17 @@ class FacebookIE(InfoExtractor): params_raw = compat_urllib_parse.unquote(data['params']) params = json.loads(params_raw) video_data = params['video_data'][0] - video_url = video_data.get('hd_src') - if not video_url: - video_url = video_data['sd_src'] - if not video_url: - raise ExtractorError('Cannot find video URL') + + formats = [] + for quality in ['sd', 'hd']: + src = video_data.get('%s_src' % quality) + if src is not None: + formats.append({ + 'format_id': quality, + 'url': src, + }) + if not formats: + raise ExtractorError('Cannot find video formats') video_title = self._html_search_regex( r'<h2 class="uiHeaderTitle">([^<]*)</h2>', webpage, 'title', @@ -146,7 +152,7 @@ class FacebookIE(InfoExtractor): return { 'id': video_id, 'title': video_title, - 'url': video_url, + 'formats': formats, 'duration': int_or_none(video_data.get('video_duration')), 'thumbnail': video_data.get('thumbnail_src'), } diff --git a/youtube_dl/extractor/firstpost.py b/youtube_dl/extractor/firstpost.py index 0993af1..298227d 100644 --- a/youtube_dl/extractor/firstpost.py +++ b/youtube_dl/extractor/firstpost.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -import re - from .common import InfoExtractor @@ -20,11 +18,10 @@ class FirstpostIE(InfoExtractor): } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') - + video_id = self._match_id(url) page = self._download_webpage(url, video_id) - title = self._html_search_meta('twitter:title', page, 'title') + + title = self._html_search_meta('twitter:title', page, 'title', fatal=True) description = self._html_search_meta('twitter:description', page, 'title') data = self._download_xml( @@ -42,6 +39,7 @@ class FirstpostIE(InfoExtractor): 'height': int(details.find('./height').text.strip()), } for details in item.findall('./source/file_details') if details.find('./file').text ] + self._sort_formats(formats) return { 'id': video_id, diff --git a/youtube_dl/extractor/firsttv.py b/youtube_dl/extractor/firsttv.py index 08ceee4..510d4b1 100644 --- a/youtube_dl/extractor/firsttv.py +++ b/youtube_dl/extractor/firsttv.py @@ -1,52 +1,71 @@ # encoding: utf-8 from __future__ import unicode_literals -import re - from .common import InfoExtractor from ..utils import int_or_none class FirstTVIE(InfoExtractor): - IE_NAME = 'firsttv' - IE_DESC = 'Видеоархив - Первый канал' - _VALID_URL = r'http://(?:www\.)?1tv\.ru/videoarchive/(?P<id>\d+)' + IE_NAME = '1tv' + IE_DESC = 'Первый канал' + _VALID_URL = r'http://(?:www\.)?1tv\.ru/(?:[^/]+/)+(?P<id>.+)' - _TEST = { + _TESTS = [{ 'url': 'http://www.1tv.ru/videoarchive/73390', - 'md5': '3de6390cf0cca4a5eae1d1d83895e5ad', + 'md5': '777f525feeec4806130f4f764bc18a4f', 'info_dict': { 'id': '73390', 'ext': 'mp4', 'title': 'Олимпийские канатные дороги', - 'description': 'md5:cc730d2bf4215463e37fff6a1e277b13', - 'thumbnail': 'http://img1.1tv.ru/imgsize640x360/PR20140210114657.JPG', + 'description': 'md5:d41d8cd98f00b204e9800998ecf8427e', + 'thumbnail': 're:^https?://.*\.(?:jpg|JPG)$', 'duration': 149, + 'like_count': int, + 'dislike_count': int, + }, + 'skip': 'Only works from Russia', + }, { + 'url': 'http://www.1tv.ru/prj/inprivate/vypusk/35930', + 'md5': 'a1b6b60d530ebcf8daacf4565762bbaf', + 'info_dict': { + 'id': '35930', + 'ext': 'mp4', + 'title': 'Наедине со всеми. Людмила Сенчина', + 'description': 'md5:89553aed1d641416001fe8d450f06cb9', + 'thumbnail': 're:^https?://.*\.(?:jpg|JPG)$', + 'duration': 2694, }, 'skip': 'Only works from Russia', - } + }] def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') + video_id = self._match_id(url) webpage = self._download_webpage(url, video_id, 'Downloading page') video_url = self._html_search_regex( - r'''(?s)jwplayer\('flashvideoportal_1'\)\.setup\({.*?'file': '([^']+)'.*?}\);''', webpage, 'video URL') + r'''(?s)(?:jwplayer\('flashvideoportal_1'\)\.setup\({|var\s+playlistObj\s*=).*?'file'\s*:\s*'([^']+)'.*?}\);''', + webpage, 'video URL') title = self._html_search_regex( - r'<div class="tv_translation">\s*<h1><a href="[^"]+">([^<]*)</a>', webpage, 'title') + [r'<div class="tv_translation">\s*<h1><a href="[^"]+">([^<]*)</a>', + r"'title'\s*:\s*'([^']+)'"], webpage, 'title') description = self._html_search_regex( - r'<div class="descr">\s*<div> </div>\s*<p>([^<]*)</p></div>', webpage, 'description', fatal=False) + r'<div class="descr">\s*<div> </div>\s*<p>([^<]*)</p></div>', + webpage, 'description', default=None) or self._html_search_meta( + 'description', webpage, 'description') thumbnail = self._og_search_thumbnail(webpage) - duration = self._og_search_property('video:duration', webpage, 'video duration', fatal=False) + duration = self._og_search_property( + 'video:duration', webpage, + 'video duration', fatal=False) - like_count = self._html_search_regex(r'title="Понравилось".*?/></label> \[(\d+)\]', - webpage, 'like count', fatal=False) - dislike_count = self._html_search_regex(r'title="Не понравилось".*?/></label> \[(\d+)\]', - webpage, 'dislike count', fatal=False) + like_count = self._html_search_regex( + r'title="Понравилось".*?/></label> \[(\d+)\]', + webpage, 'like count', default=None) + dislike_count = self._html_search_regex( + r'title="Не понравилось".*?/></label> \[(\d+)\]', + webpage, 'dislike count', default=None) return { 'id': video_id, diff --git a/youtube_dl/extractor/fivemin.py b/youtube_dl/extractor/fivemin.py index 5b24b92..157094e 100644 --- a/youtube_dl/extractor/fivemin.py +++ b/youtube_dl/extractor/fivemin.py @@ -14,6 +14,7 @@ class FiveMinIE(InfoExtractor): IE_NAME = '5min' _VALID_URL = r'''(?x) (?:https?://[^/]*?5min\.com/Scripts/PlayerSeed\.js\?(?:.*?&)?playList=| + https?://(?:(?:massively|www)\.)?joystiq\.com/video/| 5min:) (?P<id>\d+) ''' diff --git a/youtube_dl/extractor/gamekings.py b/youtube_dl/extractor/gamekings.py index cf8e90d..027f55e 100644 --- a/youtube_dl/extractor/gamekings.py +++ b/youtube_dl/extractor/gamekings.py @@ -1,41 +1,67 @@ +# coding: utf-8 from __future__ import unicode_literals -import re - from .common import InfoExtractor +from ..utils import ( + xpath_text, + xpath_with_ns, +) class GamekingsIE(InfoExtractor): - _VALID_URL = r'http://www\.gamekings\.tv/videos/(?P<name>[0-9a-z\-]+)' - _TEST = { + _VALID_URL = r'http://www\.gamekings\.tv/(?:videos|nieuws)/(?P<id>[^/]+)' + _TESTS = [{ 'url': 'http://www.gamekings.tv/videos/phoenix-wright-ace-attorney-dual-destinies-review/', # MD5 is flaky, seems to change regularly # 'md5': '2f32b1f7b80fdc5cb616efb4f387f8a3', 'info_dict': { - 'id': '20130811', + 'id': 'phoenix-wright-ace-attorney-dual-destinies-review', 'ext': 'mp4', 'title': 'Phoenix Wright: Ace Attorney \u2013 Dual Destinies Review', 'description': 'md5:36fd701e57e8c15ac8682a2374c99731', - } - } + 'thumbnail': 're:^https?://.*\.jpg$', + }, + }, { + # vimeo video + 'url': 'http://www.gamekings.tv/videos/the-legend-of-zelda-majoras-mask/', + 'md5': '12bf04dfd238e70058046937657ea68d', + 'info_dict': { + 'id': 'the-legend-of-zelda-majoras-mask', + 'ext': 'mp4', + 'title': 'The Legend of Zelda: Majora’s Mask', + 'description': 'md5:9917825fe0e9f4057601fe1e38860de3', + 'thumbnail': 're:^https?://.*\.jpg$', + }, + }, { + 'url': 'http://www.gamekings.tv/nieuws/gamekings-extra-shelly-en-david-bereiden-zich-voor-op-de-livestream/', + 'only_matching': True, + }] def _real_extract(self, url): + video_id = self._match_id(url) - mobj = re.match(self._VALID_URL, url) - name = mobj.group('name') - webpage = self._download_webpage(url, name) - video_url = self._og_search_video_url(webpage) + webpage = self._download_webpage(url, video_id) - video = re.search(r'[0-9]+', video_url) - video_id = video.group(0) + playlist_id = self._search_regex( + r'gogoVideo\(\s*\d+\s*,\s*"([^"]+)', webpage, 'playlist id') - # Todo: add medium format - video_url = video_url.replace(video_id, 'large/' + video_id) + playlist = self._download_xml( + 'http://www.gamekings.tv/wp-content/themes/gk2010/rss_playlist.php?id=%s' % playlist_id, + video_id) + + NS_MAP = { + 'jwplayer': 'http://rss.jwpcdn.com/' + } + + item = playlist.find('./channel/item') + + thumbnail = xpath_text(item, xpath_with_ns('./jwplayer:image', NS_MAP), 'thumbnail') + video_url = item.find(xpath_with_ns('./jwplayer:source', NS_MAP)).get('file') return { 'id': video_id, - 'ext': 'mp4', 'url': video_url, 'title': self._og_search_title(webpage), 'description': self._og_search_description(webpage), + 'thumbnail': thumbnail, } diff --git a/youtube_dl/extractor/gamestar.py b/youtube_dl/extractor/gamestar.py index 7591a15..590ccf5 100644 --- a/youtube_dl/extractor/gamestar.py +++ b/youtube_dl/extractor/gamestar.py @@ -1,6 +1,8 @@ # coding: utf-8 from __future__ import unicode_literals +import re + from .common import InfoExtractor from ..utils import ( int_or_none, @@ -31,7 +33,7 @@ class GameStarIE(InfoExtractor): webpage = self._download_webpage(url, video_id) og_title = self._og_search_title(webpage) - title = og_title.replace(' - Video bei GameStar.de', '').strip() + title = re.sub(r'\s*- Video (bei|-) GameStar\.de$', '', og_title) url = 'http://gamestar.de/_misc/videos/portal/getVideoUrl.cfm?premium=0&videoId=' + video_id diff --git a/youtube_dl/extractor/gdcvault.py b/youtube_dl/extractor/gdcvault.py index fed968f..f7b467b 100644 --- a/youtube_dl/extractor/gdcvault.py +++ b/youtube_dl/extractor/gdcvault.py @@ -7,6 +7,7 @@ from ..compat import ( compat_urllib_parse, compat_urllib_request, ) +from ..utils import remove_end class GDCVaultIE(InfoExtractor): @@ -65,10 +66,12 @@ class GDCVaultIE(InfoExtractor): def _parse_flv(self, xml_description): video_formats = [] - akami_url = xml_description.find('./metadata/akamaiHost').text + akamai_url = xml_description.find('./metadata/akamaiHost').text slide_video_path = xml_description.find('./metadata/slideVideo').text video_formats.append({ - 'url': 'rtmp://' + akami_url + '/' + slide_video_path, + 'url': 'rtmp://%s/ondemand?ovpfv=1.1' % akamai_url, + 'play_path': remove_end(slide_video_path, '.flv'), + 'ext': 'flv', 'format_note': 'slide deck video', 'quality': -2, 'preference': -2, @@ -76,7 +79,9 @@ class GDCVaultIE(InfoExtractor): }) speaker_video_path = xml_description.find('./metadata/speakerVideo').text video_formats.append({ - 'url': 'rtmp://' + akami_url + '/' + speaker_video_path, + 'url': 'rtmp://%s/ondemand?ovpfv=1.1' % akamai_url, + 'play_path': remove_end(speaker_video_path, '.flv'), + 'ext': 'flv', 'format_note': 'speaker video', 'quality': -1, 'preference': -1, diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index fbbc79a..27e2bc3 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -473,6 +473,7 @@ class GenericIE(InfoExtractor): { 'url': 'http://discourse.ubuntu.com/t/unity-8-desktop-mode-windows-on-mir/1986', 'info_dict': { + 'id': '1986', 'title': 'Unity 8 desktop-mode windows on Mir! - Ubuntu Discourse', }, 'playlist_mincount': 2, @@ -524,7 +525,50 @@ class GenericIE(InfoExtractor): 'upload_date': '20150126', }, 'add_ie': ['Viddler'], - } + }, + # jwplayer YouTube + { + 'url': 'http://media.nationalarchives.gov.uk/index.php/webinar-using-discovery-national-archives-online-catalogue/', + 'info_dict': { + 'id': 'Mrj4DVp2zeA', + 'ext': 'mp4', + 'upload_date': '20150212', + 'uploader': 'The National Archives UK', + 'description': 'md5:a236581cd2449dd2df4f93412f3f01c6', + 'uploader_id': 'NationalArchives08', + 'title': 'Webinar: Using Discovery, The National Archives’ online catalogue', + }, + }, + # rtl.nl embed + { + 'url': 'http://www.rtlnieuws.nl/nieuws/buitenland/aanslagen-kopenhagen', + 'playlist_mincount': 5, + 'info_dict': { + 'id': 'aanslagen-kopenhagen', + 'title': 'Aanslagen Kopenhagen | RTL Nieuws', + } + }, + # Zapiks embed + { + 'url': 'http://www.skipass.com/news/116090-bon-appetit-s5ep3-baqueira-mi-cor.html', + 'info_dict': { + 'id': '118046', + 'ext': 'mp4', + 'title': 'EP3S5 - Bon Appétit - Baqueira Mi Corazon !', + } + }, + # Kaltura embed + { + 'url': 'http://www.monumentalnetwork.com/videos/john-carlson-postgame-2-25-15', + 'info_dict': { + 'id': '1_eergr3h1', + 'ext': 'mp4', + 'upload_date': '20150226', + 'uploader_id': 'MonumentalSports-Kaltura@perfectsensedigital.com', + 'timestamp': int, + 'title': 'John Carlson Postgame 2/25/15', + }, + }, ] def report_following_redirect(self, new_url): @@ -769,6 +813,13 @@ class GenericIE(InfoExtractor): 'entries': entries, } + # Look for embedded rtl.nl player + matches = re.findall( + r'<iframe\s+(?:[a-zA-Z-]+="[^"]+"\s+)*?src="((?:https?:)?//(?:www\.)?rtl\.nl/system/videoplayer/[^"]+video_embed[^"]+)"', + webpage) + if matches: + return _playlist_from_matches(matches, ie='RtlNl') + # Look for embedded (iframe) Vimeo player mobj = re.search( r'<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//player\.vimeo\.com/video/.+?)\1', webpage) @@ -776,7 +827,6 @@ class GenericIE(InfoExtractor): player_url = unescapeHTML(mobj.group('url')) surl = smuggle_url(player_url, {'Referer': url}) return self.url_result(surl) - # Look for embedded (swf embed) Vimeo player mobj = re.search( r'<embed[^>]+?src="((?:https?:)?//(?:www\.)?vimeo\.com/moogaloop\.swf.+?)"', webpage) @@ -1034,7 +1084,12 @@ class GenericIE(InfoExtractor): # Look for embedded sbs.com.au player mobj = re.search( - r'<iframe[^>]+?src=(["\'])(?P<url>https?://(?:www\.)sbs\.com\.au/ondemand/video/single/.+?)\1', + r'''(?x) + (?: + <meta\s+property="og:video"\s+content=| + <iframe[^>]+?src= + ) + (["\'])(?P<url>https?://(?:www\.)?sbs\.com\.au/ondemand/video/.+?)\1''', webpage) if mobj is not None: return self.url_result(mobj.group('url'), 'SBS') @@ -1064,7 +1119,21 @@ class GenericIE(InfoExtractor): if mobj is not None: return self.url_result(mobj.group('url'), 'Livestream') + # Look for Zapiks embed + mobj = re.search( + r'<iframe[^>]+src="(?P<url>https?://(?:www\.)?zapiks\.fr/index\.php\?.+?)"', webpage) + if mobj is not None: + return self.url_result(mobj.group('url'), 'Zapiks') + + # Look for Kaltura embeds + mobj = re.search( + r"(?s)kWidget\.(?:thumb)?[Ee]mbed\(\{.*?'wid'\s*:\s*'_?(?P<partner_id>[^']+)',.*?'entry_id'\s*:\s*'(?P<id>[^']+)',", webpage) + if mobj is not None: + return self.url_result('kaltura:%(partner_id)s:%(id)s' % mobj.groupdict(), 'Kaltura') + def check_video(vurl): + if YoutubeIE.suitable(vurl): + return True vpath = compat_urlparse.urlparse(vurl).path vext = determine_ext(vpath) return '.' in vpath and vext not in ('swf', 'png', 'jpg', 'srt', 'sbv', 'sub', 'vtt', 'ttml') @@ -1082,7 +1151,8 @@ class GenericIE(InfoExtractor): JWPlayerOptions| jwplayer\s*\(\s*["'][^'"]+["']\s*\)\s*\.setup ) - .*?file\s*:\s*["\'](.*?)["\']''', webpage)) + .*? + ['"]?file['"]?\s*:\s*["\'](.*?)["\']''', webpage)) if not found: # Broaden the search a little bit found = filter_video(re.findall(r'[^A-Za-z0-9]?(?:file|source)=(http[^\'"&]*)', webpage)) @@ -1156,7 +1226,9 @@ class GenericIE(InfoExtractor): return entries[0] else: for num, e in enumerate(entries, start=1): - e['title'] = '%s (%d)' % (e['title'], num) + # 'url' results don't have a title + if e.get('title') is not None: + e['title'] = '%s (%d)' % (e['title'], num) return { '_type': 'playlist', 'entries': entries, diff --git a/youtube_dl/extractor/goshgay.py b/youtube_dl/extractor/goshgay.py index b116d25..1d91664 100644 --- a/youtube_dl/extractor/goshgay.py +++ b/youtube_dl/extractor/goshgay.py @@ -34,8 +34,6 @@ class GoshgayIE(InfoExtractor): duration = parse_duration(self._html_search_regex( r'<span class="duration">\s*-?\s*(.*?)</span>', webpage, 'duration', fatal=False)) - family_friendly = self._html_search_meta( - 'isFamilyFriendly', webpage, default='false') flashvars = compat_parse_qs(self._html_search_regex( r'<embed.+?id="flash-player-embed".+?flashvars="([^"]+)"', @@ -49,5 +47,5 @@ class GoshgayIE(InfoExtractor): 'title': title, 'thumbnail': thumbnail, 'duration': duration, - 'age_limit': 0 if family_friendly == 'true' else 18, + 'age_limit': self._family_friendly_search(webpage), } diff --git a/youtube_dl/extractor/history.py b/youtube_dl/extractor/history.py new file mode 100644 index 0000000..f86164a --- /dev/null +++ b/youtube_dl/extractor/history.py @@ -0,0 +1,31 @@ +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import smuggle_url + + +class HistoryIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?history\.com/(?:[^/]+/)+(?P<id>[^/]+?)(?:$|[?#])' + + _TESTS = [{ + 'url': 'http://www.history.com/topics/valentines-day/history-of-valentines-day/videos/bet-you-didnt-know-valentines-day?m=528e394da93ae&s=undefined&f=1&free=false', + 'md5': '6fe632d033c92aa10b8d4a9be047a7c5', + 'info_dict': { + 'id': 'bLx5Dv5Aka1G', + 'ext': 'mp4', + 'title': "Bet You Didn't Know: Valentine's Day", + 'description': 'md5:7b57ea4829b391995b405fa60bd7b5f7', + }, + 'add_ie': ['ThePlatform'], + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + + webpage = self._download_webpage(url, video_id) + + video_url = self._search_regex( + r'data-href="[^"]*/%s"[^>]+data-release-url="([^"]+)"' % video_id, + webpage, 'video url') + + return self.url_result(smuggle_url(video_url, {'sig': {'key': 'crazyjava', 'secret': 's3cr3t'}})) diff --git a/youtube_dl/extractor/ign.py b/youtube_dl/extractor/ign.py index 3db668c..3aade9e 100644 --- a/youtube_dl/extractor/ign.py +++ b/youtube_dl/extractor/ign.py @@ -34,6 +34,9 @@ class IGNIE(InfoExtractor): }, { 'url': 'http://me.ign.com/en/feature/15775/100-little-things-in-gta-5-that-will-blow-your-mind', + 'info_dict': { + 'id': '100-little-things-in-gta-5-that-will-blow-your-mind', + }, 'playlist': [ { 'info_dict': { diff --git a/youtube_dl/extractor/imgur.py b/youtube_dl/extractor/imgur.py new file mode 100644 index 0000000..fe5d95e --- /dev/null +++ b/youtube_dl/extractor/imgur.py @@ -0,0 +1,97 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + int_or_none, + js_to_json, + mimetype2ext, + ExtractorError, +) + + +class ImgurIE(InfoExtractor): + _VALID_URL = r'https?://(?:i\.)?imgur\.com/(?P<id>[a-zA-Z0-9]+)(?:\.mp4|\.gifv)?' + + _TESTS = [{ + 'url': 'https://i.imgur.com/A61SaA1.gifv', + 'info_dict': { + 'id': 'A61SaA1', + 'ext': 'mp4', + 'title': 're:Imgur GIF$|MRW gifv is up and running without any bugs$', + 'description': 're:The origin of the Internet\'s most viral images$|The Internet\'s visual storytelling community\. Explore, share, and discuss the best visual stories the Internet has to offer\.$', + }, + }, { + 'url': 'https://imgur.com/A61SaA1', + 'info_dict': { + 'id': 'A61SaA1', + 'ext': 'mp4', + 'title': 're:Imgur GIF$|MRW gifv is up and running without any bugs$', + 'description': 're:The origin of the Internet\'s most viral images$|The Internet\'s visual storytelling community\. Explore, share, and discuss the best visual stories the Internet has to offer\.$', + }, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + webpage = self._download_webpage(url, video_id) + + width = int_or_none(self._search_regex( + r'<param name="width" value="([0-9]+)"', + webpage, 'width', fatal=False)) + height = int_or_none(self._search_regex( + r'<param name="height" value="([0-9]+)"', + webpage, 'height', fatal=False)) + + video_elements = self._search_regex( + r'(?s)<div class="video-elements">(.*?)</div>', + webpage, 'video elements', default=None) + if not video_elements: + raise ExtractorError( + 'No sources found for video %s. Maybe an image?' % video_id, + expected=True) + + formats = [] + for m in re.finditer(r'<source\s+src="(?P<src>[^"]+)"\s+type="(?P<type>[^"]+)"', video_elements): + formats.append({ + 'format_id': m.group('type').partition('/')[2], + 'url': self._proto_relative_url(m.group('src')), + 'ext': mimetype2ext(m.group('type')), + 'acodec': 'none', + 'width': width, + 'height': height, + 'http_headers': { + 'User-Agent': 'youtube-dl (like wget)', + }, + }) + + gif_json = self._search_regex( + r'(?s)var\s+videoItem\s*=\s*(\{.*?\})', + webpage, 'GIF code', fatal=False) + if gif_json: + gifd = self._parse_json( + gif_json, video_id, transform_source=js_to_json) + formats.append({ + 'format_id': 'gif', + 'preference': -10, + 'width': width, + 'height': height, + 'ext': 'gif', + 'acodec': 'none', + 'vcodec': 'gif', + 'container': 'gif', + 'url': self._proto_relative_url(gifd['gifUrl']), + 'filesize': gifd.get('size'), + 'http_headers': { + 'User-Agent': 'youtube-dl (like wget)', + }, + }) + + self._sort_formats(formats) + + return { + 'id': video_id, + 'formats': formats, + 'description': self._og_search_description(webpage), + 'title': self._og_search_title(webpage), + } diff --git a/youtube_dl/extractor/izlesene.py b/youtube_dl/extractor/izlesene.py index d16d483..99a1361 100644 --- a/youtube_dl/extractor/izlesene.py +++ b/youtube_dl/extractor/izlesene.py @@ -80,9 +80,6 @@ class IzleseneIE(InfoExtractor): r'comment_count\s*=\s*\'([^\']+)\';', webpage, 'comment_count', fatal=False) - family_friendly = self._html_search_meta( - 'isFamilyFriendly', webpage, 'age limit', fatal=False) - content_url = self._html_search_meta( 'contentURL', webpage, 'content URL', fatal=False) ext = determine_ext(content_url, 'mp4') @@ -120,6 +117,6 @@ class IzleseneIE(InfoExtractor): 'duration': duration, 'view_count': int_or_none(view_count), 'comment_count': int_or_none(comment_count), - 'age_limit': 18 if family_friendly == 'False' else 0, + 'age_limit': self._family_friendly_search(webpage), 'formats': formats, } diff --git a/youtube_dl/extractor/kaltura.py b/youtube_dl/extractor/kaltura.py new file mode 100644 index 0000000..d287304 --- /dev/null +++ b/youtube_dl/extractor/kaltura.py @@ -0,0 +1,138 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..compat import compat_urllib_parse +from ..utils import ( + ExtractorError, + int_or_none, +) + + +class KalturaIE(InfoExtractor): + _VALID_URL = r'''(?x) + (?:kaltura:| + https?://(:?(?:www|cdnapisec)\.)?kaltura\.com/index\.php/kwidget/(?:[^/]+/)*?wid/_ + )(?P<partner_id>\d+) + (?::| + /(?:[^/]+/)*?entry_id/ + )(?P<id>[0-9a-z_]+)''' + _API_BASE = 'http://cdnapi.kaltura.com/api_v3/index.php?' + _TESTS = [ + { + 'url': 'kaltura:269692:1_1jc2y3e4', + 'md5': '3adcbdb3dcc02d647539e53f284ba171', + 'info_dict': { + 'id': '1_1jc2y3e4', + 'ext': 'mp4', + 'title': 'Track 4', + 'upload_date': '20131219', + 'uploader_id': 'mlundberg@wolfgangsvault.com', + 'description': 'The Allman Brothers Band, 12/16/1981', + 'thumbnail': 're:^https?://.*/thumbnail/.*', + 'timestamp': int, + }, + }, + { + 'url': 'http://www.kaltura.com/index.php/kwidget/cache_st/1300318621/wid/_269692/uiconf_id/3873291/entry_id/1_1jc2y3e4', + 'only_matching': True, + }, + { + 'url': 'https://cdnapisec.kaltura.com/index.php/kwidget/wid/_557781/uiconf_id/22845202/entry_id/1_plr1syf3', + 'only_matching': True, + }, + ] + + def _kaltura_api_call(self, video_id, actions, *args, **kwargs): + params = actions[0] + if len(actions) > 1: + for i, a in enumerate(actions[1:], start=1): + for k, v in a.items(): + params['%d:%s' % (i, k)] = v + + query = compat_urllib_parse.urlencode(params) + url = self._API_BASE + query + data = self._download_json(url, video_id, *args, **kwargs) + + status = data if len(actions) == 1 else data[0] + if status.get('objectType') == 'KalturaAPIException': + raise ExtractorError( + '%s said: %s' % (self.IE_NAME, status['message'])) + + return data + + def _get_kaltura_signature(self, video_id, partner_id): + actions = [{ + 'apiVersion': '3.1', + 'expiry': 86400, + 'format': 1, + 'service': 'session', + 'action': 'startWidgetSession', + 'widgetId': '_%s' % partner_id, + }] + return self._kaltura_api_call( + video_id, actions, note='Downloading Kaltura signature')['ks'] + + def _get_video_info(self, video_id, partner_id): + signature = self._get_kaltura_signature(video_id, partner_id) + actions = [ + { + 'action': 'null', + 'apiVersion': '3.1.5', + 'clientTag': 'kdp:v3.8.5', + 'format': 1, # JSON, 2 = XML, 3 = PHP + 'service': 'multirequest', + 'ks': signature, + }, + { + 'action': 'get', + 'entryId': video_id, + 'service': 'baseentry', + 'version': '-1', + }, + { + 'action': 'getContextData', + 'contextDataParams:objectType': 'KalturaEntryContextDataParams', + 'contextDataParams:referrer': 'http://www.kaltura.com/', + 'contextDataParams:streamerType': 'http', + 'entryId': video_id, + 'service': 'baseentry', + }, + ] + return self._kaltura_api_call( + video_id, actions, note='Downloading video info JSON') + + def _real_extract(self, url): + video_id = self._match_id(url) + mobj = re.match(self._VALID_URL, url) + partner_id, entry_id = mobj.group('partner_id'), mobj.group('id') + + info, source_data = self._get_video_info(entry_id, partner_id) + + formats = [{ + 'format_id': '%(fileExt)s-%(bitrate)s' % f, + 'ext': f['fileExt'], + 'tbr': f['bitrate'], + 'fps': f.get('frameRate'), + 'filesize_approx': int_or_none(f.get('size'), invscale=1024), + 'container': f.get('containerFormat'), + 'vcodec': f.get('videoCodecId'), + 'height': f.get('height'), + 'width': f.get('width'), + 'url': '%s/flavorId/%s' % (info['dataUrl'], f['id']), + } for f in source_data['flavorAssets']] + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': info['name'], + 'formats': formats, + 'description': info.get('description'), + 'thumbnail': info.get('thumbnailUrl'), + 'duration': info.get('duration'), + 'timestamp': info.get('createdAt'), + 'uploader_id': info.get('userId'), + 'view_count': info.get('plays'), + } diff --git a/youtube_dl/extractor/laola1tv.py b/youtube_dl/extractor/laola1tv.py index 2fd3b46..b459559 100644 --- a/youtube_dl/extractor/laola1tv.py +++ b/youtube_dl/extractor/laola1tv.py @@ -1,31 +1,32 @@ +# -*- coding: utf-8 -*- from __future__ import unicode_literals import random import re from .common import InfoExtractor -from ..utils import ExtractorError +from ..utils import ( + ExtractorError, + xpath_text, +) class Laola1TvIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?laola1\.tv/(?P<lang>[a-z]+)-(?P<portal>[a-z]+)/.*?/(?P<id>[0-9]+)\.html' _TEST = { - 'url': 'http://www.laola1.tv/de-de/live/bwf-bitburger-open-grand-prix-gold-court-1/250019.html', + 'url': 'http://www.laola1.tv/de-de/video/straubing-tigers-koelner-haie/227883.html', 'info_dict': { - 'id': '250019', + 'id': '227883', 'ext': 'mp4', - 'title': 'Bitburger Open Grand Prix Gold - Court 1', - 'categories': ['Badminton'], - 'uploader': 'BWF - Badminton World Federation', - 'is_live': True, + 'title': 'Straubing Tigers - Kölner Haie', + 'categories': ['Eishockey'], + 'is_live': False, }, 'params': { 'skip_download': True, } } - _BROKEN = True # Not really - extractor works fine, but f4m downloader does not support live streams yet. - def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) video_id = mobj.group('id') @@ -43,15 +44,22 @@ class Laola1TvIE(InfoExtractor): r'flashvars\.([_a-zA-Z0-9]+)\s*=\s*"([^"]*)";', iframe) flashvars = dict((m[0], m[1]) for m in flashvars_m) + partner_id = self._search_regex( + r'partnerid\s*:\s*"([^"]+)"', iframe, 'partner id') + xml_url = ('http://www.laola1.tv/server/hd_video.php?' + - 'play=%s&partner=1&portal=%s&v5ident=&lang=%s' % ( - video_id, portal, lang)) + 'play=%s&partner=%s&portal=%s&v5ident=&lang=%s' % ( + video_id, partner_id, portal, lang)) hd_doc = self._download_xml(xml_url, video_id) - title = hd_doc.find('.//video/title').text - flash_url = hd_doc.find('.//video/url').text - categories = hd_doc.find('.//video/meta_sports').text.split(',') - uploader = hd_doc.find('.//video/meta_organistation').text + title = xpath_text(hd_doc, './/video/title', fatal=True) + flash_url = xpath_text(hd_doc, './/video/url', fatal=True) + uploader = xpath_text(hd_doc, './/video/meta_organistation') + is_live = xpath_text(hd_doc, './/video/islive') == 'true' + + categories = xpath_text(hd_doc, './/video/meta_sports') + if categories: + categories = categories.split(',') ident = random.randint(10000000, 99999999) token_url = '%s&ident=%s&klub=0&unikey=0×tamp=%s&auth=%s' % ( @@ -60,15 +68,16 @@ class Laola1TvIE(InfoExtractor): token_doc = self._download_xml( token_url, video_id, note='Downloading token') token_attrib = token_doc.find('.//token').attrib - if token_attrib.get('auth') == 'blocked': - raise ExtractorError('Token error: ' % token_attrib.get('comment')) + if token_attrib.get('auth') in ('blocked', 'restricted'): + raise ExtractorError( + 'Token error: %s' % token_attrib.get('comment'), expected=True) video_url = '%s?hdnea=%s&hdcore=3.2.0' % ( token_attrib['url'], token_attrib['auth']) return { 'id': video_id, - 'is_live': True, + 'is_live': is_live, 'title': title, 'url': video_url, 'uploader': uploader, diff --git a/youtube_dl/extractor/letv.py b/youtube_dl/extractor/letv.py new file mode 100644 index 0000000..583ce35 --- /dev/null +++ b/youtube_dl/extractor/letv.py @@ -0,0 +1,190 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import datetime +import re +import time + +from .common import InfoExtractor +from ..compat import ( + compat_urlparse, + compat_urllib_parse, +) +from ..utils import ( + determine_ext, + ExtractorError, + parse_iso8601, +) + + +class LetvIE(InfoExtractor): + _VALID_URL = r'http://www\.letv\.com/ptv/vplay/(?P<id>\d+).html' + + _TESTS = [{ + 'url': 'http://www.letv.com/ptv/vplay/22005890.html', + 'md5': 'cab23bd68d5a8db9be31c9a222c1e8df', + 'info_dict': { + 'id': '22005890', + 'ext': 'mp4', + 'title': '第87届奥斯卡颁奖礼完美落幕 《鸟人》成最大赢家', + 'timestamp': 1424747397, + 'upload_date': '20150224', + 'description': 'md5:a9cb175fd753e2962176b7beca21a47c', + } + }, { + 'url': 'http://www.letv.com/ptv/vplay/1415246.html', + 'info_dict': { + 'id': '1415246', + 'ext': 'mp4', + 'title': '美人天下01', + 'description': 'md5:f88573d9d7225ada1359eaf0dbf8bcda', + }, + 'expected_warnings': [ + 'publish time' + ] + }] + # http://www.letv.com/ptv/vplay/1118082.html + # This video is available only in Mainland China + + @staticmethod + def urshift(val, n): + return val >> n if val >= 0 else (val + 0x100000000) >> n + + # ror() and calc_time_key() are reversed from a embedded swf file in KLetvPlayer.swf + def ror(self, param1, param2): + _loc3_ = 0 + while _loc3_ < param2: + param1 = self.urshift(param1, 1) + ((param1 & 1) << 31) + _loc3_ += 1 + return param1 + + def calc_time_key(self, param1): + _loc2_ = 773625421 + _loc3_ = self.ror(param1, _loc2_ % 13) + _loc3_ = _loc3_ ^ _loc2_ + _loc3_ = self.ror(_loc3_, _loc2_ % 17) + return _loc3_ + + def _real_extract(self, url): + media_id = self._match_id(url) + page = self._download_webpage(url, media_id) + params = { + 'id': media_id, + 'platid': 1, + 'splatid': 101, + 'format': 1, + 'tkey': self.calc_time_key(int(time.time())), + 'domain': 'www.letv.com' + } + play_json = self._download_json( + 'http://api.letv.com/mms/out/video/playJson?' + compat_urllib_parse.urlencode(params), + media_id, 'playJson data') + + # Check for errors + playstatus = play_json['playstatus'] + if playstatus['status'] == 0: + flag = playstatus['flag'] + if flag == 1: + msg = 'Country %s auth error' % playstatus['country'] + else: + msg = 'Generic error. flag = %d' % flag + raise ExtractorError(msg, expected=True) + + playurl = play_json['playurl'] + + formats = ['350', '1000', '1300', '720p', '1080p'] + dispatch = playurl['dispatch'] + + urls = [] + for format_id in formats: + if format_id in dispatch: + media_url = playurl['domain'][0] + dispatch[format_id][0] + + # Mimic what flvxz.com do + url_parts = list(compat_urlparse.urlparse(media_url)) + qs = dict(compat_urlparse.parse_qs(url_parts[4])) + qs.update({ + 'platid': '14', + 'splatid': '1401', + 'tss': 'no', + 'retry': 1 + }) + url_parts[4] = compat_urllib_parse.urlencode(qs) + media_url = compat_urlparse.urlunparse(url_parts) + + url_info_dict = { + 'url': media_url, + 'ext': determine_ext(dispatch[format_id][1]) + } + + if format_id[-1:] == 'p': + url_info_dict['height'] = format_id[:-1] + + urls.append(url_info_dict) + + publish_time = parse_iso8601(self._html_search_regex( + r'发布时间 ([^<>]+) ', page, 'publish time', fatal=False), + delimiter=' ', timezone=datetime.timedelta(hours=8)) + description = self._html_search_meta('description', page, fatal=False) + + return { + 'id': media_id, + 'formats': urls, + 'title': playurl['title'], + 'thumbnail': playurl['pic'], + 'description': description, + 'timestamp': publish_time, + } + + +class LetvTvIE(InfoExtractor): + _VALID_URL = r'http://www.letv.com/tv/(?P<id>\d+).html' + _TESTS = [{ + 'url': 'http://www.letv.com/tv/46177.html', + 'info_dict': { + 'id': '46177', + 'title': '美人天下', + 'description': 'md5:395666ff41b44080396e59570dbac01c' + }, + 'playlist_count': 35 + }] + + def _real_extract(self, url): + playlist_id = self._match_id(url) + page = self._download_webpage(url, playlist_id) + + media_urls = list(set(re.findall( + r'http://www.letv.com/ptv/vplay/\d+.html', page))) + entries = [self.url_result(media_url, ie='Letv') + for media_url in media_urls] + + title = self._html_search_meta('keywords', page, + fatal=False).split(',')[0] + description = self._html_search_meta('description', page, fatal=False) + + return self.playlist_result(entries, playlist_id, playlist_title=title, + playlist_description=description) + + +class LetvPlaylistIE(LetvTvIE): + _VALID_URL = r'http://tv.letv.com/[a-z]+/(?P<id>[a-z]+)/index.s?html' + _TESTS = [{ + 'url': 'http://tv.letv.com/izt/wuzetian/index.html', + 'info_dict': { + 'id': 'wuzetian', + 'title': '武媚娘传奇', + 'description': 'md5:e12499475ab3d50219e5bba00b3cb248' + }, + # This playlist contains some extra videos other than the drama itself + 'playlist_mincount': 96 + }, { + 'url': 'http://tv.letv.com/pzt/lswjzzjc/index.shtml', + 'info_dict': { + 'id': 'lswjzzjc', + # The title should be "劲舞青春", but I can't find a simple way to + # determine the playlist title + 'title': '乐视午间自制剧场', + 'description': 'md5:b1eef244f45589a7b5b1af9ff25a4489' + }, + 'playlist_mincount': 7 + }] diff --git a/youtube_dl/extractor/livestream.py b/youtube_dl/extractor/livestream.py index 5247c6f..3642089 100644 --- a/youtube_dl/extractor/livestream.py +++ b/youtube_dl/extractor/livestream.py @@ -37,6 +37,7 @@ class LivestreamIE(InfoExtractor): 'url': 'http://new.livestream.com/tedx/cityenglish', 'info_dict': { 'title': 'TEDCity2.0 (English)', + 'id': '2245590', }, 'playlist_mincount': 4, }, { @@ -148,7 +149,8 @@ class LivestreamIE(InfoExtractor): if is_relevant(video_data, video_id)] if video_id is None: # This is an event page: - return self.playlist_result(videos, info['id'], info['full_name']) + return self.playlist_result( + videos, '%s' % info['id'], info['full_name']) else: if not videos: raise ExtractorError('Cannot find video %s' % video_id) diff --git a/youtube_dl/extractor/lynda.py b/youtube_dl/extractor/lynda.py index 762cefa..5dc22da 100644 --- a/youtube_dl/extractor/lynda.py +++ b/youtube_dl/extractor/lynda.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import re import json -from .subtitles import SubtitlesInfoExtractor from .common import InfoExtractor from ..compat import ( compat_str, @@ -16,10 +15,10 @@ from ..utils import ( ) -class LyndaIE(SubtitlesInfoExtractor): +class LyndaIE(InfoExtractor): IE_NAME = 'lynda' IE_DESC = 'lynda.com videos' - _VALID_URL = r'https?://www\.lynda\.com/[^/]+/[^/]+/\d+/(\d+)-\d\.html' + _VALID_URL = r'https?://www\.lynda\.com/(?:[^/]+/[^/]+/\d+|player/embed)/(\d+)' _LOGIN_URL = 'https://www.lynda.com/login/login.aspx' _NETRC_MACHINE = 'lynda' @@ -28,7 +27,7 @@ class LyndaIE(SubtitlesInfoExtractor): ACCOUNT_CREDENTIALS_HINT = 'Use --username and --password options to provide lynda.com account credentials.' - _TEST = { + _TESTS = [{ 'url': 'http://www.lynda.com/Bootstrap-tutorials/Using-exercise-files/110885/114408-4.html', 'md5': 'ecfc6862da89489161fb9cd5f5a6fac1', 'info_dict': { @@ -37,7 +36,10 @@ class LyndaIE(SubtitlesInfoExtractor): 'title': 'Using the exercise files', 'duration': 68 } - } + }, { + 'url': 'https://www.lynda.com/player/embed/133770?tr=foo=1;bar=g;fizz=rt&fs=0', + 'only_matching': True, + }] def _real_initialize(self): self._login() @@ -88,11 +90,7 @@ class LyndaIE(SubtitlesInfoExtractor): self._check_formats(formats, video_id) self._sort_formats(formats) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, page) - return - - subtitles = self._fix_subtitles(self.extract_subtitles(video_id, page)) + subtitles = self.extract_subtitles(video_id, page) return { 'id': video_id, @@ -144,38 +142,31 @@ class LyndaIE(SubtitlesInfoExtractor): if re.search(self._SUCCESSFUL_LOGIN_REGEX, login_page) is None: raise ExtractorError('Unable to log in') - def _fix_subtitles(self, subtitles): - if subtitles is None: - return subtitles # subtitles not requested - - fixed_subtitles = {} - for k, v in subtitles.items(): - subs = json.loads(v) - if len(subs) == 0: + def _fix_subtitles(self, subs): + srt = '' + for pos in range(0, len(subs) - 1): + seq_current = subs[pos] + m_current = re.match(self._TIMECODE_REGEX, seq_current['Timecode']) + if m_current is None: continue - srt = '' - for pos in range(0, len(subs) - 1): - seq_current = subs[pos] - m_current = re.match(self._TIMECODE_REGEX, seq_current['Timecode']) - if m_current is None: - continue - seq_next = subs[pos + 1] - m_next = re.match(self._TIMECODE_REGEX, seq_next['Timecode']) - if m_next is None: - continue - appear_time = m_current.group('timecode') - disappear_time = m_next.group('timecode') - text = seq_current['Caption'] - srt += '%s\r\n%s --> %s\r\n%s' % (str(pos), appear_time, disappear_time, text) - if srt: - fixed_subtitles[k] = srt - return fixed_subtitles - - def _get_available_subtitles(self, video_id, webpage): + seq_next = subs[pos + 1] + m_next = re.match(self._TIMECODE_REGEX, seq_next['Timecode']) + if m_next is None: + continue + appear_time = m_current.group('timecode') + disappear_time = m_next.group('timecode') + text = seq_current['Caption'].lstrip() + srt += '%s\r\n%s --> %s\r\n%s' % (str(pos), appear_time, disappear_time, text) + if srt: + return srt + + def _get_subtitles(self, video_id, webpage): url = 'http://www.lynda.com/ajax/player?videoId=%s&type=transcript' % video_id - sub = self._download_webpage(url, None, False) - sub_json = json.loads(sub) - return {'en': url} if len(sub_json) > 0 else {} + subs = self._download_json(url, None, False) + if subs: + return {'en': [{'ext': 'srt', 'data': self._fix_subtitles(subs)}]} + else: + return {} class LyndaCourseIE(InfoExtractor): diff --git a/youtube_dl/extractor/mit.py b/youtube_dl/extractor/mit.py index 3c61a85..d7ab6a9 100644 --- a/youtube_dl/extractor/mit.py +++ b/youtube_dl/extractor/mit.py @@ -5,9 +5,6 @@ import json from .common import InfoExtractor from .youtube import YoutubeIE -from ..compat import ( - compat_urlparse, -) from ..utils import ( clean_html, ExtractorError, @@ -108,7 +105,6 @@ class OCWMITIE(InfoExtractor): 'upload_date': '20121109', 'uploader_id': 'MIT', 'uploader': 'MIT OpenCourseWare', - # 'subtitles': 'http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-041-probabilistic-systems-analysis-and-applied-probability-fall-2010/video-lectures/lecture-7-multiple-variables-expectations-independence/MIT6_041F11_lec07_300k.mp4.srt' } }, { @@ -121,7 +117,6 @@ class OCWMITIE(InfoExtractor): 'uploader_id': 'MIT', 'uploader': 'MIT OpenCourseWare', 'description': 'This section contains lecture video excerpts, lecture notes, an interactive mathlet with supporting documents, and problem solving videos.', - # 'subtitles': 'http://ocw.mit.edu//courses/mathematics/18-01sc-single-variable-calculus-fall-2010/ocw-18.01-f07-lec01_300k.SRT' } } ] @@ -140,7 +135,6 @@ class OCWMITIE(InfoExtractor): metadata = re.sub(r'[\'"]', '', embed_chapter_media.group(1)) metadata = re.split(r', ?', metadata) yt = metadata[1] - subs = compat_urlparse.urljoin(self._BASE_URL, metadata[7]) else: # search for call to ocw_embed_chapter_media(container_id, media_url, provider, page_url, image_url, captions_file) embed_media = re.search(r'ocw_embed_media\((.+?)\)', webpage) @@ -148,7 +142,6 @@ class OCWMITIE(InfoExtractor): metadata = re.sub(r'[\'"]', '', embed_media.group(1)) metadata = re.split(r', ?', metadata) yt = metadata[1] - subs = compat_urlparse.urljoin(self._BASE_URL, metadata[5]) else: raise ExtractorError('Unable to find embedded YouTube video.') video_id = YoutubeIE.extract_id(yt) @@ -159,7 +152,5 @@ class OCWMITIE(InfoExtractor): 'title': title, 'description': description, 'url': yt, - 'url_transparent' - 'subtitles': subs, 'ie_key': 'Youtube', } diff --git a/youtube_dl/extractor/mitele.py b/youtube_dl/extractor/mitele.py index 2567583..d8897eb 100644 --- a/youtube_dl/extractor/mitele.py +++ b/youtube_dl/extractor/mitele.py @@ -18,7 +18,7 @@ class MiTeleIE(InfoExtractor): IE_NAME = 'mitele.es' _VALID_URL = r'http://www\.mitele\.es/[^/]+/[^/]+/[^/]+/(?P<id>[^/]+)/' - _TEST = { + _TESTS = [{ 'url': 'http://www.mitele.es/programas-tv/diario-de/la-redaccion/programa-144/', 'md5': '6a75fe9d0d3275bead0cb683c616fddb', 'info_dict': { @@ -29,7 +29,7 @@ class MiTeleIE(InfoExtractor): 'display_id': 'programa-144', 'duration': 2913, }, - } + }] def _real_extract(self, url): episode = self._match_id(url) diff --git a/youtube_dl/extractor/mpora.py b/youtube_dl/extractor/mpora.py index 6db3c67..5a1bee5 100644 --- a/youtube_dl/extractor/mpora.py +++ b/youtube_dl/extractor/mpora.py @@ -5,7 +5,7 @@ from ..utils import int_or_none class MporaIE(InfoExtractor): - _VALID_URL = r'https?://(www\.)?mpora\.(?:com|de)/videos/(?P<id>[^?#/]+)' + _VALID_URL = r'https?://(?:www\.)?mpora\.(?:com|de)/videos/(?P<id>[^?#/]+)' IE_NAME = 'MPORA' _TEST = { @@ -25,7 +25,9 @@ class MporaIE(InfoExtractor): webpage = self._download_webpage(url, video_id) data_json = self._search_regex( - r"new FM\.Player\('[^']+',\s*(\{.*?)\).player;", webpage, 'json') + [r"new FM\.Player\('[^']+',\s*(\{.*?)\).player;", + r"new\s+FM\.Kaltura\.Player\('[^']+'\s*,\s*({.+?})\);"], + webpage, 'json') data = self._parse_json(data_json, video_id) uploader = data['info_overlay'].get('username') diff --git a/youtube_dl/extractor/mtv.py b/youtube_dl/extractor/mtv.py index bc7f49e..c11de1c 100644 --- a/youtube_dl/extractor/mtv.py +++ b/youtube_dl/extractor/mtv.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import re -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..compat import ( compat_urllib_parse, compat_urllib_request, @@ -23,7 +23,7 @@ def _media_xml_tag(tag): return '{http://search.yahoo.com/mrss/}%s' % tag -class MTVServicesInfoExtractor(SubtitlesInfoExtractor): +class MTVServicesInfoExtractor(InfoExtractor): _MOBILE_TEMPLATE = None @staticmethod @@ -95,25 +95,15 @@ class MTVServicesInfoExtractor(SubtitlesInfoExtractor): def _extract_subtitles(self, mdoc, mtvn_id): subtitles = {} - FORMATS = { - 'scc': 'cea-608', - 'eia-608': 'cea-608', - 'xml': 'ttml', - } - subtitles_format = FORMATS.get( - self._downloader.params.get('subtitlesformat'), 'ttml') for transcript in mdoc.findall('.//transcript'): if transcript.get('kind') != 'captions': continue lang = transcript.get('srclang') - for typographic in transcript.findall('./typographic'): - captions_format = typographic.get('format') - if captions_format == subtitles_format: - subtitles[lang] = compat_str(typographic.get('src')) - break - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(mtvn_id, subtitles) - return self.extract_subtitles(mtvn_id, subtitles) + subtitles[lang] = [{ + 'url': compat_str(typographic.get('src')), + 'ext': typographic.get('format') + } for typographic in transcript.findall('./typographic')] + return subtitles def _get_video_info(self, itemdoc): uri = itemdoc.find('guid').text @@ -196,8 +186,6 @@ class MTVServicesInfoExtractor(SubtitlesInfoExtractor): webpage, 'mgid') videos_info = self._get_videos_info(mgid) - if self._downloader.params.get('listsubtitles', False): - return return videos_info diff --git a/youtube_dl/extractor/musicvault.py b/youtube_dl/extractor/musicvault.py index ebb1eb8..0e46ac7 100644 --- a/youtube_dl/extractor/musicvault.py +++ b/youtube_dl/extractor/musicvault.py @@ -3,17 +3,13 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from ..utils import ( - parse_duration, - unified_strdate, -) class MusicVaultIE(InfoExtractor): _VALID_URL = r'https?://www\.musicvault\.com/(?P<uploader_id>[^/?#]*)/video/(?P<display_id>[^/?#]*)_(?P<id>[0-9]+)\.html' _TEST = { 'url': 'http://www.musicvault.com/the-allman-brothers-band/video/straight-from-the-heart_1010863.html', - 'md5': '2cdbb3ae75f7fb3519821507d2fb3c15', + 'md5': '3adcbdb3dcc02d647539e53f284ba171', 'info_dict': { 'id': '1010863', 'ext': 'mp4', @@ -22,9 +18,10 @@ class MusicVaultIE(InfoExtractor): 'duration': 244, 'uploader': 'The Allman Brothers Band', 'thumbnail': 're:^https?://.*/thumbnail/.*', - 'upload_date': '19811216', + 'upload_date': '20131219', 'location': 'Capitol Theatre (Passaic, NJ)', 'description': 'Listen to The Allman Brothers Band perform Straight from the Heart at Capitol Theatre (Passaic, NJ) on Dec 16, 1981', + 'timestamp': int, } } @@ -43,34 +40,24 @@ class MusicVaultIE(InfoExtractor): r'<h1.*?>(.*?)</h1>', data_div, 'uploader', fatal=False) title = self._html_search_regex( r'<h2.*?>(.*?)</h2>', data_div, 'title') - upload_date = unified_strdate(self._html_search_regex( - r'<h3.*?>(.*?)</h3>', data_div, 'uploader', fatal=False)) location = self._html_search_regex( r'<h4.*?>(.*?)</h4>', data_div, 'location', fatal=False) - duration = parse_duration(self._html_search_meta('duration', webpage)) - - VIDEO_URL_TEMPLATE = 'http://cdnapi.kaltura.com/p/%(uid)s/sp/%(wid)s/playManifest/entryId/%(entry_id)s/format/url/protocol/http' kaltura_id = self._search_regex( r'<div id="video-detail-player" data-kaltura-id="([^"]+)"', webpage, 'kaltura ID') - video_url = VIDEO_URL_TEMPLATE % { - 'entry_id': kaltura_id, - 'wid': self._search_regex(r'/wid/_([0-9]+)/', webpage, 'wid'), - 'uid': self._search_regex(r'uiconf_id/([0-9]+)/', webpage, 'uid'), - } + wid = self._search_regex(r'/wid/_([0-9]+)/', webpage, 'wid') return { 'id': mobj.group('id'), - 'url': video_url, - 'ext': 'mp4', + '_type': 'url_transparent', + 'url': 'kaltura:%s:%s' % (wid, kaltura_id), + 'ie_key': 'Kaltura', 'display_id': display_id, 'uploader_id': mobj.group('uploader_id'), 'thumbnail': thumbnail, 'description': self._html_search_meta('description', webpage), - 'upload_date': upload_date, 'location': location, 'title': title, 'uploader': uploader, - 'duration': duration, } diff --git a/youtube_dl/extractor/nationalgeographic.py b/youtube_dl/extractor/nationalgeographic.py new file mode 100644 index 0000000..c18640c --- /dev/null +++ b/youtube_dl/extractor/nationalgeographic.py @@ -0,0 +1,38 @@ +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + smuggle_url, + url_basename, +) + + +class NationalGeographicIE(InfoExtractor): + _VALID_URL = r'http://video\.nationalgeographic\.com/video/.*?' + + _TEST = { + 'url': 'http://video.nationalgeographic.com/video/news/150210-news-crab-mating-vin?source=featuredvideo', + 'info_dict': { + 'id': '4DmDACA6Qtk_', + 'ext': 'flv', + 'title': 'Mating Crabs Busted by Sharks', + 'description': 'md5:16f25aeffdeba55aaa8ec37e093ad8b3', + }, + 'add_ie': ['ThePlatform'], + } + + def _real_extract(self, url): + name = url_basename(url) + + webpage = self._download_webpage(url, name) + feed_url = self._search_regex(r'data-feed-url="([^"]+)"', webpage, 'feed url') + guid = self._search_regex(r'data-video-guid="([^"]+)"', webpage, 'guid') + + feed = self._download_xml('%s?byGuid=%s' % (feed_url, guid), name) + content = feed.find('.//{http://search.yahoo.com/mrss/}content') + theplatform_id = url_basename(content.attrib.get('url')) + + return self.url_result(smuggle_url( + 'http://link.theplatform.com/s/ngs/%s?format=SMIL&formats=MPEG4&manifest=f4m' % theplatform_id, + # For some reason, the normal links don't work and we must force the use of f4m + {'force_smil_url': True})) diff --git a/youtube_dl/extractor/nbc.py b/youtube_dl/extractor/nbc.py index f840f65..3645d30 100644 --- a/youtube_dl/extractor/nbc.py +++ b/youtube_dl/extractor/nbc.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import re -import json from .common import InfoExtractor from ..compat import ( @@ -19,13 +18,13 @@ class NBCIE(InfoExtractor): _TESTS = [ { - 'url': 'http://www.nbc.com/chicago-fire/video/i-am-a-firefighter/2734188', + 'url': 'http://www.nbc.com/the-tonight-show/segments/112966', # md5 checksum is not stable 'info_dict': { - 'id': 'bTmnLCvIbaaH', + 'id': 'c9xnCo0YPOPH', 'ext': 'flv', - 'title': 'I Am a Firefighter', - 'description': 'An emergency puts Dawson\'sf irefighter skills to the ultimate test in this four-part digital series.', + 'title': 'Jimmy Fallon Surprises Fans at Ben & Jerry\'s', + 'description': 'Jimmy gives out free scoops of his new "Tonight Dough" ice cream flavor by surprising customers at the Ben & Jerry\'s scoop shop.', }, }, { @@ -52,9 +51,9 @@ class NBCIE(InfoExtractor): class NBCNewsIE(InfoExtractor): - _VALID_URL = r'''(?x)https?://www\.nbcnews\.com/ - ((video/.+?/(?P<id>\d+))| - (feature/[^/]+/(?P<title>.+))) + _VALID_URL = r'''(?x)https?://(?:www\.)?nbcnews\.com/ + (?:video/.+?/(?P<id>\d+)| + (?:feature|nightly-news)/[^/]+/(?P<title>.+)) ''' _TESTS = [ @@ -89,6 +88,16 @@ class NBCNewsIE(InfoExtractor): 'description': 'md5:757988edbaae9d7be1d585eb5d55cc04', }, }, + { + 'url': 'http://www.nbcnews.com/nightly-news/video/nightly-news-with-brian-williams-full-broadcast-february-4-394064451844', + 'md5': 'b5dda8cddd8650baa0dcb616dd2cf60d', + 'info_dict': { + 'id': 'sekXqyTVnmN3', + 'ext': 'mp4', + 'title': 'Nightly News with Brian Williams Full Broadcast (February 4)', + 'description': 'md5:1c10c1eccbe84a26e5debb4381e2d3c5', + }, + }, ] def _real_extract(self, url): @@ -107,13 +116,13 @@ class NBCNewsIE(InfoExtractor): 'thumbnail': find_xpath_attr(info, 'media', 'type', 'thumbnail').text, } else: - # "feature" pages use theplatform.com + # "feature" and "nightly-news" pages use theplatform.com title = mobj.group('title') webpage = self._download_webpage(url, title) bootstrap_json = self._search_regex( - r'var bootstrapJson = ({.+})\s*$', webpage, 'bootstrap json', - flags=re.MULTILINE) - bootstrap = json.loads(bootstrap_json) + r'var\s+(?:bootstrapJson|playlistData)\s*=\s*({.+});?\s*$', + webpage, 'bootstrap json', flags=re.MULTILINE) + bootstrap = self._parse_json(bootstrap_json, video_id) info = bootstrap['results'][0]['video'] mpxid = info['mpxId'] diff --git a/youtube_dl/extractor/netzkino.py b/youtube_dl/extractor/netzkino.py index 93567d1..bc17e20 100644 --- a/youtube_dl/extractor/netzkino.py +++ b/youtube_dl/extractor/netzkino.py @@ -29,6 +29,9 @@ class NetzkinoIE(InfoExtractor): 'timestamp': 1344858571, 'age_limit': 12, }, + 'params': { + 'skip_download': 'Download only works from Germany', + } } def _real_extract(self, url): diff --git a/youtube_dl/extractor/npo.py b/youtube_dl/extractor/npo.py index 54be06a..9c01eb0 100644 --- a/youtube_dl/extractor/npo.py +++ b/youtube_dl/extractor/npo.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..utils import ( fix_xml_ampersands, parse_duration, @@ -11,7 +11,7 @@ from ..utils import ( ) -class NPOBaseIE(SubtitlesInfoExtractor): +class NPOBaseIE(InfoExtractor): def _get_token(self, video_id): token_page = self._download_webpage( 'http://ida.omroep.nl/npoplayer/i.js', @@ -22,7 +22,7 @@ class NPOBaseIE(SubtitlesInfoExtractor): class NPOIE(NPOBaseIE): IE_NAME = 'npo.nl' - _VALID_URL = r'https?://www\.npo\.nl/[^/]+/[^/]+/(?P<id>[^/?]+)' + _VALID_URL = r'https?://(?:www\.)?npo\.nl/(?!live|radio)[^/]+/[^/]+/(?P<id>[^/?]+)' _TESTS = [ { @@ -163,13 +163,10 @@ class NPOIE(NPOBaseIE): subtitles = {} if metadata.get('tt888') == 'ja': - subtitles['nl'] = 'http://e.omroep.nl/tt888/%s' % video_id - - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return - - subtitles = self.extract_subtitles(video_id, subtitles) + subtitles['nl'] = [{ + 'ext': 'vtt', + 'url': 'http://e.omroep.nl/tt888/%s' % video_id, + }] return { 'id': video_id, @@ -185,7 +182,7 @@ class NPOIE(NPOBaseIE): class NPOLiveIE(NPOBaseIE): IE_NAME = 'npo.nl:live' - _VALID_URL = r'https?://www\.npo\.nl/live/(?P<id>.+)' + _VALID_URL = r'https?://(?:www\.)?npo\.nl/live/(?P<id>.+)' _TEST = { 'url': 'http://www.npo.nl/live/npo-1', @@ -260,6 +257,84 @@ class NPOLiveIE(NPOBaseIE): } +class NPORadioIE(InfoExtractor): + IE_NAME = 'npo.nl:radio' + _VALID_URL = r'https?://(?:www\.)?npo\.nl/radio/(?P<id>[^/]+)/?$' + + _TEST = { + 'url': 'http://www.npo.nl/radio/radio-1', + 'info_dict': { + 'id': 'radio-1', + 'ext': 'mp3', + 'title': 're:^NPO Radio 1 [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$', + 'is_live': True, + }, + 'params': { + 'skip_download': True, + } + } + + @staticmethod + def _html_get_attribute_regex(attribute): + return r'{0}\s*=\s*\'([^\']+)\''.format(attribute) + + def _real_extract(self, url): + video_id = self._match_id(url) + + webpage = self._download_webpage(url, video_id) + + title = self._html_search_regex( + self._html_get_attribute_regex('data-channel'), webpage, 'title') + + stream = self._parse_json( + self._html_search_regex(self._html_get_attribute_regex('data-streams'), webpage, 'data-streams'), + video_id) + + codec = stream.get('codec') + + return { + 'id': video_id, + 'url': stream['url'], + 'title': self._live_title(title), + 'acodec': codec, + 'ext': codec, + 'is_live': True, + } + + +class NPORadioFragmentIE(InfoExtractor): + IE_NAME = 'npo.nl:radio:fragment' + _VALID_URL = r'https?://(?:www\.)?npo\.nl/radio/[^/]+/fragment/(?P<id>\d+)' + + _TEST = { + 'url': 'http://www.npo.nl/radio/radio-5/fragment/174356', + 'md5': 'dd8cc470dad764d0fdc70a9a1e2d18c2', + 'info_dict': { + 'id': '174356', + 'ext': 'mp3', + 'title': 'Jubileumconcert Willeke Alberti', + }, + } + + def _real_extract(self, url): + audio_id = self._match_id(url) + + webpage = self._download_webpage(url, audio_id) + + title = self._html_search_regex( + r'href="/radio/[^/]+/fragment/%s" title="([^"]+)"' % audio_id, + webpage, 'title') + + audio_url = self._search_regex( + r"data-streams='([^']+)'", webpage, 'audio url') + + return { + 'id': audio_id, + 'url': audio_url, + 'title': title, + } + + class TegenlichtVproIE(NPOIE): IE_NAME = 'tegenlicht.vpro.nl' _VALID_URL = r'https?://tegenlicht\.vpro\.nl/afleveringen/.*?' diff --git a/youtube_dl/extractor/nrk.py b/youtube_dl/extractor/nrk.py index f6de260..1e4cfa2 100644 --- a/youtube_dl/extractor/nrk.py +++ b/youtube_dl/extractor/nrk.py @@ -4,13 +4,13 @@ from __future__ import unicode_literals import re from .common import InfoExtractor +from ..compat import compat_str from ..utils import ( ExtractorError, float_or_none, parse_duration, unified_strdate, ) -from .subtitles import SubtitlesInfoExtractor class NRKIE(InfoExtractor): @@ -73,7 +73,7 @@ class NRKIE(InfoExtractor): } -class NRKTVIE(SubtitlesInfoExtractor): +class NRKTVIE(InfoExtractor): _VALID_URL = r'(?P<baseurl>http://tv\.nrk(?:super)?\.no/)(?:serie/[^/]+|program)/(?P<id>[a-zA-Z]{4}\d{8})(?:/\d{2}-\d{2}-\d{4})?(?:#del=(?P<part_id>\d+))?' _TESTS = [ @@ -156,10 +156,12 @@ class NRKTVIE(SubtitlesInfoExtractor): if self._downloader.params.get('verbose', False): self.to_screen('[debug] %s' % txt) - def _extract_captions(self, subtitlesurl, video_id, baseurl): + def _get_subtitles(self, subtitlesurl, video_id, baseurl): url = "%s%s" % (baseurl, subtitlesurl) self._debug_print('%s: Subtitle url: %s' % (video_id, url)) - captions = self._download_xml(url, video_id, 'Downloading subtitles') + captions = self._download_xml( + url, video_id, 'Downloading subtitles', + transform_source=lambda s: s.replace(r'<br />', '\r\n')) lang = captions.get('lang', 'no') ps = captions.findall('./{0}body/{0}div/{0}p'.format('{http://www.w3.org/ns/ttml}')) srt = '' @@ -168,9 +170,11 @@ class NRKTVIE(SubtitlesInfoExtractor): duration = parse_duration(p.get('dur')) starttime = self._seconds2str(begin) endtime = self._seconds2str(begin + duration) - text = '\n'.join(p.itertext()) - srt += '%s\r\n%s --> %s\r\n%s\r\n\r\n' % (str(pos), starttime, endtime, text) - return {lang: srt} + srt += '%s\r\n%s --> %s\r\n%s\r\n\r\n' % (compat_str(pos), starttime, endtime, p.text) + return {lang: [ + {'ext': 'ttml', 'url': url}, + {'ext': 'srt', 'data': srt}, + ]} def _extract_f4m(self, manifest_url, video_id): return self._extract_f4m_formats(manifest_url + '?hdcore=3.1.1&plugin=aasp-3.1.1.69.124', video_id) @@ -243,10 +247,7 @@ class NRKTVIE(SubtitlesInfoExtractor): webpage, 'subtitle URL', default=None) subtitles = None if subtitles_url: - subtitles = self._extract_captions(subtitles_url, video_id, baseurl) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return + subtitles = self.extract_subtitles(subtitles_url, video_id, baseurl) return { 'id': video_id, diff --git a/youtube_dl/extractor/ntvru.py b/youtube_dl/extractor/ntvru.py index 0ab8d51..2cd924d 100644 --- a/youtube_dl/extractor/ntvru.py +++ b/youtube_dl/extractor/ntvru.py @@ -3,7 +3,9 @@ from __future__ import unicode_literals from .common import InfoExtractor from ..utils import ( - unescapeHTML + clean_html, + xpath_text, + int_or_none, ) @@ -14,73 +16,63 @@ class NTVRuIE(InfoExtractor): _TESTS = [ { 'url': 'http://www.ntv.ru/novosti/863142/', + 'md5': 'ba7ea172a91cb83eb734cad18c10e723', 'info_dict': { 'id': '746000', - 'ext': 'flv', + 'ext': 'mp4', 'title': 'Командующий Черноморским флотом провел переговоры в штабе ВМС Украины', 'description': 'Командующий Черноморским флотом провел переговоры в штабе ВМС Украины', + 'thumbnail': 're:^http://.*\.jpg', 'duration': 136, }, - 'params': { - # rtmp download - 'skip_download': True, - }, }, { 'url': 'http://www.ntv.ru/video/novosti/750370/', + 'md5': 'adecff79691b4d71e25220a191477124', 'info_dict': { 'id': '750370', - 'ext': 'flv', + 'ext': 'mp4', 'title': 'Родные пассажиров пропавшего Boeing не верят в трагический исход', 'description': 'Родные пассажиров пропавшего Boeing не верят в трагический исход', + 'thumbnail': 're:^http://.*\.jpg', 'duration': 172, }, - 'params': { - # rtmp download - 'skip_download': True, - }, }, { 'url': 'http://www.ntv.ru/peredacha/segodnya/m23700/o232416', + 'md5': '82dbd49b38e3af1d00df16acbeab260c', 'info_dict': { 'id': '747480', - 'ext': 'flv', - 'title': '«Сегодня». 21 марта 2014 года. 16:00 ', - 'description': '«Сегодня». 21 марта 2014 года. 16:00 ', + 'ext': 'mp4', + 'title': '«Сегодня». 21 марта 2014 года. 16:00', + 'description': '«Сегодня». 21 марта 2014 года. 16:00', + 'thumbnail': 're:^http://.*\.jpg', 'duration': 1496, }, - 'params': { - # rtmp download - 'skip_download': True, - }, }, { 'url': 'http://www.ntv.ru/kino/Koma_film', + 'md5': 'f825770930937aa7e5aca0dc0d29319a', 'info_dict': { - 'id': '758100', - 'ext': 'flv', + 'id': '1007609', + 'ext': 'mp4', 'title': 'Остросюжетный фильм «Кома»', 'description': 'Остросюжетный фильм «Кома»', + 'thumbnail': 're:^http://.*\.jpg', 'duration': 5592, }, - 'params': { - # rtmp download - 'skip_download': True, - }, }, { 'url': 'http://www.ntv.ru/serial/Delo_vrachey/m31760/o233916/', + 'md5': '9320cd0e23f3ea59c330dc744e06ff3b', 'info_dict': { 'id': '751482', - 'ext': 'flv', + 'ext': 'mp4', 'title': '«Дело врачей»: «Деревце жизни»', 'description': '«Дело врачей»: «Деревце жизни»', + 'thumbnail': 're:^http://.*\.jpg', 'duration': 2590, }, - 'params': { - # rtmp download - 'skip_download': True, - }, }, ] @@ -92,45 +84,36 @@ class NTVRuIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - page = self._download_webpage(url, video_id) - video_id = self._html_search_regex(self._VIDEO_ID_REGEXES, page, 'video id') + webpage = self._download_webpage(url, video_id) - player = self._download_xml('http://www.ntv.ru/vi%s/' % video_id, video_id, 'Downloading video XML') - title = unescapeHTML(player.find('./data/title').text) - description = unescapeHTML(player.find('./data/description').text) + video_id = self._html_search_regex(self._VIDEO_ID_REGEXES, webpage, 'video id') - video = player.find('./data/video') - video_id = video.find('./id').text - thumbnail = video.find('./splash').text - duration = int(video.find('./totaltime').text) - view_count = int(video.find('./views').text) - puid22 = video.find('./puid22').text + player = self._download_xml( + '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')) - apps = { - '4': 'video1', - '7': 'video2', - } + 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')) - app = apps.get(puid22, apps['4']) + 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_ = video.find('./%sfile' % format_id) + if file_ is None: continue size = video.find('./%ssize' % format_id) formats.append({ - 'url': 'rtmp://media.ntv.ru/%s' % app, - 'app': app, - 'play_path': file.text, - 'rtmp_conn': 'B:1', - 'player_url': 'http://www.ntv.ru/swf/vps1.swf?update=20131128', - 'page_url': 'http://www.ntv.ru', - 'flash_version': 'LNX 11,2,202,341', - 'rtmp_live': True, - 'ext': 'flv', - 'filesize': int(size.text), + '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), }) self._sort_formats(formats) diff --git a/youtube_dl/extractor/odnoklassniki.py b/youtube_dl/extractor/odnoklassniki.py new file mode 100644 index 0000000..155d0ee --- /dev/null +++ b/youtube_dl/extractor/odnoklassniki.py @@ -0,0 +1,85 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + unified_strdate, + int_or_none, + qualities, +) + + +class OdnoklassnikiIE(InfoExtractor): + _VALID_URL = r'https?://(?:odnoklassniki|ok)\.ru/(?:video|web-api/video/moviePlayer)/(?P<id>\d+)' + _TESTS = [{ + 'url': 'http://ok.ru/video/20079905452', + 'md5': '8e24ad2da6f387948e7a7d44eb8668fe', + 'info_dict': { + 'id': '20079905452', + 'ext': 'mp4', + 'title': 'Культура меняет нас (прекрасный ролик!))', + 'duration': 100, + 'upload_date': '20141207', + 'uploader_id': '330537914540', + 'uploader': 'Виталий Добровольский', + 'like_count': int, + 'age_limit': 0, + }, + }, { + 'url': 'http://ok.ru/web-api/video/moviePlayer/20079905452', + 'only_matching': True, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + + webpage = self._download_webpage(url, video_id) + + player = self._parse_json( + self._search_regex( + r"OKVideo\.start\(({.+?})\s*,\s*'VideoAutoplay_player'", webpage, 'player'), + video_id) + + metadata = self._parse_json(player['flashvars']['metadata'], video_id) + + movie = metadata['movie'] + title = movie['title'] + thumbnail = movie.get('poster') + duration = int_or_none(movie.get('duration')) + + author = metadata.get('author', {}) + uploader_id = author.get('id') + uploader = author.get('name') + + upload_date = unified_strdate(self._html_search_meta( + 'ya:ovs:upload_date', webpage, 'upload date')) + + age_limit = None + adult = self._html_search_meta( + 'ya:ovs:adult', webpage, 'age limit') + if adult: + age_limit = 18 if adult == 'true' else 0 + + like_count = int_or_none(metadata.get('likeCount')) + + quality = qualities(('mobile', 'lowest', 'low', 'sd', 'hd')) + + formats = [{ + 'url': f['url'], + 'ext': 'mp4', + 'format_id': f['name'], + 'quality': quality(f['name']), + } for f in metadata['videos']] + + return { + 'id': video_id, + 'title': title, + 'thumbnail': thumbnail, + 'duration': duration, + 'upload_date': upload_date, + 'uploader': uploader, + 'uploader_id': uploader_id, + 'like_count': like_count, + 'age_limit': age_limit, + 'formats': formats, + } diff --git a/youtube_dl/extractor/patreon.py b/youtube_dl/extractor/patreon.py index 5429592..f179ea2 100644 --- a/youtube_dl/extractor/patreon.py +++ b/youtube_dl/extractor/patreon.py @@ -1,9 +1,6 @@ # encoding: utf-8 from __future__ import unicode_literals -import json -import re - from .common import InfoExtractor from ..utils import ( js_to_json, @@ -11,7 +8,7 @@ from ..utils import ( class PatreonIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?patreon\.com/creation\?hid=(.+)' + _VALID_URL = r'https?://(?:www\.)?patreon\.com/creation\?hid=(?P<id>[^&#]+)' _TESTS = [ { 'url': 'http://www.patreon.com/creation?hid=743933', @@ -35,6 +32,23 @@ class PatreonIE(InfoExtractor): 'thumbnail': 're:^https?://.*$', }, }, + { + 'url': 'https://www.patreon.com/creation?hid=1682498', + 'info_dict': { + 'id': 'SU4fj_aEMVw', + 'ext': 'mp4', + 'title': 'I\'m on Patreon!', + 'uploader': 'TraciJHines', + 'thumbnail': 're:^https?://.*$', + 'upload_date': '20150211', + 'description': 'md5:c5a706b1f687817a3de09db1eb93acd4', + 'uploader_id': 'TraciJHines', + }, + 'params': { + 'noplaylist': True, + 'skip_download': True, + } + } ] # Currently Patreon exposes download URL via hidden CSS, so login is not @@ -65,26 +79,29 @@ class PatreonIE(InfoExtractor): ''' def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group(1) - + video_id = self._match_id(url) webpage = self._download_webpage(url, video_id) title = self._og_search_title(webpage).strip() attach_fn = self._html_search_regex( r'<div class="attach"><a target="_blank" href="([^"]+)">', webpage, 'attachment URL', default=None) + embed = self._html_search_regex( + r'<div id="watchCreation">\s*<iframe class="embedly-embed" src="([^"]+)"', + webpage, 'embedded URL', default=None) + if attach_fn is not None: video_url = 'http://www.patreon.com' + attach_fn thumbnail = self._og_search_thumbnail(webpage) uploader = self._html_search_regex( r'<strong>(.*?)</strong> is creating', webpage, 'uploader') + elif embed is not None: + return self.url_result(embed) else: - playlist_js = self._search_regex( + playlist = self._parse_json(self._search_regex( r'(?s)new\s+jPlayerPlaylist\(\s*\{\s*[^}]*},\s*(\[.*?,?\s*\])', - webpage, 'playlist JSON') - playlist_json = js_to_json(playlist_js) - playlist = json.loads(playlist_json) + webpage, 'playlist JSON'), + video_id, transform_source=js_to_json) data = playlist[0] video_url = self._proto_relative_url(data['mp3']) thumbnail = self._proto_relative_url(data.get('cover')) diff --git a/youtube_dl/extractor/pornhd.py b/youtube_dl/extractor/pornhd.py index 954dfcc..dbb2c3b 100644 --- a/youtube_dl/extractor/pornhd.py +++ b/youtube_dl/extractor/pornhd.py @@ -46,16 +46,17 @@ class PornHdIE(InfoExtractor): quality = qualities(['sd', 'hd']) sources = json.loads(js_to_json(self._search_regex( - r"(?s)'sources'\s*:\s*(\{.+?\})\s*\}\);", webpage, 'sources'))) + r"(?s)'sources'\s*:\s*(\{.+?\})\s*\}[;,)]", + webpage, 'sources'))) formats = [] - for container, s in sources.items(): - for qname, video_url in s.items(): - formats.append({ - 'url': video_url, - 'container': container, - 'format_id': '%s-%s' % (container, qname), - 'quality': quality(qname), - }) + for qname, video_url in sources.items(): + if not video_url: + continue + formats.append({ + 'url': video_url, + 'format_id': qname, + 'quality': quality(qname), + }) self._sort_formats(formats) return { diff --git a/youtube_dl/extractor/pornhub.py b/youtube_dl/extractor/pornhub.py index fb20328..3a27e37 100644 --- a/youtube_dl/extractor/pornhub.py +++ b/youtube_dl/extractor/pornhub.py @@ -56,7 +56,7 @@ class PornHubIE(InfoExtractor): video_title = self._html_search_regex(r'<h1 [^>]+>([^<]+)', webpage, 'title') video_uploader = self._html_search_regex( - r'(?s)From: .+?<(?:a href="/users/|a href="/channels/|<span class="username)[^>]+>(.+?)<', + r'(?s)From: .+?<(?:a href="/users/|a href="/channels/|span class="username)[^>]+>(.+?)<', webpage, 'uploader', fatal=False) thumbnail = self._html_search_regex(r'"image_url":"([^"]+)', webpage, 'thumbnail', fatal=False) if thumbnail: @@ -110,3 +110,33 @@ class PornHubIE(InfoExtractor): 'formats': formats, 'age_limit': 18, } + + +class PornHubPlaylistIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?pornhub\.com/playlist/(?P<id>\d+)' + _TESTS = [{ + 'url': 'http://www.pornhub.com/playlist/6201671', + 'info_dict': { + 'id': '6201671', + 'title': 'P0p4', + }, + 'playlist_mincount': 35, + }] + + def _real_extract(self, url): + playlist_id = self._match_id(url) + + webpage = self._download_webpage(url, playlist_id) + + entries = [ + self.url_result('http://www.pornhub.com/%s' % video_url, 'PornHub') + for video_url in set(re.findall('href="/?(view_video\.php\?viewkey=\d+[^"]*)"', webpage)) + ] + + playlist = self._parse_json( + self._search_regex( + r'playlistObject\s*=\s*({.+?});', webpage, 'playlist'), + playlist_id) + + return self.playlist_result( + entries, playlist_id, playlist.get('title'), playlist.get('description')) diff --git a/youtube_dl/extractor/puls4.py b/youtube_dl/extractor/puls4.py new file mode 100644 index 0000000..cce84b9 --- /dev/null +++ b/youtube_dl/extractor/puls4.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + ExtractorError, + unified_strdate, + int_or_none, +) + + +class Puls4IE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?puls4\.com/video/[^/]+/play/(?P<id>[0-9]+)' + _TESTS = [{ + 'url': 'http://www.puls4.com/video/pro-und-contra/play/2716816', + 'md5': '49f6a6629747eeec43cef6a46b5df81d', + 'info_dict': { + 'id': '2716816', + 'ext': 'mp4', + 'title': 'Pro und Contra vom 23.02.2015', + 'description': 'md5:293e44634d9477a67122489994675db6', + 'duration': 2989, + 'upload_date': '20150224', + 'uploader': 'PULS_4', + }, + 'skip': 'Only works from Germany', + }, { + 'url': 'http://www.puls4.com/video/kult-spielfilme/play/1298106', + 'md5': '6a48316c8903ece8dab9b9a7bf7a59ec', + 'info_dict': { + 'id': '1298106', + 'ext': 'mp4', + 'title': 'Lucky Fritz', + }, + 'skip': 'Only works from Germany', + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + webpage = self._download_webpage(url, video_id) + + error_message = self._html_search_regex( + r'<div class="message-error">(.+?)</div>', + webpage, 'error message', default=None) + if error_message: + raise ExtractorError( + '%s returned error: %s' % (self.IE_NAME, error_message), expected=True) + + real_url = self._html_search_regex( + r'\"fsk-button\".+?href=\"([^"]+)', + webpage, 'fsk_button', default=None) + if real_url: + webpage = self._download_webpage(real_url, video_id) + + player = self._search_regex( + r'p4_video_player(?:_iframe)?\("video_\d+_container"\s*,(.+?)\);\s*\}', + webpage, 'player') + + player_json = self._parse_json( + '[%s]' % player, video_id, + transform_source=lambda s: s.replace('undefined,', '')) + + formats = None + result = None + + for v in player_json: + if isinstance(v, list) and not formats: + formats = [{ + 'url': f['url'], + 'format': 'hd' if f.get('hd') else 'sd', + 'width': int_or_none(f.get('size_x')), + 'height': int_or_none(f.get('size_y')), + 'tbr': int_or_none(f.get('bitrate')), + } for f in v] + self._sort_formats(formats) + elif isinstance(v, dict) and not result: + result = { + 'id': video_id, + 'title': v['videopartname'].strip(), + 'description': v.get('videotitle'), + 'duration': int_or_none(v.get('videoduration') or v.get('episodeduration')), + 'upload_date': unified_strdate(v.get('clipreleasetime')), + 'uploader': v.get('channel'), + } + + result['formats'] = formats + + return result diff --git a/youtube_dl/extractor/r7.py b/youtube_dl/extractor/r7.py new file mode 100644 index 0000000..976c8fe --- /dev/null +++ b/youtube_dl/extractor/r7.py @@ -0,0 +1,88 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + js_to_json, + unescapeHTML, + int_or_none, +) + + +class R7IE(InfoExtractor): + _VALID_URL = r'''(?x)https?:// + (?: + (?:[a-zA-Z]+)\.r7\.com(?:/[^/]+)+/idmedia/| + noticias\.r7\.com(?:/[^/]+)+/[^/]+-| + player\.r7\.com/video/i/ + ) + (?P<id>[\da-f]{24}) + ''' + _TESTS = [{ + 'url': 'http://videos.r7.com/policiais-humilham-suspeito-a-beira-da-morte-morre-com-dignidade-/idmedia/54e7050b0cf2ff57e0279389.html', + 'md5': '403c4e393617e8e8ddc748978ee8efde', + 'info_dict': { + 'id': '54e7050b0cf2ff57e0279389', + 'ext': 'mp4', + 'title': 'Policiais humilham suspeito à beira da morte: "Morre com dignidade"', + 'thumbnail': 're:^https?://.*\.jpg$', + 'duration': 98, + 'like_count': int, + 'view_count': int, + }, + }, { + 'url': 'http://esportes.r7.com/videos/cigano-manda-recado-aos-fas/idmedia/4e176727b51a048ee6646a1b.html', + 'only_matching': True, + }, { + 'url': 'http://noticias.r7.com/record-news/video/representante-do-instituto-sou-da-paz-fala-sobre-fim-do-estatuto-do-desarmamento-5480fc580cf2285b117f438d/', + 'only_matching': True, + }, { + 'url': 'http://player.r7.com/video/i/54e7050b0cf2ff57e0279389?play=true&video=http://vsh.r7.com/54e7050b0cf2ff57e0279389/ER7_RE_BG_MORTE_JOVENS_570kbps_2015-02-2009f17818-cc82-4c8f-86dc-89a66934e633-ATOS_copy.mp4&linkCallback=http://videos.r7.com/policiais-humilham-suspeito-a-beira-da-morte-morre-com-dignidade-/idmedia/54e7050b0cf2ff57e0279389.html&thumbnail=http://vtb.r7.com/ER7_RE_BG_MORTE_JOVENS_570kbps_2015-02-2009f17818-cc82-4c8f-86dc-89a66934e633-thumb.jpg&idCategory=192&share=true&layout=full&full=true', + 'only_matching': True, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + + webpage = self._download_webpage( + 'http://player.r7.com/video/i/%s' % video_id, video_id) + + item = self._parse_json(js_to_json(self._search_regex( + r'(?s)var\s+item\s*=\s*({.+?});', webpage, 'player')), video_id) + + title = unescapeHTML(item['title']) + thumbnail = item.get('init', {}).get('thumbUri') + duration = None + + statistics = item.get('statistics', {}) + like_count = int_or_none(statistics.get('likes')) + view_count = int_or_none(statistics.get('views')) + + formats = [] + for format_key, format_dict in item['playlist'][0].items(): + src = format_dict.get('src') + if not src: + continue + format_id = format_dict.get('format') or format_key + if duration is None: + duration = format_dict.get('duration') + if '.f4m' in src: + formats.extend(self._extract_f4m_formats(src, video_id, preference=-1)) + elif src.endswith('.m3u8'): + formats.extend(self._extract_m3u8_formats(src, video_id, 'mp4', preference=-2)) + else: + formats.append({ + 'url': src, + 'format_id': format_id, + }) + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'thumbnail': thumbnail, + 'duration': duration, + 'like_count': like_count, + 'view_count': view_count, + 'formats': formats, + } diff --git a/youtube_dl/extractor/radiode.py b/youtube_dl/extractor/radiode.py index f95bc94..aa5f6f8 100644 --- a/youtube_dl/extractor/radiode.py +++ b/youtube_dl/extractor/radiode.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -import json - from .common import InfoExtractor @@ -10,13 +8,13 @@ class RadioDeIE(InfoExtractor): _VALID_URL = r'https?://(?P<id>.+?)\.(?:radio\.(?:de|at|fr|pt|es|pl|it)|rad\.io)' _TEST = { 'url': 'http://ndr2.radio.de/', - 'md5': '3b4cdd011bc59174596b6145cda474a4', 'info_dict': { 'id': 'ndr2', 'ext': 'mp3', 'title': 're:^NDR 2 [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$', 'description': 'md5:591c49c702db1a33751625ebfb67f273', 'thumbnail': 're:^https?://.*\.png', + 'is_live': True, }, 'params': { 'skip_download': True, @@ -25,16 +23,15 @@ class RadioDeIE(InfoExtractor): def _real_extract(self, url): radio_id = self._match_id(url) - webpage = self._download_webpage(url, radio_id) + jscode = self._search_regex( + r"'components/station/stationService':\s*\{\s*'?station'?:\s*(\{.*?\s*\}),\n", + webpage, 'broadcast') - broadcast = json.loads(self._search_regex( - r'_getBroadcast\s*=\s*function\(\s*\)\s*{\s*return\s+({.+?})\s*;\s*}', - webpage, 'broadcast')) - + broadcast = self._parse_json(jscode, radio_id) title = self._live_title(broadcast['name']) description = broadcast.get('description') or broadcast.get('shortDescription') - thumbnail = broadcast.get('picture4Url') or broadcast.get('picture4TransUrl') + thumbnail = broadcast.get('picture4Url') or broadcast.get('picture4TransUrl') or broadcast.get('logo100x100') formats = [{ 'url': stream['streamUrl'], diff --git a/youtube_dl/extractor/rai.py b/youtube_dl/extractor/rai.py index aa26b7e..144e339 100644 --- a/youtube_dl/extractor/rai.py +++ b/youtube_dl/extractor/rai.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import re -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..compat import ( compat_urllib_parse, ) @@ -12,7 +12,7 @@ from ..utils import ( ) -class RaiIE(SubtitlesInfoExtractor): +class RaiIE(InfoExtractor): _VALID_URL = r'(?P<url>http://(?:.+?\.)?(?:rai\.it|rai\.tv|rainews\.it)/dl/.+?-(?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})(?:-.+?)?\.html)' _TESTS = [ { @@ -89,15 +89,7 @@ class RaiIE(SubtitlesInfoExtractor): 'ext': 'mp4', }) - if self._downloader.params.get('listsubtitles', False): - page = self._download_webpage(url, video_id) - self._list_available_subtitles(video_id, page) - return - - subtitles = {} - if self._have_to_download_any_subtitles: - page = self._download_webpage(url, video_id) - subtitles = self.extract_subtitles(video_id, page) + subtitles = self.extract_subtitles(video_id, url) return { 'id': video_id, @@ -111,7 +103,8 @@ class RaiIE(SubtitlesInfoExtractor): 'subtitles': subtitles, } - def _get_available_subtitles(self, video_id, webpage): + def _get_subtitles(self, video_id, url): + webpage = self._download_webpage(url, video_id) subtitles = {} m = re.search(r'<meta name="closedcaption" content="(?P<captions>[^"]+)"', webpage) if m: @@ -120,5 +113,8 @@ class RaiIE(SubtitlesInfoExtractor): SRT_EXT = '.srt' if captions.endswith(STL_EXT): captions = captions[:-len(STL_EXT)] + SRT_EXT - subtitles['it'] = 'http://www.rai.tv%s' % compat_urllib_parse.quote(captions) + subtitles['it'] = [{ + 'ext': 'srt', + 'url': 'http://www.rai.tv%s' % compat_urllib_parse.quote(captions), + }] return subtitles diff --git a/youtube_dl/extractor/rtlnl.py b/youtube_dl/extractor/rtlnl.py index a3ca79f..cfce455 100644 --- a/youtube_dl/extractor/rtlnl.py +++ b/youtube_dl/extractor/rtlnl.py @@ -1,16 +1,25 @@ +# coding: utf-8 from __future__ import unicode_literals -import re - from .common import InfoExtractor -from ..utils import parse_duration +from ..utils import ( + int_or_none, + parse_duration, +) -class RtlXlIE(InfoExtractor): - IE_NAME = 'rtlxl.nl' - _VALID_URL = r'https?://(www\.)?rtlxl\.nl/#!/[^/]+/(?P<uuid>[^/?]+)' +class RtlNlIE(InfoExtractor): + IE_NAME = 'rtl.nl' + IE_DESC = 'rtl.nl and rtlxl.nl' + _VALID_URL = r'''(?x) + https?://(www\.)? + (?: + rtlxl\.nl/\#!/[^/]+/| + rtl\.nl/system/videoplayer/[^?#]+?/video_embed\.html\#uuid= + ) + (?P<id>[0-9a-f-]+)''' - _TEST = { + _TESTS = [{ 'url': 'http://www.rtlxl.nl/#!/rtl-nieuws-132237/6e4203a6-0a5e-3596-8424-c599a59e0677', 'md5': 'cc16baa36a6c169391f0764fa6b16654', 'info_dict': { @@ -22,21 +31,30 @@ class RtlXlIE(InfoExtractor): 'upload_date': '20140814', 'duration': 576.880, }, - } + }, { + 'url': 'http://www.rtl.nl/system/videoplayer/derden/rtlnieuws/video_embed.html#uuid=84ae5571-ac25-4225-ae0c-ef8d9efb2aed/autoplay=false', + 'md5': 'dea7474214af1271d91ef332fb8be7ea', + 'info_dict': { + 'id': '84ae5571-ac25-4225-ae0c-ef8d9efb2aed', + 'ext': 'mp4', + 'timestamp': 1424039400, + 'title': 'RTL Nieuws - Nieuwe beelden Kopenhagen: chaos direct na aanslag', + 'thumbnail': 're:^https?://screenshots\.rtl\.nl/system/thumb/sz=[0-9]+x[0-9]+/uuid=84ae5571-ac25-4225-ae0c-ef8d9efb2aed$', + 'upload_date': '20150215', + 'description': 'Er zijn nieuwe beelden vrijgegeven die vlak na de aanslag in Kopenhagen zijn gemaakt. Op de video is goed te zien hoe omstanders zich bekommeren om één van de slachtoffers, terwijl de eerste agenten ter plaatse komen.', + } + }] def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - uuid = mobj.group('uuid') - + uuid = self._match_id(url) info = self._download_json( 'http://www.rtl.nl/system/s4m/vfd/version=2/uuid=%s/fmt=flash/' % uuid, uuid) material = info['material'][0] - episode_info = info['episodes'][0] - progname = info['abstracts'][0]['name'] subtitle = material['title'] or info['episodes'][0]['name'] + description = material.get('synopsis') or info['episodes'][0]['synopsis'] # Use unencrypted m3u8 streams (See https://github.com/rg3/youtube-dl/issues/4118) videopath = material['videopath'].replace('.f4m', '.m3u8') @@ -58,14 +76,29 @@ class RtlXlIE(InfoExtractor): 'quality': 0, } ]) - self._sort_formats(formats) + thumbnails = [] + meta = info.get('meta', {}) + for p in ('poster_base_url', '"thumb_base_url"'): + if not meta.get(p): + continue + + thumbnails.append({ + 'url': self._proto_relative_url(meta[p] + uuid), + 'width': int_or_none(self._search_regex( + r'/sz=([0-9]+)', meta[p], 'thumbnail width', fatal=False)), + 'height': int_or_none(self._search_regex( + r'/sz=[0-9]+x([0-9]+)', + meta[p], 'thumbnail height', fatal=False)) + }) + return { 'id': uuid, 'title': '%s - %s' % (progname, subtitle), 'formats': formats, 'timestamp': material['original_date'], - 'description': episode_info['synopsis'], + 'description': description, 'duration': parse_duration(material.get('duration')), + 'thumbnails': thumbnails, } diff --git a/youtube_dl/extractor/rtlnow.py b/youtube_dl/extractor/rtlnow.py index 285c3c4..785a804 100644 --- a/youtube_dl/extractor/rtlnow.py +++ b/youtube_dl/extractor/rtlnow.py @@ -91,6 +91,15 @@ class RTLnowIE(InfoExtractor): }, }, { + 'url': 'http://rtl-now.rtl.de/der-bachelor/folge-4.php?film_id=188729&player=1&season=5', + 'info_dict': { + 'id': '188729', + 'ext': 'flv', + 'upload_date': '20150204', + 'description': 'md5:5e1ce23095e61a79c166d134b683cecc', + 'title': 'Der Bachelor - Folge 4', + } + }, { 'url': 'http://www.n-tvnow.de/deluxe-alles-was-spass-macht/thema-ua-luxushotel-fuer-vierbeiner.php?container_id=153819&player=1&season=0', 'only_matching': True, }, @@ -134,9 +143,18 @@ class RTLnowIE(InfoExtractor): 'player_url': video_page_url + 'includes/vodplayer.swf', } else: - fmt = { - 'url': filename.text, - } + mobj = re.search(r'.*/(?P<hoster>[^/]+)/videos/(?P<play_path>.+)\.f4m', filename.text) + if mobj: + fmt = { + 'url': 'rtmpe://fms.rtl.de/' + mobj.group('hoster'), + 'play_path': 'mp4:' + mobj.group('play_path'), + 'page_url': url, + 'player_url': video_page_url + 'includes/vodplayer.swf', + } + else: + fmt = { + 'url': filename.text, + } fmt.update({ 'width': int_or_none(filename.get('width')), 'height': int_or_none(filename.get('height')), diff --git a/youtube_dl/extractor/rtp.py b/youtube_dl/extractor/rtp.py index 4511cba..ecf4939 100644 --- a/youtube_dl/extractor/rtp.py +++ b/youtube_dl/extractor/rtp.py @@ -1,16 +1,16 @@ # coding: utf-8 from __future__ import unicode_literals -import json +import re from .common import InfoExtractor -from ..utils import js_to_json class RTPIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?rtp\.pt/play/p(?P<program_id>[0-9]+)/(?P<id>[^/?#]+)/?' _TESTS = [{ 'url': 'http://www.rtp.pt/play/p405/e174042/paixoes-cruzadas', + 'md5': 'e736ce0c665e459ddb818546220b4ef8', 'info_dict': { 'id': 'e174042', 'ext': 'mp3', @@ -18,9 +18,6 @@ class RTPIE(InfoExtractor): 'description': 'As paixões musicais de António Cartaxo e António Macedo', 'thumbnail': 're:^https?://.*\.jpg', }, - 'params': { - 'skip_download': True, # RTMP download - }, }, { 'url': 'http://www.rtp.pt/play/p831/a-quimica-das-coisas', 'only_matching': True, @@ -37,21 +34,48 @@ class RTPIE(InfoExtractor): player_config = self._search_regex( r'(?s)RTPPLAY\.player\.newPlayer\(\s*(\{.*?\})\s*\)', webpage, 'player config') - config = json.loads(js_to_json(player_config)) + config = self._parse_json(player_config, video_id) path, ext = config.get('file').rsplit('.', 1) formats = [{ + 'format_id': 'rtmp', + 'ext': ext, + 'vcodec': config.get('type') == 'audio' and 'none' or None, + 'preference': -2, + 'url': 'rtmp://{streamer:s}/{application:s}'.format(**config), 'app': config.get('application'), 'play_path': '{ext:s}:{path:s}'.format(ext=ext, path=path), 'page_url': url, - 'url': 'rtmp://{streamer:s}/{application:s}'.format(**config), 'rtmp_live': config.get('live', False), - 'ext': ext, - 'vcodec': config.get('type') == 'audio' and 'none' or None, 'player_url': 'http://programas.rtp.pt/play/player.swf?v3', 'rtmp_real_time': True, }] + # Construct regular HTTP download URLs + replacements = { + 'audio': { + 'format_id': 'mp3', + 'pattern': r'^nas2\.share/wavrss/', + 'repl': 'http://rsspod.rtp.pt/podcasts/', + 'vcodec': 'none', + }, + 'video': { + 'format_id': 'mp4_h264', + 'pattern': r'^nas2\.share/h264/', + 'repl': 'http://rsspod.rtp.pt/videocasts/', + 'vcodec': 'h264', + }, + } + r = replacements[config['type']] + if re.match(r['pattern'], config['file']) is not None: + formats.append({ + 'format_id': r['format_id'], + 'url': re.sub(r['pattern'], r['repl'], config['file']), + 'vcodec': r['vcodec'], + }) + + self._sort_formats(formats) + return { 'id': video_id, 'title': title, diff --git a/youtube_dl/extractor/rtve.py b/youtube_dl/extractor/rtve.py index 3469d95..b42442d 100644 --- a/youtube_dl/extractor/rtve.py +++ b/youtube_dl/extractor/rtve.py @@ -6,9 +6,11 @@ import re import time from .common import InfoExtractor +from ..compat import compat_urlparse from ..utils import ( - struct_unpack, + float_or_none, remove_end, + struct_unpack, ) @@ -66,6 +68,7 @@ class RTVEALaCartaIE(InfoExtractor): 'id': '2491869', 'ext': 'mp4', 'title': 'Balonmano - Swiss Cup masculina. Final: España-Suecia', + 'duration': 5024.566, }, }, { 'note': 'Live stream', @@ -96,12 +99,14 @@ class RTVEALaCartaIE(InfoExtractor): ).replace('.net.rtve', '.multimedia.cdn.rtve') video_path = self._download_webpage( auth_url, video_id, 'Getting video url') - # Use mvod.akcdn instead of flash.akamaihd.multimedia.cdn to get + # Use mvod1.akcdn instead of flash.akamaihd.multimedia.cdn to get # the right Content-Length header and the mp4 format - video_url = ( - 'http://mvod.akcdn.rtve.es/{0}&v=2.6.8' - '&fp=MAC%2016,0,0,296&r=MRUGG&g=OEOJWFXNFGCP'.format(video_path) - ) + video_url = compat_urlparse.urljoin( + 'http://mvod1.akcdn.rtve.es/', video_path) + + subtitles = None + if info.get('sbtFile') is not None: + subtitles = self.extract_subtitles(video_id, info['sbtFile']) return { 'id': video_id, @@ -109,8 +114,18 @@ class RTVEALaCartaIE(InfoExtractor): 'url': video_url, 'thumbnail': info.get('image'), 'page_url': url, + 'subtitles': subtitles, + 'duration': float_or_none(info.get('duration'), scale=1000), } + def _get_subtitles(self, video_id, sub_file): + subs = self._download_json( + sub_file + '.json', video_id, + 'Downloading subtitles info')['page']['items'] + return dict( + (s['lang'], [{'ext': 'vtt', 'url': s['src']}]) + for s in subs) + class RTVELiveIE(InfoExtractor): IE_NAME = 'rtve.es:live' diff --git a/youtube_dl/extractor/sandia.py b/youtube_dl/extractor/sandia.py new file mode 100644 index 0000000..9c88167 --- /dev/null +++ b/youtube_dl/extractor/sandia.py @@ -0,0 +1,117 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import itertools +import json +import re + +from .common import InfoExtractor +from ..compat import ( + compat_urllib_request, + compat_urlparse, +) +from ..utils import ( + int_or_none, + js_to_json, + mimetype2ext, + unified_strdate, +) + + +class SandiaIE(InfoExtractor): + IE_DESC = 'Sandia National Laboratories' + _VALID_URL = r'https?://digitalops\.sandia\.gov/Mediasite/Play/(?P<id>[0-9a-f]+)' + _TEST = { + 'url': 'http://digitalops.sandia.gov/Mediasite/Play/24aace4429fc450fb5b38cdbf424a66e1d', + 'md5': '9422edc9b9a60151727e4b6d8bef393d', + 'info_dict': { + 'id': '24aace4429fc450fb5b38cdbf424a66e1d', + 'ext': 'mp4', + 'title': 'Xyce Software Training - Section 1', + 'description': 're:(?s)SAND Number: SAND 2013-7800.{200,}', + 'upload_date': '20120904', + 'duration': 7794, + } + } + + def _real_extract(self, url): + video_id = self._match_id(url) + + req = compat_urllib_request.Request(url) + req.add_header('Cookie', 'MediasitePlayerCaps=ClientPlugins=4') + webpage = self._download_webpage(req, video_id) + + js_path = self._search_regex( + r'<script type="text/javascript" src="(/Mediasite/FileServer/Presentation/[^"]+)"', + webpage, 'JS code URL') + js_url = compat_urlparse.urljoin(url, js_path) + + js_code = self._download_webpage( + js_url, video_id, note='Downloading player') + + def extract_str(key, **args): + return self._search_regex( + r'Mediasite\.PlaybackManifest\.%s\s*=\s*(.+);\s*?\n' % re.escape(key), + js_code, key, **args) + + def extract_data(key, **args): + data_json = extract_str(key, **args) + if data_json is None: + return data_json + return self._parse_json( + data_json, video_id, transform_source=js_to_json) + + formats = [] + for i in itertools.count(): + fd = extract_data('VideoUrls[%d]' % i, default=None) + if fd is None: + break + formats.append({ + 'format_id': '%s' % i, + 'format_note': fd['MimeType'].partition('/')[2], + 'ext': mimetype2ext(fd['MimeType']), + 'url': fd['Location'], + 'protocol': 'f4m' if fd['MimeType'] == 'video/x-mp4-fragmented' else None, + }) + self._sort_formats(formats) + + slide_baseurl = compat_urlparse.urljoin( + url, extract_data('SlideBaseUrl')) + slide_template = slide_baseurl + re.sub( + r'\{0:D?([0-9+])\}', r'%0\1d', extract_data('SlideImageFileNameTemplate')) + slides = [] + last_slide_time = 0 + for i in itertools.count(1): + sd = extract_str('Slides[%d]' % i, default=None) + if sd is None: + break + timestamp = int_or_none(self._search_regex( + r'^Mediasite\.PlaybackManifest\.CreateSlide\("[^"]*"\s*,\s*([0-9]+),', + sd, 'slide %s timestamp' % i, fatal=False)) + slides.append({ + 'url': slide_template % i, + 'duration': timestamp - last_slide_time, + }) + last_slide_time = timestamp + formats.append({ + 'format_id': 'slides', + 'protocol': 'slideshow', + 'url': json.dumps(slides), + 'preference': -10000, # Downloader not yet written + }) + self._sort_formats(formats) + + title = extract_data('Title') + description = extract_data('Description', fatal=False) + duration = int_or_none(extract_data( + 'Duration', fatal=False), scale=1000) + upload_date = unified_strdate(extract_data('AirDate', fatal=False)) + + return { + 'id': video_id, + 'title': title, + 'description': description, + 'formats': formats, + 'upload_date': upload_date, + 'duration': duration, + } diff --git a/youtube_dl/extractor/sockshare.py b/youtube_dl/extractor/sockshare.py index 7d3c0e9..b5fa6f1 100644 --- a/youtube_dl/extractor/sockshare.py +++ b/youtube_dl/extractor/sockshare.py @@ -25,7 +25,6 @@ class SockshareIE(InfoExtractor): 'id': '437BE28B89D799D7', 'title': 'big_buck_bunny_720p_surround.avi', 'ext': 'avi', - 'thumbnail': 're:^http://.*\.jpg$', } } @@ -45,7 +44,7 @@ class SockshareIE(InfoExtractor): ''', webpage, 'hash') fields = { - "hash": confirm_hash, + "hash": confirm_hash.encode('utf-8'), "confirm": "Continue as Free User" } @@ -68,7 +67,7 @@ class SockshareIE(InfoExtractor): webpage, 'title', default=None) thumbnail = self._html_search_regex( r'<img\s+src="([^"]*)".+?name="bg"', - webpage, 'thumbnail') + webpage, 'thumbnail', default=None) formats = [{ 'format_id': 'sd', diff --git a/youtube_dl/extractor/soulanime.py b/youtube_dl/extractor/soulanime.py deleted file mode 100644 index feef33e..0000000 --- a/youtube_dl/extractor/soulanime.py +++ /dev/null @@ -1,80 +0,0 @@ -from __future__ import unicode_literals - -import re - -from .common import InfoExtractor -from ..utils import ( - HEADRequest, - urlhandle_detect_ext, -) - - -class SoulAnimeWatchingIE(InfoExtractor): - IE_NAME = "soulanime:watching" - IE_DESC = "SoulAnime video" - _TEST = { - 'url': 'http://www.soul-anime.net/watching/seirei-tsukai-no-blade-dance-episode-9/', - 'md5': '05fae04abf72298098b528e98abf4298', - 'info_dict': { - 'id': 'seirei-tsukai-no-blade-dance-episode-9', - 'ext': 'mp4', - 'title': 'seirei-tsukai-no-blade-dance-episode-9', - 'description': 'seirei-tsukai-no-blade-dance-episode-9' - } - } - _VALID_URL = r'http://[w.]*soul-anime\.(?P<domain>[^/]+)/watch[^/]*/(?P<id>[^/]+)' - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') - domain = mobj.group('domain') - - page = self._download_webpage(url, video_id) - - video_url_encoded = self._html_search_regex( - r'<div id="download">[^<]*<a href="(?P<url>[^"]+)"', page, 'url') - video_url = "http://www.soul-anime." + domain + video_url_encoded - - ext_req = HEADRequest(video_url) - ext_handle = self._request_webpage( - ext_req, video_id, note='Determining extension') - ext = urlhandle_detect_ext(ext_handle) - - return { - 'id': video_id, - 'url': video_url, - 'ext': ext, - 'title': video_id, - 'description': video_id - } - - -class SoulAnimeSeriesIE(InfoExtractor): - IE_NAME = "soulanime:series" - IE_DESC = "SoulAnime Series" - - _VALID_URL = r'http://[w.]*soul-anime\.(?P<domain>[^/]+)/anime./(?P<id>[^/]+)' - - _EPISODE_REGEX = r'<option value="(/watch[^/]*/[^"]+)">[^<]*</option>' - - _TEST = { - 'url': 'http://www.soul-anime.net/anime1/black-rock-shooter-tv/', - 'info_dict': { - 'id': 'black-rock-shooter-tv' - }, - 'playlist_count': 8 - } - - def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - series_id = mobj.group('id') - domain = mobj.group('domain') - - pattern = re.compile(self._EPISODE_REGEX) - - page = self._download_webpage(url, series_id, "Downloading series page") - mobj = pattern.findall(page) - - entries = [self.url_result("http://www.soul-anime." + domain + obj) for obj in mobj] - - return self.playlist_result(entries, series_id) diff --git a/youtube_dl/extractor/soundgasm.py b/youtube_dl/extractor/soundgasm.py index a4f8ce6..3a4ddf5 100644 --- a/youtube_dl/extractor/soundgasm.py +++ b/youtube_dl/extractor/soundgasm.py @@ -7,6 +7,7 @@ from .common import InfoExtractor class SoundgasmIE(InfoExtractor): + IE_NAME = 'soundgasm' _VALID_URL = r'https?://(?:www\.)?soundgasm\.net/u/(?P<user>[0-9a-zA-Z_\-]+)/(?P<title>[0-9a-zA-Z_\-]+)' _TEST = { 'url': 'http://soundgasm.net/u/ytdl/Piano-sample', @@ -38,3 +39,26 @@ class SoundgasmIE(InfoExtractor): 'title': audio_title, 'description': description } + + +class SoundgasmProfileIE(InfoExtractor): + IE_NAME = 'soundgasm:profile' + _VALID_URL = r'https?://(?:www\.)?soundgasm\.net/u/(?P<id>[^/]+)/?(?:\#.*)?$' + _TEST = { + 'url': 'http://soundgasm.net/u/ytdl', + 'info_dict': { + 'id': 'ytdl', + }, + 'playlist_count': 1, + } + + def _real_extract(self, url): + profile_id = self._match_id(url) + + webpage = self._download_webpage(url, profile_id) + + entries = [ + self.url_result(audio_url, 'Soundgasm') + for audio_url in re.findall(r'href="([^"]+/u/%s/[^"]+)' % profile_id, webpage)] + + return self.playlist_result(entries, profile_id) diff --git a/youtube_dl/extractor/streamcz.py b/youtube_dl/extractor/streamcz.py index c3ceb5f..e92b932 100644 --- a/youtube_dl/extractor/streamcz.py +++ b/youtube_dl/extractor/streamcz.py @@ -1,14 +1,30 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +import hashlib +import time + from .common import InfoExtractor +from ..compat import ( + compat_urllib_request, +) from ..utils import ( int_or_none, ) +def _get_api_key(api_path): + if api_path.endswith('?'): + api_path = api_path[:-1] + + api_key = 'fb5f58a820353bd7095de526253c14fd' + a = '{0:}{1:}{2:}'.format(api_key, api_path, int(round(time.time() / 24 / 3600))) + return hashlib.md5(a.encode('ascii')).hexdigest() + + class StreamCZIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?stream\.cz/.+/(?P<id>[0-9]+)' + _API_URL = 'http://www.stream.cz/API' _TESTS = [{ 'url': 'http://www.stream.cz/peklonataliri/765767-ecka-pro-deti', @@ -36,8 +52,11 @@ class StreamCZIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - data = self._download_json( - 'http://www.stream.cz/API/episode/%s' % video_id, video_id) + api_path = '/episode/%s' % video_id + + req = compat_urllib_request.Request(self._API_URL + api_path) + req.add_header('Api-Password', _get_api_key(api_path)) + data = self._download_json(req, video_id) formats = [] for quality, video in enumerate(data['video_qualities']): diff --git a/youtube_dl/extractor/subtitles.py b/youtube_dl/extractor/subtitles.py deleted file mode 100644 index 59a5126..0000000 --- a/youtube_dl/extractor/subtitles.py +++ /dev/null @@ -1,99 +0,0 @@ -from __future__ import unicode_literals -from .common import InfoExtractor - -from ..compat import compat_str -from ..utils import ( - ExtractorError, -) - - -class SubtitlesInfoExtractor(InfoExtractor): - @property - def _have_to_download_any_subtitles(self): - return any([self._downloader.params.get('writesubtitles', False), - self._downloader.params.get('writeautomaticsub')]) - - def _list_available_subtitles(self, video_id, webpage): - """ outputs the available subtitles for the video """ - sub_lang_list = self._get_available_subtitles(video_id, webpage) - auto_captions_list = self._get_available_automatic_caption(video_id, webpage) - sub_lang = ",".join(list(sub_lang_list.keys())) - self.to_screen('%s: Available subtitles for video: %s' % - (video_id, sub_lang)) - auto_lang = ",".join(auto_captions_list.keys()) - self.to_screen('%s: Available automatic captions for video: %s' % - (video_id, auto_lang)) - - def extract_subtitles(self, video_id, webpage): - """ - returns {sub_lang: sub} ,{} if subtitles not found or None if the - subtitles aren't requested. - """ - if not self._have_to_download_any_subtitles: - return None - available_subs_list = {} - if self._downloader.params.get('writeautomaticsub', False): - available_subs_list.update(self._get_available_automatic_caption(video_id, webpage)) - if self._downloader.params.get('writesubtitles', False): - available_subs_list.update(self._get_available_subtitles(video_id, webpage)) - - if not available_subs_list: # error, it didn't get the available subtitles - return {} - if self._downloader.params.get('allsubtitles', False): - sub_lang_list = available_subs_list - else: - if self._downloader.params.get('subtitleslangs', False): - requested_langs = self._downloader.params.get('subtitleslangs') - elif 'en' in available_subs_list: - requested_langs = ['en'] - else: - requested_langs = [list(available_subs_list.keys())[0]] - - sub_lang_list = {} - for sub_lang in requested_langs: - if sub_lang not in available_subs_list: - self._downloader.report_warning('no closed captions found in the specified language "%s"' % sub_lang) - continue - sub_lang_list[sub_lang] = available_subs_list[sub_lang] - - subtitles = {} - for sub_lang, url in sub_lang_list.items(): - subtitle = self._request_subtitle_url(sub_lang, url) - if subtitle: - subtitles[sub_lang] = subtitle - return subtitles - - def _download_subtitle_url(self, sub_lang, url): - return self._download_webpage(url, None, note=False) - - def _request_subtitle_url(self, sub_lang, url): - """ makes the http request for the subtitle """ - try: - sub = self._download_subtitle_url(sub_lang, url) - except ExtractorError as err: - self._downloader.report_warning('unable to download video subtitles for %s: %s' % (sub_lang, compat_str(err))) - return - if not sub: - self._downloader.report_warning('Did not fetch video subtitles') - return - return sub - - def _get_available_subtitles(self, video_id, webpage): - """ - returns {sub_lang: url} or {} if not available - Must be redefined by the subclasses - """ - - # By default, allow implementations to simply pass in the result - assert isinstance(webpage, dict), \ - '_get_available_subtitles not implemented' - return webpage - - def _get_available_automatic_caption(self, video_id, webpage): - """ - returns {sub_lang: url} or {} if not available - Must be redefined by the subclasses that support automatic captions, - otherwise it will return {} - """ - self._downloader.report_warning('Automatic Captions not supported by this server') - return {} diff --git a/youtube_dl/extractor/sunporno.py b/youtube_dl/extractor/sunporno.py index 8a333f1..854d01b 100644 --- a/youtube_dl/extractor/sunporno.py +++ b/youtube_dl/extractor/sunporno.py @@ -52,7 +52,7 @@ class SunPornoIE(InfoExtractor): formats = [] quality = qualities(['mp4', 'flv']) - for video_url in re.findall(r'<source src="([^"]+)"', webpage): + for video_url in re.findall(r'<(?:source|video) src="([^"]+)"', webpage): video_ext = determine_ext(video_url) formats.append({ 'url': video_url, diff --git a/youtube_dl/extractor/svtplay.py b/youtube_dl/extractor/svtplay.py new file mode 100644 index 0000000..433dfd1 --- /dev/null +++ b/youtube_dl/extractor/svtplay.py @@ -0,0 +1,82 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + determine_ext, +) + + +class SVTPlayIE(InfoExtractor): + IE_DESC = 'SVT Play and Öppet arkiv' + _VALID_URL = r'https?://(?:www\.)?(?P<host>svtplay|oppetarkiv)\.se/video/(?P<id>[0-9]+)' + _TESTS = [{ + 'url': 'http://www.svtplay.se/video/2609989/sm-veckan/sm-veckan-rally-final-sasong-1-sm-veckan-rally-final', + 'md5': 'ade3def0643fa1c40587a422f98edfd9', + 'info_dict': { + 'id': '2609989', + 'ext': 'flv', + 'title': 'SM veckan vinter, Örebro - Rally, final', + 'duration': 4500, + 'thumbnail': 're:^https?://.*[\.-]jpg$', + 'age_limit': 0, + }, + }, { + 'url': 'http://www.oppetarkiv.se/video/1058509/rederiet-sasong-1-avsnitt-1-av-318', + 'md5': 'c3101a17ce9634f4c1f9800f0746c187', + 'info_dict': { + 'id': '1058509', + 'ext': 'flv', + 'title': 'Farlig kryssning', + 'duration': 2566, + 'thumbnail': 're:^https?://.*[\.-]jpg$', + 'age_limit': 0, + }, + 'skip': 'Only works from Sweden', + }] + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + host = mobj.group('host') + + info = self._download_json( + 'http://www.%s.se/video/%s?output=json' % (host, video_id), video_id) + + title = info['context']['title'] + thumbnail = info['context'].get('thumbnailImage') + + video_info = info['video'] + formats = [] + for vr in video_info['videoReferences']: + vurl = vr['url'] + ext = determine_ext(vurl) + if ext == 'm3u8': + formats.extend(self._extract_m3u8_formats( + vurl, video_id, + ext='mp4', entry_protocol='m3u8_native', + m3u8_id=vr.get('playerType'))) + elif ext == 'f4m': + formats.extend(self._extract_f4m_formats( + vurl + '?hdcore=3.3.0', video_id, + f4m_id=vr.get('playerType'))) + else: + formats.append({ + 'format_id': vr.get('playerType'), + 'url': vurl, + }) + self._sort_formats(formats) + + duration = video_info.get('materialLength') + age_limit = 18 if video_info.get('inappropriateForChildren') else 0 + + return { + 'id': video_id, + 'title': title, + 'formats': formats, + 'thumbnail': thumbnail, + 'duration': duration, + 'age_limit': age_limit, + } diff --git a/youtube_dl/extractor/teamcoco.py b/youtube_dl/extractor/teamcoco.py index 18a8237..5793dbc 100644 --- a/youtube_dl/extractor/teamcoco.py +++ b/youtube_dl/extractor/teamcoco.py @@ -1,8 +1,10 @@ from __future__ import unicode_literals +import base64 import re from .common import InfoExtractor +from ..utils import qualities class TeamcocoIE(InfoExtractor): @@ -15,7 +17,8 @@ class TeamcocoIE(InfoExtractor): 'id': '80187', 'ext': 'mp4', 'title': 'Conan Becomes A Mary Kay Beauty Consultant', - 'description': 'Mary Kay is perhaps the most trusted name in female beauty, so of course Conan is a natural choice to sell their products.' + 'description': 'Mary Kay is perhaps the most trusted name in female beauty, so of course Conan is a natural choice to sell their products.', + 'age_limit': 0, } }, { 'url': 'http://teamcoco.com/video/louis-ck-interview-george-w-bush', @@ -23,11 +26,17 @@ class TeamcocoIE(InfoExtractor): 'info_dict': { 'id': '19705', 'ext': 'mp4', - "description": "Louis C.K. got starstruck by George W. Bush, so what? Part one.", - "title": "Louis C.K. Interview Pt. 1 11/3/11" + 'description': 'Louis C.K. got starstruck by George W. Bush, so what? Part one.', + 'title': 'Louis C.K. Interview Pt. 1 11/3/11', + 'age_limit': 0, } } ] + _VIDEO_ID_REGEXES = ( + r'"eVar42"\s*:\s*(\d+)', + r'Ginger\.TeamCoco\.openInApp\("video",\s*"([^"]+)"', + r'"id_not"\s*:\s*(\d+)' + ) def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) @@ -35,43 +44,39 @@ class TeamcocoIE(InfoExtractor): display_id = mobj.group('display_id') webpage = self._download_webpage(url, display_id) - video_id = mobj.group("video_id") + video_id = mobj.group('video_id') if not video_id: video_id = self._html_search_regex( - r'<div\s+class="player".*?data-id="(\d+?)"', - webpage, 'video id') + self._VIDEO_ID_REGEXES, webpage, 'video id') - data_url = 'http://teamcoco.com/cvp/2.0/%s.xml' % video_id - data = self._download_xml( - data_url, display_id, 'Downloading data webpage') + embed_url = 'http://teamcoco.com/embed/v/%s' % video_id + embed = self._download_webpage( + embed_url, video_id, 'Downloading embed page') + + encoded_data = self._search_regex( + r'"preload"\s*:\s*"([^"]+)"', embed, 'encoded data') + data = self._parse_json( + base64.b64decode(encoded_data.encode('ascii')).decode('utf-8'), video_id) - qualities = ['500k', '480p', '1000k', '720p', '1080p'] formats = [] - for filed in data.findall('files/file'): - if filed.attrib.get('playmode') == 'all': - # it just duplicates one of the entries - break - file_url = filed.text - m_format = re.search(r'(\d+(k|p))\.mp4', file_url) + get_quality = qualities(['500k', '480p', '1000k', '720p', '1080p']) + for filed in data['files']: + m_format = re.search(r'(\d+(k|p))\.mp4', filed['url']) if m_format is not None: format_id = m_format.group(1) else: - format_id = filed.attrib['bitrate'] + format_id = filed['bitrate'] tbr = ( - int(filed.attrib['bitrate']) - if filed.attrib['bitrate'].isdigit() + int(filed['bitrate']) + if filed['bitrate'].isdigit() else None) - try: - quality = qualities.index(format_id) - except ValueError: - quality = -1 formats.append({ - 'url': file_url, + 'url': filed['url'], 'ext': 'mp4', 'tbr': tbr, 'format_id': format_id, - 'quality': quality, + 'quality': get_quality(format_id), }) self._sort_formats(formats) @@ -80,7 +85,8 @@ class TeamcocoIE(InfoExtractor): 'id': video_id, 'display_id': display_id, 'formats': formats, - 'title': self._og_search_title(webpage), - 'thumbnail': self._og_search_thumbnail(webpage), - 'description': self._og_search_description(webpage), + 'title': data['title'], + 'thumbnail': data.get('thumb', {}).get('href'), + 'description': data.get('teaser'), + 'age_limit': self._family_friendly_search(webpage), } diff --git a/youtube_dl/extractor/ted.py b/youtube_dl/extractor/ted.py index 10b3b70..4cec06f 100644 --- a/youtube_dl/extractor/ted.py +++ b/youtube_dl/extractor/ted.py @@ -3,14 +3,14 @@ from __future__ import unicode_literals import json import re -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..compat import ( compat_str, ) -class TEDIE(SubtitlesInfoExtractor): +class TEDIE(InfoExtractor): _VALID_URL = r'''(?x) (?P<proto>https?://) (?P<type>www|embed(?:-ssl)?)(?P<urlmain>\.ted\.com/ @@ -83,6 +83,22 @@ class TEDIE(SubtitlesInfoExtractor): 'params': { 'skip_download': True, }, + }, { + # YouTube video + 'url': 'http://www.ted.com/talks/jeffrey_kluger_the_sibling_bond', + 'add_ie': ['Youtube'], + 'info_dict': { + 'id': 'aFBIPO-P7LM', + 'ext': 'mp4', + 'title': 'The hidden power of siblings: Jeff Kluger at TEDxAsheville', + 'description': 'md5:3d7a4f50d95ca5dd67104e2a20f43fe1', + 'uploader': 'TEDx Talks', + 'uploader_id': 'TEDxTalks', + 'upload_date': '20111216', + }, + 'params': { + 'skip_download': True, + }, }] _NATIVE_FORMATS = { @@ -132,11 +148,16 @@ class TEDIE(SubtitlesInfoExtractor): talk_info = self._extract_info(webpage)['talks'][0] - if talk_info.get('external') is not None: - self.to_screen('Found video from %s' % talk_info['external']['service']) + external = talk_info.get('external') + if external: + service = external['service'] + self.to_screen('Found video from %s' % service) + ext_url = None + if service.lower() == 'youtube': + ext_url = external.get('code') return { '_type': 'url', - 'url': talk_info['external']['uri'], + 'url': ext_url or external['uri'], } formats = [{ @@ -163,11 +184,6 @@ class TEDIE(SubtitlesInfoExtractor): self._sort_formats(formats) video_id = compat_str(talk_info['id']) - # subtitles - video_subtitles = self.extract_subtitles(video_id, talk_info) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, talk_info) - return thumbnail = talk_info['thumb'] if not thumbnail.startswith('http'): @@ -178,21 +194,25 @@ class TEDIE(SubtitlesInfoExtractor): 'uploader': talk_info['speaker'], 'thumbnail': thumbnail, 'description': self._og_search_description(webpage), - 'subtitles': video_subtitles, + 'subtitles': self._get_subtitles(video_id, talk_info), 'formats': formats, 'duration': talk_info.get('duration'), } - def _get_available_subtitles(self, video_id, talk_info): + def _get_subtitles(self, video_id, talk_info): languages = [lang['languageCode'] for lang in talk_info.get('languages', [])] if languages: sub_lang_list = {} for l in languages: - url = 'http://www.ted.com/talks/subtitles/id/%s/lang/%s/format/srt' % (video_id, l) - sub_lang_list[l] = url + sub_lang_list[l] = [ + { + 'url': 'http://www.ted.com/talks/subtitles/id/%s/lang/%s/format/%s' % (video_id, l, ext), + 'ext': ext, + } + for ext in ['ted', 'srt'] + ] return sub_lang_list else: - self._downloader.report_warning('video doesn\'t have subtitles') return {} def _watch_info(self, url, name): diff --git a/youtube_dl/extractor/telecinco.py b/youtube_dl/extractor/telecinco.py index be3f72d..251a686 100644 --- a/youtube_dl/extractor/telecinco.py +++ b/youtube_dl/extractor/telecinco.py @@ -6,9 +6,9 @@ from .mitele import MiTeleIE class TelecincoIE(MiTeleIE): IE_NAME = 'telecinco.es' - _VALID_URL = r'https?://www\.telecinco\.es/[^/]+/[^/]+/[^/]+/(?P<id>.*?)\.html' + _VALID_URL = r'https?://www\.telecinco\.es/[^/]+/[^/]+/(?:[^/]+/)?(?P<id>.*?)\.html' - _TEST = { + _TESTS = [{ 'url': 'http://www.telecinco.es/robinfood/temporada-01/t01xp14/Bacalao-cocochas-pil-pil_0_1876350223.html', 'info_dict': { 'id': 'MDSVID20141015_0058', @@ -16,4 +16,7 @@ class TelecincoIE(MiTeleIE): 'title': 'Con Martín Berasategui, hacer un bacalao al ...', 'duration': 662, }, - } + }, { + 'url': 'http://www.telecinco.es/informativos/nacional/Pablo_Iglesias-Informativos_Telecinco-entrevista-Pedro_Piqueras_2_1945155182.html', + 'only_matching': True, + }] diff --git a/youtube_dl/extractor/theonion.py b/youtube_dl/extractor/theonion.py index b65d8e0..10239c9 100644 --- a/youtube_dl/extractor/theonion.py +++ b/youtube_dl/extractor/theonion.py @@ -4,11 +4,10 @@ from __future__ import unicode_literals import re from .common import InfoExtractor -from ..utils import ExtractorError class TheOnionIE(InfoExtractor): - _VALID_URL = r'(?x)https?://(?:www\.)?theonion\.com/video/[^,]+,(?P<article_id>[0-9]+)/?' + _VALID_URL = r'https?://(?:www\.)?theonion\.com/video/[^,]+,(?P<id>[0-9]+)/?' _TEST = { 'url': 'http://www.theonion.com/video/man-wearing-mm-jacket-gods-image,36918/', 'md5': '19eaa9a39cf9b9804d982e654dc791ee', @@ -22,10 +21,8 @@ class TheOnionIE(InfoExtractor): } def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - article_id = mobj.group('article_id') - - webpage = self._download_webpage(url, article_id) + display_id = self._match_id(url) + webpage = self._download_webpage(url, display_id) video_id = self._search_regex( r'"videoId":\s(\d+),', webpage, 'video ID') @@ -34,10 +31,6 @@ class TheOnionIE(InfoExtractor): thumbnail = self._og_search_thumbnail(webpage) sources = re.findall(r'<source src="([^"]+)" type="([^"]+)"', webpage) - if not sources: - raise ExtractorError( - 'No sources found for video %s' % video_id, expected=True) - formats = [] for src, type_ in sources: if type_ == 'video/mp4': @@ -54,15 +47,15 @@ class TheOnionIE(InfoExtractor): }) elif type_ == 'application/x-mpegURL': formats.extend( - self._extract_m3u8_formats(src, video_id, preference=-1)) + self._extract_m3u8_formats(src, display_id, preference=-1)) else: self.report_warning( 'Encountered unexpected format: %s' % type_) - self._sort_formats(formats) return { 'id': video_id, + 'display_id': display_id, 'title': title, 'formats': formats, 'thumbnail': thumbnail, diff --git a/youtube_dl/extractor/theplatform.py b/youtube_dl/extractor/theplatform.py index 110ed97..feac666 100644 --- a/youtube_dl/extractor/theplatform.py +++ b/youtube_dl/extractor/theplatform.py @@ -2,8 +2,13 @@ from __future__ import unicode_literals import re import json +import time +import hmac +import binascii +import hashlib -from .subtitles import SubtitlesInfoExtractor + +from .common import InfoExtractor from ..compat import ( compat_str, ) @@ -11,14 +16,15 @@ from ..utils import ( determine_ext, ExtractorError, xpath_with_ns, + unsmuggle_url, ) _x = lambda p: xpath_with_ns(p, {'smil': 'http://www.w3.org/2005/SMIL21/Language'}) -class ThePlatformIE(SubtitlesInfoExtractor): +class ThePlatformIE(InfoExtractor): _VALID_URL = r'''(?x) - (?:https?://(?:link|player)\.theplatform\.com/[sp]/[^/]+/ + (?:https?://(?:link|player)\.theplatform\.com/[sp]/(?P<provider_id>[^/]+)/ (?P<config>(?:[^/\?]+/(?:swf|config)|onsite)/select/)? |theplatform:)(?P<id>[^/\?&]+)''' @@ -38,18 +44,48 @@ class ThePlatformIE(SubtitlesInfoExtractor): }, } + @staticmethod + def _sign_url(url, sig_key, sig_secret, life=600, include_qs=False): + flags = '10' if include_qs else '00' + expiration_date = '%x' % (int(time.time()) + life) + + def str_to_hex(str): + return binascii.b2a_hex(str.encode('ascii')).decode('ascii') + + def hex_to_str(hex): + return binascii.a2b_hex(hex) + + relative_path = url.split('http://link.theplatform.com/s/')[1].split('?')[0] + clear_text = hex_to_str(flags + expiration_date + str_to_hex(relative_path)) + checksum = hmac.new(sig_key.encode('ascii'), clear_text, hashlib.sha1).hexdigest() + sig = flags + expiration_date + checksum + str_to_hex(sig_secret) + return '%s&sig=%s' % (url, sig) + def _real_extract(self, url): + url, smuggled_data = unsmuggle_url(url, {}) + mobj = re.match(self._VALID_URL, url) + provider_id = mobj.group('provider_id') video_id = mobj.group('id') - if mobj.group('config'): + + if not provider_id: + provider_id = 'dJ5BDC' + + if smuggled_data.get('force_smil_url', False): + smil_url = url + elif mobj.group('config'): config_url = url + '&form=json' config_url = config_url.replace('swf/', 'config/') config_url = config_url.replace('onsite/', 'onsite/config/') config = self._download_json(config_url, video_id, 'Downloading config') smil_url = config['releaseUrl'] + '&format=SMIL&formats=MPEG4&manifest=f4m' else: - smil_url = ('http://link.theplatform.com/s/dJ5BDC/{0}/meta.smil?' - 'format=smil&mbr=true'.format(video_id)) + smil_url = ('http://link.theplatform.com/s/{0}/{1}/meta.smil?' + 'format=smil&mbr=true'.format(provider_id, video_id)) + + sig = smuggled_data.get('sig') + if sig: + smil_url = self._sign_url(smil_url, sig['key'], sig['secret']) meta = self._download_xml(smil_url, video_id) try: @@ -62,7 +98,7 @@ class ThePlatformIE(SubtitlesInfoExtractor): else: raise ExtractorError(error_msg, expected=True) - info_url = 'http://link.theplatform.com/s/dJ5BDC/{0}?format=preview'.format(video_id) + info_url = 'http://link.theplatform.com/s/{0}/{1}?format=preview'.format(provider_id, video_id) info_json = self._download_webpage(info_url, video_id) info = json.loads(info_json) @@ -70,15 +106,11 @@ class ThePlatformIE(SubtitlesInfoExtractor): captions = info.get('captions') if isinstance(captions, list): for caption in captions: - lang, src = caption.get('lang'), caption.get('src') - if lang and src: - subtitles[lang] = src - - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return - - subtitles = self.extract_subtitles(video_id, subtitles) + lang, src, mime = caption.get('lang', 'en'), caption.get('src'), caption.get('type') + subtitles[lang] = [{ + 'ext': 'srt' if mime == 'text/srt' else 'ttml', + 'url': src, + }] head = meta.find(_x('smil:head')) body = meta.find(_x('smil:body')) diff --git a/youtube_dl/extractor/trilulilu.py b/youtube_dl/extractor/trilulilu.py index 220a05b..185accc 100644 --- a/youtube_dl/extractor/trilulilu.py +++ b/youtube_dl/extractor/trilulilu.py @@ -1,40 +1,55 @@ +# coding: utf-8 from __future__ import unicode_literals -import json +import re from .common import InfoExtractor +from ..utils import ExtractorError class TriluliluIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?trilulilu\.ro/video-[^/]+/(?P<id>[^/]+)' + _VALID_URL = r'https?://(?:www\.)?trilulilu\.ro/(?:video-[^/]+/)?(?P<id>[^/#\?]+)' _TEST = { 'url': 'http://www.trilulilu.ro/video-animatie/big-buck-bunny-1', + 'md5': 'c1450a00da251e2769b74b9005601cac', 'info_dict': { - 'id': 'big-buck-bunny-1', + 'id': 'ae2899e124140b', 'ext': 'mp4', 'title': 'Big Buck Bunny', 'description': ':) pentru copilul din noi', }, - # Server ignores Range headers (--test) - 'params': { - 'skip_download': True - } } def _real_extract(self, url): - video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) + display_id = self._match_id(url) + webpage = self._download_webpage(url, display_id) + + if re.search(r'Fişierul nu este disponibil pentru vizionare în Å£ara dumneavoastră', webpage): + raise ExtractorError( + 'This video is not available in your country.', expected=True) + elif re.search('Fişierul poate fi accesat doar de către prietenii lui', webpage): + raise ExtractorError('This video is private.', expected=True) + + flashvars_str = self._search_regex( + r'block_flash_vars\s*=\s*(\{[^\}]+\})', webpage, 'flashvars', fatal=False, default=None) + if flashvars_str: + flashvars = self._parse_json(flashvars_str, display_id) + else: + raise ExtractorError( + 'This page does not contain videos', expected=True) + + if flashvars['isMP3'] == 'true': + raise ExtractorError( + 'Audio downloads are currently not supported', expected=True) + + video_id = flashvars['hash'] title = self._og_search_title(webpage) thumbnail = self._og_search_thumbnail(webpage) - description = self._og_search_description(webpage) - - log_str = self._search_regex( - r'block_flash_vars[ ]=[ ]({[^}]+})', webpage, 'log info') - log = json.loads(log_str) + description = self._og_search_description(webpage, default=None) format_url = ('http://fs%(server)s.trilulilu.ro/%(hash)s/' - 'video-formats2' % log) + 'video-formats2' % flashvars) format_doc = self._download_xml( format_url, video_id, note='Downloading formats', @@ -44,10 +59,10 @@ class TriluliluIE(InfoExtractor): 'http://fs%(server)s.trilulilu.ro/stream.php?type=video' '&source=site&hash=%(hash)s&username=%(userid)s&' 'key=ministhebest&format=%%s&sig=&exp=' % - log) + flashvars) formats = [ { - 'format': fnode.text, + 'format_id': fnode.text.partition('-')[2], 'url': video_url_template % fnode.text, 'ext': fnode.text.partition('-')[0] } @@ -56,8 +71,8 @@ class TriluliluIE(InfoExtractor): ] return { - '_type': 'video', 'id': video_id, + 'display_id': display_id, 'formats': formats, 'title': title, 'description': description, diff --git a/youtube_dl/extractor/tv4.py b/youtube_dl/extractor/tv4.py new file mode 100644 index 0000000..1c4b6d6 --- /dev/null +++ b/youtube_dl/extractor/tv4.py @@ -0,0 +1,100 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import ( + ExtractorError, + parse_iso8601, +) + + +class TV4IE(InfoExtractor): + IE_DESC = 'tv4.se and tv4play.se' + _VALID_URL = r'''(?x)https?://(?:www\.)? + (?: + tv4\.se/(?:[^/]+)/klipp/(?:.*)-| + tv4play\.se/ + (?: + (?:program|barn)/(?:[^\?]+)\?video_id=| + iframe/video/| + film/| + sport/| + ) + )(?P<id>[0-9]+)''' + _TESTS = [ + { + 'url': 'http://www.tv4.se/kalla-fakta/klipp/kalla-fakta-5-english-subtitles-2491650', + 'md5': '909d6454b87b10a25aa04c4bdd416a9b', + 'info_dict': { + 'id': '2491650', + 'ext': 'mp4', + 'title': 'Kalla Fakta 5 (english subtitles)', + 'thumbnail': 're:^https?://.*\.jpg$', + 'timestamp': int, + 'upload_date': '20131125', + }, + }, + { + 'url': 'http://www.tv4play.se/iframe/video/3054113', + 'md5': '77f851c55139ffe0ebd41b6a5552489b', + 'info_dict': { + 'id': '3054113', + 'ext': 'mp4', + 'title': 'SÃ¥ här jobbar ficktjuvarna - se avslöjande bilder', + 'thumbnail': 're:^https?://.*\.jpg$', + 'description': 'Unika bilder avslöjar hur turisternas fickor vittjas mitt pÃ¥ Stockholms central. TvÃ¥ experter pÃ¥ ficktjuvarna avslöjar knepen du ska se upp för.', + 'timestamp': int, + 'upload_date': '20150130', + }, + }, + { + 'url': 'http://www.tv4play.se/sport/3060959', + 'only_matching': True, + }, + { + 'url': 'http://www.tv4play.se/film/2378136', + 'only_matching': True, + }, + { + 'url': 'http://www.tv4play.se/barn/looney-tunes?video_id=3062412', + 'only_matching': True, + }, + ] + + def _real_extract(self, url): + video_id = self._match_id(url) + + info = self._download_json( + 'http://www.tv4play.se/player/assets/%s.json' % video_id, video_id, 'Downloading video info JSON') + + # If is_geo_restricted is true, it doesn't neceserally mean we can't download it + if info['is_geo_restricted']: + self.report_warning('This content might not be available in your country due to licensing restrictions.') + if info['requires_subscription']: + raise ExtractorError('This content requires subscription.', expected=True) + + sources_data = self._download_json( + 'https://prima.tv4play.se/api/web/asset/%s/play.json?protocol=http&videoFormat=MP4' % video_id, video_id, 'Downloading sources JSON') + sources = sources_data['playback'] + + formats = [] + for item in sources.get('items', {}).get('item', []): + ext, bitrate = item['mediaFormat'], item['bitrate'] + formats.append({ + 'format_id': '%s_%s' % (ext, bitrate), + 'tbr': bitrate, + 'ext': ext, + 'url': item['url'], + }) + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': info['title'], + 'formats': formats, + 'description': info.get('description'), + 'timestamp': parse_iso8601(info.get('broadcast_date_time')), + 'duration': info.get('duration'), + 'thumbnail': info.get('image'), + 'is_live': sources.get('live'), + } diff --git a/youtube_dl/extractor/tvigle.py b/youtube_dl/extractor/tvigle.py index ba65996..102362b 100644 --- a/youtube_dl/extractor/tvigle.py +++ b/youtube_dl/extractor/tvigle.py @@ -1,6 +1,8 @@ # encoding: utf-8 from __future__ import unicode_literals +import re + from .common import InfoExtractor from ..utils import ( float_or_none, @@ -11,7 +13,7 @@ from ..utils import ( class TvigleIE(InfoExtractor): IE_NAME = 'tvigle' IE_DESC = 'Интернет-телевидение Tvigle.ru' - _VALID_URL = r'http://(?:www\.)?tvigle\.ru/(?:[^/]+/)+(?P<id>[^/]+)/$' + _VALID_URL = r'https?://(?:www\.)?(?:tvigle\.ru/(?:[^/]+/)+(?P<display_id>[^/]+)/$|cloud\.tvigle\.ru/video/(?P<id>\d+))' _TESTS = [ { @@ -38,16 +40,22 @@ class TvigleIE(InfoExtractor): 'duration': 186.080, 'age_limit': 0, }, - }, + }, { + 'url': 'https://cloud.tvigle.ru/video/5267604/', + 'only_matching': True, + } ] def _real_extract(self, url): - display_id = self._match_id(url) - - webpage = self._download_webpage(url, display_id) + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + display_id = mobj.group('display_id') - video_id = self._html_search_regex( - r'<li class="video-preview current_playing" id="(\d+)">', webpage, 'video id') + if not video_id: + webpage = self._download_webpage(url, display_id) + video_id = self._html_search_regex( + r'<li class="video-preview current_playing" id="(\d+)">', + webpage, 'video id') video_data = self._download_json( 'http://cloud.tvigle.ru/api/play/video/%s/' % video_id, display_id) diff --git a/youtube_dl/extractor/twitch.py b/youtube_dl/extractor/twitch.py index 87290d0..4b0ce54 100644 --- a/youtube_dl/extractor/twitch.py +++ b/youtube_dl/extractor/twitch.py @@ -34,7 +34,15 @@ class TwitchBaseIE(InfoExtractor): expected=True) def _download_json(self, url, video_id, note='Downloading JSON metadata'): - response = super(TwitchBaseIE, self)._download_json(url, video_id, note) + headers = { + 'Referer': 'http://api.twitch.tv/crossdomain/receiver.html?v=2', + 'X-Requested-With': 'XMLHttpRequest', + } + for cookie in self._downloader.cookiejar: + if cookie.name == 'api_token': + headers['Twitch-Api-Token'] = cookie.value + request = compat_urllib_request.Request(url, headers=headers) + response = super(TwitchBaseIE, self)._download_json(request, video_id, note) self._handle_error(response) return response @@ -349,6 +357,13 @@ class TwitchStreamIE(TwitchBaseIE): % (self._USHER_BASE, channel_id, compat_urllib_parse.urlencode(query).encode('utf-8')), channel_id, 'mp4') + # prefer the 'source' stream, the others are limited to 30 fps + def _sort_source(f): + if f.get('m3u8_media') is not None and f['m3u8_media'].get('NAME') == 'Source': + return 1 + return 0 + formats = sorted(formats, key=_sort_source) + view_count = stream.get('viewers') timestamp = parse_iso8601(stream.get('created_at')) diff --git a/youtube_dl/extractor/videolecturesnet.py b/youtube_dl/extractor/videolecturesnet.py index ebd2a3d..d6a7eb2 100644 --- a/youtube_dl/extractor/videolecturesnet.py +++ b/youtube_dl/extractor/videolecturesnet.py @@ -49,15 +49,31 @@ class VideoLecturesNetIE(InfoExtractor): thumbnail = ( None if thumbnail_el is None else thumbnail_el.attrib.get('src')) - formats = [{ - 'url': v.attrib['src'], - 'width': int_or_none(v.attrib.get('width')), - 'height': int_or_none(v.attrib.get('height')), - 'filesize': int_or_none(v.attrib.get('size')), - 'tbr': int_or_none(v.attrib.get('systemBitrate')) / 1000.0, - 'ext': v.attrib.get('ext'), - } for v in switch.findall('./video') - if v.attrib.get('proto') == 'http'] + formats = [] + for v in switch.findall('./video'): + proto = v.attrib.get('proto') + if proto not in ['http', 'rtmp']: + continue + f = { + 'width': int_or_none(v.attrib.get('width')), + 'height': int_or_none(v.attrib.get('height')), + 'filesize': int_or_none(v.attrib.get('size')), + 'tbr': int_or_none(v.attrib.get('systemBitrate')) / 1000.0, + 'ext': v.attrib.get('ext'), + } + src = v.attrib['src'] + if proto == 'http': + if self._is_valid_url(src, video_id): + f['url'] = src + formats.append(f) + elif proto == 'rtmp': + f.update({ + 'url': v.attrib['streamer'], + 'play_path': src, + 'rtmp_real_time': True, + }) + formats.append(f) + self._sort_formats(formats) return { 'id': video_id, diff --git a/youtube_dl/extractor/viki.py b/youtube_dl/extractor/viki.py index 944901e..6816dac 100644 --- a/youtube_dl/extractor/viki.py +++ b/youtube_dl/extractor/viki.py @@ -2,16 +2,17 @@ from __future__ import unicode_literals import re +from ..compat import compat_urlparse from ..utils import ( ExtractorError, unescapeHTML, unified_strdate, US_RATINGS, ) -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor -class VikiIE(SubtitlesInfoExtractor): +class VikiIE(InfoExtractor): IE_NAME = 'viki' _VALID_URL = r'^https?://(?:www\.)?viki\.com/videos/(?P<id>[0-9]+v)' @@ -69,9 +70,6 @@ class VikiIE(SubtitlesInfoExtractor): # subtitles video_subtitles = self.extract_subtitles(video_id, info_webpage) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, info_webpage) - return return { 'id': video_id, @@ -85,12 +83,15 @@ class VikiIE(SubtitlesInfoExtractor): 'upload_date': upload_date, } - def _get_available_subtitles(self, video_id, info_webpage): + def _get_subtitles(self, video_id, info_webpage): res = {} - for sturl_html in re.findall(r'<track src="([^"]+)"/>', info_webpage): + for sturl_html in re.findall(r'<track src="([^"]+)"', info_webpage): sturl = unescapeHTML(sturl_html) m = re.search(r'/(?P<lang>[a-z]+)\.vtt', sturl) if not m: continue - res[m.group('lang')] = sturl + res[m.group('lang')] = [{ + 'url': compat_urlparse.urljoin('http://www.viki.com', sturl), + 'ext': 'vtt', + }] return res diff --git a/youtube_dl/extractor/vimeo.py b/youtube_dl/extractor/vimeo.py index 1bb4735..8f540f5 100644 --- a/youtube_dl/extractor/vimeo.py +++ b/youtube_dl/extractor/vimeo.py @@ -4,9 +4,9 @@ from __future__ import unicode_literals import json import re import itertools +import hashlib from .common import InfoExtractor -from .subtitles import SubtitlesInfoExtractor from ..compat import ( compat_HTTPError, compat_urllib_parse, @@ -18,6 +18,7 @@ from ..utils import ( InAdvancePagedList, int_or_none, RegexNotFoundError, + smuggle_url, std_headers, unsmuggle_url, urlencode_postdata, @@ -51,7 +52,7 @@ class VimeoBaseInfoExtractor(InfoExtractor): self._download_webpage(login_request, None, False, 'Wrong login info') -class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): +class VimeoIE(VimeoBaseInfoExtractor): """Information extractor for vimeo.com.""" # _VALID_URL matches Vimeo URLs @@ -174,7 +175,7 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): def _verify_video_password(self, url, video_id, webpage): password = self._downloader.params.get('videopassword', None) 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) token = self._search_regex(r'xsrft: \'(.*?)\'', webpage, 'login token') data = compat_urllib_parse.urlencode({ 'password': password, @@ -188,9 +189,9 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): password_request = compat_urllib_request.Request(pass_url + '/password', data) password_request.add_header('Content-Type', 'application/x-www-form-urlencoded') password_request.add_header('Cookie', 'xsrft=%s' % token) - self._download_webpage(password_request, video_id, - 'Verifying the password', - 'Wrong password') + return self._download_webpage( + password_request, video_id, + 'Verifying the password', 'Wrong password') def _verify_player_video_password(self, url, video_id): password = self._downloader.params.get('videopassword', None) @@ -224,6 +225,11 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): if mobj.group('pro') or mobj.group('player'): url = 'http://player.vimeo.com/video/' + video_id + password = self._downloader.params.get('videopassword', None) + if password: + headers['Cookie'] = '%s_password=%s' % ( + video_id, hashlib.md5(password.encode('utf-8')).hexdigest()) + # Retrieve video webpage to extract further information request = compat_urllib_request.Request(url, None, headers) try: @@ -266,9 +272,12 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): if re.search('The creator of this video has not given you permission to embed it on this domain.', webpage): raise ExtractorError('The author has restricted the access to this video, try with the "--referer" option') - if re.search('<form[^>]+?id="pw_form"', webpage) is not None: + if re.search(r'<form[^>]+?id="pw_form"', webpage) is not None: + if data and '_video_password_verified' in data: + raise ExtractorError('video password verification failed!') self._verify_video_password(url, video_id, webpage) - return self._real_extract(url) + return self._real_extract( + smuggle_url(url, {'_video_password_verified': 'verified'})) else: raise ExtractorError('Unable to extract info section', cause=e) @@ -368,12 +377,10 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): text_tracks = config['request'].get('text_tracks') if text_tracks: for tt in text_tracks: - subtitles[tt['lang']] = 'http://vimeo.com' + tt['url'] - - video_subtitles = self.extract_subtitles(video_id, subtitles) - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return + subtitles[tt['lang']] = [{ + 'ext': 'vtt', + 'url': 'http://vimeo.com' + tt['url'], + }] return { 'id': video_id, @@ -389,7 +396,7 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): 'view_count': view_count, 'like_count': like_count, 'comment_count': comment_count, - 'subtitles': video_subtitles, + 'subtitles': subtitles, } @@ -401,6 +408,7 @@ class VimeoChannelIE(InfoExtractor): _TESTS = [{ 'url': 'http://vimeo.com/channels/tributes', 'info_dict': { + 'id': 'tributes', 'title': 'Vimeo Tributes', }, 'playlist_mincount': 25, @@ -412,12 +420,47 @@ class VimeoChannelIE(InfoExtractor): def _extract_list_title(self, webpage): return self._html_search_regex(self._TITLE_RE, webpage, 'list title') + def _login_list_password(self, page_url, list_id, webpage): + login_form = self._search_regex( + r'(?s)<form[^>]+?id="pw_form"(.*?)</form>', + webpage, 'login form', default=None) + if not login_form: + return webpage + + password = self._downloader.params.get('videopassword', None) + if password is None: + raise ExtractorError('This album is protected by a password, use the --video-password option', expected=True) + fields = dict(re.findall(r'''(?x)<input\s+ + type="hidden"\s+ + name="([^"]+)"\s+ + value="([^"]*)" + ''', login_form)) + token = self._search_regex(r'xsrft: \'(.*?)\'', webpage, 'login token') + fields['token'] = token + fields['password'] = password + post = compat_urllib_parse.urlencode(fields) + password_path = self._search_regex( + r'action="([^"]+)"', login_form, 'password URL') + password_url = compat_urlparse.urljoin(page_url, password_path) + password_request = compat_urllib_request.Request(password_url, post) + password_request.add_header('Content-type', 'application/x-www-form-urlencoded') + self._set_cookie('vimeo.com', 'xsrft', token) + + return self._download_webpage( + password_request, list_id, + 'Verifying the password', 'Wrong password') + def _extract_videos(self, list_id, base_url): video_ids = [] for pagenum in itertools.count(1): + page_url = self._page_url(base_url, pagenum) webpage = self._download_webpage( - self._page_url(base_url, pagenum), list_id, + page_url, list_id, 'Downloading page %s' % pagenum) + + if pagenum == 1: + webpage = self._login_list_password(page_url, list_id, webpage) + video_ids.extend(re.findall(r'id="clip_(\d+?)"', webpage)) if re.search(self._MORE_PAGES_INDICATOR, webpage, re.DOTALL) is None: break @@ -444,6 +487,7 @@ class VimeoUserIE(VimeoChannelIE): 'url': 'http://vimeo.com/nkistudio/videos', 'info_dict': { 'title': 'Nki', + 'id': 'nkistudio', }, 'playlist_mincount': 66, }] @@ -461,17 +505,28 @@ class VimeoAlbumIE(VimeoChannelIE): _TESTS = [{ 'url': 'http://vimeo.com/album/2632481', 'info_dict': { + 'id': '2632481', 'title': 'Staff Favorites: November 2013', }, 'playlist_mincount': 13, + }, { + 'note': 'Password-protected album', + 'url': 'https://vimeo.com/album/3253534', + 'info_dict': { + 'title': 'test', + 'id': '3253534', + }, + 'playlist_count': 1, + 'params': { + 'videopassword': 'youtube-dl', + } }] def _page_url(self, base_url, pagenum): return '%s/page:%d/' % (base_url, pagenum) def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - album_id = mobj.group('id') + album_id = self._match_id(url) return self._extract_videos(album_id, 'http://vimeo.com/album/%s' % album_id) @@ -481,6 +536,7 @@ class VimeoGroupsIE(VimeoAlbumIE): _TESTS = [{ 'url': 'http://vimeo.com/groups/rolexawards', 'info_dict': { + 'id': 'rolexawards', 'title': 'Rolex Awards for Enterprise', }, 'playlist_mincount': 73, @@ -563,6 +619,7 @@ class VimeoLikesIE(InfoExtractor): 'url': 'https://vimeo.com/user755559/likes/', 'playlist_mincount': 293, "info_dict": { + 'id': 'user755559_likes', "description": "See all the videos urza likes", "title": 'Videos urza likes', }, diff --git a/youtube_dl/extractor/vk.py b/youtube_dl/extractor/vk.py index 81e02a6..7dea8c5 100644 --- a/youtube_dl/extractor/vk.py +++ b/youtube_dl/extractor/vk.py @@ -217,6 +217,9 @@ class VKUserVideosIE(InfoExtractor): _TEMPLATE_URL = 'https://vk.com/videos' _TEST = { 'url': 'http://vk.com/videos205387401', + 'info_dict': { + 'id': '205387401', + }, 'playlist_mincount': 4, } diff --git a/youtube_dl/extractor/walla.py b/youtube_dl/extractor/walla.py index 672bda7..24efbd6 100644 --- a/youtube_dl/extractor/walla.py +++ b/youtube_dl/extractor/walla.py @@ -3,14 +3,14 @@ from __future__ import unicode_literals import re -from .subtitles import SubtitlesInfoExtractor +from .common import InfoExtractor from ..utils import ( xpath_text, int_or_none, ) -class WallaIE(SubtitlesInfoExtractor): +class WallaIE(InfoExtractor): _VALID_URL = r'http://vod\.walla\.co\.il/[^/]+/(?P<id>\d+)/(?P<display_id>.+)' _TEST = { 'url': 'http://vod.walla.co.il/movie/2642630/one-direction-all-for-one', @@ -52,13 +52,10 @@ class WallaIE(SubtitlesInfoExtractor): subtitles = {} for subtitle in item.findall('./subtitles/subtitle'): lang = xpath_text(subtitle, './title') - subtitles[self._SUBTITLE_LANGS.get(lang, lang)] = xpath_text(subtitle, './src') - - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, subtitles) - return - - subtitles = self.extract_subtitles(video_id, subtitles) + subtitles[self._SUBTITLE_LANGS.get(lang, lang)] = [{ + 'ext': 'srt', + 'url': xpath_text(subtitle, './src'), + }] formats = [] for quality in item.findall('./qualities/quality'): diff --git a/youtube_dl/extractor/wdr.py b/youtube_dl/extractor/wdr.py index c904885..b468023 100644 --- a/youtube_dl/extractor/wdr.py +++ b/youtube_dl/extractor/wdr.py @@ -28,6 +28,7 @@ class WDRIE(InfoExtractor): 'title': 'Servicezeit', 'description': 'md5:c8f43e5e815eeb54d0b96df2fba906cb', 'upload_date': '20140310', + 'is_live': False }, 'params': { 'skip_download': True, @@ -41,6 +42,7 @@ class WDRIE(InfoExtractor): 'title': 'Marga Spiegel ist tot', 'description': 'md5:2309992a6716c347891c045be50992e4', 'upload_date': '20140311', + 'is_live': False }, 'params': { 'skip_download': True, @@ -55,6 +57,7 @@ class WDRIE(InfoExtractor): 'title': 'Erlebte Geschichten: Marga Spiegel (29.11.2009)', 'description': 'md5:2309992a6716c347891c045be50992e4', 'upload_date': '20091129', + 'is_live': False }, }, { @@ -66,6 +69,7 @@ class WDRIE(InfoExtractor): 'title': 'Flavia Coelho: Amar é Amar', 'description': 'md5:7b29e97e10dfb6e265238b32fa35b23a', 'upload_date': '20140717', + 'is_live': False }, }, { @@ -74,6 +78,20 @@ class WDRIE(InfoExtractor): 'info_dict': { 'id': 'mediathek/video/sendungen/quarks_und_co/filterseite-quarks-und-co100', } + }, + { + 'url': 'http://www1.wdr.de/mediathek/video/livestream/index.html', + 'info_dict': { + 'id': 'mdb-103364', + 'title': 're:^WDR Fernsehen [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$', + 'description': 'md5:ae2ff888510623bf8d4b115f95a9b7c9', + 'ext': 'flv', + 'upload_date': '20150212', + 'is_live': True + }, + 'params': { + 'skip_download': True, + }, } ] @@ -119,6 +137,10 @@ class WDRIE(InfoExtractor): video_url = flashvars['dslSrc'][0] title = flashvars['trackerClipTitle'][0] thumbnail = flashvars['startPicture'][0] if 'startPicture' in flashvars else None + is_live = flashvars.get('isLive', ['0'])[0] == '1' + + if is_live: + title = self._live_title(title) if 'trackerClipAirTime' in flashvars: upload_date = flashvars['trackerClipAirTime'][0] @@ -131,6 +153,13 @@ class WDRIE(InfoExtractor): if video_url.endswith('.f4m'): video_url += '?hdcore=3.2.0&plugin=aasp-3.2.0.77.18' ext = 'flv' + elif video_url.endswith('.smil'): + fmt = self._extract_smil_formats(video_url, page_id)[0] + video_url = fmt['url'] + sep = '&' if '?' in video_url else '?' + video_url += sep + video_url += 'hdcore=3.3.0&plugin=aasp-3.3.0.99.43' + ext = fmt['ext'] else: ext = determine_ext(video_url) @@ -144,6 +173,7 @@ class WDRIE(InfoExtractor): 'description': description, 'thumbnail': thumbnail, 'upload_date': upload_date, + 'is_live': is_live } diff --git a/youtube_dl/extractor/webofstories.py b/youtube_dl/extractor/webofstories.py index 396cf4e..73077a3 100644 --- a/youtube_dl/extractor/webofstories.py +++ b/youtube_dl/extractor/webofstories.py @@ -45,19 +45,17 @@ class WebOfStoriesIE(InfoExtractor): description = self._html_search_meta('description', webpage) thumbnail = self._og_search_thumbnail(webpage) - story_filename = self._search_regex( - r'\.storyFileName\("([^"]+)"\)', webpage, 'story filename') - speaker_id = self._search_regex( - r'\.speakerId\("([^"]+)"\)', webpage, 'speaker ID') - story_id = self._search_regex( - r'\.storyId\((\d+)\)', webpage, 'story ID') - speaker_type = self._search_regex( - r'\.speakerType\("([^"]+)"\)', webpage, 'speaker type') - great_life = self._search_regex( - r'isGreatLifeStory\s*=\s*(true|false)', webpage, 'great life story') + embed_params = [s.strip(" \r\n\t'") for s in self._search_regex( + r'(?s)\$\("#embedCode"\).html\(getEmbedCode\((.*?)\)', + webpage, 'embed params').split(',')] + + ( + _, speaker_id, story_id, story_duration, + speaker_type, great_life, _thumbnail, _has_subtitles, + story_filename, _story_order) = embed_params + is_great_life_series = great_life == 'true' - duration = int_or_none(self._search_regex( - r'\.duration\((\d+)\)', webpage, 'duration', fatal=False)) + duration = int_or_none(story_duration) # URL building, see: http://www.webofstories.com/scripts/player.js ms_prefix = '' diff --git a/youtube_dl/extractor/wsj.py b/youtube_dl/extractor/wsj.py index cbe3dc7..2ddf29a 100644 --- a/youtube_dl/extractor/wsj.py +++ b/youtube_dl/extractor/wsj.py @@ -18,8 +18,8 @@ class WSJIE(InfoExtractor): 'id': '1BD01A4C-BFE8-40A5-A42F-8A8AF9898B1A', 'ext': 'mp4', 'upload_date': '20150202', - 'uploader_id': 'bbright', - 'creator': 'bbright', + 'uploader_id': 'jdesai', + 'creator': 'jdesai', 'categories': list, # a long list 'duration': 90, 'title': 'Bills Coach Rex Ryan Updates His Old Jets Tattoo', diff --git a/youtube_dl/extractor/xtube.py b/youtube_dl/extractor/xtube.py index e8490b0..1644f53 100644 --- a/youtube_dl/extractor/xtube.py +++ b/youtube_dl/extractor/xtube.py @@ -22,7 +22,7 @@ class XTubeIE(InfoExtractor): 'id': 'kVTUy_G222_', 'ext': 'mp4', 'title': 'strange erotica', - 'description': 'http://www.xtube.com an ET kind of thing', + 'description': 'contains:an ET kind of thing', 'uploader': 'greenshowers', 'duration': 450, 'age_limit': 18, diff --git a/youtube_dl/extractor/yahoo.py b/youtube_dl/extractor/yahoo.py index f8e7041..97dbac4 100644 --- a/youtube_dl/extractor/yahoo.py +++ b/youtube_dl/extractor/yahoo.py @@ -24,7 +24,6 @@ class YahooIE(InfoExtractor): _TESTS = [ { 'url': 'http://screen.yahoo.com/julian-smith-travis-legg-watch-214727115.html', - 'md5': '4962b075c08be8690a922ee026d05e69', 'info_dict': { 'id': '2d25e626-2378-391f-ada0-ddaf1417e588', 'ext': 'mp4', diff --git a/youtube_dl/extractor/yam.py b/youtube_dl/extractor/yam.py new file mode 100644 index 0000000..b294767 --- /dev/null +++ b/youtube_dl/extractor/yam.py @@ -0,0 +1,81 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..compat import compat_urlparse +from ..utils import ( + float_or_none, + month_by_abbreviation, +) + + +class YamIE(InfoExtractor): + _VALID_URL = r'http://mymedia.yam.com/m/(?P<id>\d+)' + + _TESTS = [{ + # An audio hosted on Yam + 'url': 'http://mymedia.yam.com/m/2283921', + 'md5': 'c011b8e262a52d5473d9c2e3c9963b9c', + 'info_dict': { + 'id': '2283921', + 'ext': 'mp3', + 'title': '發現 - 趙薇 京華煙雲主題曲', + 'uploader_id': 'princekt', + 'upload_date': '20080807', + 'duration': 313.0, + } + }, { + # An external video hosted on YouTube + 'url': 'http://mymedia.yam.com/m/3598173', + 'md5': '0238ceec479c654e8c2f1223755bf3e9', + 'info_dict': { + 'id': 'pJ2Deys283c', + 'ext': 'mp4', + 'upload_date': '20150202', + 'uploader': '新莊社大瑜伽社', + 'description': 'md5:f5cc72f0baf259a70fb731654b0d2eff', + 'uploader_id': '2323agoy', + 'title': '外婆的澎湖灣KTV-潘安邦', + } + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + page = self._download_webpage(url, video_id) + + # Is it hosted externally on YouTube? + youtube_url = self._html_search_regex( + r'<embed src="(http://www.youtube.com/[^"]+)"', + page, 'YouTube url', default=None) + if youtube_url: + return self.url_result(youtube_url, 'Youtube') + + api_page = self._download_webpage( + 'http://mymedia.yam.com/api/a/?pID=' + video_id, video_id, + note='Downloading API page') + api_result_obj = compat_urlparse.parse_qs(api_page) + + uploader_id = self._html_search_regex( + r'<!-- 發表作者 -->:[\n ]+<a href="/([a-z]+)"', + page, 'uploader id', fatal=False) + mobj = re.search(r'<!-- 發表於 -->(?P<mon>[A-Z][a-z]{2}) ' + + r'(?P<day>\d{1,2}), (?P<year>\d{4})', page) + if mobj: + upload_date = '%s%02d%02d' % ( + mobj.group('year'), + month_by_abbreviation(mobj.group('mon')), + int(mobj.group('day'))) + else: + upload_date = None + duration = float_or_none(api_result_obj['totaltime'][0], scale=1000) + + return { + 'id': video_id, + 'url': api_result_obj['mp3file'][0], + 'title': self._html_search_meta('description', page), + 'duration': duration, + 'uploader_id': uploader_id, + 'upload_date': upload_date, + } diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index e4b26b8..3690f80 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -11,7 +11,6 @@ import time import traceback from .common import InfoExtractor, SearchInfoExtractor -from .subtitles import SubtitlesInfoExtractor from ..jsinterp import JSInterpreter from ..swfinterp import SWFInterpreter from ..compat import ( @@ -25,6 +24,7 @@ from ..compat import ( from ..utils import ( clean_html, ExtractorError, + float_or_none, get_element_by_attribute, get_element_by_id, int_or_none, @@ -184,7 +184,7 @@ class YoutubeBaseInfoExtractor(InfoExtractor): return -class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): +class YoutubeIE(YoutubeBaseInfoExtractor): IE_DESC = 'YouTube.com' _VALID_URL = r"""(?x)^ ( @@ -540,26 +540,30 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): if cache_spec is not None: return lambda s: ''.join(s[i] for i in cache_spec) + download_note = ( + 'Downloading player %s' % player_url + if self._downloader.params.get('verbose') else + 'Downloading %s player %s' % (player_type, player_id) + ) if player_type == 'js': code = self._download_webpage( player_url, video_id, - note='Downloading %s player %s' % (player_type, player_id), + note=download_note, errnote='Download of %s failed' % player_url) res = self._parse_sig_js(code) elif player_type == 'swf': urlh = self._request_webpage( player_url, video_id, - note='Downloading %s player %s' % (player_type, player_id), + note=download_note, errnote='Download of %s failed' % player_url) code = urlh.read() res = self._parse_sig_swf(code) else: assert False, 'Invalid player type %r' % player_type - if cache_spec is None: - test_string = ''.join(map(compat_chr, range(len(example_sig)))) - cache_res = res(test_string) - cache_spec = [ord(c) for c in cache_res] + test_string = ''.join(map(compat_chr, range(len(example_sig)))) + cache_res = res(test_string) + cache_spec = [ord(c) for c in cache_res] self._downloader.cache.store('youtube-sigfuncs', func_id, cache_spec) return res @@ -643,7 +647,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): raise ExtractorError( 'Signature extraction failed: ' + tb, cause=e) - def _get_available_subtitles(self, video_id, webpage): + def _get_subtitles(self, video_id, webpage): try: subs_doc = self._download_xml( 'https://video.google.com/timedtext?hl=en&type=list&v=%s' % video_id, @@ -657,23 +661,27 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): lang = track.attrib['lang_code'] if lang in sub_lang_list: continue - params = compat_urllib_parse.urlencode({ - 'lang': lang, - 'v': video_id, - 'fmt': self._downloader.params.get('subtitlesformat', 'srt'), - 'name': track.attrib['name'].encode('utf-8'), - }) - url = 'https://www.youtube.com/api/timedtext?' + params - sub_lang_list[lang] = url + sub_formats = [] + for ext in ['sbv', 'vtt', 'srt']: + params = compat_urllib_parse.urlencode({ + 'lang': lang, + 'v': video_id, + 'fmt': ext, + 'name': track.attrib['name'].encode('utf-8'), + }) + sub_formats.append({ + 'url': 'https://www.youtube.com/api/timedtext?' + params, + 'ext': ext, + }) + sub_lang_list[lang] = sub_formats if not sub_lang_list: self._downloader.report_warning('video doesn\'t have subtitles') return {} return sub_lang_list - def _get_available_automatic_caption(self, video_id, webpage): + def _get_automatic_captions(self, video_id, webpage): """We need the webpage for getting the captions url, pass it as an argument to speed up the process.""" - sub_format = self._downloader.params.get('subtitlesformat', 'srt') self.to_screen('%s: Looking for automatic captions' % video_id) mobj = re.search(r';ytplayer.config = ({.*?});', webpage) err_msg = 'Couldn\'t find automatic captions for %s' % video_id @@ -703,14 +711,20 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): sub_lang_list = {} for lang_node in caption_list.findall('target'): sub_lang = lang_node.attrib['lang_code'] - params = compat_urllib_parse.urlencode({ - 'lang': original_lang, - 'tlang': sub_lang, - 'fmt': sub_format, - 'ts': timestamp, - 'kind': caption_kind, - }) - sub_lang_list[sub_lang] = caption_url + '&' + params + sub_formats = [] + for ext in ['sbv', 'vtt', 'srt']: + params = compat_urllib_parse.urlencode({ + 'lang': original_lang, + 'tlang': sub_lang, + 'fmt': ext, + 'ts': timestamp, + 'kind': caption_kind, + }) + sub_formats.append({ + 'url': caption_url + '&' + params, + 'ext': ext, + }) + sub_lang_list[sub_lang] = sub_formats return sub_lang_list # An extractor error can be raise by the download process if there are # no automatic captions but there are subtitles @@ -780,8 +794,9 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): fo for fo in formats if fo['format_id'] == format_id) except StopIteration: - f.update(self._formats.get(format_id, {}).items()) - formats.append(f) + full_info = self._formats.get(format_id, {}).copy() + full_info.update(f) + formats.append(full_info) else: existing_format.update(f) return formats @@ -964,10 +979,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): # subtitles video_subtitles = self.extract_subtitles(video_id, video_webpage) - - if self._downloader.params.get('listsubtitles', False): - self._list_available_subtitles(video_id, video_webpage) - return + automatic_captions = self.extract_automatic_captions(video_id, video_webpage) if 'length_seconds' not in video_info: self._downloader.report_warning('unable to extract video duration') @@ -1116,6 +1128,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): 'description': video_description, 'categories': video_categories, 'subtitles': video_subtitles, + 'automatic_captions': automatic_captions, 'duration': video_duration, 'age_limit': 18 if age_gate else 0, 'annotations': video_annotations, @@ -1123,6 +1136,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): 'view_count': view_count, 'like_count': like_count, 'dislike_count': dislike_count, + 'average_rating': float_or_none(video_info.get('avg_rating', [None])[0]), 'formats': formats, } @@ -1139,13 +1153,13 @@ class YoutubePlaylistIE(YoutubeBaseInfoExtractor): | p/ ) ( - (?:PL|LL|EC|UU|FL|RD)?[0-9A-Za-z-_]{10,} + (?:PL|LL|EC|UU|FL|RD|UL)?[0-9A-Za-z-_]{10,} # Top tracks, they can also include dots |(?:MC)[\w\.]* ) .* | - ((?:PL|LL|EC|UU|FL|RD)[0-9A-Za-z-_]{10,}) + ((?:PL|LL|EC|UU|FL|RD|UL)[0-9A-Za-z-_]{10,}) )""" _TEMPLATE_URL = 'https://www.youtube.com/playlist?list=%s' _VIDEO_RE = r'href="\s*/watch\?v=(?P<id>[0-9A-Za-z_-]{11})&[^"]*?index=(?P<index>\d+)' @@ -1230,7 +1244,7 @@ class YoutubePlaylistIE(YoutubeBaseInfoExtractor): for vid_id in ids] def _extract_mix(self, playlist_id): - # The mixes are generated from a a single video + # The mixes are generated from a single video # the id of the playlist is just 'RD' + video_id url = 'https://youtube.com/watch?v=%s&list=%s' % (playlist_id[-11:], playlist_id) webpage = self._download_webpage( @@ -1266,7 +1280,7 @@ class YoutubePlaylistIE(YoutubeBaseInfoExtractor): else: self.to_screen('Downloading playlist %s - add --no-playlist to just download video %s' % (playlist_id, video_id)) - if playlist_id.startswith('RD'): + if playlist_id.startswith('RD') or playlist_id.startswith('UL'): # Mixes require a custom extraction process return self._extract_mix(playlist_id) diff --git a/youtube_dl/extractor/zapiks.py b/youtube_dl/extractor/zapiks.py new file mode 100644 index 0000000..22a9a57 --- /dev/null +++ b/youtube_dl/extractor/zapiks.py @@ -0,0 +1,110 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + parse_duration, + parse_iso8601, + xpath_with_ns, + xpath_text, + int_or_none, +) + + +class ZapiksIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?zapiks\.(?:fr|com)/(?:(?:[a-z]{2}/)?(?P<display_id>.+?)\.html|index\.php\?.*\bmedia_id=(?P<id>\d+))' + _TESTS = [ + { + 'url': 'http://www.zapiks.fr/ep2s3-bon-appetit-eh-be-viva.html', + 'md5': 'aeb3c473b2d564b2d46d664d28d5f050', + 'info_dict': { + 'id': '80798', + 'ext': 'mp4', + 'title': 'EP2S3 - Bon Appétit - Eh bé viva les pyrénées con!', + 'description': 'md5:7054d6f6f620c6519be1fe710d4da847', + 'thumbnail': 're:^https?://.*\.jpg$', + 'duration': 528, + 'timestamp': 1359044972, + 'upload_date': '20130124', + 'view_count': int, + 'comment_count': int, + }, + }, + { + 'url': 'http://www.zapiks.com/ep3s5-bon-appetit-baqueira-m-1.html', + 'only_matching': True, + }, + { + 'url': 'http://www.zapiks.com/nl/ep3s5-bon-appetit-baqueira-m-1.html', + 'only_matching': True, + }, + { + 'url': 'http://www.zapiks.fr/index.php?action=playerIframe&media_id=118046&width=640&height=360&autoStart=false&language=fr', + 'only_matching': True, + }, + ] + + 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) + + if not video_id: + video_id = self._search_regex( + r'data-media-id="(\d+)"', webpage, 'video id') + + playlist = self._download_xml( + 'http://www.zapiks.fr/view/index.php?action=playlist&media_id=%s&lang=en' % video_id, + display_id) + + NS_MAP = { + 'jwplayer': 'http://rss.jwpcdn.com/' + } + + def ns(path): + return xpath_with_ns(path, NS_MAP) + + item = playlist.find('./channel/item') + + title = xpath_text(item, 'title', 'title') or self._og_search_title(webpage) + description = self._og_search_description(webpage, default=None) + thumbnail = xpath_text( + item, ns('./jwplayer:image'), 'thumbnail') or self._og_search_thumbnail(webpage, default=None) + duration = parse_duration(self._html_search_meta( + 'duration', webpage, 'duration', default=None)) + timestamp = parse_iso8601(self._html_search_meta( + 'uploadDate', webpage, 'upload date', default=None), ' ') + + view_count = int_or_none(self._search_regex( + r'UserPlays:(\d+)', webpage, 'view count', default=None)) + comment_count = int_or_none(self._search_regex( + r'UserComments:(\d+)', webpage, 'comment count', default=None)) + + formats = [] + for source in item.findall(ns('./jwplayer:source')): + format_id = source.attrib['label'] + f = { + 'url': source.attrib['file'], + 'format_id': format_id, + } + m = re.search(r'^(?P<height>\d+)[pP]', format_id) + if m: + f['height'] = int(m.group('height')) + formats.append(f) + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + 'duration': duration, + 'timestamp': timestamp, + 'view_count': view_count, + 'comment_count': comment_count, + 'formats': formats, + } diff --git a/youtube_dl/jsinterp.py b/youtube_dl/jsinterp.py index 453e273..0e0c7d9 100644 --- a/youtube_dl/jsinterp.py +++ b/youtube_dl/jsinterp.py @@ -30,13 +30,10 @@ class JSInterpreter(object): def __init__(self, code, objects=None): if objects is None: objects = {} - self.code = self._remove_comments(code) + self.code = code self._functions = {} self._objects = objects - def _remove_comments(self, code): - return re.sub(r'(?s)/\*.*?\*/', '', code) - def interpret_statement(self, stmt, local_vars, allow_recursion=100): if allow_recursion < 0: raise ExtractorError('Recursion limit reached') diff --git a/youtube_dl/options.py b/youtube_dl/options.py index d5e5759..58f8111 100644 --- a/youtube_dl/options.py +++ b/youtube_dl/options.py @@ -165,6 +165,11 @@ def parseOpts(overrideArguments=None): action='store_const', dest='extract_flat', const='in_playlist', default=False, help='Do not extract the videos of a playlist, only list them.') + general.add_option( + '--no-color', '--no-colors', + action='store_true', dest='no_color', + default=False, + help='Do not emit color codes in output.') network = optparse.OptionGroup(parser, 'Network Options') network.add_option( @@ -244,10 +249,33 @@ def parseOpts(overrideArguments=None): '--max-views', metavar='COUNT', dest='max_views', default=None, type=int, help='Do not download any videos with more than COUNT views') + selection.add_option( + '--match-filter', + metavar='FILTER', dest='match_filter', default=None, + help=( + '(Experimental) Generic video filter. ' + 'Specify any key (see help for -o for a list of available keys) to' + ' match if the key is present, ' + '!key to check if the key is not present,' + 'key > NUMBER (like "comment_count > 12", also works with ' + '>=, <, <=, !=, =) to compare against a number, and ' + '& to require multiple matches. ' + 'Values which are not known are excluded unless you' + ' put a question mark (?) after the operator.' + 'For example, to only match videos that have been liked more than ' + '100 times and disliked less than 50 times (or the dislike ' + 'functionality is not available at the given service), but who ' + 'also have a description, use --match-filter ' + '"like_count > 100 & dislike_count <? 50 & description" .' + )) selection.add_option( '--no-playlist', action='store_true', dest='noplaylist', default=False, help='If the URL refers to a video and a playlist, download only the video.') + selection.add_option( + '--yes-playlist', + action='store_false', dest='noplaylist', default=False, + help='If the URL refers to a video and a playlist, download the playlist.') selection.add_option( '--age-limit', metavar='YEARS', dest='age_limit', default=None, type=int, @@ -297,8 +325,10 @@ def parseOpts(overrideArguments=None): ' You can filter the video results by putting a condition in' ' brackets, as in -f "best[height=720]"' ' (or -f "[filesize>10M]"). ' - ' This works for filesize, height, width, tbr, abr, vbr, and fps' - ' and the comparisons <, <=, >, >=, =, != .' + ' This works for filesize, height, width, tbr, abr, vbr, asr, and fps' + ' and the comparisons <, <=, >, >=, =, !=' + ' and for ext, acodec, vcodec, container, and protocol' + ' and the comparisons =, != .' ' Formats for which the value is not known are excluded unless you' ' put a question mark (?) after the operator.' ' You can combine format filters, so ' @@ -361,8 +391,8 @@ def parseOpts(overrideArguments=None): help='lists all available subtitles for the video') subtitles.add_option( '--sub-format', - action='store', dest='subtitlesformat', metavar='FORMAT', default='srt', - help='subtitle format (default=srt) ([sbv/vtt] youtube only)') + action='store', dest='subtitlesformat', metavar='FORMAT', default='best', + help='subtitle format, accepts formats preference, for example: "ass/srt/best"') subtitles.add_option( '--sub-lang', '--sub-langs', '--srt-lang', action='callback', dest='subtitleslangs', metavar='LANGS', type='str', @@ -398,6 +428,10 @@ def parseOpts(overrideArguments=None): '--xattr-set-filesize', dest='xattr_set_filesize', action='store_true', help='(experimental) set file xattribute ytdl.filesize with expected filesize') + downloader.add_option( + '--hls-prefer-native', + dest='hls_prefer_native', action='store_true', + help='(experimental) Use the native HLS downloader instead of ffmpeg.') downloader.add_option( '--external-downloader', dest='external_downloader', metavar='COMMAND', @@ -531,7 +565,7 @@ def parseOpts(overrideArguments=None): action='store_true', dest='youtube_print_sig_code', default=False, help=optparse.SUPPRESS_HELP) verbosity.add_option( - '--print-traffic', + '--print-traffic', '--dump-headers', dest='debug_printtraffic', action='store_true', default=False, help='Display sent and read HTTP traffic') verbosity.add_option( @@ -709,10 +743,18 @@ def parseOpts(overrideArguments=None): '--prefer-ffmpeg', action='store_true', dest='prefer_ffmpeg', help='Prefer ffmpeg over avconv for running the postprocessors') + postproc.add_option( + '--ffmpeg-location', '--avconv-location', metavar='PATH', + dest='ffmpeg_location', + help='Location of the ffmpeg/avconv binary; either the path to the binary or its containing directory.') postproc.add_option( '--exec', metavar='CMD', dest='exec_cmd', help='Execute a command on the file after downloading, similar to find\'s -exec syntax. Example: --exec \'adb push {} /sdcard/Music/ && rm {}\'') + postproc.add_option( + '--convert-subtitles', '--convert-subs', + metavar='FORMAT', dest='convertsubtitles', default=None, + help='Convert the subtitles to other format (currently supported: srt|ass|vtt)') parser.add_option_group(general) parser.add_option_group(network) @@ -732,22 +774,22 @@ def parseOpts(overrideArguments=None): if opts.verbose: write_string('[debug] Override config: ' + repr(overrideArguments) + '\n') else: - commandLineConf = sys.argv[1:] - if '--ignore-config' in commandLineConf: - systemConf = [] - userConf = [] + command_line_conf = sys.argv[1:] + if '--ignore-config' in command_line_conf: + system_conf = [] + user_conf = [] else: - systemConf = _readOptions('/etc/youtube-dl.conf') - if '--ignore-config' in systemConf: - userConf = [] + system_conf = _readOptions('/etc/youtube-dl.conf') + if '--ignore-config' in system_conf: + user_conf = [] else: - userConf = _readUserConf() - argv = systemConf + userConf + commandLineConf + user_conf = _readUserConf() + argv = system_conf + user_conf + command_line_conf opts, args = parser.parse_args(argv) if opts.verbose: - write_string('[debug] System config: ' + repr(_hide_login_info(systemConf)) + '\n') - write_string('[debug] User config: ' + repr(_hide_login_info(userConf)) + '\n') - write_string('[debug] Command-line args: ' + repr(_hide_login_info(commandLineConf)) + '\n') + write_string('[debug] System config: ' + repr(_hide_login_info(system_conf)) + '\n') + write_string('[debug] User config: ' + repr(_hide_login_info(user_conf)) + '\n') + write_string('[debug] Command-line args: ' + repr(_hide_login_info(command_line_conf)) + '\n') return parser, opts, args diff --git a/youtube_dl/postprocessor/__init__.py b/youtube_dl/postprocessor/__init__.py index 0ffbca2..708df3d 100644 --- a/youtube_dl/postprocessor/__init__.py +++ b/youtube_dl/postprocessor/__init__.py @@ -11,6 +11,7 @@ from .ffmpeg import ( FFmpegMergerPP, FFmpegMetadataPP, FFmpegVideoConvertorPP, + FFmpegSubtitlesConvertorPP, ) from .xattrpp import XAttrMetadataPP from .execafterdownload import ExecAfterDownloadPP @@ -31,6 +32,7 @@ __all__ = [ 'FFmpegMergerPP', 'FFmpegMetadataPP', 'FFmpegPostProcessor', + 'FFmpegSubtitlesConvertorPP', 'FFmpegVideoConvertorPP', 'XAttrMetadataPP', ] diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index 4a4422c..30094c2 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +import io import os import subprocess import sys @@ -30,54 +31,95 @@ class FFmpegPostProcessorError(PostProcessingError): class FFmpegPostProcessor(PostProcessor): def __init__(self, downloader=None, deletetempfiles=False): PostProcessor.__init__(self, downloader) - self._versions = self.get_versions() self._deletetempfiles = deletetempfiles + self._determine_executables() def check_version(self): - if not self._executable: + if not self.available: raise FFmpegPostProcessorError('ffmpeg or avconv not found. Please install one.') - required_version = '10-0' if self._uses_avconv() else '1.0' + required_version = '10-0' if self.basename == 'avconv' else '1.0' if is_outdated_version( - self._versions[self._executable], required_version): + self._versions[self.basename], required_version): warning = 'Your copy of %s is outdated, update %s to version %s or newer if you encounter any errors.' % ( - self._executable, self._executable, required_version) + self.basename, self.basename, required_version) if self._downloader: self._downloader.report_warning(warning) @staticmethod - def get_versions(): - programs = ['avprobe', 'avconv', 'ffmpeg', 'ffprobe'] - return dict((p, get_exe_version(p, args=['-version'])) for p in programs) - - @property - def available(self): - return self._executable is not None + def get_versions(downloader=None): + return FFmpegPostProcessor(downloader)._versions - @property - def _executable(self): - if self._downloader.params.get('prefer_ffmpeg', False): + def _determine_executables(self): + programs = ['avprobe', 'avconv', 'ffmpeg', 'ffprobe'] + prefer_ffmpeg = self._downloader.params.get('prefer_ffmpeg', False) + + self.basename = None + self.probe_basename = None + + self._paths = None + self._versions = None + if self._downloader: + location = self._downloader.params.get('ffmpeg_location') + if location is not None: + if not os.path.exists(location): + self._downloader.report_warning( + 'ffmpeg-location %s does not exist! ' + 'Continuing without avconv/ffmpeg.' % (location)) + self._versions = {} + return + elif not os.path.isdir(location): + basename = os.path.splitext(os.path.basename(location))[0] + if basename not in programs: + self._downloader.report_warning( + 'Cannot identify executable %s, its basename should be one of %s. ' + 'Continuing without avconv/ffmpeg.' % + (location, ', '.join(programs))) + self._versions = {} + return None + location = os.path.dirname(os.path.abspath(location)) + if basename in ('ffmpeg', 'ffprobe'): + prefer_ffmpeg = True + + self._paths = dict( + (p, os.path.join(location, p)) for p in programs) + self._versions = dict( + (p, get_exe_version(self._paths[p], args=['-version'])) + for p in programs) + if self._versions is None: + self._versions = dict( + (p, get_exe_version(p, args=['-version'])) for p in programs) + self._paths = dict((p, p) for p in programs) + + if prefer_ffmpeg: prefs = ('ffmpeg', 'avconv') else: prefs = ('avconv', 'ffmpeg') for p in prefs: if self._versions[p]: - return p - return None + self.basename = p + break - @property - def _probe_executable(self): - if self._downloader.params.get('prefer_ffmpeg', False): + if prefer_ffmpeg: prefs = ('ffprobe', 'avprobe') else: prefs = ('avprobe', 'ffprobe') for p in prefs: if self._versions[p]: - return p - return None + self.probe_basename = p + break + + @property + def available(self): + return self.basename is not None - def _uses_avconv(self): - return self._executable == 'avconv' + @property + def executable(self): + return self._paths[self.basename] + + @property + def probe_executable(self): + return self._paths[self.probe_basename] def run_ffmpeg_multiple_files(self, input_paths, out_path, opts): self.check_version() @@ -88,14 +130,14 @@ class FFmpegPostProcessor(PostProcessor): files_cmd = [] for path in input_paths: files_cmd.extend([encodeArgument('-i'), encodeFilename(path, True)]) - cmd = ([encodeFilename(self._executable, True), encodeArgument('-y')] + + cmd = ([encodeFilename(self.executable, True), encodeArgument('-y')] + files_cmd + [encodeArgument(o) for o in opts] + [encodeFilename(self._ffmpeg_filename_argument(out_path), True)]) if self._downloader.params.get('verbose', False): self._downloader.to_screen('[debug] ffmpeg command line: %s' % shell_quote(cmd)) - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate() if p.returncode != 0: stderr = stderr.decode('utf-8', 'replace') @@ -127,14 +169,16 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): def get_audio_codec(self, path): - if not self._probe_executable: + if not self.probe_executable: raise PostProcessingError('ffprobe or avprobe not found. Please install one.') try: cmd = [ - encodeFilename(self._probe_executable, True), + encodeFilename(self.probe_executable, True), encodeArgument('-show_streams'), encodeFilename(self._ffmpeg_filename_argument(path), True)] - handle = subprocess.Popen(cmd, stderr=compat_subprocess_get_DEVNULL(), stdout=subprocess.PIPE) + if self._downloader.params.get('verbose', False): + self._downloader.to_screen('[debug] %s command line: %s' % (self.basename, shell_quote(cmd))) + handle = subprocess.Popen(cmd, stderr=compat_subprocess_get_DEVNULL(), stdout=subprocess.PIPE, stdin=subprocess.PIPE) output = handle.communicate()[0] if handle.wait() != 0: return None @@ -166,14 +210,13 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): if filecodec is None: raise PostProcessingError('WARNING: unable to obtain file audio codec with ffprobe') - uses_avconv = self._uses_avconv() more_opts = [] if self._preferredcodec == 'best' or self._preferredcodec == filecodec or (self._preferredcodec == 'm4a' and filecodec == 'aac'): if filecodec == 'aac' and self._preferredcodec in ['m4a', 'best']: # Lossless, but in another container acodec = 'copy' extension = 'm4a' - more_opts = ['-bsf:a' if uses_avconv else '-absf', 'aac_adtstoasc'] + more_opts = ['-bsf:a', 'aac_adtstoasc'] elif filecodec in ['aac', 'mp3', 'vorbis', 'opus']: # Lossless if possible acodec = 'copy' @@ -189,9 +232,9 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): more_opts = [] if self._preferredquality is not None: if int(self._preferredquality) < 10: - more_opts += ['-q:a' if uses_avconv else '-aq', self._preferredquality] + more_opts += ['-q:a', self._preferredquality] else: - more_opts += ['-b:a' if uses_avconv else '-ab', self._preferredquality + 'k'] + more_opts += ['-b:a', self._preferredquality + 'k'] else: # We convert the audio (lossy) acodec = {'mp3': 'libmp3lame', 'aac': 'aac', 'm4a': 'aac', 'opus': 'opus', 'vorbis': 'libvorbis', 'wav': None}[self._preferredcodec] @@ -200,13 +243,13 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): if self._preferredquality is not None: # The opus codec doesn't support the -aq option if int(self._preferredquality) < 10 and extension != 'opus': - more_opts += ['-q:a' if uses_avconv else '-aq', self._preferredquality] + more_opts += ['-q:a', self._preferredquality] else: - more_opts += ['-b:a' if uses_avconv else '-ab', self._preferredquality + 'k'] + more_opts += ['-b:a', self._preferredquality + 'k'] if self._preferredcodec == 'aac': more_opts += ['-f', 'adts'] if self._preferredcodec == 'm4a': - more_opts += ['-bsf:a' if uses_avconv else '-absf', 'aac_adtstoasc'] + more_opts += ['-bsf:a', 'aac_adtstoasc'] if self._preferredcodec == 'vorbis': extension = 'ogg' if self._preferredcodec == 'wav': @@ -224,14 +267,14 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): if self._nopostoverwrites and os.path.exists(encodeFilename(new_path)): self._downloader.to_screen('[youtube] Post-process file %s exists, skipping' % new_path) else: - self._downloader.to_screen('[' + self._executable + '] Destination: ' + new_path) + self._downloader.to_screen('[' + self.basename + '] Destination: ' + new_path) self.run_ffmpeg(path, new_path, acodec, more_opts) except: etype, e, tb = sys.exc_info() if isinstance(e, AudioConversionError): msg = 'audio conversion failed: ' + e.msg else: - msg = 'error running ' + self._executable + msg = 'error running ' + self.basename raise PostProcessingError(msg) # Try to update the date time for extracted audio file. @@ -454,10 +497,6 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor): 'zu': 'zul', } - def __init__(self, downloader=None, subtitlesformat='srt'): - super(FFmpegEmbedSubtitlePP, self).__init__(downloader) - self._subformat = subtitlesformat - @classmethod def _conver_lang_code(cls, code): """Convert language code from ISO 639-1 to ISO 639-2/T""" @@ -467,13 +506,14 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor): if information['ext'] != 'mp4': self._downloader.to_screen('[ffmpeg] Subtitles can only be embedded in mp4 files') return True, information - if not information.get('subtitles'): + subtitles = information.get('requested_subtitles') + if not subtitles: self._downloader.to_screen('[ffmpeg] There aren\'t any subtitles to embed') return True, information - sub_langs = [key for key in information['subtitles']] + sub_langs = list(subtitles.keys()) filename = information['filepath'] - input_files = [filename] + [subtitles_filename(filename, lang, self._subformat) for lang in sub_langs] + input_files = [filename] + [subtitles_filename(filename, lang, sub_info['ext']) for lang, sub_info in subtitles.items()] opts = [ '-map', '0', @@ -596,3 +636,40 @@ class FFmpegFixupM4aPP(FFmpegPostProcessor): os.rename(encodeFilename(temp_filename), encodeFilename(filename)) return True, info + + +class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor): + def __init__(self, downloader=None, format=None): + super(FFmpegSubtitlesConvertorPP, self).__init__(downloader) + self.format = format + + def run(self, info): + subs = info.get('requested_subtitles') + filename = info['filepath'] + new_ext = self.format + new_format = new_ext + if new_format == 'vtt': + new_format = 'webvtt' + if subs is None: + self._downloader.to_screen('[ffmpeg] There aren\'t any subtitles to convert') + return True, info + self._downloader.to_screen('[ffmpeg] Converting subtitles') + for lang, sub in subs.items(): + ext = sub['ext'] + if ext == new_ext: + self._downloader.to_screen( + '[ffmpeg] Subtitle file for %s is already in the requested' + 'format' % new_ext) + continue + new_file = subtitles_filename(filename, lang, new_ext) + self.run_ffmpeg( + subtitles_filename(filename, lang, ext), + new_file, ['-f', new_format]) + + with io.open(new_file, 'rt', encoding='utf-8') as f: + subs[lang] = { + 'ext': ext, + 'data': f.read(), + } + + return True, info diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 8f5463f..1f3bfef 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -17,6 +17,7 @@ import io import json import locale import math +import operator import os import pipes import platform @@ -53,7 +54,7 @@ from .compat import ( compiled_regex_type = type(re.compile('')) std_headers = { - 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0 (Chrome)', + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20150101 Firefox/20.0 (Chrome)', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', @@ -61,6 +62,11 @@ std_headers = { } +ENGLISH_MONTH_NAMES = [ + 'January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December'] + + def preferredencoding(): """Get preferred encoding. @@ -298,6 +304,8 @@ def sanitize_filename(s, restricted=False, is_id=False): # Common case of "Foreign band name - English song title" if restricted and result.startswith('-_'): result = result[2:] + if result.startswith('-'): + result = '_' + result[len('-'):] if not result: result = '_' return result @@ -665,26 +673,27 @@ class YoutubeDLHTTPSHandler(compat_urllib_request.HTTPSHandler): req, **kwargs) -def parse_iso8601(date_str, delimiter='T'): +def parse_iso8601(date_str, delimiter='T', timezone=None): """ Return a UNIX timestamp from the given date """ if date_str is None: return None - m = re.search( - r'(\.[0-9]+)?(?:Z$| ?(?P<sign>\+|-)(?P<hours>[0-9]{2}):?(?P<minutes>[0-9]{2})$)', - date_str) - if not m: - timezone = datetime.timedelta() - else: - date_str = date_str[:-len(m.group(0))] - if not m.group('sign'): + if timezone is None: + m = re.search( + r'(\.[0-9]+)?(?:Z$| ?(?P<sign>\+|-)(?P<hours>[0-9]{2}):?(?P<minutes>[0-9]{2})$)', + date_str) + if not m: timezone = datetime.timedelta() else: - sign = 1 if m.group('sign') == '+' else -1 - timezone = datetime.timedelta( - hours=sign * int(m.group('hours')), - minutes=sign * int(m.group('minutes'))) + date_str = date_str[:-len(m.group(0))] + if not m.group('sign'): + timezone = datetime.timedelta() + else: + sign = 1 if m.group('sign') == '+' else -1 + timezone = datetime.timedelta( + hours=sign * int(m.group('hours')), + minutes=sign * int(m.group('minutes'))) date_format = '%Y-%m-%d{0}%H:%M:%S'.format(delimiter) dt = datetime.datetime.strptime(date_str, date_format) - timezone return calendar.timegm(dt.timetuple()) @@ -893,8 +902,8 @@ def _windows_write_string(s, out): def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True - return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR - or GetConsoleMode(handle, ctypes.byref(ctypes.wintypes.DWORD())) == 0) + return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or + GetConsoleMode(handle, ctypes.byref(ctypes.wintypes.DWORD())) == 0) if not_a_console(h): return False @@ -1183,11 +1192,18 @@ def get_term_width(): def month_by_name(name): """ Return the number of a month by (locale-independently) English name """ - ENGLISH_NAMES = [ - 'January', 'February', 'March', 'April', 'May', 'June', - 'July', 'August', 'September', 'October', 'November', 'December'] try: - return ENGLISH_NAMES.index(name) + 1 + return ENGLISH_MONTH_NAMES.index(name) + 1 + except ValueError: + return None + + +def month_by_abbreviation(abbrev): + """ Return the number of a month by (locale-independently) English + abbreviations """ + + try: + return [s[:3] for s in ENGLISH_MONTH_NAMES].index(abbrev) + 1 except ValueError: return None @@ -1274,6 +1290,7 @@ def parse_duration(s): (?P<only_mins>[0-9.]+)\s*(?:mins?|minutes?)\s*| (?P<only_hours>[0-9.]+)\s*(?:hours?)| + \s*(?P<hours_reversed>[0-9]+)\s*(?:[:h]|hours?)\s*(?P<mins_reversed>[0-9]+)\s*(?:[:m]|mins?|minutes?)\s*| (?: (?: (?:(?P<days>[0-9]+)\s*(?:[:d]|days?)\s*)? @@ -1292,10 +1309,14 @@ def parse_duration(s): return float_or_none(m.group('only_hours'), invscale=60 * 60) if m.group('secs'): res += int(m.group('secs')) + if m.group('mins_reversed'): + res += int(m.group('mins_reversed')) * 60 if m.group('mins'): res += int(m.group('mins')) * 60 if m.group('hours'): res += int(m.group('hours')) * 60 * 60 + if m.group('hours_reversed'): + res += int(m.group('hours_reversed')) * 60 * 60 if m.group('days'): res += int(m.group('days')) * 24 * 60 * 60 if m.group('ms'): @@ -1546,8 +1567,8 @@ def js_to_json(code): return '"%s"' % v res = re.sub(r'''(?x) - "(?:[^"\\]*(?:\\\\|\\")?)*"| - '(?:[^'\\]*(?:\\\\|\\')?)*'| + "(?:[^"\\]*(?:\\\\|\\['"nu]))*[^"\\]*"| + '(?:[^'\\]*(?:\\\\|\\['"nu]))*[^'\\]*'| [a-zA-Z_][.a-zA-Z_0-9]* ''', fix_kv, code) res = re.sub(r',(\s*\])', lambda m: m.group(1), res) @@ -1602,6 +1623,15 @@ def args_to_str(args): return ' '.join(shlex_quote(a) for a in args) +def mimetype2ext(mt): + _, _, res = mt.rpartition('/') + + return { + 'x-ms-wmv': 'wmv', + 'x-mp4-fragmented': 'mp4', + }.get(res, res) + + def urlhandle_detect_ext(url_handle): try: url_handle.headers @@ -1617,7 +1647,7 @@ def urlhandle_detect_ext(url_handle): if e: return e - return getheader('Content-Type').split("/")[1] + return mimetype2ext(getheader('Content-Type')) def age_restricted(content_limit, age_limit): @@ -1678,3 +1708,79 @@ def render_table(header_row, data): max_lens = [max(len(compat_str(v)) for v in col) for col in zip(*table)] format_str = ' '.join('%-' + compat_str(ml + 1) + 's' for ml in max_lens[:-1]) + '%s' return '\n'.join(format_str % tuple(row) for row in table) + + +def _match_one(filter_part, dct): + COMPARISON_OPERATORS = { + '<': operator.lt, + '<=': operator.le, + '>': operator.gt, + '>=': operator.ge, + '=': operator.eq, + '!=': operator.ne, + } + operator_rex = re.compile(r'''(?x)\s* + (?P<key>[a-z_]+) + \s*(?P<op>%s)(?P<none_inclusive>\s*\?)?\s* + (?: + (?P<intval>[0-9.]+(?:[kKmMgGtTpPeEzZyY]i?[Bb]?)?)| + (?P<strval>(?![0-9.])[a-z0-9A-Z]*) + ) + \s*$ + ''' % '|'.join(map(re.escape, COMPARISON_OPERATORS.keys()))) + m = operator_rex.search(filter_part) + if m: + op = COMPARISON_OPERATORS[m.group('op')] + if m.group('strval') is not None: + if m.group('op') not in ('=', '!='): + raise ValueError( + 'Operator %s does not support string values!' % m.group('op')) + comparison_value = m.group('strval') + else: + try: + comparison_value = int(m.group('intval')) + except ValueError: + comparison_value = parse_filesize(m.group('intval')) + if comparison_value is None: + comparison_value = parse_filesize(m.group('intval') + 'B') + if comparison_value is None: + raise ValueError( + 'Invalid integer value %r in filter part %r' % ( + m.group('intval'), filter_part)) + actual_value = dct.get(m.group('key')) + if actual_value is None: + return m.group('none_inclusive') + return op(actual_value, comparison_value) + + UNARY_OPERATORS = { + '': lambda v: v is not None, + '!': lambda v: v is None, + } + operator_rex = re.compile(r'''(?x)\s* + (?P<op>%s)\s*(?P<key>[a-z_]+) + \s*$ + ''' % '|'.join(map(re.escape, UNARY_OPERATORS.keys()))) + m = operator_rex.search(filter_part) + if m: + op = UNARY_OPERATORS[m.group('op')] + actual_value = dct.get(m.group('key')) + return op(actual_value) + + raise ValueError('Invalid filter part %r' % filter_part) + + +def match_str(filter_str, dct): + """ Filter a dictionary with a simple string syntax. Returns True (=passes filter) or false """ + + return all( + _match_one(filter_part, dct) for filter_part in filter_str.split('&')) + + +def match_filter_func(filter_str): + def _match_func(info_dict): + if match_str(filter_str, info_dict): + return None + else: + video_title = info_dict.get('title', info_dict.get('id', 'video')) + return '%s does not pass filter %s, skipping ..' % (video_title, filter_str) + return _match_func diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 1091ae6..5582348 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,3 +1,3 @@ from __future__ import unicode_literals -__version__ = '2015.02.06' +__version__ = '2015.02.28' -- 2.41.1