Merge branch 'master' into totalwebcasting
commit
97bc05116e
@ -1,7 +1,9 @@
|
|||||||
include README.md
|
include README.md
|
||||||
include test/*.py
|
include LICENSE
|
||||||
include test/*.json
|
include AUTHORS
|
||||||
|
include ChangeLog
|
||||||
include youtube-dl.bash-completion
|
include youtube-dl.bash-completion
|
||||||
include youtube-dl.fish
|
include youtube-dl.fish
|
||||||
include youtube-dl.1
|
include youtube-dl.1
|
||||||
recursive-include docs Makefile conf.py *.rst
|
recursive-include docs Makefile conf.py *.rst
|
||||||
|
recursive-include test *
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
wget http://central.maven.org/maven2/org/python/jython-installer/2.7.1/jython-installer-2.7.1.jar
|
||||||
|
java -jar jython-installer-2.7.1.jar -s -d "$HOME/jython"
|
||||||
|
$HOME/jython/bin/jython -m pip install nose
|
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Keep this list in sync with the `offlinetest` target in Makefile
|
||||||
|
DOWNLOAD_TESTS="age_restriction|download|iqiyi_sdk_interpreter|socks|subtitles|write_annotations|youtube_lists|youtube_signature"
|
||||||
|
|
||||||
|
test_set=""
|
||||||
|
multiprocess_args=""
|
||||||
|
|
||||||
|
case "$YTDL_TEST_SET" in
|
||||||
|
core)
|
||||||
|
test_set="-I test_($DOWNLOAD_TESTS)\.py"
|
||||||
|
;;
|
||||||
|
download)
|
||||||
|
test_set="-I test_(?!$DOWNLOAD_TESTS).+\.py"
|
||||||
|
multiprocess_args="--processes=4 --process-timeout=540"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
nosetests test --verbose $test_set $multiprocess_args
|
@ -0,0 +1,26 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# Allow direct execution
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
|
from youtube_dl.options import _hide_login_info
|
||||||
|
|
||||||
|
|
||||||
|
class TestOptions(unittest.TestCase):
|
||||||
|
def test_hide_login_info(self):
|
||||||
|
self.assertEqual(_hide_login_info(['-u', 'foo', '-p', 'bar']),
|
||||||
|
['-u', 'PRIVATE', '-p', 'PRIVATE'])
|
||||||
|
self.assertEqual(_hide_login_info(['-u']), ['-u'])
|
||||||
|
self.assertEqual(_hide_login_info(['-u', 'foo', '-u', 'bar']),
|
||||||
|
['-u', 'PRIVATE', '-u', 'PRIVATE'])
|
||||||
|
self.assertEqual(_hide_login_info(['--username=foo']),
|
||||||
|
['--username=PRIVATE'])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<manifest xmlns="http://ns.adobe.com/f4m/1.0">
|
||||||
|
<streamType>recorded</streamType>
|
||||||
|
<baseURL>http://vod.livestream.com/events/0000000000673980/</baseURL>
|
||||||
|
<duration>269.293</duration>
|
||||||
|
<bootstrapInfo profile="named" id="bootstrap_1">AAAAm2Fic3QAAAAAAAAAAQAAAAPoAAAAAAAEG+0AAAAAAAAAAAAAAAAAAQAAABlhc3J0AAAAAAAAAAABAAAAAQAAAC4BAAAAVmFmcnQAAAAAAAAD6AAAAAAEAAAAAQAAAAAAAAAAAAAXcAAAAC0AAAAAAAQHQAAAE5UAAAAuAAAAAAAEGtUAAAEYAAAAAAAAAAAAAAAAAAAAAAA=</bootstrapInfo>
|
||||||
|
<media url="b90f532f-b0f6-4f4e-8289-706d490b2fd8_2292" bootstrapInfoId="bootstrap_1" bitrate="2148" width="1280" height="720" videoCodec="avc1.4d401f" audioCodec="mp4a.40.2">
|
||||||
|
<metadata>AgAKb25NZXRhRGF0YQgAAAAIAAhkdXJhdGlvbgBAcNSwIMSbpgAFd2lkdGgAQJQAAAAAAAAABmhlaWdodABAhoAAAAAAAAAJZnJhbWVyYXRlAEA4/7DoLwW3AA12aWRlb2RhdGFyYXRlAECe1DLgjcobAAx2aWRlb2NvZGVjaWQAQBwAAAAAAAAADWF1ZGlvZGF0YXJhdGUAQGSimlvaPKQADGF1ZGlvY29kZWNpZABAJAAAAAAAAAAACQ==</metadata>
|
||||||
|
</media>
|
||||||
|
</manifest>
|
@ -0,0 +1,14 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXT-X-VERSION:5
|
||||||
|
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Francais",DEFAULT=NO,FORCED=NO,URI="http://replayftv-pmd.francetv.fr/subtitles/2017/16/156589847-1492488987.m3u8",LANGUAGE="fra"
|
||||||
|
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",LANGUAGE="fra",NAME="Francais",DEFAULT=YES, AUTOSELECT=YES
|
||||||
|
#EXT-X-STREAM-INF:SUBTITLES="subs",AUDIO="aac",PROGRAM-ID=1,BANDWIDTH=180000,RESOLUTION=256x144,CODECS="avc1.66.30, mp4a.40.2"
|
||||||
|
http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_0_av.m3u8?null=0
|
||||||
|
#EXT-X-STREAM-INF:SUBTITLES="subs",AUDIO="aac",PROGRAM-ID=1,BANDWIDTH=303000,RESOLUTION=320x180,CODECS="avc1.66.30, mp4a.40.2"
|
||||||
|
http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_1_av.m3u8?null=0
|
||||||
|
#EXT-X-STREAM-INF:SUBTITLES="subs",AUDIO="aac",PROGRAM-ID=1,BANDWIDTH=575000,RESOLUTION=512x288,CODECS="avc1.66.30, mp4a.40.2"
|
||||||
|
http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_2_av.m3u8?null=0
|
||||||
|
#EXT-X-STREAM-INF:SUBTITLES="subs",AUDIO="aac",PROGRAM-ID=1,BANDWIDTH=831000,RESOLUTION=704x396,CODECS="avc1.77.30, mp4a.40.2"
|
||||||
|
http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_3_av.m3u8?null=0
|
||||||
|
#EXT-X-STREAM-INF:SUBTITLES="subs",AUDIO="aac",PROGRAM-ID=1,BANDWIDTH=1467000,RESOLUTION=1024x576,CODECS="avc1.77.30, mp4a.40.2"
|
||||||
|
http://replayftv-vh.akamaihd.net/i/streaming-adaptatif_france-dom-tom/2017/S16/J2/156589847-58f59130c1f52-,standard1,standard2,standard3,standard4,standard5,.mp4.csmil/index_4_av.m3u8?null=0
|
@ -0,0 +1,16 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-0",NAME="Default",AUTOSELECT=YES,DEFAULT=YES,URI="hls/CONAN_020217_Highlight_show-audio-160k_v4.m3u8"
|
||||||
|
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-1",NAME="Default",AUTOSELECT=YES,DEFAULT=YES,URI="hls/CONAN_020217_Highlight_show-audio-64k_v4.m3u8"
|
||||||
|
#EXT-X-I-FRAME-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=37862000,CODECS="avc1.4d001f",URI="hls/CONAN_020217_Highlight_show-2m_iframe.m3u8"
|
||||||
|
#EXT-X-I-FRAME-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=18750000,CODECS="avc1.4d001e",URI="hls/CONAN_020217_Highlight_show-1m_iframe.m3u8"
|
||||||
|
#EXT-X-I-FRAME-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=6535000,CODECS="avc1.42001e",URI="hls/CONAN_020217_Highlight_show-400k_iframe.m3u8"
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2374000,RESOLUTION=1024x576,CODECS="avc1.4d001f,mp4a.40.2",AUDIO="audio-0"
|
||||||
|
hls/CONAN_020217_Highlight_show-2m_v4.m3u8
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1205000,RESOLUTION=640x360,CODECS="avc1.4d001e,mp4a.40.2",AUDIO="audio-0"
|
||||||
|
hls/CONAN_020217_Highlight_show-1m_v4.m3u8
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=522000,RESOLUTION=400x224,CODECS="avc1.42001e,mp4a.40.2",AUDIO="audio-0"
|
||||||
|
hls/CONAN_020217_Highlight_show-400k_v4.m3u8
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=413000,RESOLUTION=400x224,CODECS="avc1.42001e,mp4a.40.5",AUDIO="audio-1"
|
||||||
|
hls/CONAN_020217_Highlight_show-400k_v4.m3u8
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=71000,CODECS="mp4a.40.5",AUDIO="audio-1"
|
||||||
|
hls/CONAN_020217_Highlight_show-audio-64k_v4.m3u8
|
@ -0,0 +1,13 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXT-X-VERSION:4
|
||||||
|
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="eng",NAME="English",URI="http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_sa2ntrdg/name/a.mp4/index.m3u8"
|
||||||
|
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="und",NAME="Undefined",URI="http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_r7y0nitg/name/a.mp4/index.m3u8"
|
||||||
|
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=155648,RESOLUTION=320x180,AUDIO="audio"
|
||||||
|
http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_qlk9hlzr/name/a.mp4/index.m3u8
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=502784,RESOLUTION=480x270,AUDIO="audio"
|
||||||
|
http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/2/pv/1/flavorId/0_oefackmi/name/a.mp4/index.m3u8
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=827392,RESOLUTION=640x360,AUDIO="audio"
|
||||||
|
http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/12/pv/1/flavorId/0_vyg9pj7k/name/a.mp4/index.m3u8
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1396736,RESOLUTION=854x480,AUDIO="audio"
|
||||||
|
http://k.toggle.sg/fhls/p/2082311/sp/208231100/serveFlavor/entryId/0_89q6e8ku/v/12/pv/1/flavorId/0_50n4psvx/name/a.mp4/index.m3u8
|
@ -0,0 +1,20 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXT-X-TWITCH-INFO:ORIGIN="s3",CLUSTER="edgecast_vod",REGION="EU",MANIFEST-CLUSTER="edgecast_vod",USER-IP="109.171.17.81"
|
||||||
|
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="chunked",NAME="Source",AUTOSELECT=YES,DEFAULT=YES
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3214134,CODECS="avc1.100.31,mp4a.40.2",RESOLUTION="1280x720",VIDEO="chunked"
|
||||||
|
https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/chunked/index-muted-HM49I092CC.m3u8
|
||||||
|
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="high",NAME="High",AUTOSELECT=YES,DEFAULT=YES
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1603789,CODECS="avc1.42C01F,mp4a.40.2",RESOLUTION="1280x720",VIDEO="high"
|
||||||
|
https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/high/index-muted-HM49I092CC.m3u8
|
||||||
|
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="medium",NAME="Medium",AUTOSELECT=YES,DEFAULT=YES
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=893387,CODECS="avc1.42C01E,mp4a.40.2",RESOLUTION="852x480",VIDEO="medium"
|
||||||
|
https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/medium/index-muted-HM49I092CC.m3u8
|
||||||
|
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Low",AUTOSELECT=YES,DEFAULT=YES
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=628347,CODECS="avc1.42C01E,mp4a.40.2",RESOLUTION="640x360",VIDEO="low"
|
||||||
|
https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/low/index-muted-HM49I092CC.m3u8
|
||||||
|
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mobile",NAME="Mobile",AUTOSELECT=YES,DEFAULT=YES
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=280474,CODECS="avc1.42C00D,mp4a.40.2",RESOLUTION="400x226",VIDEO="mobile"
|
||||||
|
https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/mobile/index-muted-HM49I092CC.m3u8
|
||||||
|
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="audio_only",NAME="Audio Only",AUTOSELECT=NO,DEFAULT=NO
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=182725,CODECS="mp4a.40.2",VIDEO="audio_only"
|
||||||
|
https://vod.edgecast.hls.ttvnw.net/e5da31ab49_riotgames_15001215120_261543898/audio_only/index-muted-HM49I092CC.m3u8
|
@ -0,0 +1,10 @@
|
|||||||
|
#EXTM3U
|
||||||
|
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=300000,RESOLUTION=480x270,NAME="270p 3G"
|
||||||
|
https://cdn1-a.production.vidio.static6.com/uploads/165683/dj_ambred-4383-b300.mp4.m3u8
|
||||||
|
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=600000,RESOLUTION=640x360,NAME="360p SD"
|
||||||
|
https://cdn1-a.production.vidio.static6.com/uploads/165683/dj_ambred-4383-b600.mp4.m3u8
|
||||||
|
|
||||||
|
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1200000,RESOLUTION=1280x720,NAME="720p HD"
|
||||||
|
https://cdn1-a.production.vidio.static6.com/uploads/165683/dj_ambred-4383-b1200.mp4.m3u8
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" type="static" minBufferTime="PT2S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT6014S">
|
||||||
|
<Period bitstreamSwitching="true">
|
||||||
|
<AdaptationSet mimeType="audio/mp4" codecs="mp4a.40.2" startWithSAP="1" segmentAlignment="true">
|
||||||
|
<SegmentTemplate timescale="1000000" presentationTimeOffset="0" initialization="ai_$RepresentationID$.mp4d" media="a_$RepresentationID$_$Number$.mp4d" duration="2000000.0" startNumber="0"></SegmentTemplate>
|
||||||
|
<Representation id="318597" bandwidth="61587"></Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
<AdaptationSet mimeType="video/mp4" startWithSAP="1" segmentAlignment="true">
|
||||||
|
<SegmentTemplate timescale="1000000" presentationTimeOffset="0" initialization="vi_$RepresentationID$.mp4d" media="v_$RepresentationID$_$Number$.mp4d" duration="2000000.0" startNumber="0"></SegmentTemplate>
|
||||||
|
<Representation id="318597" codecs="avc1.42001f" width="340" height="192" bandwidth="318597"></Representation>
|
||||||
|
<Representation id="638590" codecs="avc1.42001f" width="512" height="288" bandwidth="638590"></Representation>
|
||||||
|
<Representation id="1022565" codecs="avc1.4d001f" width="688" height="384" bandwidth="1022565"></Representation>
|
||||||
|
<Representation id="2046506" codecs="avc1.4d001f" width="1024" height="576" bandwidth="2046506"></Representation>
|
||||||
|
<Representation id="3998017" codecs="avc1.640029" width="1280" height="720" bandwidth="3998017"></Representation>
|
||||||
|
<Representation id="5997485" codecs="avc1.640032" width="1920" height="1080" bandwidth="5997485"></Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
</Period>
|
||||||
|
</MPD>
|
@ -0,0 +1,218 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
<MPD maxSegmentDuration="PT0H0M10.000S" mediaPresentationDuration="PT0H4M1.728S" minBufferTime="PT1.500S" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011">
|
||||||
|
<Period duration="PT0H4M1.728S">
|
||||||
|
<AdaptationSet bitstreamSwitching="true" lang="und" maxHeight="1080" maxWidth="1920" par="16:9" segmentAlignment="true">
|
||||||
|
<ContentComponent contentType="video" id="1"/>
|
||||||
|
<Representation audioSamplingRate="44100" bandwidth="200000" codecs="avc3.42c01e,mp4a.40.2" frameRate="25" height="144" id="h264_aac_144p_m4s" mimeType="video/mp4" sar="1:1" startWithSAP="1" width="256">
|
||||||
|
<SegmentList duration="10000" timescale="1000">
|
||||||
|
<Initialization sourceURL="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/init/432f65a0.mp4"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/0/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/1/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/2/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/3/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/4/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/5/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/6/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/7/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/8/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/9/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/10/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/11/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/12/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/13/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/14/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/15/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/16/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/17/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/18/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/19/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/20/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/21/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/22/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/23/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_144p_m4s/24/432f65a0.m4s"/>
|
||||||
|
</SegmentList>
|
||||||
|
</Representation>
|
||||||
|
<Representation audioSamplingRate="44100" bandwidth="400000" codecs="avc3.42c01e,mp4a.40.2" frameRate="25" height="240" id="h264_aac_240p_m4s" mimeType="video/mp4" sar="160:159" startWithSAP="1" width="424">
|
||||||
|
<SegmentList duration="10000" timescale="1000">
|
||||||
|
<Initialization sourceURL="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/init/432f65a0.mp4"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/0/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/1/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/2/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/3/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/4/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/5/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/6/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/7/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/8/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/9/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/10/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/11/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/12/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/13/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/14/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/15/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/16/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/17/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/18/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/19/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/20/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/21/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/22/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/23/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_240p_m4s/24/432f65a0.m4s"/>
|
||||||
|
</SegmentList>
|
||||||
|
</Representation>
|
||||||
|
<Representation audioSamplingRate="44100" bandwidth="800000" codecs="avc3.42c01e,mp4a.40.2" frameRate="25" height="360" id="h264_aac_360p_m4s" mimeType="video/mp4" sar="1:1" startWithSAP="1" width="640">
|
||||||
|
<SegmentList duration="10000" timescale="1000">
|
||||||
|
<Initialization sourceURL="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/init/432f65a0.mp4"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/0/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/1/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/2/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/3/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/4/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/5/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/6/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/7/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/8/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/9/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/10/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/11/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/12/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/13/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/14/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/15/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/16/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/17/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/18/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/19/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/20/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/21/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/22/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/23/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_360p_m4s/24/432f65a0.m4s"/>
|
||||||
|
</SegmentList>
|
||||||
|
</Representation>
|
||||||
|
<Representation audioSamplingRate="44100" bandwidth="1200000" codecs="avc3.42c01e,mp4a.40.2" frameRate="25" height="480" id="h264_aac_480p_m4s" mimeType="video/mp4" sar="320:321" startWithSAP="1" width="856">
|
||||||
|
<SegmentList duration="10000" timescale="1000">
|
||||||
|
<Initialization sourceURL="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/init/432f65a0.mp4"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/0/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/1/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/2/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/3/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/4/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/5/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/6/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/7/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/8/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/9/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/10/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/11/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/12/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/13/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/14/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/15/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/16/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/17/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/18/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/19/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/20/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/21/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/22/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/23/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_480p_m4s/24/432f65a0.m4s"/>
|
||||||
|
</SegmentList>
|
||||||
|
</Representation>
|
||||||
|
<Representation audioSamplingRate="44100" bandwidth="1600000" codecs="avc3.42c01e,mp4a.40.2" frameRate="25" height="576" id="h264_aac_576p_m4s" mimeType="video/mp4" sar="1:1" startWithSAP="1" width="1024">
|
||||||
|
<SegmentList duration="10000" timescale="1000">
|
||||||
|
<Initialization sourceURL="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/init/432f65a0.mp4"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/0/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/1/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/2/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/3/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/4/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/5/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/6/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/7/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/8/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/9/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/10/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/11/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/12/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/13/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/14/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/15/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/16/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/17/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/18/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/19/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/20/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/21/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/22/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/23/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_576p_m4s/24/432f65a0.m4s"/>
|
||||||
|
</SegmentList>
|
||||||
|
</Representation>
|
||||||
|
<Representation audioSamplingRate="44100" bandwidth="2400000" codecs="avc3.42c01e,mp4a.40.2" frameRate="25" height="720" id="h264_aac_720p_m4s" mimeType="video/mp4" sar="1:1" startWithSAP="1" width="1280">
|
||||||
|
<SegmentList duration="10000" timescale="1000">
|
||||||
|
<Initialization sourceURL="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/init/432f65a0.mp4"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/0/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/1/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/2/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/3/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/4/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/5/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/6/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/7/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/8/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/9/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/10/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/11/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/12/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/13/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/14/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/15/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/16/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/17/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/18/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/19/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/20/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/21/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/22/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/23/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_720p_m4s/24/432f65a0.m4s"/>
|
||||||
|
</SegmentList>
|
||||||
|
</Representation>
|
||||||
|
<Representation audioSamplingRate="44100" bandwidth="4400000" codecs="avc3.42c01e,mp4a.40.2" frameRate="25" height="1080" id="h264_aac_1080p_m4s" mimeType="video/mp4" sar="1:1" startWithSAP="1" width="1920">
|
||||||
|
<SegmentList duration="10000" timescale="1000">
|
||||||
|
<Initialization sourceURL="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/init/432f65a0.mp4"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/0/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/1/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/2/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/3/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/4/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/5/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/6/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/7/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/8/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/9/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/10/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/11/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/12/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/13/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/14/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/15/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/16/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/17/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/18/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/19/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/20/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/21/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/22/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/23/432f65a0.m4s"/>
|
||||||
|
<SegmentURL media="../vd_5999c902ea707c67d8e267a9_1503250723/h264_aac_1080p_m4s/24/432f65a0.m4s"/>
|
||||||
|
</SegmentList>
|
||||||
|
</Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
</Period>
|
||||||
|
</MPD>
|
@ -0,0 +1,150 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..aes import aes_cbc_decrypt
|
||||||
|
from ..compat import compat_ord
|
||||||
|
from ..utils import (
|
||||||
|
bytes_to_intlist,
|
||||||
|
ExtractorError,
|
||||||
|
float_or_none,
|
||||||
|
intlist_to_bytes,
|
||||||
|
srt_subtitles_timecode,
|
||||||
|
strip_or_none,
|
||||||
|
urljoin,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ADNIE(InfoExtractor):
|
||||||
|
IE_DESC = 'Anime Digital Network'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?animedigitalnetwork\.fr/video/[^/]+/(?P<id>\d+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'http://animedigitalnetwork.fr/video/blue-exorcist-kyoto-saga/7778-episode-1-debut-des-hostilites',
|
||||||
|
'md5': 'e497370d847fd79d9d4c74be55575c7a',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '7778',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Blue Exorcist - Kyôto Saga - Épisode 1',
|
||||||
|
'description': 'md5:2f7b5aa76edbc1a7a92cedcda8a528d5',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_BASE_URL = 'http://animedigitalnetwork.fr'
|
||||||
|
|
||||||
|
def _get_subtitles(self, sub_path, video_id):
|
||||||
|
if not sub_path:
|
||||||
|
return None
|
||||||
|
|
||||||
|
enc_subtitles = self._download_webpage(
|
||||||
|
urljoin(self._BASE_URL, sub_path),
|
||||||
|
video_id, fatal=False, headers={
|
||||||
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0',
|
||||||
|
})
|
||||||
|
if not enc_subtitles:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# http://animedigitalnetwork.fr/components/com_vodvideo/videojs/adn-vjs.min.js
|
||||||
|
dec_subtitles = intlist_to_bytes(aes_cbc_decrypt(
|
||||||
|
bytes_to_intlist(base64.b64decode(enc_subtitles[24:])),
|
||||||
|
bytes_to_intlist(b'\x1b\xe0\x29\x61\x38\x94\x24\x00\x12\xbd\xc5\x80\xac\xce\xbe\xb0'),
|
||||||
|
bytes_to_intlist(base64.b64decode(enc_subtitles[:24]))
|
||||||
|
))
|
||||||
|
subtitles_json = self._parse_json(
|
||||||
|
dec_subtitles[:-compat_ord(dec_subtitles[-1])].decode(),
|
||||||
|
None, fatal=False)
|
||||||
|
if not subtitles_json:
|
||||||
|
return None
|
||||||
|
|
||||||
|
subtitles = {}
|
||||||
|
for sub_lang, sub in subtitles_json.items():
|
||||||
|
srt = ''
|
||||||
|
for num, current in enumerate(sub):
|
||||||
|
start, end, text = (
|
||||||
|
float_or_none(current.get('startTime')),
|
||||||
|
float_or_none(current.get('endTime')),
|
||||||
|
current.get('text'))
|
||||||
|
if start is None or end is None or text is None:
|
||||||
|
continue
|
||||||
|
srt += os.linesep.join(
|
||||||
|
(
|
||||||
|
'%d' % num,
|
||||||
|
'%s --> %s' % (
|
||||||
|
srt_subtitles_timecode(start),
|
||||||
|
srt_subtitles_timecode(end)),
|
||||||
|
text,
|
||||||
|
os.linesep,
|
||||||
|
))
|
||||||
|
|
||||||
|
if sub_lang == 'vostf':
|
||||||
|
sub_lang = 'fr'
|
||||||
|
subtitles.setdefault(sub_lang, []).extend([{
|
||||||
|
'ext': 'json',
|
||||||
|
'data': json.dumps(sub),
|
||||||
|
}, {
|
||||||
|
'ext': 'srt',
|
||||||
|
'data': srt,
|
||||||
|
}])
|
||||||
|
return subtitles
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
player_config = self._parse_json(self._search_regex(
|
||||||
|
r'playerConfig\s*=\s*({.+});', webpage, 'player config'), video_id)
|
||||||
|
|
||||||
|
video_info = {}
|
||||||
|
video_info_str = self._search_regex(
|
||||||
|
r'videoInfo\s*=\s*({.+});', webpage,
|
||||||
|
'video info', fatal=False)
|
||||||
|
if video_info_str:
|
||||||
|
video_info = self._parse_json(
|
||||||
|
video_info_str, video_id, fatal=False) or {}
|
||||||
|
|
||||||
|
options = player_config.get('options') or {}
|
||||||
|
metas = options.get('metas') or {}
|
||||||
|
title = metas.get('title') or video_info['title']
|
||||||
|
links = player_config.get('links') or {}
|
||||||
|
error = None
|
||||||
|
if not links:
|
||||||
|
links_url = player_config['linksurl']
|
||||||
|
links_data = self._download_json(urljoin(
|
||||||
|
self._BASE_URL, links_url), video_id)
|
||||||
|
links = links_data.get('links') or {}
|
||||||
|
error = links_data.get('error')
|
||||||
|
|
||||||
|
formats = []
|
||||||
|
for format_id, qualities in links.items():
|
||||||
|
if not isinstance(qualities, dict):
|
||||||
|
continue
|
||||||
|
for load_balancer_url in qualities.values():
|
||||||
|
load_balancer_data = self._download_json(
|
||||||
|
load_balancer_url, video_id, fatal=False) or {}
|
||||||
|
m3u8_url = load_balancer_data.get('location')
|
||||||
|
if not m3u8_url:
|
||||||
|
continue
|
||||||
|
m3u8_formats = self._extract_m3u8_formats(
|
||||||
|
m3u8_url, video_id, 'mp4', 'm3u8_native',
|
||||||
|
m3u8_id=format_id, fatal=False)
|
||||||
|
if format_id == 'vf':
|
||||||
|
for f in m3u8_formats:
|
||||||
|
f['language'] = 'fr'
|
||||||
|
formats.extend(m3u8_formats)
|
||||||
|
if not error:
|
||||||
|
error = options.get('error')
|
||||||
|
if not formats and error:
|
||||||
|
raise ExtractorError('%s said: %s' % (self.IE_NAME, error), expected=True)
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': video_id,
|
||||||
|
'title': title,
|
||||||
|
'description': strip_or_none(metas.get('summary') or video_info.get('resume')),
|
||||||
|
'thumbnail': video_info.get('image'),
|
||||||
|
'formats': formats,
|
||||||
|
'subtitles': self.extract_subtitles(player_config.get('subtitles'), video_id),
|
||||||
|
'episode': metas.get('subtitle') or video_info.get('videoTitle'),
|
||||||
|
'series': video_info.get('playlistTitle'),
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..compat import compat_str
|
||||||
|
from ..utils import (
|
||||||
|
float_or_none,
|
||||||
|
try_get,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AliExpressLiveIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://live\.aliexpress\.com/live/(?P<id>\d+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'https://live.aliexpress.com/live/2800002704436634',
|
||||||
|
'md5': 'e729e25d47c5e557f2630eaf99b740a5',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '2800002704436634',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'CASIMA7.22',
|
||||||
|
'thumbnail': r're:http://.*\.jpg',
|
||||||
|
'uploader': 'CASIMA Official Store',
|
||||||
|
'timestamp': 1500717600,
|
||||||
|
'upload_date': '20170722',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = self._match_id(url)
|
||||||
|
|
||||||
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
|
data = self._parse_json(
|
||||||
|
self._search_regex(
|
||||||
|
r'(?s)runParams\s*=\s*({.+?})\s*;?\s*var',
|
||||||
|
webpage, 'runParams'),
|
||||||
|
video_id)
|
||||||
|
|
||||||
|
title = data['title']
|
||||||
|
|
||||||
|
formats = self._extract_m3u8_formats(
|
||||||
|
data['replyStreamUrl'], video_id, 'mp4',
|
||||||
|
entry_protocol='m3u8_native', m3u8_id='hls')
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': video_id,
|
||||||
|
'title': title,
|
||||||
|
'thumbnail': data.get('coverUrl'),
|
||||||
|
'uploader': try_get(
|
||||||
|
data, lambda x: x['followBar']['name'], compat_str),
|
||||||
|
'timestamp': float_or_none(data.get('startTimeLong'), scale=1000),
|
||||||
|
'formats': formats,
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..utils import (
|
||||||
|
clean_html,
|
||||||
|
int_or_none,
|
||||||
|
try_get,
|
||||||
|
unified_strdate,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AmericasTestKitchenIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?americastestkitchen\.com/(?:episode|videos)/(?P<id>\d+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://www.americastestkitchen.com/episode/548-summer-dinner-party',
|
||||||
|
'md5': 'b861c3e365ac38ad319cfd509c30577f',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '1_5g5zua6e',
|
||||||
|
'title': 'Summer Dinner Party',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'description': 'md5:858d986e73a4826979b6a5d9f8f6a1ec',
|
||||||
|
'thumbnail': r're:^https?://.*\.jpg',
|
||||||
|
'timestamp': 1497285541,
|
||||||
|
'upload_date': '20170612',
|
||||||
|
'uploader_id': 'roger.metcalf@americastestkitchen.com',
|
||||||
|
'release_date': '20170617',
|
||||||
|
'series': "America's Test Kitchen",
|
||||||
|
'season_number': 17,
|
||||||
|
'episode': 'Summer Dinner Party',
|
||||||
|
'episode_number': 24,
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.americastestkitchen.com/videos/3420-pan-seared-salmon',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = self._match_id(url)
|
||||||
|
|
||||||
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
|
partner_id = self._search_regex(
|
||||||
|
r'src=["\'](?:https?:)?//(?:[^/]+\.)kaltura\.com/(?:[^/]+/)*(?:p|partner_id)/(\d+)',
|
||||||
|
webpage, 'kaltura partner id')
|
||||||
|
|
||||||
|
video_data = self._parse_json(
|
||||||
|
self._search_regex(
|
||||||
|
r'window\.__INITIAL_STATE__\s*=\s*({.+?})\s*;\s*</script>',
|
||||||
|
webpage, 'initial context'),
|
||||||
|
video_id)
|
||||||
|
|
||||||
|
ep_data = try_get(
|
||||||
|
video_data,
|
||||||
|
(lambda x: x['episodeDetail']['content']['data'],
|
||||||
|
lambda x: x['videoDetail']['content']['data']), dict)
|
||||||
|
ep_meta = ep_data.get('full_video', {})
|
||||||
|
external_id = ep_data.get('external_id') or ep_meta['external_id']
|
||||||
|
|
||||||
|
title = ep_data.get('title') or ep_meta.get('title')
|
||||||
|
description = clean_html(ep_meta.get('episode_description') or ep_data.get(
|
||||||
|
'description') or ep_meta.get('description'))
|
||||||
|
thumbnail = try_get(ep_meta, lambda x: x['photo']['image_url'])
|
||||||
|
release_date = unified_strdate(ep_data.get('aired_at'))
|
||||||
|
|
||||||
|
season_number = int_or_none(ep_meta.get('season_number'))
|
||||||
|
episode = ep_meta.get('title')
|
||||||
|
episode_number = int_or_none(ep_meta.get('episode_number'))
|
||||||
|
|
||||||
|
return {
|
||||||
|
'_type': 'url_transparent',
|
||||||
|
'url': 'kaltura:%s:%s' % (partner_id, external_id),
|
||||||
|
'ie_key': 'Kaltura',
|
||||||
|
'title': title,
|
||||||
|
'description': description,
|
||||||
|
'thumbnail': thumbnail,
|
||||||
|
'release_date': release_date,
|
||||||
|
'series': "America's Test Kitchen",
|
||||||
|
'season_number': season_number,
|
||||||
|
'episode': episode,
|
||||||
|
'episode_number': episode_number,
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from .kaltura import KalturaIE
|
||||||
|
from ..utils import (
|
||||||
|
extract_attributes,
|
||||||
|
remove_end,
|
||||||
|
urlencode_postdata,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AsianCrushIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?asiancrush\.com/video/(?:[^/]+/)?0+(?P<id>\d+)v\b'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://www.asiancrush.com/video/012869v/women-who-flirt/',
|
||||||
|
'md5': 'c3b740e48d0ba002a42c0b72857beae6',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '1_y4tmjm5r',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Women Who Flirt',
|
||||||
|
'description': 'md5:3db14e9186197857e7063522cb89a805',
|
||||||
|
'timestamp': 1496936429,
|
||||||
|
'upload_date': '20170608',
|
||||||
|
'uploader_id': 'craig@crifkin.com',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.asiancrush.com/video/she-was-pretty/011886v-pretty-episode-3/',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = self._match_id(url)
|
||||||
|
|
||||||
|
data = self._download_json(
|
||||||
|
'https://www.asiancrush.com/wp-admin/admin-ajax.php', video_id,
|
||||||
|
data=urlencode_postdata({
|
||||||
|
'postid': video_id,
|
||||||
|
'action': 'get_channel_kaltura_vars',
|
||||||
|
}))
|
||||||
|
|
||||||
|
entry_id = data['entry_id']
|
||||||
|
|
||||||
|
return self.url_result(
|
||||||
|
'kaltura:%s:%s' % (data['partner_id'], entry_id),
|
||||||
|
ie=KalturaIE.ie_key(), video_id=entry_id,
|
||||||
|
video_title=data.get('vid_label'))
|
||||||
|
|
||||||
|
|
||||||
|
class AsianCrushPlaylistIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?asiancrush\.com/series/0+(?P<id>\d+)s\b'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'https://www.asiancrush.com/series/012481s/scholar-walks-night/',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '12481',
|
||||||
|
'title': 'Scholar Who Walks the Night',
|
||||||
|
'description': 'md5:7addd7c5132a09fd4741152d96cce886',
|
||||||
|
},
|
||||||
|
'playlist_count': 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
playlist_id = self._match_id(url)
|
||||||
|
|
||||||
|
webpage = self._download_webpage(url, playlist_id)
|
||||||
|
|
||||||
|
entries = []
|
||||||
|
|
||||||
|
for mobj in re.finditer(
|
||||||
|
r'<a[^>]+href=(["\'])(?P<url>%s.*?)\1[^>]*>' % AsianCrushIE._VALID_URL,
|
||||||
|
webpage):
|
||||||
|
attrs = extract_attributes(mobj.group(0))
|
||||||
|
if attrs.get('class') == 'clearfix':
|
||||||
|
entries.append(self.url_result(
|
||||||
|
mobj.group('url'), ie=AsianCrushIE.ie_key()))
|
||||||
|
|
||||||
|
title = remove_end(
|
||||||
|
self._html_search_regex(
|
||||||
|
r'(?s)<h1\b[^>]\bid=["\']movieTitle[^>]+>(.+?)</h1>', webpage,
|
||||||
|
'title', default=None) or self._og_search_title(
|
||||||
|
webpage, default=None) or self._html_search_meta(
|
||||||
|
'twitter:title', webpage, 'title',
|
||||||
|
default=None) or self._search_regex(
|
||||||
|
r'<title>([^<]+)</title>', webpage, 'title', fatal=False),
|
||||||
|
' | AsianCrush')
|
||||||
|
|
||||||
|
description = self._og_search_description(
|
||||||
|
webpage, default=None) or self._html_search_meta(
|
||||||
|
'twitter:description', webpage, 'description', fatal=False)
|
||||||
|
|
||||||
|
return self.playlist_result(entries, playlist_id, title, description)
|
@ -0,0 +1,73 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..utils import (
|
||||||
|
determine_ext,
|
||||||
|
int_or_none,
|
||||||
|
unescapeHTML,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ATVAtIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?atv\.at/(?:[^/]+/){2}(?P<id>[dv]\d+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'http://atv.at/aktuell/di-210317-2005-uhr/v1698449/',
|
||||||
|
'md5': 'c3b6b975fb3150fc628572939df205f2',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '1698447',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'DI, 21.03.17 | 20:05 Uhr 1/1',
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'url': 'http://atv.at/aktuell/meinrad-knapp/d8416/',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
display_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, display_id)
|
||||||
|
video_data = self._parse_json(unescapeHTML(self._search_regex(
|
||||||
|
r'class="[^"]*jsb_video/FlashPlayer[^"]*"[^>]+data-jsb="([^"]+)"',
|
||||||
|
webpage, 'player data')), display_id)['config']['initial_video']
|
||||||
|
|
||||||
|
video_id = video_data['id']
|
||||||
|
video_title = video_data['title']
|
||||||
|
|
||||||
|
parts = []
|
||||||
|
for part in video_data.get('parts', []):
|
||||||
|
part_id = part['id']
|
||||||
|
part_title = part['title']
|
||||||
|
|
||||||
|
formats = []
|
||||||
|
for source in part.get('sources', []):
|
||||||
|
source_url = source.get('src')
|
||||||
|
if not source_url:
|
||||||
|
continue
|
||||||
|
ext = determine_ext(source_url)
|
||||||
|
if ext == 'm3u8':
|
||||||
|
formats.extend(self._extract_m3u8_formats(
|
||||||
|
source_url, part_id, 'mp4', 'm3u8_native',
|
||||||
|
m3u8_id='hls', fatal=False))
|
||||||
|
else:
|
||||||
|
formats.append({
|
||||||
|
'format_id': source.get('delivery'),
|
||||||
|
'url': source_url,
|
||||||
|
})
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
parts.append({
|
||||||
|
'id': part_id,
|
||||||
|
'title': part_title,
|
||||||
|
'thumbnail': part.get('preview_image_url'),
|
||||||
|
'duration': int_or_none(part.get('duration')),
|
||||||
|
'is_live': part.get('is_livestream'),
|
||||||
|
'formats': formats,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
'_type': 'multi_video',
|
||||||
|
'id': video_id,
|
||||||
|
'title': video_title,
|
||||||
|
'entries': parts,
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import hashlib
|
||||||
|
import hmac
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..compat import compat_urllib_parse_urlencode
|
||||||
|
|
||||||
|
|
||||||
|
class AWSIE(InfoExtractor):
|
||||||
|
_AWS_ALGORITHM = 'AWS4-HMAC-SHA256'
|
||||||
|
_AWS_REGION = 'us-east-1'
|
||||||
|
|
||||||
|
def _aws_execute_api(self, aws_dict, video_id, query=None):
|
||||||
|
query = query or {}
|
||||||
|
amz_date = datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')
|
||||||
|
date = amz_date[:8]
|
||||||
|
headers = {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Host': self._AWS_PROXY_HOST,
|
||||||
|
'X-Amz-Date': amz_date,
|
||||||
|
'X-Api-Key': self._AWS_API_KEY
|
||||||
|
}
|
||||||
|
session_token = aws_dict.get('session_token')
|
||||||
|
if session_token:
|
||||||
|
headers['X-Amz-Security-Token'] = session_token
|
||||||
|
|
||||||
|
def aws_hash(s):
|
||||||
|
return hashlib.sha256(s.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
# Task 1: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
||||||
|
canonical_querystring = compat_urllib_parse_urlencode(query)
|
||||||
|
canonical_headers = ''
|
||||||
|
for header_name, header_value in sorted(headers.items()):
|
||||||
|
canonical_headers += '%s:%s\n' % (header_name.lower(), header_value)
|
||||||
|
signed_headers = ';'.join([header.lower() for header in sorted(headers.keys())])
|
||||||
|
canonical_request = '\n'.join([
|
||||||
|
'GET',
|
||||||
|
aws_dict['uri'],
|
||||||
|
canonical_querystring,
|
||||||
|
canonical_headers,
|
||||||
|
signed_headers,
|
||||||
|
aws_hash('')
|
||||||
|
])
|
||||||
|
|
||||||
|
# Task 2: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
|
||||||
|
credential_scope_list = [date, self._AWS_REGION, 'execute-api', 'aws4_request']
|
||||||
|
credential_scope = '/'.join(credential_scope_list)
|
||||||
|
string_to_sign = '\n'.join([self._AWS_ALGORITHM, amz_date, credential_scope, aws_hash(canonical_request)])
|
||||||
|
|
||||||
|
# Task 3: http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
|
||||||
|
def aws_hmac(key, msg):
|
||||||
|
return hmac.new(key, msg.encode('utf-8'), hashlib.sha256)
|
||||||
|
|
||||||
|
def aws_hmac_digest(key, msg):
|
||||||
|
return aws_hmac(key, msg).digest()
|
||||||
|
|
||||||
|
def aws_hmac_hexdigest(key, msg):
|
||||||
|
return aws_hmac(key, msg).hexdigest()
|
||||||
|
|
||||||
|
k_signing = ('AWS4' + aws_dict['secret_key']).encode('utf-8')
|
||||||
|
for value in credential_scope_list:
|
||||||
|
k_signing = aws_hmac_digest(k_signing, value)
|
||||||
|
|
||||||
|
signature = aws_hmac_hexdigest(k_signing, string_to_sign)
|
||||||
|
|
||||||
|
# Task 4: http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
|
||||||
|
headers['Authorization'] = ', '.join([
|
||||||
|
'%s Credential=%s/%s' % (self._AWS_ALGORITHM, aws_dict['access_key'], credential_scope),
|
||||||
|
'SignedHeaders=%s' % signed_headers,
|
||||||
|
'Signature=%s' % signature,
|
||||||
|
])
|
||||||
|
|
||||||
|
return self._download_json(
|
||||||
|
'https://%s%s%s' % (self._AWS_PROXY_HOST, aws_dict['uri'], '?' + canonical_querystring if canonical_querystring else ''),
|
||||||
|
video_id, headers=headers)
|
@ -0,0 +1,213 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from .kaltura import KalturaIE
|
||||||
|
from ..utils import (
|
||||||
|
get_element_by_class,
|
||||||
|
get_element_by_id,
|
||||||
|
strip_or_none,
|
||||||
|
urljoin,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AZMedienBaseIE(InfoExtractor):
|
||||||
|
def _kaltura_video(self, partner_id, entry_id):
|
||||||
|
return self.url_result(
|
||||||
|
'kaltura:%s:%s' % (partner_id, entry_id), ie=KalturaIE.ie_key(),
|
||||||
|
video_id=entry_id)
|
||||||
|
|
||||||
|
|
||||||
|
class AZMedienIE(AZMedienBaseIE):
|
||||||
|
IE_DESC = 'AZ Medien videos'
|
||||||
|
_VALID_URL = r'''(?x)
|
||||||
|
https?://
|
||||||
|
(?:www\.)?
|
||||||
|
(?:
|
||||||
|
telezueri\.ch|
|
||||||
|
telebaern\.tv|
|
||||||
|
telem1\.ch
|
||||||
|
)/
|
||||||
|
[0-9]+-show-[^/\#]+
|
||||||
|
(?:
|
||||||
|
/[0-9]+-episode-[^/\#]+
|
||||||
|
(?:
|
||||||
|
/[0-9]+-segment-(?:[^/\#]+\#)?|
|
||||||
|
\#
|
||||||
|
)|
|
||||||
|
\#
|
||||||
|
)
|
||||||
|
(?P<id>[^\#]+)
|
||||||
|
'''
|
||||||
|
|
||||||
|
_TESTS = [{
|
||||||
|
# URL with 'segment'
|
||||||
|
'url': 'http://www.telezueri.ch/62-show-zuerinews/13772-episode-sonntag-18-dezember-2016/32419-segment-massenabweisungen-beim-hiltl-club-wegen-pelzboom',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '1_2444peh4',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Massenabweisungen beim Hiltl Club wegen Pelzboom',
|
||||||
|
'description': 'md5:9ea9dd1b159ad65b36ddcf7f0d7c76a8',
|
||||||
|
'uploader_id': 'TeleZ?ri',
|
||||||
|
'upload_date': '20161218',
|
||||||
|
'timestamp': 1482084490,
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
# URL with 'segment' and fragment:
|
||||||
|
'url': 'http://www.telebaern.tv/118-show-news/14240-episode-dienstag-17-januar-2017/33666-segment-achtung-gefahr#zu-wenig-pflegerinnen-und-pfleger',
|
||||||
|
'only_matching': True
|
||||||
|
}, {
|
||||||
|
# URL with 'episode' and fragment:
|
||||||
|
'url': 'http://www.telem1.ch/47-show-sonntalk/13986-episode-soldaten-fuer-grenzschutz-energiestrategie-obama-bilanz#soldaten-fuer-grenzschutz-energiestrategie-obama-bilanz',
|
||||||
|
'only_matching': True
|
||||||
|
}, {
|
||||||
|
# URL with 'show' and fragment:
|
||||||
|
'url': 'http://www.telezueri.ch/66-show-sonntalk#burka-plakate-trump-putin-china-besuch',
|
||||||
|
'only_matching': True
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = self._match_id(url)
|
||||||
|
|
||||||
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
|
partner_id = self._search_regex(
|
||||||
|
r'<script[^>]+src=["\'](?:https?:)?//(?:[^/]+\.)?kaltura\.com(?:/[^/]+)*/(?:p|partner_id)/([0-9]+)',
|
||||||
|
webpage, 'kaltura partner id')
|
||||||
|
entry_id = self._html_search_regex(
|
||||||
|
r'<a[^>]+data-id=(["\'])(?P<id>(?:(?!\1).)+)\1[^>]+data-slug=["\']%s'
|
||||||
|
% re.escape(video_id), webpage, 'kaltura entry id', group='id')
|
||||||
|
|
||||||
|
return self._kaltura_video(partner_id, entry_id)
|
||||||
|
|
||||||
|
|
||||||
|
class AZMedienPlaylistIE(AZMedienBaseIE):
|
||||||
|
IE_DESC = 'AZ Medien playlists'
|
||||||
|
_VALID_URL = r'''(?x)
|
||||||
|
https?://
|
||||||
|
(?:www\.)?
|
||||||
|
(?:
|
||||||
|
telezueri\.ch|
|
||||||
|
telebaern\.tv|
|
||||||
|
telem1\.ch
|
||||||
|
)/
|
||||||
|
(?P<id>[0-9]+-
|
||||||
|
(?:
|
||||||
|
show|
|
||||||
|
topic|
|
||||||
|
themen
|
||||||
|
)-[^/\#]+
|
||||||
|
(?:
|
||||||
|
/[0-9]+-episode-[^/\#]+
|
||||||
|
)?
|
||||||
|
)$
|
||||||
|
'''
|
||||||
|
|
||||||
|
_TESTS = [{
|
||||||
|
# URL with 'episode'
|
||||||
|
'url': 'http://www.telebaern.tv/118-show-news/13735-episode-donnerstag-15-dezember-2016',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '118-show-news/13735-episode-donnerstag-15-dezember-2016',
|
||||||
|
'title': 'News - Donnerstag, 15. Dezember 2016',
|
||||||
|
},
|
||||||
|
'playlist_count': 9,
|
||||||
|
}, {
|
||||||
|
# URL with 'themen'
|
||||||
|
'url': 'http://www.telem1.ch/258-themen-tele-m1-classics',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '258-themen-tele-m1-classics',
|
||||||
|
'title': 'Tele M1 Classics',
|
||||||
|
},
|
||||||
|
'playlist_mincount': 15,
|
||||||
|
}, {
|
||||||
|
# URL with 'topic', contains nested playlists
|
||||||
|
'url': 'http://www.telezueri.ch/219-topic-aera-trump-hat-offiziell-begonnen',
|
||||||
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
# URL with 'show' only
|
||||||
|
'url': 'http://www.telezueri.ch/86-show-talktaeglich',
|
||||||
|
'only_matching': True
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
show_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, show_id)
|
||||||
|
|
||||||
|
entries = []
|
||||||
|
|
||||||
|
partner_id = self._search_regex(
|
||||||
|
r'src=["\'](?:https?:)?//(?:[^/]+\.)kaltura\.com/(?:[^/]+/)*(?:p|partner_id)/(\d+)',
|
||||||
|
webpage, 'kaltura partner id', default=None)
|
||||||
|
|
||||||
|
if partner_id:
|
||||||
|
entries = [
|
||||||
|
self._kaltura_video(partner_id, m.group('id'))
|
||||||
|
for m in re.finditer(
|
||||||
|
r'data-id=(["\'])(?P<id>(?:(?!\1).)+)\1', webpage)]
|
||||||
|
|
||||||
|
if not entries:
|
||||||
|
entries = [
|
||||||
|
self.url_result(m.group('url'), ie=AZMedienIE.ie_key())
|
||||||
|
for m in re.finditer(
|
||||||
|
r'<a[^>]+data-real=(["\'])(?P<url>http.+?)\1', webpage)]
|
||||||
|
|
||||||
|
if not entries:
|
||||||
|
entries = [
|
||||||
|
# May contain nested playlists (e.g. [1]) thus no explicit
|
||||||
|
# ie_key
|
||||||
|
# 1. http://www.telezueri.ch/219-topic-aera-trump-hat-offiziell-begonnen)
|
||||||
|
self.url_result(urljoin(url, m.group('url')))
|
||||||
|
for m in re.finditer(
|
||||||
|
r'<a[^>]+name=[^>]+href=(["\'])(?P<url>/.+?)\1', webpage)]
|
||||||
|
|
||||||
|
title = self._search_regex(
|
||||||
|
r'episodeShareTitle\s*=\s*(["\'])(?P<title>(?:(?!\1).)+)\1',
|
||||||
|
webpage, 'title',
|
||||||
|
default=strip_or_none(get_element_by_id(
|
||||||
|
'video-title', webpage)), group='title')
|
||||||
|
|
||||||
|
return self.playlist_result(entries, show_id, title)
|
||||||
|
|
||||||
|
|
||||||
|
class AZMedienShowPlaylistIE(AZMedienBaseIE):
|
||||||
|
IE_DESC = 'AZ Medien show playlists'
|
||||||
|
_VALID_URL = r'''(?x)
|
||||||
|
https?://
|
||||||
|
(?:www\.)?
|
||||||
|
(?:
|
||||||
|
telezueri\.ch|
|
||||||
|
telebaern\.tv|
|
||||||
|
telem1\.ch
|
||||||
|
)/
|
||||||
|
(?:
|
||||||
|
all-episodes|
|
||||||
|
alle-episoden
|
||||||
|
)/
|
||||||
|
(?P<id>[^/?#&]+)
|
||||||
|
'''
|
||||||
|
|
||||||
|
_TEST = {
|
||||||
|
'url': 'http://www.telezueri.ch/all-episodes/astrotalk',
|
||||||
|
'info_dict': {
|
||||||
|
'id': 'astrotalk',
|
||||||
|
'title': 'TeleZüri: AstroTalk - alle episoden',
|
||||||
|
'description': 'md5:4c0f7e7d741d906004266e295ceb4a26',
|
||||||
|
},
|
||||||
|
'playlist_mincount': 13,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
playlist_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, playlist_id)
|
||||||
|
episodes = get_element_by_class('search-mobile-box', webpage)
|
||||||
|
entries = [self.url_result(
|
||||||
|
urljoin(url, m.group('url'))) for m in re.finditer(
|
||||||
|
r'<a[^>]+href=(["\'])(?P<url>(?:(?!\1).)+)\1', episodes)]
|
||||||
|
title = self._og_search_title(webpage, fatal=False)
|
||||||
|
description = self._og_search_description(webpage)
|
||||||
|
return self.playlist_result(entries, playlist_id, title, description)
|
@ -1,140 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from .common import InfoExtractor
|
|
||||||
from ..utils import (
|
|
||||||
ExtractorError,
|
|
||||||
float_or_none,
|
|
||||||
sanitized_Request,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AzubuIE(InfoExtractor):
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?azubu\.(?:tv|uol.com.br)/[^/]+#!/play/(?P<id>\d+)'
|
|
||||||
_TESTS = [
|
|
||||||
{
|
|
||||||
'url': 'http://www.azubu.tv/GSL#!/play/15575/2014-hot6-cup-last-big-match-ro8-day-1',
|
|
||||||
'md5': 'a88b42fcf844f29ad6035054bd9ecaf4',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '15575',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': '2014 HOT6 CUP LAST BIG MATCH Ro8 Day 1',
|
|
||||||
'description': 'md5:d06bdea27b8cc4388a90ad35b5c66c01',
|
|
||||||
'thumbnail': r're:^https?://.*\.jpe?g',
|
|
||||||
'timestamp': 1417523507.334,
|
|
||||||
'upload_date': '20141202',
|
|
||||||
'duration': 9988.7,
|
|
||||||
'uploader': 'GSL',
|
|
||||||
'uploader_id': 414310,
|
|
||||||
'view_count': int,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'url': 'http://www.azubu.tv/FnaticTV#!/play/9344/-fnatic-at-worlds-2014:-toyz---%22i-love-rekkles,-he-has-amazing-mechanics%22-',
|
|
||||||
'md5': 'b72a871fe1d9f70bd7673769cdb3b925',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '9344',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'Fnatic at Worlds 2014: Toyz - "I love Rekkles, he has amazing mechanics"',
|
|
||||||
'description': 'md5:4a649737b5f6c8b5c5be543e88dc62af',
|
|
||||||
'thumbnail': r're:^https?://.*\.jpe?g',
|
|
||||||
'timestamp': 1410530893.320,
|
|
||||||
'upload_date': '20140912',
|
|
||||||
'duration': 172.385,
|
|
||||||
'uploader': 'FnaticTV',
|
|
||||||
'uploader_id': 272749,
|
|
||||||
'view_count': int,
|
|
||||||
},
|
|
||||||
'skip': 'Channel offline',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
video_id = self._match_id(url)
|
|
||||||
|
|
||||||
data = self._download_json(
|
|
||||||
'http://www.azubu.tv/api/video/%s' % video_id, video_id)['data']
|
|
||||||
|
|
||||||
title = data['title'].strip()
|
|
||||||
description = data.get('description')
|
|
||||||
thumbnail = data.get('thumbnail')
|
|
||||||
view_count = data.get('view_count')
|
|
||||||
user = data.get('user', {})
|
|
||||||
uploader = user.get('username')
|
|
||||||
uploader_id = user.get('id')
|
|
||||||
|
|
||||||
stream_params = json.loads(data['stream_params'])
|
|
||||||
|
|
||||||
timestamp = float_or_none(stream_params.get('creationDate'), 1000)
|
|
||||||
duration = float_or_none(stream_params.get('length'), 1000)
|
|
||||||
|
|
||||||
renditions = stream_params.get('renditions') or []
|
|
||||||
video = stream_params.get('FLVFullLength') or stream_params.get('videoFullLength')
|
|
||||||
if video:
|
|
||||||
renditions.append(video)
|
|
||||||
|
|
||||||
if not renditions and not user.get('channel', {}).get('is_live', True):
|
|
||||||
raise ExtractorError('%s said: channel is offline.' % self.IE_NAME, expected=True)
|
|
||||||
|
|
||||||
formats = [{
|
|
||||||
'url': fmt['url'],
|
|
||||||
'width': fmt['frameWidth'],
|
|
||||||
'height': fmt['frameHeight'],
|
|
||||||
'vbr': float_or_none(fmt['encodingRate'], 1000),
|
|
||||||
'filesize': fmt['size'],
|
|
||||||
'vcodec': fmt['videoCodec'],
|
|
||||||
'container': fmt['videoContainer'],
|
|
||||||
} for fmt in renditions if fmt['url']]
|
|
||||||
self._sort_formats(formats)
|
|
||||||
|
|
||||||
return {
|
|
||||||
'id': video_id,
|
|
||||||
'title': title,
|
|
||||||
'description': description,
|
|
||||||
'thumbnail': thumbnail,
|
|
||||||
'timestamp': timestamp,
|
|
||||||
'duration': duration,
|
|
||||||
'uploader': uploader,
|
|
||||||
'uploader_id': uploader_id,
|
|
||||||
'view_count': view_count,
|
|
||||||
'formats': formats,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class AzubuLiveIE(InfoExtractor):
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?azubu\.(?:tv|uol.com.br)/(?P<id>[^/]+)$'
|
|
||||||
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'http://www.azubu.tv/MarsTVMDLen',
|
|
||||||
'only_matching': True,
|
|
||||||
}, {
|
|
||||||
'url': 'http://azubu.uol.com.br/adolfz',
|
|
||||||
'only_matching': True,
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
user = self._match_id(url)
|
|
||||||
|
|
||||||
info = self._download_json(
|
|
||||||
'http://api.azubu.tv/public/modules/last-video/{0}/info'.format(user),
|
|
||||||
user)['data']
|
|
||||||
if info['type'] != 'STREAM':
|
|
||||||
raise ExtractorError('{0} is not streaming live'.format(user), expected=True)
|
|
||||||
|
|
||||||
req = sanitized_Request(
|
|
||||||
'https://edge-elb.api.brightcove.com/playback/v1/accounts/3361910549001/videos/ref:' + info['reference_id'])
|
|
||||||
req.add_header('Accept', 'application/json;pk=BCpkADawqM1gvI0oGWg8dxQHlgT8HkdE2LnAlWAZkOlznO39bSZX726u4JqnDsK3MDXcO01JxXK2tZtJbgQChxgaFzEVdHRjaDoxaOu8hHOO8NYhwdxw9BzvgkvLUlpbDNUuDoc4E4wxDToV')
|
|
||||||
bc_info = self._download_json(req, user)
|
|
||||||
m3u8_url = next(source['src'] for source in bc_info['sources'] if source['container'] == 'M2TS')
|
|
||||||
formats = self._extract_m3u8_formats(m3u8_url, user, ext='mp4')
|
|
||||||
self._sort_formats(formats)
|
|
||||||
|
|
||||||
return {
|
|
||||||
'id': info['id'],
|
|
||||||
'title': self._live_title(info['title']),
|
|
||||||
'uploader_id': user,
|
|
||||||
'formats': formats,
|
|
||||||
'is_live': True,
|
|
||||||
'thumbnail': bc_info['poster'],
|
|
||||||
}
|
|
@ -0,0 +1,188 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..utils import (
|
||||||
|
ExtractorError,
|
||||||
|
clean_html,
|
||||||
|
compat_str,
|
||||||
|
float_or_none,
|
||||||
|
int_or_none,
|
||||||
|
parse_iso8601,
|
||||||
|
try_get,
|
||||||
|
urljoin,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BeamProBaseIE(InfoExtractor):
|
||||||
|
_API_BASE = 'https://mixer.com/api/v1'
|
||||||
|
_RATINGS = {'family': 0, 'teen': 13, '18+': 18}
|
||||||
|
|
||||||
|
def _extract_channel_info(self, chan):
|
||||||
|
user_id = chan.get('userId') or try_get(chan, lambda x: x['user']['id'])
|
||||||
|
return {
|
||||||
|
'uploader': chan.get('token') or try_get(
|
||||||
|
chan, lambda x: x['user']['username'], compat_str),
|
||||||
|
'uploader_id': compat_str(user_id) if user_id else None,
|
||||||
|
'age_limit': self._RATINGS.get(chan.get('audience')),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BeamProLiveIE(BeamProBaseIE):
|
||||||
|
IE_NAME = 'Mixer:live'
|
||||||
|
_VALID_URL = r'https?://(?:\w+\.)?(?:beam\.pro|mixer\.com)/(?P<id>[^/?#&]+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'http://mixer.com/niterhayven',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '261562',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Introducing The Witcher 3 // The Grind Starts Now!',
|
||||||
|
'description': 'md5:0b161ac080f15fe05d18a07adb44a74d',
|
||||||
|
'thumbnail': r're:https://.*\.jpg$',
|
||||||
|
'timestamp': 1483477281,
|
||||||
|
'upload_date': '20170103',
|
||||||
|
'uploader': 'niterhayven',
|
||||||
|
'uploader_id': '373396',
|
||||||
|
'age_limit': 18,
|
||||||
|
'is_live': True,
|
||||||
|
'view_count': int,
|
||||||
|
},
|
||||||
|
'skip': 'niterhayven is offline',
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_MANIFEST_URL_TEMPLATE = '%s/channels/%%s/manifest.%%s' % BeamProBaseIE._API_BASE
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def suitable(cls, url):
|
||||||
|
return False if BeamProVodIE.suitable(url) else super(BeamProLiveIE, cls).suitable(url)
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
channel_name = self._match_id(url)
|
||||||
|
|
||||||
|
chan = self._download_json(
|
||||||
|
'%s/channels/%s' % (self._API_BASE, channel_name), channel_name)
|
||||||
|
|
||||||
|
if chan.get('online') is False:
|
||||||
|
raise ExtractorError(
|
||||||
|
'{0} is offline'.format(channel_name), expected=True)
|
||||||
|
|
||||||
|
channel_id = chan['id']
|
||||||
|
|
||||||
|
def manifest_url(kind):
|
||||||
|
return self._MANIFEST_URL_TEMPLATE % (channel_id, kind)
|
||||||
|
|
||||||
|
formats = self._extract_m3u8_formats(
|
||||||
|
manifest_url('m3u8'), channel_name, ext='mp4', m3u8_id='hls',
|
||||||
|
fatal=False)
|
||||||
|
formats.extend(self._extract_smil_formats(
|
||||||
|
manifest_url('smil'), channel_name, fatal=False))
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
info = {
|
||||||
|
'id': compat_str(chan.get('id') or channel_name),
|
||||||
|
'title': self._live_title(chan.get('name') or channel_name),
|
||||||
|
'description': clean_html(chan.get('description')),
|
||||||
|
'thumbnail': try_get(
|
||||||
|
chan, lambda x: x['thumbnail']['url'], compat_str),
|
||||||
|
'timestamp': parse_iso8601(chan.get('updatedAt')),
|
||||||
|
'is_live': True,
|
||||||
|
'view_count': int_or_none(chan.get('viewersTotal')),
|
||||||
|
'formats': formats,
|
||||||
|
}
|
||||||
|
info.update(self._extract_channel_info(chan))
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
class BeamProVodIE(BeamProBaseIE):
|
||||||
|
IE_NAME = 'Mixer:vod'
|
||||||
|
_VALID_URL = r'https?://(?:\w+\.)?(?:beam\.pro|mixer\.com)/[^/?#&]+\?.*?\bvod=(?P<id>\d+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'https://mixer.com/willow8714?vod=2259830',
|
||||||
|
'md5': 'b2431e6e8347dc92ebafb565d368b76b',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '2259830',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'willow8714\'s Channel',
|
||||||
|
'duration': 6828.15,
|
||||||
|
'thumbnail': r're:https://.*source\.png$',
|
||||||
|
'timestamp': 1494046474,
|
||||||
|
'upload_date': '20170506',
|
||||||
|
'uploader': 'willow8714',
|
||||||
|
'uploader_id': '6085379',
|
||||||
|
'age_limit': 13,
|
||||||
|
'view_count': int,
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _extract_format(vod, vod_type):
|
||||||
|
if not vod.get('baseUrl'):
|
||||||
|
return []
|
||||||
|
|
||||||
|
if vod_type == 'hls':
|
||||||
|
filename, protocol = 'manifest.m3u8', 'm3u8_native'
|
||||||
|
elif vod_type == 'raw':
|
||||||
|
filename, protocol = 'source.mp4', 'https'
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
data = vod.get('data') if isinstance(vod.get('data'), dict) else {}
|
||||||
|
|
||||||
|
format_id = [vod_type]
|
||||||
|
if isinstance(data.get('Height'), compat_str):
|
||||||
|
format_id.append('%sp' % data['Height'])
|
||||||
|
|
||||||
|
return [{
|
||||||
|
'url': urljoin(vod['baseUrl'], filename),
|
||||||
|
'format_id': '-'.join(format_id),
|
||||||
|
'ext': 'mp4',
|
||||||
|
'protocol': protocol,
|
||||||
|
'width': int_or_none(data.get('Width')),
|
||||||
|
'height': int_or_none(data.get('Height')),
|
||||||
|
'fps': int_or_none(data.get('Fps')),
|
||||||
|
'tbr': int_or_none(data.get('Bitrate'), 1000),
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
vod_id = self._match_id(url)
|
||||||
|
|
||||||
|
vod_info = self._download_json(
|
||||||
|
'%s/recordings/%s' % (self._API_BASE, vod_id), vod_id)
|
||||||
|
|
||||||
|
state = vod_info.get('state')
|
||||||
|
if state != 'AVAILABLE':
|
||||||
|
raise ExtractorError(
|
||||||
|
'VOD %s is not available (state: %s)' % (vod_id, state),
|
||||||
|
expected=True)
|
||||||
|
|
||||||
|
formats = []
|
||||||
|
thumbnail_url = None
|
||||||
|
|
||||||
|
for vod in vod_info['vods']:
|
||||||
|
vod_type = vod.get('format')
|
||||||
|
if vod_type in ('hls', 'raw'):
|
||||||
|
formats.extend(self._extract_format(vod, vod_type))
|
||||||
|
elif vod_type == 'thumbnail':
|
||||||
|
thumbnail_url = urljoin(vod.get('baseUrl'), 'source.png')
|
||||||
|
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
info = {
|
||||||
|
'id': vod_id,
|
||||||
|
'title': vod_info.get('name') or vod_id,
|
||||||
|
'duration': float_or_none(vod_info.get('duration')),
|
||||||
|
'thumbnail': thumbnail_url,
|
||||||
|
'timestamp': parse_iso8601(vod_info.get('createdAt')),
|
||||||
|
'view_count': int_or_none(vod_info.get('viewsTotal')),
|
||||||
|
'formats': formats,
|
||||||
|
}
|
||||||
|
info.update(self._extract_channel_info(vod_info.get('channel') or {}))
|
||||||
|
|
||||||
|
return info
|
@ -0,0 +1,72 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
|
||||||
|
from ..utils import (
|
||||||
|
extract_attributes,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BostonGlobeIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'(?i)https?://(?:www\.)?bostonglobe\.com/.*/(?P<id>[^/]+)/\w+(?:\.html)?'
|
||||||
|
_TESTS = [
|
||||||
|
{
|
||||||
|
'url': 'http://www.bostonglobe.com/metro/2017/02/11/tree-finally-succumbs-disease-leaving-hole-neighborhood/h1b4lviqzMTIn9sVy8F3gP/story.html',
|
||||||
|
'md5': '0a62181079c85c2d2b618c9a738aedaf',
|
||||||
|
'info_dict': {
|
||||||
|
'title': 'A tree finally succumbs to disease, leaving a hole in a neighborhood',
|
||||||
|
'id': '5320421710001',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'description': 'It arrived as a sapling when the Back Bay was in its infancy, a spindly American elm tamped down into a square of dirt cut into the brick sidewalk of 1880s Marlborough Street, no higher than the first bay window of the new brownstone behind it.',
|
||||||
|
'timestamp': 1486877593,
|
||||||
|
'upload_date': '20170212',
|
||||||
|
'uploader_id': '245991542',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Embedded youtube video; we hand it off to the Generic extractor.
|
||||||
|
'url': 'https://www.bostonglobe.com/lifestyle/names/2017/02/17/does-ben-affleck-play-matt-damon-favorite-version-batman/ruqkc9VxKBYmh5txn1XhSI/story.html',
|
||||||
|
'md5': '582b40327089d5c0c949b3c54b13c24b',
|
||||||
|
'info_dict': {
|
||||||
|
'title': "Who Is Matt Damon's Favorite Batman?",
|
||||||
|
'id': 'ZW1QCnlA6Qc',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'upload_date': '20170217',
|
||||||
|
'description': 'md5:3b3dccb9375867e0b4d527ed87d307cb',
|
||||||
|
'uploader': 'The Late Late Show with James Corden',
|
||||||
|
'uploader_id': 'TheLateLateShow',
|
||||||
|
},
|
||||||
|
'expected_warnings': ['404'],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
page_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, page_id)
|
||||||
|
|
||||||
|
page_title = self._og_search_title(webpage, default=None)
|
||||||
|
|
||||||
|
# <video data-brightcove-video-id="5320421710001" data-account="245991542" data-player="SJWAiyYWg" data-embed="default" class="video-js" controls itemscope itemtype="http://schema.org/VideoObject">
|
||||||
|
entries = []
|
||||||
|
for video in re.findall(r'(?i)(<video[^>]+>)', webpage):
|
||||||
|
attrs = extract_attributes(video)
|
||||||
|
|
||||||
|
video_id = attrs.get('data-brightcove-video-id')
|
||||||
|
account_id = attrs.get('data-account')
|
||||||
|
player_id = attrs.get('data-player')
|
||||||
|
embed = attrs.get('data-embed')
|
||||||
|
|
||||||
|
if video_id and account_id and player_id and embed:
|
||||||
|
entries.append(
|
||||||
|
'http://players.brightcove.net/%s/%s_%s/index.html?videoId=%s'
|
||||||
|
% (account_id, player_id, embed, video_id))
|
||||||
|
|
||||||
|
if len(entries) == 0:
|
||||||
|
return self.url_result(url, 'Generic')
|
||||||
|
elif len(entries) == 1:
|
||||||
|
return self.url_result(entries[0], 'BrightcoveNew')
|
||||||
|
else:
|
||||||
|
return self.playlist_from_matches(entries, page_id, page_title, ie='BrightcoveNew')
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue