mirror of https://github.com/yt-dlp/yt-dlp
Merge branch 'master' into rtmpdump
Conflicts: youtube_dl/FileDownloader.py Mergepull/8/head
commit
2b35c9ef74
@ -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'
|
||||||
|
Loading…
Reference in New Issue