Browse Source
Merge branch 'master' into rtmpdump
Merge branch 'master' into rtmpdump
Conflicts: youtube_dl/FileDownloader.py Mergemaster
64 changed files with 1653 additions and 638 deletions
Split View
Diff Options
-
6README.md
-
1setup.py
-
17test/helper.py
-
20test/test_YoutubeDL.py
-
70test/test_dailymotion_subtitles.py
-
75test/test_download.py
-
18test/test_playlists.py
-
211test/test_subtitles.py
-
95test/test_youtube_subtitles.py
-
75youtube_dl/FileDownloader.py
-
2youtube_dl/PostProcessor.py
-
158youtube_dl/YoutubeDL.py
-
113youtube_dl/__init__.py
-
18youtube_dl/extractor/__init__.py
-
52youtube_dl/extractor/arte.py
-
81youtube_dl/extractor/bambuser.py
-
61youtube_dl/extractor/brightcove.py
-
6youtube_dl/extractor/canalc2.py
-
4youtube_dl/extractor/cinemassacre.py
-
2youtube_dl/extractor/cnn.py
-
27youtube_dl/extractor/common.py
-
31youtube_dl/extractor/dailymotion.py
-
2youtube_dl/extractor/depositfiles.py
-
37youtube_dl/extractor/eitb.py
-
2youtube_dl/extractor/exfm.py
-
50youtube_dl/extractor/extremetube.py
-
38youtube_dl/extractor/gamekings.py
-
28youtube_dl/extractor/generic.py
-
4youtube_dl/extractor/hypem.py
-
7youtube_dl/extractor/kankan.py
-
8youtube_dl/extractor/keezmovies.py
-
54youtube_dl/extractor/livestream.py
-
51youtube_dl/extractor/metacafe.py
-
49youtube_dl/extractor/mofosex.py
-
5youtube_dl/extractor/mtv.py
-
48youtube_dl/extractor/myspace.py
-
6youtube_dl/extractor/pornhub.py
-
4youtube_dl/extractor/redtube.py
-
12youtube_dl/extractor/rtlnow.py
-
1youtube_dl/extractor/slashdot.py
-
132youtube_dl/extractor/soundcloud.py
-
25youtube_dl/extractor/southparkstudios.py
-
35youtube_dl/extractor/space.py
-
6youtube_dl/extractor/spankwire.py
-
50youtube_dl/extractor/spiegel.py
-
12youtube_dl/extractor/subtitles.py
-
41youtube_dl/extractor/teamcoco.py
-
72youtube_dl/extractor/ted.py
-
6youtube_dl/extractor/tube8.py
-
42youtube_dl/extractor/tvp.py
-
95youtube_dl/extractor/vevo.py
-
2youtube_dl/extractor/viddler.py
-
17youtube_dl/extractor/vimeo.py
-
2youtube_dl/extractor/vine.py
-
45youtube_dl/extractor/vk.py
-
1youtube_dl/extractor/weibo.py
-
2youtube_dl/extractor/xnxx.py
-
55youtube_dl/extractor/xtube.py
-
2youtube_dl/extractor/yahoo.py
-
6youtube_dl/extractor/youku.py
-
8youtube_dl/extractor/youporn.py
-
78youtube_dl/extractor/youtube.py
-
6youtube_dl/update.py
-
2youtube_dl/version.py
@ -1,70 +0,0 @@ |
|||
#!/usr/bin/env python |
|||
|
|||
# Allow direct execution |
|||
import os |
|||
import sys |
|||
import unittest |
|||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|||
|
|||
from test.helper import FakeYDL, global_setup, md5 |
|||
global_setup() |
|||
|
|||
|
|||
from youtube_dl.extractor import DailymotionIE |
|||
|
|||
class TestDailymotionSubtitles(unittest.TestCase): |
|||
def setUp(self): |
|||
self.DL = FakeYDL() |
|||
self.url = 'http://www.dailymotion.com/video/xczg00' |
|||
def getInfoDict(self): |
|||
IE = DailymotionIE(self.DL) |
|||
info_dict = IE.extract(self.url) |
|||
return info_dict |
|||
def getSubtitles(self): |
|||
info_dict = self.getInfoDict() |
|||
return info_dict[0]['subtitles'] |
|||
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(u'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(u'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_nosubtitles(self): |
|||
self.DL.expect_warning(u'video doesn\'t have subtitles') |
|||
self.url = 'http://www.dailymotion.com/video/x12u166_le-zapping-tele-star-du-08-aout-2013_tv' |
|||
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, u'Subtitles for \'%s\' not extracted' % lang) |
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
@ -0,0 +1,211 @@ |
|||
#!/usr/bin/env python |
|||
|
|||
# Allow direct execution |
|||
import os |
|||
import sys |
|||
import unittest |
|||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|||
|
|||
from test.helper import FakeYDL, global_setup, md5 |
|||
global_setup() |
|||
|
|||
|
|||
from youtube_dl.extractor import ( |
|||
YoutubeIE, |
|||
DailymotionIE, |
|||
TEDIE, |
|||
) |
|||
|
|||
|
|||
class BaseTestSubtitles(unittest.TestCase): |
|||
url = None |
|||
IE = None |
|||
def setUp(self): |
|||
self.DL = FakeYDL() |
|||
self.ie = self.IE(self.DL) |
|||
|
|||
def getInfoDict(self): |
|||
info_dict = self.ie.extract(self.url) |
|||
return info_dict |
|||
|
|||
def getSubtitles(self): |
|||
info_dict = self.getInfoDict() |
|||
return info_dict['subtitles'] |
|||
|
|||
|
|||
class TestYoutubeSubtitles(BaseTestSubtitles): |
|||
url = 'QRS8MkLhQmM' |
|||
IE = YoutubeIE |
|||
|
|||
def getSubtitles(self): |
|||
info_dict = self.getInfoDict() |
|||
return info_dict[0]['subtitles'] |
|||
|
|||
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) |
|||
|
|||
def test_youtube_subtitles_sbv_format(self): |
|||
self.DL.params['writesubtitles'] = True |
|||
self.DL.params['subtitlesformat'] = 'sbv' |
|||
subtitles = self.getSubtitles() |
|||
self.assertEqual(md5(subtitles['en']), '13aeaa0c245a8bed9a451cb643e3ad8b') |
|||
|
|||
def test_youtube_subtitles_vtt_format(self): |
|||
self.DL.params['writesubtitles'] = True |
|||
self.DL.params['subtitlesformat'] = 'vtt' |
|||
subtitles = self.getSubtitles() |
|||
self.assertEqual(md5(subtitles['en']), '356cdc577fde0c6783b9b822e7206ff7') |
|||
|
|||
def test_youtube_list_subtitles(self): |
|||
self.DL.expect_warning(u'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 |
|||
self.DL.params['subtitleslangs'] = ['it'] |
|||
subtitles = self.getSubtitles() |
|||
self.assertTrue(subtitles['it'] is not None) |
|||
|
|||
def test_youtube_nosubtitles(self): |
|||
self.DL.expect_warning(u'video doesn\'t have subtitles') |
|||
self.url = 'sAjKT8FhjI8' |
|||
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, u'Subtitles for \'%s\' not extracted' % lang) |
|||
|
|||
|
|||
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(u'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(u'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_nosubtitles(self): |
|||
self.DL.expect_warning(u'video doesn\'t have subtitles') |
|||
self.url = 'http://www.dailymotion.com/video/x12u166_le-zapping-tele-star-du-08-aout-2013_tv' |
|||
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, u'Subtitles for \'%s\' not extracted' % lang) |
|||
|
|||
|
|||
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']), '2154f31ff9b9f89a0aa671537559c21d') |
|||
|
|||
def test_subtitles_lang(self): |
|||
self.DL.params['writesubtitles'] = True |
|||
self.DL.params['subtitleslangs'] = ['fr'] |
|||
subtitles = self.getSubtitles() |
|||
self.assertEqual(md5(subtitles['fr']), '7616cbc6df20ec2c1204083c83871cf6') |
|||
|
|||
def test_allsubtitles(self): |
|||
self.DL.params['writesubtitles'] = True |
|||
self.DL.params['allsubtitles'] = True |
|||
subtitles = self.getSubtitles() |
|||
self.assertEqual(len(subtitles.keys()), 28) |
|||
|
|||
def test_list_subtitles(self): |
|||
self.DL.expect_warning(u'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(u'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.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang) |
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
@ -1,95 +0,0 @@ |
|||
#!/usr/bin/env python |
|||
|
|||
# Allow direct execution |
|||
import os |
|||
import sys |
|||
import unittest |
|||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
|||
|
|||
from test.helper import FakeYDL, global_setup, md5 |
|||
global_setup() |
|||
|
|||
|
|||
from youtube_dl.extractor import YoutubeIE |
|||
|
|||
|
|||
class TestYoutubeSubtitles(unittest.TestCase): |
|||
def setUp(self): |
|||
self.DL = FakeYDL() |
|||
self.url = 'QRS8MkLhQmM' |
|||
|
|||
def getInfoDict(self): |
|||
IE = YoutubeIE(self.DL) |
|||
info_dict = IE.extract(self.url) |
|||
return info_dict |
|||
|
|||
def getSubtitles(self): |
|||
info_dict = self.getInfoDict() |
|||
return info_dict[0]['subtitles'] |
|||
|
|||
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) |
|||
|
|||
def test_youtube_subtitles_sbv_format(self): |
|||
self.DL.params['writesubtitles'] = True |
|||
self.DL.params['subtitlesformat'] = 'sbv' |
|||
subtitles = self.getSubtitles() |
|||
self.assertEqual(md5(subtitles['en']), '13aeaa0c245a8bed9a451cb643e3ad8b') |
|||
|
|||
def test_youtube_subtitles_vtt_format(self): |
|||
self.DL.params['writesubtitles'] = True |
|||
self.DL.params['subtitlesformat'] = 'vtt' |
|||
subtitles = self.getSubtitles() |
|||
self.assertEqual(md5(subtitles['en']), '356cdc577fde0c6783b9b822e7206ff7') |
|||
|
|||
def test_youtube_list_subtitles(self): |
|||
self.DL.expect_warning(u'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 |
|||
self.DL.params['subtitleslangs'] = ['it'] |
|||
subtitles = self.getSubtitles() |
|||
self.assertTrue(subtitles['it'] is not None) |
|||
|
|||
def test_youtube_nosubtitles(self): |
|||
self.DL.expect_warning(u'video doesn\'t have subtitles') |
|||
self.url = 'sAjKT8FhjI8' |
|||
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, u'Subtitles for \'%s\' not extracted' % lang) |
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
@ -0,0 +1,81 @@ |
|||
import re |
|||
import json |
|||
import itertools |
|||
|
|||
from .common import InfoExtractor |
|||
from ..utils import ( |
|||
compat_urllib_request, |
|||
) |
|||
|
|||
|
|||
class BambuserIE(InfoExtractor): |
|||
IE_NAME = u'bambuser' |
|||
_VALID_URL = r'https?://bambuser\.com/v/(?P<id>\d+)' |
|||
_API_KEY = '005f64509e19a868399060af746a00aa' |
|||
|
|||
_TEST = { |
|||
u'url': u'http://bambuser.com/v/4050584', |
|||
# MD5 seems to be flaky, see https://travis-ci.org/rg3/youtube-dl/jobs/14051016#L388 |
|||
#u'md5': u'fba8f7693e48fd4e8641b3fd5539a641', |
|||
u'info_dict': { |
|||
u'id': u'4050584', |
|||
u'ext': u'flv', |
|||
u'title': u'Education engineering days - lightning talks', |
|||
u'duration': 3741, |
|||
u'uploader': u'pixelversity', |
|||
u'uploader_id': u'344706', |
|||
}, |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
video_id = mobj.group('id') |
|||
info_url = ('http://player-c.api.bambuser.com/getVideo.json?' |
|||
'&api_key=%s&vid=%s' % (self._API_KEY, video_id)) |
|||
info_json = self._download_webpage(info_url, video_id) |
|||
info = json.loads(info_json)['result'] |
|||
|
|||
return { |
|||
'id': video_id, |
|||
'title': info['title'], |
|||
'url': info['url'], |
|||
'thumbnail': info.get('preview'), |
|||
'duration': int(info['length']), |
|||
'view_count': int(info['views_total']), |
|||
'uploader': info['username'], |
|||
'uploader_id': info['uid'], |
|||
} |
|||
|
|||
|
|||
class BambuserChannelIE(InfoExtractor): |
|||
IE_NAME = u'bambuser:channel' |
|||
_VALID_URL = r'http://bambuser.com/channel/(?P<user>.*?)(?:/|#|\?|$)' |
|||
# The maximum number we can get with each request |
|||
_STEP = 50 |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
user = mobj.group('user') |
|||
urls = [] |
|||
last_id = '' |
|||
for i in itertools.count(1): |
|||
req_url = ('http://bambuser.com/xhr-api/index.php?username={user}' |
|||
'&sort=created&access_mode=0%2C1%2C2&limit={count}' |
|||
'&method=broadcast&format=json&vid_older_than={last}' |
|||
).format(user=user, count=self._STEP, last=last_id) |
|||
req = compat_urllib_request.Request(req_url) |
|||
# Without setting this header, we wouldn't get any result |
|||
req.add_header('Referer', 'http://bambuser.com/channel/%s' % user) |
|||
info_json = self._download_webpage(req, user, |
|||
u'Downloading page %d' % i) |
|||
results = json.loads(info_json)['result'] |
|||
if len(results) == 0: |
|||
break |
|||
last_id = results[-1]['vid'] |
|||
urls.extend(self.url_result(v['page'], 'Bambuser') for v in results) |
|||
|
|||
return { |
|||
'_type': 'playlist', |
|||
'title': user, |
|||
'entries': urls, |
|||
} |
@ -0,0 +1,37 @@ |
|||
# encoding: utf-8 |
|||
import re |
|||
|
|||
from .common import InfoExtractor |
|||
from .brightcove import BrightcoveIE |
|||
from ..utils import ExtractorError |
|||
|
|||
|
|||
class EitbIE(InfoExtractor): |
|||
IE_NAME = u'eitb.tv' |
|||
_VALID_URL = r'https?://www\.eitb\.tv/(eu/bideoa|es/video)/[^/]+/(?P<playlist_id>\d+)/(?P<chapter_id>\d+)' |
|||
|
|||
_TEST = { |
|||
u'add_ie': ['Brightcove'], |
|||
u'url': u'http://www.eitb.tv/es/video/60-minutos-60-minutos-2013-2014/2677100210001/2743577154001/lasa-y-zabala-30-anos/', |
|||
u'md5': u'edf4436247185adee3ea18ce64c47998', |
|||
u'info_dict': { |
|||
u'id': u'2743577154001', |
|||
u'ext': u'mp4', |
|||
u'title': u'60 minutos (Lasa y Zabala, 30 años)', |
|||
# All videos from eitb has this description in the brightcove info |
|||
u'description': u'.', |
|||
u'uploader': u'Euskal Telebista', |
|||
}, |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
chapter_id = mobj.group('chapter_id') |
|||
webpage = self._download_webpage(url, chapter_id) |
|||
bc_url = BrightcoveIE._extract_brightcove_url(webpage) |
|||
if bc_url is None: |
|||
raise ExtractorError(u'Could not extract the Brightcove url') |
|||
# The BrightcoveExperience object doesn't contain the video id, we set |
|||
# it manually |
|||
bc_url += '&%40videoPlayer={0}'.format(chapter_id) |
|||
return self.url_result(bc_url, BrightcoveIE.ie_key()) |
@ -0,0 +1,50 @@ |
|||
import os |
|||
import re |
|||
|
|||
from .common import InfoExtractor |
|||
from ..utils import ( |
|||
compat_urllib_parse_urlparse, |
|||
compat_urllib_request, |
|||
compat_urllib_parse, |
|||
) |
|||
|
|||
class ExtremeTubeIE(InfoExtractor): |
|||
_VALID_URL = r'^(?:https?://)?(?:www\.)?(?P<url>extremetube\.com/video/.+?(?P<videoid>[0-9]+))(?:[/?&]|$)' |
|||
_TEST = { |
|||
u'url': u'http://www.extremetube.com/video/music-video-14-british-euro-brit-european-cumshots-swallow-652431', |
|||
u'file': u'652431.mp4', |
|||
u'md5': u'1fb9228f5e3332ec8c057d6ac36f33e0', |
|||
u'info_dict': { |
|||
u"title": u"Music Video 14 british euro brit european cumshots swallow", |
|||
u"uploader": u"unknown", |
|||
u"age_limit": 18, |
|||
} |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
video_id = mobj.group('videoid') |
|||
url = 'http://www.' + mobj.group('url') |
|||
|
|||
req = compat_urllib_request.Request(url) |
|||
req.add_header('Cookie', 'age_verified=1') |
|||
webpage = self._download_webpage(req, video_id) |
|||
|
|||
video_title = self._html_search_regex(r'<h1 [^>]*?title="([^"]+)"[^>]*>\1<', webpage, u'title') |
|||
uploader = self._html_search_regex(r'>Posted by:(?=<)(?:\s|<[^>]*>)*(.+?)\|', webpage, u'uploader', fatal=False) |
|||
video_url = compat_urllib_parse.unquote(self._html_search_regex(r'video_url=(.+?)&', webpage, u'video_url')) |
|||
path = compat_urllib_parse_urlparse(video_url).path |
|||
extension = os.path.splitext(path)[1][1:] |
|||
format = path.split('/')[5].split('_')[:2] |
|||
format = "-".join(format) |
|||
|
|||
return { |
|||
'id': video_id, |
|||
'title': video_title, |
|||
'uploader': uploader, |
|||
'url': video_url, |
|||
'ext': extension, |
|||
'format': format, |
|||
'format_id': format, |
|||
'age_limit': 18, |
|||
} |
@ -0,0 +1,38 @@ |
|||
import re |
|||
|
|||
from .common import InfoExtractor |
|||
|
|||
|
|||
class GamekingsIE(InfoExtractor): |
|||
_VALID_URL = r'http?://www\.gamekings\.tv/videos/(?P<name>[0-9a-z\-]+)' |
|||
_TEST = { |
|||
u"url": u"http://www.gamekings.tv/videos/phoenix-wright-ace-attorney-dual-destinies-review/", |
|||
u'file': u'20130811.mp4', |
|||
# MD5 is flaky, seems to change regularly |
|||
#u'md5': u'2f32b1f7b80fdc5cb616efb4f387f8a3', |
|||
u'info_dict': { |
|||
u"title": u"Phoenix Wright: Ace Attorney \u2013 Dual Destinies Review", |
|||
u"description": u"Melle en Steven hebben voor de review een week in de rechtbank doorbracht met Phoenix Wright: Ace Attorney - Dual Destinies.", |
|||
} |
|||
} |
|||
|
|||
def _real_extract(self, 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) |
|||
|
|||
video = re.search(r'[0-9]+', video_url) |
|||
video_id = video.group(0) |
|||
|
|||
# Todo: add medium format |
|||
video_url = video_url.replace(video_id, 'large/' + video_id) |
|||
|
|||
return { |
|||
'id': video_id, |
|||
'ext': 'mp4', |
|||
'url': video_url, |
|||
'title': self._og_search_title(webpage), |
|||
'description': self._og_search_description(webpage), |
|||
} |
@ -0,0 +1,49 @@ |
|||
import os |
|||
import re |
|||
|
|||
from .common import InfoExtractor |
|||
from ..utils import ( |
|||
compat_urllib_parse_urlparse, |
|||
compat_urllib_request, |
|||
compat_urllib_parse, |
|||
) |
|||
|
|||
class MofosexIE(InfoExtractor): |
|||
_VALID_URL = r'^(?:https?://)?(?:www\.)?(?P<url>mofosex\.com/videos/(?P<videoid>[0-9]+)/.*?\.html)' |
|||
_TEST = { |
|||
u'url': u'http://www.mofosex.com/videos/5018/japanese-teen-music-video.html', |
|||
u'file': u'5018.mp4', |
|||
u'md5': u'1b2eb47ac33cc75d4a80e3026b613c5a', |
|||
u'info_dict': { |
|||
u"title": u"Japanese Teen Music Video", |
|||
u"age_limit": 18, |
|||
} |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
video_id = mobj.group('videoid') |
|||
url = 'http://www.' + mobj.group('url') |
|||
|
|||
req = compat_urllib_request.Request(url) |
|||
req.add_header('Cookie', 'age_verified=1') |
|||
webpage = self._download_webpage(req, video_id) |
|||
|
|||
video_title = self._html_search_regex(r'<h1>(.+?)<', webpage, u'title') |
|||
video_url = compat_urllib_parse.unquote(self._html_search_regex(r'flashvars.video_url = \'([^\']+)', webpage, u'video_url')) |
|||
path = compat_urllib_parse_urlparse(video_url).path |
|||
extension = os.path.splitext(path)[1][1:] |
|||
format = path.split('/')[5].split('_')[:2] |
|||
format = "-".join(format) |
|||
|
|||
age_limit = self._rta_search(webpage) |
|||
|
|||
return { |
|||
'id': video_id, |
|||
'title': video_title, |
|||
'url': video_url, |
|||
'ext': extension, |
|||
'format': format, |
|||
'format_id': format, |
|||
'age_limit': age_limit, |
|||
} |
@ -0,0 +1,48 @@ |
|||
import re |
|||
import json |
|||
|
|||
from .common import InfoExtractor |
|||
from ..utils import ( |
|||
compat_str, |
|||
) |
|||
|
|||
|
|||
class MySpaceIE(InfoExtractor): |
|||
_VALID_URL = r'https?://myspace\.com/([^/]+)/video/[^/]+/(?P<id>\d+)' |
|||
|
|||
_TEST = { |
|||
u'url': u'https://myspace.com/coldplay/video/viva-la-vida/100008689', |
|||
u'info_dict': { |
|||
u'id': u'100008689', |
|||
u'ext': u'flv', |
|||
u'title': u'Viva La Vida', |
|||
u'description': u'The official Viva La Vida video, directed by Hype Williams', |
|||
u'uploader': u'Coldplay', |
|||
u'uploader_id': u'coldplay', |
|||
}, |
|||
u'params': { |
|||
# rtmp download |
|||
u'skip_download': True, |
|||
}, |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
video_id = mobj.group('id') |
|||
webpage = self._download_webpage(url, video_id) |
|||
context = json.loads(self._search_regex(r'context = ({.*?});', webpage, |
|||
u'context')) |
|||
video = context['video'] |
|||
rtmp_url, play_path = video['streamUrl'].split(';', 1) |
|||
|
|||
return { |
|||
'id': compat_str(video['mediaId']), |
|||
'title': video['title'], |
|||
'url': rtmp_url, |
|||
'play_path': play_path, |
|||
'ext': 'flv', |
|||
'description': video['description'], |
|||
'thumbnail': video['imageUrl'], |
|||
'uploader': video['artistName'], |
|||
'uploader_id': video['artistUsername'], |
|||
} |
@ -0,0 +1,35 @@ |
|||
import re |
|||
|
|||
from .common import InfoExtractor |
|||
from .brightcove import BrightcoveIE |
|||
from ..utils import RegexNotFoundError, ExtractorError |
|||
|
|||
|
|||
class SpaceIE(InfoExtractor): |
|||
_VALID_URL = r'https?://www\.space\.com/\d+-(?P<title>[^/\.\?]*?)-video.html' |
|||
_TEST = { |
|||
u'add_ie': ['Brightcove'], |
|||
u'url': u'http://www.space.com/23373-huge-martian-landforms-detail-revealed-by-european-probe-video.html', |
|||
u'info_dict': { |
|||
u'id': u'2780937028001', |
|||
u'ext': u'mp4', |
|||
u'title': u'Huge Martian Landforms\' Detail Revealed By European Probe | Video', |
|||
u'description': u'md5:db81cf7f3122f95ed234b631a6ea1e61', |
|||
u'uploader': u'TechMedia Networks', |
|||
}, |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
title = mobj.group('title') |
|||
webpage = self._download_webpage(url, title) |
|||
try: |
|||
# Some videos require the playerKey field, which isn't define in |
|||
# the BrightcoveExperience object |
|||
brightcove_url = self._og_search_video_url(webpage) |
|||
except RegexNotFoundError: |
|||
# Other videos works fine with the info from the object |
|||
brightcove_url = BrightcoveIE._extract_brightcove_url(webpage) |
|||
if brightcove_url is None: |
|||
raise ExtractorError(u'The webpage does not contain a video', expected=True) |
|||
return self.url_result(brightcove_url, BrightcoveIE.ie_key()) |
@ -0,0 +1,42 @@ |
|||
import json |
|||
import re |
|||
|
|||
from .common import InfoExtractor |
|||
|
|||
|
|||
class TvpIE(InfoExtractor): |
|||
IE_NAME = u'tvp.pl' |
|||
_VALID_URL = r'https?://www\.tvp\.pl/.*?wideo/(?P<date>\d+)/(?P<id>\d+)' |
|||
|
|||
_TEST = { |
|||
u'url': u'http://www.tvp.pl/warszawa/magazyny/campusnews/wideo/31102013/12878238', |
|||
u'md5': u'148408967a6a468953c0a75cbdaf0d7a', |
|||
u'file': u'12878238.wmv', |
|||
u'info_dict': { |
|||
u'title': u'31.10.2013 - Odcinek 2', |
|||
u'description': u'31.10.2013 - Odcinek 2', |
|||
}, |
|||
u'skip': u'Download has to use same server IP as extraction. Therefore, a good (load-balancing) DNS resolver will make the download fail.' |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
video_id = mobj.group('id') |
|||
webpage = self._download_webpage(url, video_id) |
|||
json_url = 'http://www.tvp.pl/pub/stat/videofileinfo?video_id=%s' % video_id |
|||
json_params = self._download_webpage( |
|||
json_url, video_id, u"Downloading video metadata") |
|||
|
|||
params = json.loads(json_params) |
|||
self.report_extraction(video_id) |
|||
video_url = params['video_url'] |
|||
|
|||
title = self._og_search_title(webpage, fatal=True) |
|||
return { |
|||
'id': video_id, |
|||
'title': title, |
|||
'ext': 'wmv', |
|||
'url': video_url, |
|||
'description': self._og_search_description(webpage), |
|||
'thumbnail': self._og_search_thumbnail(webpage), |
|||
} |
@ -0,0 +1,45 @@ |
|||
# encoding: utf-8 |
|||
import re |
|||
import json |
|||
|
|||
from .common import InfoExtractor |
|||
from ..utils import ( |
|||
compat_str, |
|||
unescapeHTML, |
|||
) |
|||
|
|||
|
|||
class VKIE(InfoExtractor): |
|||
IE_NAME = u'vk.com' |
|||
_VALID_URL = r'https?://vk\.com/(?:videos.*?\?.*?z=)?video(?P<id>.*?)(?:\?|%2F|$)' |
|||
|
|||
_TEST = { |
|||
u'url': u'http://vk.com/videos-77521?z=video-77521_162222515%2Fclub77521', |
|||
u'md5': u'0deae91935c54e00003c2a00646315f0', |
|||
u'info_dict': { |
|||
u'id': u'162222515', |
|||
u'ext': u'flv', |
|||
u'title': u'ProtivoGunz - Хуёвая песня', |
|||
u'uploader': u'Noize MC', |
|||
}, |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
video_id = mobj.group('id') |
|||
info_url = 'http://vk.com/al_video.php?act=show&al=1&video=%s' % video_id |
|||
info_page = self._download_webpage(info_url, video_id) |
|||
m_yt = re.search(r'src="(http://www.youtube.com/.*?)"', info_page) |
|||
if m_yt is not None: |
|||
self.to_screen(u'Youtube video detected') |
|||
return self.url_result(m_yt.group(1), 'Youtube') |
|||
vars_json = self._search_regex(r'var vars = ({.*?});', info_page, u'vars') |
|||
vars = json.loads(vars_json) |
|||
|
|||
return { |
|||
'id': compat_str(vars['vid']), |
|||
'url': vars['url240'], |
|||
'title': unescapeHTML(vars['md_title']), |
|||
'thumbnail': vars['jpg'], |
|||
'uploader': vars['md_author'], |
|||
} |
@ -0,0 +1,55 @@ |
|||
import os |
|||
import re |
|||
|
|||
from .common import InfoExtractor |
|||
from ..utils import ( |
|||
compat_urllib_parse_urlparse, |
|||
compat_urllib_request, |
|||
compat_urllib_parse, |
|||
) |
|||
|
|||
class XTubeIE(InfoExtractor): |
|||
_VALID_URL = r'^(?:https?://)?(?:www\.)?(?P<url>xtube\.com/watch\.php\?v=(?P<videoid>[^/?&]+))' |
|||
_TEST = { |
|||
u'url': u'http://www.xtube.com/watch.php?v=kVTUy_G222_', |
|||
u'file': u'kVTUy_G222_.mp4', |
|||
u'md5': u'092fbdd3cbe292c920ef6fc6a8a9cdab', |
|||
u'info_dict': { |
|||
u"title": u"strange erotica", |
|||
u"description": u"surreal gay themed erotica...almost an ET kind of thing", |
|||
u"uploader": u"greenshowers", |
|||
u"age_limit": 18, |
|||
} |
|||
} |
|||
|
|||
def _real_extract(self, url): |
|||
mobj = re.match(self._VALID_URL, url) |
|||
video_id = mobj.group('videoid') |
|||
url = 'http://www.' + mobj.group('url') |
|||
|
|||
req = compat_urllib_request.Request(url) |
|||
req.add_header('Cookie', 'age_verified=1') |
|||
webpage = self._download_webpage(req, video_id) |
|||
|
|||
video_title = self._html_search_regex(r'<div class="p_5px[^>]*>([^<]+)', webpage, u'title') |
|||
video_uploader = self._html_search_regex(r'so_s\.addVariable\("owner_u", "([^"]+)', webpage, u'uploader', fatal=False) |
|||
video_description = self._html_search_regex(r'<p class="video_description">([^<]+)', webpage, u'description', default=None) |
|||
video_url= self._html_search_regex(r'var videoMp4 = "([^"]+)', webpage, u'video_url').replace('\\/', '/') |
|||
path = compat_urllib_parse_urlparse(video_url).path |
|||
extension = os.path.splitext(path)[1][1:] |
|||
format = path.split('/')[5].split('_')[:2] |
|||
format[0] += 'p' |
|||
format[1] += 'k' |
|||
format = "-".join(format) |
|||
|
|||
return { |
|||
'id': video_id, |
|||
'title': video_title, |
|||
'uploader': video_uploader, |
|||
'description': video_description, |
|||
'url': video_url, |
|||
'ext': extension, |
|||
'format': format, |
|||
'format_id': format, |
|||
'age_limit': 18, |
|||
} |
@ -1,2 +1,2 @@ |
|||
|
|||
__version__ = '2013.10.28' |
|||
__version__ = '2013.11.17' |
xxxxxxxxxx