--version print program version and exit
-U, --update update this program to latest version
-i, --ignore-errors continue on download errors
- -r, --rate-limit LIMIT maximum download rate (e.g. 50k or 44.6m)
- -R, --retries RETRIES number of retries (default is 10)
- --buffer-size SIZE size of download buffer (e.g. 1024 or 16k)
- (default is 1024)
- --no-resize-buffer do not automatically adjust the buffer size. By
- default, the buffer size is automatically resized
- from an initial value of SIZE.
--dump-user-agent display the current browser identification
--user-agent UA specify a custom user agent
--referer REF specify a custom referer, use if the video access
is restricted to one domain
--list-extractors List all supported extractors and the URLs they
would handle
+ --extractor-descriptions Output descriptions of all supported extractors
--proxy URL Use the specified HTTP/HTTPS proxy
--no-check-certificate Suppress HTTPS certificate validation.
--datebefore DATE download only videos uploaded before this date
--dateafter DATE download only videos uploaded after this date
+## Download Options:
+ -r, --rate-limit LIMIT maximum download rate (e.g. 50k or 44.6m)
+ -R, --retries RETRIES number of retries (default is 10)
+ --buffer-size SIZE size of download buffer (e.g. 1024 or 16k)
+ (default is 1024)
+ --no-resize-buffer do not automatically adjust the buffer size. By
+ default, the buffer size is automatically resized
+ from an initial value of SIZE.
+
## Filesystem Options:
-t, --title use title in file name (default)
--id use only video ID in file name
- `playlist`: The name or the id of the playlist that contains the video.
- `playlist_index`: The index of the video in the playlist, a five-digit number.
-The current default template is `%(id)s.%(ext)s`, but that will be switchted to `%(title)s-%(id)s.%(ext)s` (which can be requested with `-t` at the moment).
+The current default template is `%(title)s-%(id)s.%(ext)s`.
In some cases, you don't want special characters such as 中, spaces, or &, such as when transferring the downloaded filename to a Windows system or the filename through an 8bit-unsafe channel. In these cases, add the `--restrict-filenames` flag to get a shorter title:
### Can you please put the -b option back?
-Most people asking this question are not aware that youtube-dl now defaults to downloading the highest available quality as reported by YouTube, which will be 1080p or 720p in some cases, so you no longer need the -b option. For some specific videos, maybe YouTube does not report them to be available in a specific high quality format you''re interested in. In that case, simply request it with the -f option and youtube-dl will try to download it.
+Most people asking this question are not aware that youtube-dl now defaults to downloading the highest available quality as reported by YouTube, which will be 1080p or 720p in some cases, so you no longer need the `-b` option. For some specific videos, maybe YouTube does not report them to be available in a specific high quality format you're interested in. In that case, simply request it with the `-f` option and youtube-dl will try to download it.
### I get HTTP error 402 when trying to download a video. What's this?
-Apparently YouTube requires you to pass a CAPTCHA test if you download too much. We''re [considering to provide a way to let you solve the CAPTCHA](https://github.com/rg3/youtube-dl/issues/154), but at the moment, your best course of action is pointing a webbrowser to the youtube URL, solving the CAPTCHA, and restart youtube-dl.
+Apparently YouTube requires you to pass a CAPTCHA test if you download too much. We're [considering to provide a way to let you solve the CAPTCHA](https://github.com/rg3/youtube-dl/issues/154), but at the moment, your best course of action is pointing a webbrowser to the youtube URL, solving the CAPTCHA, and restart youtube-dl.
### I have downloaded a video but how can I play it?
--version print program version and exit
-U, --update update this program to latest version
-i, --ignore-errors continue on download errors
- -r, --rate-limit LIMIT maximum download rate (e.g. 50k or 44.6m)
- -R, --retries RETRIES number of retries (default is 10)
- --buffer-size SIZE size of download buffer (e.g. 1024 or 16k)
- (default is 1024)
- --no-resize-buffer do not automatically adjust the buffer size. By
- default, the buffer size is automatically resized
- from an initial value of SIZE.
--dump-user-agent display the current browser identification
--user-agent UA specify a custom user agent
--referer REF specify a custom referer, use if the video access
is restricted to one domain
--list-extractors List all supported extractors and the URLs they
would handle
+ --extractor-descriptions Output descriptions of all supported extractors
--proxy URL Use the specified HTTP/HTTPS proxy
--no-check-certificate Suppress HTTPS certificate validation.
--datebefore DATE download only videos uploaded before this date
--dateafter DATE download only videos uploaded after this date
+Download Options:
+-----------------
+
+ -r, --rate-limit LIMIT maximum download rate (e.g. 50k or 44.6m)
+ -R, --retries RETRIES number of retries (default is 10)
+ --buffer-size SIZE size of download buffer (e.g. 1024 or 16k)
+ (default is 1024)
+ --no-resize-buffer do not automatically adjust the buffer size. By
+ default, the buffer size is automatically resized
+ from an initial value of SIZE.
+
Filesystem Options:
-------------------
- playlist_index: The index of the video in the playlist, a five-digit
number.
-The current default template is %(id)s.%(ext)s, but that will be
-switchted to %(title)s-%(id)s.%(ext)s (which can be requested with -t at
-the moment).
+The current default template is %(title)s-%(id)s.%(ext)s.
In some cases, you don't want special characters such as 中, spaces, or
&, such as when transferring the downloaded filename to a Windows system
defaults to downloading the highest available quality as reported by
YouTube, which will be 1080p or 720p in some cases, so you no longer
need the -b option. For some specific videos, maybe YouTube does not
-report them to be available in a specific high quality format you''re
+report them to be available in a specific high quality format you're
interested in. In that case, simply request it with the -f option and
youtube-dl will try to download it.
I get HTTP error 402 when trying to download a video. What's this?
Apparently YouTube requires you to pass a CAPTCHA test if you download
-too much. We''re considering to provide a way to let you solve the
+too much. We're considering to provide a way to let you solve the
CAPTCHA, but at the moment, your best course of action is pointing a
webbrowser to the youtube URL, solving the CAPTCHA, and restart
youtube-dl.
import sys
tests = [
+ # 88
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[]}|:;?/>.<",
"J:|}][{=+-_)(*&;%$#@>MNBVCXZASDFGH^KLPOIUYTREWQ0987654321mnbvcxzasdfghrklpoiuytej"),
+ # 87
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<",
"!?;:|}][{=+-_)(*&^$#@/MNBVCXZASqFGHJKLPOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytr"),
+ # 86 - vfl_ymO4Z 2013/06/27
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<",
"ertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!/#$%^&*()_-+={[|};?@"),
+ # 85
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<",
"{>/?;}[.=+-_)(*&^%$#@!MqBVCXZASDFwHJKLPOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytr"),
+ # 84
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<",
"<.>?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWe098765432rmnbvcxzasdfghjklpoiuyt1"),
+ # 83
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!#$%^&*()_+={[};?/>.<",
"D.>/?;}[{=+_)(*&^%$#!MNBVCXeAS<FGHJKLPOIUYTREWZ0987654321mnbvcxzasdfghjklpoiuytrQ"),
+ # 82
("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKHGFDSAZXCVBNM!@#$%^&*(-+={[};?/>.<",
"Q>/?;}[{=+-(*<^%$#@!MNBVCXZASDFGHKLPOIUY8REWT0q&7654321mnbvcxzasdfghjklpoiuytrew9"),
]
from distutils.core import setup
try:
+ # This will create an exe that needs Microsoft Visual C++ 2008
+ # Redistributable Package
import py2exe
- """This will create an exe that needs Microsoft Visual C++ 2008 Redistributable Package"""
except ImportError:
if len(sys.argv) >= 2 and sys.argv[1] == 'py2exe':
print("Cannot import py2exe", file=sys.stderr)
"dist_dir": '.',
"dll_excludes": ['w9xpopen.exe'],
}
+
py2exe_console = [{
"script": "./youtube_dl/__main__.py",
"dest_base": "youtube-dl",
}]
+
py2exe_params = {
'console': py2exe_console,
- 'options': { "py2exe": py2exe_options },
+ 'options': {"py2exe": py2exe_options},
'zipfile': None
}
else:
params = {
'scripts': ['bin/youtube-dl'],
- 'data_files': [('etc/bash_completion.d', ['youtube-dl.bash-completion']), # Installing system-wide would require sudo...
- ('share/doc/youtube_dl', ['README.txt']),
- ('share/man/man1/', ['youtube-dl.1'])]
+ 'data_files': [ # Installing system-wide would require sudo...
+ ('etc/bash_completion.d', ['youtube-dl.bash-completion']),
+ ('share/doc/youtube_dl', ['README.txt']),
+ ('share/man/man1/', ['youtube-dl.1'])
+ ]
}
# Get the version from youtube_dl/version.py without importing the package
-exec(compile(open('youtube_dl/version.py').read(), 'youtube_dl/version.py', 'exec'))
+exec(compile(open('youtube_dl/version.py').read(),
+ 'youtube_dl/version.py', 'exec'))
setup(
- name = 'youtube_dl',
- version = __version__,
- description = 'YouTube video downloader',
- long_description = 'Small command-line program to download videos from YouTube.com and other video sites.',
- url = 'https://github.com/rg3/youtube-dl',
- author = 'Ricardo Garcia',
- maintainer = 'Philipp Hagemeister',
- maintainer_email = 'phihag@phihag.de',
- packages = ['youtube_dl', 'youtube_dl.extractor'],
+ name='youtube_dl',
+ version=__version__,
+ description='YouTube video downloader',
+ long_description='Small command-line program to download videos from'
+ ' YouTube.com and other video sites.',
+ url='https://github.com/rg3/youtube-dl',
+ author='Ricardo Garcia',
+ maintainer='Philipp Hagemeister',
+ maintainer_email='phihag@phihag.de',
+ packages=['youtube_dl', 'youtube_dl.extractor'],
# Provokes warning on most systems (why?!)
- #test_suite = 'nose.collector',
- #test_requires = ['nosetest'],
+ # test_suite = 'nose.collector',
+ # test_requires = ['nosetest'],
- classifiers = [
+ classifiers=[
"Topic :: Multimedia :: Video",
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
import json
import os.path
+import youtube_dl.extractor
from youtube_dl import YoutubeDL, YoutubeDLHandler
from youtube_dl.utils import (
compat_cookiejar,
def trouble(self, s, tb=None):
raise Exception(s)
def download(self, x):
- self.result.append(x)
\ No newline at end of file
+ self.result.append(x)
+
+def get_testcases():
+ for ie in youtube_dl.extractor.gen_extractors():
+ t = getattr(ie, '_TEST', None)
+ if t:
+ t['name'] = type(ie).__name__[:-len('IE')]
+ yield t
+ for t in getattr(ie, '_TESTS', []):
+ t['name'] = type(ie).__name__[:-len('IE')]
+ yield t
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from youtube_dl.extractor import YoutubeIE, YoutubePlaylistIE, YoutubeChannelIE, JustinTVIE
+from youtube_dl.extractor import YoutubeIE, YoutubePlaylistIE, YoutubeChannelIE, JustinTVIE, gen_extractors
+from helper import get_testcases
class TestAllURLsMatching(unittest.TestCase):
def test_youtube_playlist_matching(self):
self.assertEqual(YoutubeIE()._extract_id('https://www.youtube.com/watch?&v=BaW_jenozKc'), 'BaW_jenozKc')
self.assertEqual(YoutubeIE()._extract_id('https://www.youtube.com/watch?feature=player_embedded&v=BaW_jenozKc'), 'BaW_jenozKc')
+ def test_no_duplicates(self):
+ ies = gen_extractors()
+ for tc in get_testcases():
+ url = tc['url']
+ for ie in ies:
+ if type(ie).__name__ in ['GenericIE', tc['name'] + 'IE']:
+ self.assertTrue(ie.suitable(url), '%s should match URL %r' % (type(ie).__name__, url))
+ else:
+ self.assertFalse(ie.suitable(url), '%s should not match URL %r' % (type(ie).__name__, url))
+
+
if __name__ == '__main__':
unittest.main()
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import youtube_dl.YoutubeDL
-import youtube_dl.extractor
from youtube_dl.utils import *
-DEF_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tests.json')
PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "parameters.json")
RETRIES = 3
with open(fn, 'rb') as f:
return hashlib.md5(f.read()).hexdigest()
-with io.open(DEF_FILE, encoding='utf-8') as deff:
- defs = json.load(deff)
+from helper import get_testcases
+defs = get_testcases()
+
with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
parameters = json.load(pf)
def test_template(self):
ie = youtube_dl.extractor.get_info_extractor(test_case['name'])
+ def print_skipping(reason):
+ print('Skipping %s: %s' % (test_case['name'], reason))
if not ie._WORKING:
- print('Skipping: IE marked as not _WORKING')
+ print_skipping('IE marked as not _WORKING')
return
if 'playlist' not in test_case and not test_case['file']:
- print('Skipping: No output file specified')
+ print_skipping('No output file specified')
return
if 'skip' in test_case:
- print('Skipping: {0}'.format(test_case['skip']))
+ print_skipping(test_case['skip'])
return
params = self.parameters.copy()
params.update(test_case.get('params', {}))
ydl = YoutubeDL(params)
- for ie in youtube_dl.extractor.gen_extractors():
- ydl.add_info_extractor(ie)
+ ydl.add_default_info_extractors()
finished_hook_called = set()
def _hook(status):
if status['status'] == 'finished':
### And add them to TestDownload
for n, test_case in enumerate(defs):
test_method = generator(test_case)
- test_method.__name__ = "test_{0}".format(test_case["name"])
- if getattr(TestDownload, test_method.__name__, False):
- test_method.__name__ = "test_{0}_{1}".format(test_case["name"], n)
+ tname = 'test_' + str(test_case['name'])
+ i = 1
+ while hasattr(TestDownload, tname):
+ tname = 'test_' + str(test_case['name']) + '_' + str(i)
+ i += 1
+ test_method.__name__ = tname
setattr(TestDownload, test_method.__name__, test_method)
del test_method
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from youtube_dl.extractor import YoutubeUserIE, YoutubePlaylistIE, YoutubeIE, YoutubeChannelIE
+from youtube_dl.extractor import YoutubeUserIE, YoutubePlaylistIE, YoutubeIE, YoutubeChannelIE, YoutubeShowIE
from youtube_dl.utils import *
from helper import FakeYDL
result = ie.extract('PLtPgu7CB4gbY9oDN3drwC3cMbJggS7dKl')[0]
self.assertEqual(len(result['entries']), 2)
+ def test_youtube_show(self):
+ dl = FakeYDL()
+ ie = YoutubeShowIE(dl)
+ result = ie.extract('http://www.youtube.com/show/airdisasters')
+ self.assertTrue(len(result) >= 4)
+
if __name__ == '__main__':
unittest.main()
+++ /dev/null
-[
- {
- "name": "Youtube",
- "url": "http://www.youtube.com/watch?v=BaW_jenozKc",
- "file": "BaW_jenozKc.mp4",
- "info_dict": {
- "title": "youtube-dl test video \"'/\\ä↭𝕐",
- "uploader": "Philipp Hagemeister",
- "uploader_id": "phihag",
- "upload_date": "20121002",
- "description": "test chars: \"'/\\ä↭𝕐\n\nThis is a test video for youtube-dl.\n\nFor more information, contact phihag@phihag.de ."
- }
- },
- {
- "name": "Youtube",
- "url": "http://www.youtube.com/watch?v=1ltcDfZMA3U",
- "file": "1ltcDfZMA3U.flv",
- "note": "Test VEVO video (#897)",
- "info_dict": {
- "upload_date": "20070518",
- "title": "Maps - It Will Find You",
- "description": "Music video by Maps performing It Will Find You.",
- "uploader": "MuteUSA",
- "uploader_id": "MuteUSA"
- }
- },
- {
- "name": "Youtube",
- "url": "http://www.youtube.com/watch?v=UxxajLWwzqY",
- "file": "UxxajLWwzqY.mp4",
- "note": "Test generic use_cipher_signature video (#897)",
- "info_dict": {
- "upload_date": "20120506",
- "title": "Icona Pop - I Love It (feat. Charli XCX) [OFFICIAL VIDEO]",
- "description": "md5:b085c9804f5ab69f4adea963a2dceb3c",
- "uploader": "IconaPop",
- "uploader_id": "IconaPop"
- }
- },
- {
- "name": "Dailymotion",
- "md5": "392c4b85a60a90dc4792da41ce3144eb",
- "url": "http://www.dailymotion.com/video/x33vw9_tutoriel-de-youtubeur-dl-des-video_tech",
- "file": "x33vw9.mp4",
- "info_dict": {
- "uploader": "Alex and Van .",
- "title": "Tutoriel de Youtubeur\"DL DES VIDEO DE YOUTUBE\""
- }
- },
- {
- "name": "Metacafe",
- "add_ie": ["Youtube"],
- "url": "http://metacafe.com/watch/yt-_aUehQsCQtM/the_electric_company_short_i_pbs_kids_go/",
- "file": "_aUehQsCQtM.flv",
- "info_dict": {
- "upload_date": "20090102",
- "title": "The Electric Company | \"Short I\" | PBS KIDS GO!",
- "description": "md5:2439a8ef6d5a70e380c22f5ad323e5a8",
- "uploader": "PBS",
- "uploader_id": "PBS"
- }
- },
- {
- "name": "BlipTV",
- "md5": "b2d849efcf7ee18917e4b4d9ff37cafe",
- "url": "http://blip.tv/cbr/cbr-exclusive-gotham-city-imposters-bats-vs-jokerz-short-3-5796352",
- "file": "5779306.m4v",
- "info_dict": {
- "upload_date": "20111205",
- "description": "md5:9bc31f227219cde65e47eeec8d2dc596",
- "uploader": "Comic Book Resources - CBR TV",
- "title": "CBR EXCLUSIVE: \"Gotham City Imposters\" Bats VS Jokerz Short 3"
- }
- },
- {
- "name": "XVideos",
- "md5": "1d0c835822f0a71a7bf011855db929d0",
- "url": "http://www.xvideos.com/video939581/funny_porns_by_s_-1",
- "file": "939581.flv",
- "info_dict": {
- "title": "Funny Porns By >>>>S<<<<<< -1"
- }
- },
- {
- "name": "YouPorn",
- "md5": "c37ddbaaa39058c76a7e86c6813423c1",
- "url": "http://www.youporn.com/watch/505835/sex-ed-is-it-safe-to-masturbate-daily/",
- "file": "505835.mp4",
- "info_dict": {
- "upload_date": "20101221",
- "description": "Love & Sex Answers: http://bit.ly/DanAndJenn -- Is It Unhealthy To Masturbate Daily?",
- "uploader": "Ask Dan And Jennifer",
- "title": "Sex Ed: Is It Safe To Masturbate Daily?"
- }
- },
- {
- "name": "Pornotube",
- "md5": "374dd6dcedd24234453b295209aa69b6",
- "url": "http://pornotube.com/c/173/m/1689755/Marilyn-Monroe-Bathing",
- "file": "1689755.flv",
- "info_dict": {
- "upload_date": "20090708",
- "title": "Marilyn-Monroe-Bathing"
- }
- },
- {
- "name": "YouJizz",
- "md5": "07e15fa469ba384c7693fd246905547c",
- "url": "http://www.youjizz.com/videos/zeichentrick-1-2189178.html",
- "file": "2189178.flv",
- "info_dict": {
- "title": "Zeichentrick 1"
- }
- },
- {
- "name": "Vimeo",
- "md5": "8879b6cc097e987f02484baf890129e5",
- "url": "http://vimeo.com/56015672",
- "file": "56015672.mp4",
- "info_dict": {
- "title": "youtube-dl test video - ★ \" ' 幸 / \\ ä ↭ 𝕐",
- "uploader": "Filippo Valsorda",
- "uploader_id": "user7108434",
- "upload_date": "20121220",
- "description": "This is a test case for youtube-dl.\nFor more information, see github.com/rg3/youtube-dl\nTest chars: ★ \" ' 幸 / \\ ä ↭ 𝕐"
- }
- },
- {
- "name": "Soundcloud",
- "md5": "ebef0a451b909710ed1d7787dddbf0d7",
- "url": "http://soundcloud.com/ethmusic/lostin-powers-she-so-heavy",
- "file": "62986583.mp3",
- "info_dict": {
- "upload_date": "20121011",
- "description": "No Downloads untill we record the finished version this weekend, i was too pumped n i had to post it , earl is prolly gonna b hella p.o'd",
- "uploader": "E.T. ExTerrestrial Music",
- "title": "Lostin Powers - She so Heavy (SneakPreview) Adrian Ackers Blueprint 1"
- }
- },
- {
- "name": "StanfordOpenClassroom",
- "md5": "544a9468546059d4e80d76265b0443b8",
- "url": "http://openclassroom.stanford.edu/MainFolder/VideoPage.php?course=PracticalUnix&video=intro-environment&speed=100",
- "file": "PracticalUnix_intro-environment.mp4",
- "info_dict": {
- "title": "Intro Environment"
- }
- },
- {
- "name": "XNXX",
- "md5": "0831677e2b4761795f68d417e0b7b445",
- "url": "http://video.xnxx.com/video1135332/lida_naked_funny_actress_5_",
- "file": "1135332.flv",
- "info_dict": {
- "title": "lida » Naked Funny Actress (5)"
- }
- },
- {
- "name": "Youku",
- "url": "http://v.youku.com/v_show/id_XNDgyMDQ2NTQw.html",
- "file": "XNDgyMDQ2NTQw_part00.flv",
- "md5": "ffe3f2e435663dc2d1eea34faeff5b5b",
- "params": { "test": false },
- "info_dict": {
- "title": "youtube-dl test video \"'/\\ä↭𝕐"
- }
- },
- {
- "name": "NBA",
- "url": "http://www.nba.com/video/games/nets/2012/12/04/0021200253-okc-bkn-recap.nba/index.html",
- "file": "0021200253-okc-bkn-recap.nba.mp4",
- "md5": "c0edcfc37607344e2ff8f13c378c88a4",
- "info_dict": {
- "description": "Kevin Durant scores 32 points and dishes out six assists as the Thunder beat the Nets in Brooklyn.",
- "title": "Thunder vs. Nets"
- }
- },
- {
- "name": "JustinTV",
- "url": "http://www.twitch.tv/thegamedevhub/b/296128360",
- "file": "296128360.flv",
- "md5": "ecaa8a790c22a40770901460af191c9a",
- "info_dict": {
- "upload_date": "20110927",
- "uploader_id": 25114803,
- "uploader": "thegamedevhub",
- "title": "Beginner Series - Scripting With Python Pt.1"
- }
- },
- {
- "name": "MyVideo",
- "url": "http://www.myvideo.de/watch/8229274/bowling_fail_or_win",
- "file": "8229274.flv",
- "md5": "2d2753e8130479ba2cb7e0a37002053e",
- "info_dict": {
- "title": "bowling-fail-or-win"
- }
- },
- {
- "name": "Escapist",
- "url": "http://www.escapistmagazine.com/videos/view/the-escapist-presents/6618-Breaking-Down-Baldurs-Gate",
- "file": "6618-Breaking-Down-Baldurs-Gate.mp4",
- "md5": "c6793dbda81388f4264c1ba18684a74d",
- "info_dict": {
- "description": "Baldur's Gate: Original, Modded or Enhanced Edition? I'll break down what you can expect from the new Baldur's Gate: Enhanced Edition.",
- "uploader": "the-escapist-presents",
- "title": "Breaking Down Baldur's Gate"
- }
- },
- {
- "name": "GooglePlus",
- "url": "https://plus.google.com/u/0/108897254135232129896/posts/ZButuJc6CtH",
- "file": "ZButuJc6CtH.flv",
- "info_dict": {
- "upload_date": "20120613",
- "uploader": "井上ヨシマサ",
- "title": "嘆きの天使 降臨"
- }
- },
- {
- "name": "FunnyOrDie",
- "url": "http://www.funnyordie.com/videos/0732f586d7/heart-shaped-box-literal-video-version",
- "file": "0732f586d7.mp4",
- "md5": "f647e9e90064b53b6e046e75d0241fbd",
- "info_dict": {
- "description": "Lyrics changed to match the video. Spoken cameo by Obscurus Lupa (from ThatGuyWithTheGlasses.com). Based on a concept by Dustin McLean (DustFilms.com). Performed, edited, and written by David A. Scott.",
- "title": "Heart-Shaped Box: Literal Video Version"
- }
- },
- {
- "name": "Steam",
- "url": "http://store.steampowered.com/video/105600/",
- "playlist": [
- {
- "file": "81300.flv",
- "md5": "f870007cee7065d7c76b88f0a45ecc07",
- "info_dict": {
- "title": "Terraria 1.1 Trailer"
- }
- },
- {
- "file": "80859.flv",
- "md5": "61aaf31a5c5c3041afb58fb83cbb5751",
- "info_dict": {
- "title": "Terraria Trailer"
- }
- }
- ]
- },
- {
- "name": "Ustream",
- "url": "http://www.ustream.tv/recorded/20274954",
- "file": "20274954.flv",
- "md5": "088f151799e8f572f84eb62f17d73e5c",
- "info_dict": {
- "title": "Young Americans for Liberty February 7, 2012 2:28 AM",
- "uploader": "Young Americans for Liberty"
- }
- },
- {
- "name": "InfoQ",
- "url": "http://www.infoq.com/presentations/A-Few-of-My-Favorite-Python-Things",
- "file": "12-jan-pythonthings.mp4",
- "info_dict": {
- "description": "Mike Pirnat presents some tips and tricks, standard libraries and third party packages that make programming in Python a richer experience.",
- "title": "A Few of My Favorite [Python] Things"
- },
- "params": {
- "skip_download": true
- }
- },
- {
- "name": "ComedyCentral",
- "url": "http://www.thedailyshow.com/watch/thu-december-13-2012/kristen-stewart",
- "file": "422212.mp4",
- "md5": "4e2f5cb088a83cd8cdb7756132f9739d",
- "info_dict": {
- "upload_date": "20121214",
- "description": "Kristen Stewart",
- "uploader": "thedailyshow",
- "title": "thedailyshow-kristen-stewart part 1"
- }
- },
- {
- "name": "RBMARadio",
- "url": "http://www.rbmaradio.com/shows/ford-lopatin-live-at-primavera-sound-2011",
- "file": "ford-lopatin-live-at-primavera-sound-2011.mp3",
- "md5": "6bc6f9bcb18994b4c983bc3bf4384d95",
- "info_dict": {
- "title": "Live at Primavera Sound 2011",
- "description": "Joel Ford and Daniel \u2019Oneohtrix Point Never\u2019 Lopatin fly their midified pop extravaganza to Spain. Live at Primavera Sound 2011.",
- "uploader": "Ford & Lopatin",
- "uploader_id": "ford-lopatin",
- "location": "Spain"
- }
- },
- {
- "name": "Facebook",
- "url": "https://www.facebook.com/photo.php?v=120708114770723",
- "file": "120708114770723.mp4",
- "md5": "48975a41ccc4b7a581abd68651c1a5a8",
- "info_dict": {
- "title": "PEOPLE ARE AWESOME 2013",
- "duration": 279
- }
- },
- {
- "name": "EightTracks",
- "url": "http://8tracks.com/ytdl/youtube-dl-test-tracks-a",
- "playlist": [
- {
- "file": "11885610.m4a",
- "md5": "96ce57f24389fc8734ce47f4c1abcc55",
- "info_dict": {
- "title": "youtue-dl project<>\"' - youtube-dl test track 1 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
- }
- },
- {
- "file": "11885608.m4a",
- "md5": "4ab26f05c1f7291ea460a3920be8021f",
- "info_dict": {
- "title": "youtube-dl project - youtube-dl test track 2 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
-
- }
- },
- {
- "file": "11885679.m4a",
- "md5": "d30b5b5f74217410f4689605c35d1fd7",
- "info_dict": {
- "title": "youtube-dl project as well - youtube-dl test track 3 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
- }
- },
- {
- "file": "11885680.m4a",
- "md5": "4eb0a669317cd725f6bbd336a29f923a",
- "info_dict": {
- "title": "youtube-dl project as well - youtube-dl test track 4 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
- }
- },
- {
- "file": "11885682.m4a",
- "md5": "1893e872e263a2705558d1d319ad19e8",
- "info_dict": {
- "title": "PH - youtube-dl test track 5 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
- }
- },
- {
- "file": "11885683.m4a",
- "md5": "b673c46f47a216ab1741ae8836af5899",
- "info_dict": {
- "title": "PH - youtube-dl test track 6 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
- }
- },
- {
- "file": "11885684.m4a",
- "md5": "1d74534e95df54986da7f5abf7d842b7",
- "info_dict": {
- "title": "phihag - youtube-dl test track 7 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
- }
- },
- {
- "file": "11885685.m4a",
- "md5": "f081f47af8f6ae782ed131d38b9cd1c0",
- "info_dict": {
- "title": "phihag - youtube-dl test track 8 \"'/\\\u00e4\u21ad",
- "uploader_id": "ytdl"
- }
- }
- ]
- },
- {
- "name": "Keek",
- "url": "http://www.keek.com/ytdl/keeks/NODfbab",
- "file": "NODfbab.mp4",
- "md5": "9b0636f8c0f7614afa4ea5e4c6e57e83",
- "info_dict": {
- "uploader": "ytdl",
- "title": "test chars: \"'/\\ä<>This is a test video for youtube-dl.For more information, contact phihag@phihag.de ."
- }
- },
- {
- "name": "TED",
- "url": "http://www.ted.com/talks/dan_dennett_on_our_consciousness.html",
- "file": "102.mp4",
- "md5": "8cd9dfa41ee000ce658fd48fb5d89a61",
- "info_dict": {
- "title": "Dan Dennett: The illusion of consciousness",
- "description": "md5:c6fa72e6eedbd938c9caf6b2702f5922"
- }
- },
- {
- "name": "MySpass",
- "url": "http://www.myspass.de/myspass/shows/tvshows/absolute-mehrheit/Absolute-Mehrheit-vom-17022013-Die-Highlights-Teil-2--/11741/",
- "file": "11741.mp4",
- "md5": "0b49f4844a068f8b33f4b7c88405862b",
- "info_dict": {
- "description": "Wer kann in die Fußstapfen von Wolfgang Kubicki treten und die Mehrheit der Zuschauer hinter sich versammeln? Wird vielleicht sogar die Absolute Mehrheit geknackt und der Jackpot von 200.000 Euro mit nach Hause genommen?",
- "title": "Absolute Mehrheit vom 17.02.2013 - Die Highlights, Teil 2"
- }
- },
- {
- "name": "Generic",
- "url": "http://www.hodiho.fr/2013/02/regis-plante-sa-jeep.html",
- "file": "13601338388002.mp4",
- "md5": "85b90ccc9d73b4acd9138d3af4c27f89",
- "info_dict": {
- "uploader": "www.hodiho.fr",
- "title": "Régis plante sa Jeep"
- }
- },
- {
- "name": "Spiegel",
- "url": "http://www.spiegel.de/video/vulkan-tungurahua-in-ecuador-ist-wieder-aktiv-video-1259285.html",
- "file": "1259285.mp4",
- "md5": "2c2754212136f35fb4b19767d242f66e",
- "info_dict": {
- "title": "Vulkanausbruch in Ecuador: Der \"Feuerschlund\" ist wieder aktiv"
- }
- },
- {
- "name": "LiveLeak",
- "md5": "0813c2430bea7a46bf13acf3406992f4",
- "url": "http://www.liveleak.com/view?i=757_1364311680",
- "file": "757_1364311680.mp4",
- "info_dict": {
- "title": "Most unlucky car accident",
- "description": "extremely bad day for this guy..!",
- "uploader": "ljfriel2"
- }
- },
- {
- "name": "WorldStarHipHop",
- "url": "http://www.worldstarhiphop.com/videos/video.php?v=wshh6a7q1ny0G34ZwuIO",
- "file": "wshh6a7q1ny0G34ZwuIO.mp4",
- "md5": "9d04de741161603bf7071bbf4e883186",
- "info_dict": {
- "title": "Video: KO Of The Week: MMA Fighter Gets Knocked Out By Swift Head Kick!"
- }
- },
- {
- "name": "ARD",
- "url": "http://www.ardmediathek.de/das-erste/tagesschau-in-100-sek?documentId=14077640",
- "file": "14077640.mp4",
- "md5": "6ca8824255460c787376353f9e20bbd8",
- "info_dict": {
- "title": "11.04.2013 09:23 Uhr - Tagesschau in 100 Sekunden"
- },
- "skip": "Requires rtmpdump"
- },
- {
- "name": "Tumblr",
- "url": "http://resigno.tumblr.com/post/53364321212/e-de-extrema-importancia-que-esse-video-seja",
- "file": "53364321212.mp4",
- "md5": "0716d3dd51baf68a28b40fdf1251494e",
- "info_dict": {
- "title": "Rafael Lemos | Tumblr"
- }
- },
- {
- "name": "SoundcloudSet",
- "url":"https://soundcloud.com/the-concept-band/sets/the-royal-concept-ep",
- "playlist":[
- {
- "file":"30510138.mp3",
- "md5":"f9136bf103901728f29e419d2c70f55d",
- "info_dict": {
- "upload_date": "20111213",
- "description": "The Royal Concept from Stockholm\r\nFilip / Povel / David / Magnus\r\nwww.royalconceptband.com",
- "uploader": "The Royal Concept",
- "title": "D-D-Dance"
- }
- },
- {
- "file":"47127625.mp3",
- "md5":"09b6758a018470570f8fd423c9453dd8",
- "info_dict": {
- "upload_date": "20120521",
- "description": "The Royal Concept from Stockholm\r\nFilip / Povel / David / Magnus\r\nwww.royalconceptband.com",
- "uploader": "The Royal Concept",
- "title": "The Royal Concept - Gimme Twice"
- }
- },
- {
- "file":"47127627.mp3",
- "md5":"154abd4e418cea19c3b901f1e1306d9c",
- "info_dict": {
- "upload_date": "20120521",
- "uploader": "The Royal Concept",
- "title": "Goldrushed"
- }
- },
- {
- "file":"47127629.mp3",
- "md5":"2f5471edc79ad3f33a683153e96a79c1",
- "info_dict": {
- "upload_date": "20120521",
- "description": "The Royal Concept from Stockholm\r\nFilip / Povel / David / Magnus\r\nwww.royalconceptband.com",
- "uploader": "The Royal Concept",
- "title": "In the End"
- }
- },
- {
- "file":"47127631.mp3",
- "md5":"f9ba87aa940af7213f98949254f1c6e2",
- "info_dict": {
- "upload_date": "20120521",
- "description": "The Royal Concept from Stockholm\r\nFilip / David / Povel / Magnus\r\nwww.theroyalconceptband.com",
- "uploader": "The Royal Concept",
- "title": "Knocked Up"
- }
- },
- {
- "file":"75206121.mp3",
- "md5":"f9d1fe9406717e302980c30de4af9353",
- "info_dict": {
- "upload_date": "20130116",
- "description": "The unreleased track World on Fire premiered on the CW's hit show Arrow (8pm/7pm central). \r\nAs a gift to our fans we would like to offer you a free download of the track! ",
- "uploader": "The Royal Concept",
- "title": "World On Fire"
- }
- }
- ]
- },
- {
- "name":"Bandcamp",
- "url":"http://youtube-dl.bandcamp.com/track/youtube-dl-test-song",
- "file":"1812978515.mp3",
- "md5":"cdeb30cdae1921719a3cbcab696ef53c",
- "info_dict": {
- "title":"youtube-dl test song \"'/\\ä↭"
- },
- "skip": "There is a limit of 200 free downloads / month for the test song"
- },
- {
- "name": "RedTube",
- "url": "http://www.redtube.com/66418",
- "file": "66418.mp4",
- "md5": "7b8c22b5e7098a3e1c09709df1126d2d",
- "info_dict":{
- "title":"Sucked on a toilet"
- }
- },
- {
- "name": "Photobucket",
- "url": "http://media.photobucket.com/user/rachaneronas/media/TiredofLinkBuildingTryBacklinkMyDomaincom_zpsc0c3b9fa.mp4.html?filters[term]=search&filters[primary]=videos&filters[secondary]=images&sort=1&o=0",
- "file": "zpsc0c3b9fa.mp4",
- "md5": "7dabfb92b0a31f6c16cebc0f8e60ff99",
- "info_dict": {
- "upload_date": "20130504",
- "uploader": "rachaneronas",
- "title": "Tired of Link Building? Try BacklinkMyDomain.com!"
- }
- },
- {
- "name": "Ina",
- "url": "www.ina.fr/video/I12055569/francois-hollande-je-crois-que-c-est-clair-video.html",
- "file": "I12055569.mp4",
- "md5": "a667021bf2b41f8dc6049479d9bb38a3",
- "info_dict":{
- "title":"François Hollande \"Je crois que c'est clair\""
- }
- },
- {
- "name": "Yahoo",
- "url": "http://screen.yahoo.com/julian-smith-travis-legg-watch-214727115.html",
- "file": "214727115.flv",
- "md5": "2e717f169c1be93d84d3794a00d4a325",
- "info_dict": {
- "title": "Julian Smith & Travis Legg Watch Julian Smith"
- },
- "skip": "Requires rtmpdump"
- },
- {
- "name": "Howcast",
- "url": "http://www.howcast.com/videos/390161-How-to-Tie-a-Square-Knot-Properly",
- "file": "390161.mp4",
- "md5": "1d7ba54e2c9d7dc6935ef39e00529138",
- "info_dict":{
- "title":"How to Tie a Square Knot Properly",
- "description":"The square knot, also known as the reef knot, is one of the oldest, most basic knots to tie, and can be used in many different ways. Here's the proper way to tie a square knot."
- }
- },
- {
- "name": "Vine",
- "url": "https://vine.co/v/b9KOOWX7HUx",
- "file": "b9KOOWX7HUx.mp4",
- "md5": "2f36fed6235b16da96ce9b4dc890940d",
- "info_dict":{
- "title": "Chicken.",
- "uploader": "Jack Dorsey"
- }
- },
- {
- "name": "Flickr",
- "url": "http://www.flickr.com/photos/forestwander-nature-pictures/5645318632/in/photostream/",
- "file": "5645318632.mp4",
- "md5": "6fdc01adbc89d72fc9c4f15b4a4ba87b",
- "info_dict":{
- "title": "Dark Hollow Waterfalls",
- "uploader_id": "forestwander-nature-pictures",
- "description": "Waterfalls in the Springtime at Dark Hollow Waterfalls. These are located just off of Skyline Drive in Virginia. They are only about 6/10 of a mile hike but it is a pretty steep hill and a good climb back up."
- }
- },
- {
- "name": "Teamcoco",
- "url": "http://teamcoco.com/video/louis-ck-interview-george-w-bush",
- "file": "19705.mp4",
- "md5": "27b6f7527da5acf534b15f21b032656e",
- "info_dict":{
- "title": "Louis C.K. Interview Pt. 1 11/3/11",
- "description": "Louis C.K. got starstruck by George W. Bush, so what? Part one."
- }
- },
- {
- "name": "XHamster",
- "url": "http://xhamster.com/movies/1509445/femaleagent_shy_beauty_takes_the_bait.html",
- "file": "1509445.flv",
- "md5": "9f48e0e8d58e3076bb236ff412ab62fa",
- "info_dict": {
- "upload_date": "20121014",
- "uploader_id": "Ruseful2011",
- "title": "FemaleAgent Shy beauty takes the bait"
- }
- },
- {
- "name": "Hypem",
- "url": "http://hypem.com/track/1v6ga/BODYWORK+-+TAME",
- "file": "1v6ga.mp3",
- "md5": "b9cc91b5af8995e9f0c1cee04c575828",
- "info_dict":{
- "title":"Tame"
- }
- },
- {
- "name": "Vbox7",
- "url": "http://vbox7.com/play:249bb972c2",
- "file": "249bb972c2.flv",
- "md5": "9c70d6d956f888bdc08c124acc120cfe",
- "info_dict":{
- "title":"Смях! Чудо - чист за секунди - Скрита камера"
- }
- },
- {
- "name": "Gametrailers",
- "url": "http://www.gametrailers.com/videos/zbvr8i/mirror-s-edge-2-e3-2013--debut-trailer",
- "file": "zbvr8i.flv",
- "md5": "c3edbc995ab4081976e16779bd96a878",
- "info_dict": {
- "title": "E3 2013: Debut Trailer"
- },
- "skip": "Requires rtmpdump"
- },
- {
- "name": "Statigram",
- "url": "http://statigr.am/p/484091715184808010_284179915",
- "file": "484091715184808010_284179915.mp4",
- "md5": "deda4ff333abe2e118740321e992605b",
- "info_dict": {
- "uploader_id": "videoseconds",
- "title": "Instagram photo by @videoseconds (Videos)"
- }
- },
- {
- "name": "Break",
- "url": "http://www.break.com/video/when-girls-act-like-guys-2468056",
- "file": "2468056.mp4",
- "md5": "a3513fb1547fba4fb6cfac1bffc6c46b",
- "info_dict": {
- "title": "When Girls Act Like D-Bags"
- }
- },
- {
- "name": "Vevo",
- "url": "http://www.vevo.com/watch/hurts/somebody-to-die-for/GB1101300280",
- "file": "GB1101300280.mp4",
- "md5": "06bea460acb744eab74a9d7dcb4bfd61",
- "info_dict": {
- "title": "Somebody To Die For",
- "upload_date": "20130624",
- "uploader": "Hurts"
- }
- },
- {
- "name": "Tudou",
- "url": "http://www.tudou.com/listplay/zzdE77v6Mmo/2xN2duXMxmw.html",
- "file": "159447792.f4v",
- "md5": "ad7c358a01541e926a1e413612c6b10a",
- "info_dict": {
- "title": "卡马乔国足开大脚长传冲吊集锦"
- }
- },
- {
- "name": "CSpan",
- "url": "http://www.c-spanvideo.org/program/HolderonV",
- "file": "315139.flv",
- "md5": "74a623266956f69e4df0068ab6c80fe4",
- "info_dict": {
- "title": "Attorney General Eric Holder on Voting Rights Act Decision"
- },
- "skip": "Requires rtmpdump"
- },
- {
- "name": "Wimp",
- "url": "http://www.wimp.com/deerfence/",
- "file": "deerfence.flv",
- "md5": "8b215e2e0168c6081a1cf84b2846a2b5",
- "info_dict": {
- "title": "Watch Till End: Herd of deer jump over a fence."
- }
- }
-]
\-\-version\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ print\ program\ version\ and\ exit
\-U,\ \-\-update\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ update\ this\ program\ to\ latest\ version
\-i,\ \-\-ignore\-errors\ \ \ \ \ \ \ \ continue\ on\ download\ errors
-\-r,\ \-\-rate\-limit\ LIMIT\ \ \ \ \ maximum\ download\ rate\ (e.g.\ 50k\ or\ 44.6m)
-\-R,\ \-\-retries\ RETRIES\ \ \ \ \ \ number\ of\ retries\ (default\ is\ 10)
-\-\-buffer\-size\ SIZE\ \ \ \ \ \ \ \ \ size\ of\ download\ buffer\ (e.g.\ 1024\ or\ 16k)
-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (default\ is\ 1024)
-\-\-no\-resize\-buffer\ \ \ \ \ \ \ \ \ do\ not\ automatically\ adjust\ the\ buffer\ size.\ By
-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ default,\ the\ buffer\ size\ is\ automatically\ resized
-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ from\ an\ initial\ value\ of\ SIZE.
\-\-dump\-user\-agent\ \ \ \ \ \ \ \ \ \ display\ the\ current\ browser\ identification
\-\-user\-agent\ UA\ \ \ \ \ \ \ \ \ \ \ \ specify\ a\ custom\ user\ agent
\-\-referer\ REF\ \ \ \ \ \ \ \ \ \ \ \ \ \ specify\ a\ custom\ referer,\ use\ if\ the\ video\ access
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ is\ restricted\ to\ one\ domain
\-\-list\-extractors\ \ \ \ \ \ \ \ \ \ List\ all\ supported\ extractors\ and\ the\ URLs\ they
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ would\ handle
+\-\-extractor\-descriptions\ \ \ Output\ descriptions\ of\ all\ supported\ extractors
\-\-proxy\ URL\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Use\ the\ specified\ HTTP/HTTPS\ proxy
\-\-no\-check\-certificate\ \ \ \ \ Suppress\ HTTPS\ certificate\ validation.
\f[]
\-\-dateafter\ DATE\ \ \ \ \ \ \ \ \ \ \ download\ only\ videos\ uploaded\ after\ this\ date
\f[]
.fi
+.SS Download Options:
+.IP
+.nf
+\f[C]
+\-r,\ \-\-rate\-limit\ LIMIT\ \ \ \ \ maximum\ download\ rate\ (e.g.\ 50k\ or\ 44.6m)
+\-R,\ \-\-retries\ RETRIES\ \ \ \ \ \ number\ of\ retries\ (default\ is\ 10)
+\-\-buffer\-size\ SIZE\ \ \ \ \ \ \ \ \ size\ of\ download\ buffer\ (e.g.\ 1024\ or\ 16k)
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (default\ is\ 1024)
+\-\-no\-resize\-buffer\ \ \ \ \ \ \ \ \ do\ not\ automatically\ adjust\ the\ buffer\ size.\ By
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ default,\ the\ buffer\ size\ is\ automatically\ resized
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ from\ an\ initial\ value\ of\ SIZE.
+\f[]
+.fi
.SS Filesystem Options:
.IP
.nf
\f[C]playlist_index\f[]: The index of the video in the playlist, a
five\-digit number.
.PP
-The current default template is \f[C]%(id)s.%(ext)s\f[], but that will
-be switchted to \f[C]%(title)s\-%(id)s.%(ext)s\f[] (which can be
-requested with \f[C]\-t\f[] at the moment).
+The current default template is \f[C]%(title)s\-%(id)s.%(ext)s\f[].
.PP
In some cases, you don\[aq]t want special characters such as 中, spaces,
or &, such as when transferring the downloaded filename to a Windows
Most people asking this question are not aware that youtube\-dl now
defaults to downloading the highest available quality as reported by
YouTube, which will be 1080p or 720p in some cases, so you no longer
-need the \-b option.
+need the \f[C]\-b\f[] option.
For some specific videos, maybe YouTube does not report them to be
-available in a specific high quality format you\[aq]\[aq]re interested
-in.
-In that case, simply request it with the \-f option and youtube\-dl will
-try to download it.
+available in a specific high quality format you\[aq]re interested in.
+In that case, simply request it with the \f[C]\-f\f[] option and
+youtube\-dl will try to download it.
.SS I get HTTP error 402 when trying to download a video. What\[aq]s
this?
.PP
Apparently YouTube requires you to pass a CAPTCHA test if you download
too much.
-We\[aq]\[aq]re considering to provide a way to let you solve the
+We\[aq]re considering to provide a way to let you solve the
CAPTCHA (https://github.com/rg3/youtube-dl/issues/154), but at the
moment, your best course of action is pointing a webbrowser to the
youtube URL, solving the CAPTCHA, and restart youtube\-dl.
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
- opts="--help --version --update --ignore-errors --rate-limit --retries --buffer-size --no-resize-buffer --dump-user-agent --user-agent --referer --list-extractors --proxy --no-check-certificate --test --playlist-start --playlist-end --match-title --reject-title --max-downloads --min-filesize --max-filesize --date --datebefore --dateafter --title --id --literal --auto-number --output --autonumber-size --restrict-filenames --batch-file --no-overwrites --continue --no-continue --cookies --no-part --no-mtime --write-description --write-info-json --write-thumbnail --quiet --simulate --skip-download --get-url --get-title --get-id --get-thumbnail --get-description --get-filename --get-format --newline --no-progress --console-title --verbose --dump-intermediate-pages --format --all-formats --prefer-free-formats --max-quality --list-formats --write-sub --write-auto-sub --only-sub --all-subs --list-subs --sub-format --sub-lang --username --password --netrc --video-password --extract-audio --audio-format --audio-quality --recode-video --keep-video --no-post-overwrites"
+ opts="--help --version --update --ignore-errors --dump-user-agent --user-agent --referer --list-extractors --extractor-descriptions --proxy --no-check-certificate --playlist-start --playlist-end --match-title --reject-title --max-downloads --min-filesize --max-filesize --date --datebefore --dateafter --rate-limit --retries --buffer-size --no-resize-buffer --test --title --id --literal --auto-number --output --autonumber-size --restrict-filenames --batch-file --no-overwrites --continue --no-continue --cookies --no-part --no-mtime --write-description --write-info-json --write-thumbnail --quiet --simulate --skip-download --get-url --get-title --get-id --get-thumbnail --get-description --get-filename --get-format --newline --no-progress --console-title --verbose --dump-intermediate-pages --format --all-formats --prefer-free-formats --max-quality --list-formats --write-sub --write-auto-sub --only-sub --all-subs --list-subs --sub-format --sub-lang --username --password --netrc --video-password --extract-audio --audio-format --audio-quality --recode-video --keep-video --no-post-overwrites"
if [[ ${cur} == * ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
import traceback
from .utils import *
-from .extractor import get_info_extractor
+from .extractor import get_info_extractor, gen_extractors
from .FileDownloader import FileDownloader
self._ies.append(ie)
ie.set_downloader(self)
+ def add_default_info_extractors(self):
+ """
+ Add the InfoExtractors returned by gen_extractors to the end of the list
+ """
+ for ie in gen_extractors():
+ self.add_info_extractor(ie)
+
def add_post_processor(self, pp):
"""Add a PostProcessor object to the end of the chain."""
self._pps.append(pp)
'Julien Fraichard',
'Johny Mo Swag',
'Axel Noack',
- )
+ 'Albert Kim',
+)
__license__ = 'Public Domain'
import getpass
import optparse
import os
+import random
import re
import shlex
import socket
selection = optparse.OptionGroup(parser, 'Video Selection')
authentication = optparse.OptionGroup(parser, 'Authentication Options')
video_format = optparse.OptionGroup(parser, 'Video Format Options')
+ downloader = optparse.OptionGroup(parser, 'Download Options')
postproc = optparse.OptionGroup(parser, 'Post-processing Options')
filesystem = optparse.OptionGroup(parser, 'Filesystem Options')
verbosity = optparse.OptionGroup(parser, 'Verbosity / Simulation Options')
action='store_true', dest='update_self', help='update this program to latest version')
general.add_option('-i', '--ignore-errors',
action='store_true', dest='ignoreerrors', help='continue on download errors', default=False)
- general.add_option('-r', '--rate-limit',
- dest='ratelimit', metavar='LIMIT', help='maximum download rate (e.g. 50k or 44.6m)')
- general.add_option('-R', '--retries',
- dest='retries', metavar='RETRIES', help='number of retries (default is %default)', default=10)
- general.add_option('--buffer-size',
- dest='buffersize', metavar='SIZE', help='size of download buffer (e.g. 1024 or 16k) (default is %default)', default="1024")
- general.add_option('--no-resize-buffer',
- action='store_true', dest='noresizebuffer',
- help='do not automatically adjust the buffer size. By default, the buffer size is automatically resized from an initial value of SIZE.', default=False)
general.add_option('--dump-user-agent',
action='store_true', dest='dump_user_agent',
help='display the current browser identification', default=False)
general.add_option('--list-extractors',
action='store_true', dest='list_extractors',
help='List all supported extractors and the URLs they would handle', default=False)
+ general.add_option('--extractor-descriptions',
+ action='store_true', dest='list_extractor_descriptions',
+ help='Output descriptions of all supported extractors', default=False)
general.add_option('--proxy', dest='proxy', default=None, help='Use the specified HTTP/HTTPS proxy', metavar='URL')
general.add_option('--no-check-certificate', action='store_true', dest='no_check_certificate', default=False, help='Suppress HTTPS certificate validation.')
- general.add_option('--test', action='store_true', dest='test', default=False, help=optparse.SUPPRESS_HELP)
+
selection.add_option('--playlist-start',
dest='playliststart', metavar='NUMBER', help='playlist video to start at (default is %default)', default=1)
action='store', dest='subtitleslang', metavar='LANG',
help='language of the subtitles to download (optional) use IETF language tags like \'en\'')
+ downloader.add_option('-r', '--rate-limit',
+ dest='ratelimit', metavar='LIMIT', help='maximum download rate (e.g. 50k or 44.6m)')
+ downloader.add_option('-R', '--retries',
+ dest='retries', metavar='RETRIES', help='number of retries (default is %default)', default=10)
+ downloader.add_option('--buffer-size',
+ dest='buffersize', metavar='SIZE', help='size of download buffer (e.g. 1024 or 16k) (default is %default)', default="1024")
+ downloader.add_option('--no-resize-buffer',
+ action='store_true', dest='noresizebuffer',
+ help='do not automatically adjust the buffer size. By default, the buffer size is automatically resized from an initial value of SIZE.', default=False)
+ downloader.add_option('--test', action='store_true', dest='test', default=False, help=optparse.SUPPRESS_HELP)
+
verbosity.add_option('-q', '--quiet',
action='store_true', dest='quiet', help='activates quiet mode', default=False)
verbosity.add_option('-s', '--simulate',
parser.add_option_group(general)
parser.add_option_group(selection)
+ parser.add_option_group(downloader)
parser.add_option_group(filesystem)
parser.add_option_group(verbosity)
parser.add_option_group(video_format)
extractors = gen_extractors()
if opts.list_extractors:
- for ie in extractors:
+ for ie in sorted(extractors, key=lambda ie: ie.IE_NAME.lower()):
compat_print(ie.IE_NAME + (' (CURRENTLY BROKEN)' if not ie._WORKING else ''))
matchedUrls = [url for url in all_urls if ie.suitable(url)]
all_urls = [url for url in all_urls if url not in matchedUrls]
for mu in matchedUrls:
compat_print(u' ' + mu)
sys.exit(0)
+ if opts.list_extractor_descriptions:
+ for ie in sorted(extractors, key=lambda ie: ie.IE_NAME.lower()):
+ if not ie._WORKING:
+ continue
+ desc = getattr(ie, 'IE_DESC', ie.IE_NAME)
+ if hasattr(ie, 'SEARCH_KEY'):
+ _SEARCHES = (u'cute kittens', u'slithering pythons', u'falling cat', u'angry poodle', u'purple fish', u'running tortoise')
+ _COUNTS = (u'', u'5', u'10', u'all')
+ desc += u' (Example: "%s%s:%s" )' % (ie.SEARCH_KEY, random.choice(_COUNTS), random.choice(_SEARCHES))
+ compat_print(desc)
+ sys.exit(0)
+
# Conflicting, missing and erroneous options
if opts.usenetrc and (opts.username is not None or opts.password is not None):
if opts.verbose:
ydl.to_screen(u'[debug] youtube-dl version ' + __version__)
try:
- sp = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- cwd=os.path.dirname(os.path.abspath(__file__)))
+ sp = subprocess.Popen(
+ ['git', 'rev-parse', '--short', 'HEAD'],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ cwd=os.path.dirname(os.path.abspath(__file__)))
out, err = sp.communicate()
out = out.decode().strip()
if re.match('[0-9a-f]+', out):
ydl.to_screen(u'[debug] Git HEAD: ' + out)
except:
- pass
+ sys.exc_clear()
ydl.to_screen(u'[debug] Python version %s - %s' %(platform.python_version(), platform.platform()))
ydl.to_screen(u'[debug] Proxy map: ' + str(proxy_handler.proxies))
- for extractor in extractors:
- ydl.add_info_extractor(extractor)
+ ydl.add_default_info_extractors()
# PostProcessors
if opts.extractaudio:
from .ard import ARDIE
from .arte import ArteTvIE
+from .auengine import AUEngineIE
from .bandcamp import BandcampIE
from .bliptv import BlipTVIE, BlipTVUserIE
from .breakcom import BreakIE
from .facebook import FacebookIE
from .flickr import FlickrIE
from .funnyordie import FunnyOrDieIE
+from .gamespot import GameSpotIE
from .gametrailers import GametrailersIE
from .generic import GenericIE
from .googleplus import GooglePlusIE
from .googlesearch import GoogleSearchIE
+from .hotnewhiphop import HotNewHipHopIE
from .howcast import HowcastIE
from .hypem import HypemIE
from .ina import InaIE
from .infoq import InfoQIE
+from .instagram import InstagramIE
from .jukebox import JukeboxIE
from .justintv import JustinTVIE
from .keek import KeekIE
from .pornotube import PornotubeIE
from .rbmaradio import RBMARadioIE
from .redtube import RedTubeIE
+from .ringtv import RingTVIE
from .soundcloud import SoundcloudIE, SoundcloudSetIE
from .spiegel import SpiegelIE
from .stanfordoc import StanfordOpenClassroomIE
from .steam import SteamIE
from .teamcoco import TeamcocoIE
from .ted import TEDIE
+from .tf1 import TF1IE
+from .traileraddict import TrailerAddictIE
from .tudou import TudouIE
from .tumblr import TumblrIE
+from .tutv import TutvIE
from .ustream import UstreamIE
from .vbox7 import Vbox7IE
from .vevo import VevoIE
from .vimeo import VimeoIE
from .vine import VineIE
+from .wat import WatIE
from .wimp import WimpIE
from .worldstarhiphop import WorldStarHipHopIE
from .xhamster import XHamsterIE
from .youjizz import YouJizzIE
from .youku import YoukuIE
from .youporn import YouPornIE
-from .youtube import YoutubeIE, YoutubePlaylistIE, YoutubeSearchIE, YoutubeUserIE, YoutubeChannelIE
+from .youtube import YoutubeIE, YoutubePlaylistIE, YoutubeSearchIE, YoutubeUserIE, YoutubeChannelIE, YoutubeShowIE
from .zdf import ZDFIE
+_ALL_CLASSES = [
+ klass
+ for name, klass in globals().items()
+ if name.endswith('IE') and name != 'GenericIE'
+]
+_ALL_CLASSES.append(GenericIE)
+
def gen_extractors():
""" Return a list of an instance of every supported extractor.
The order does matter; the first extractor matched is the one handling the URL.
"""
- return [
- YoutubePlaylistIE(),
- YoutubeChannelIE(),
- YoutubeUserIE(),
- YoutubeSearchIE(),
- YoutubeIE(),
- MetacafeIE(),
- DailymotionIE(),
- GoogleSearchIE(),
- PhotobucketIE(),
- YahooIE(),
- YahooSearchIE(),
- DepositFilesIE(),
- FacebookIE(),
- BlipTVIE(),
- BlipTVUserIE(),
- VimeoIE(),
- MyVideoIE(),
- ComedyCentralIE(),
- EscapistIE(),
- CollegeHumorIE(),
- XVideosIE(),
- SoundcloudSetIE(),
- SoundcloudIE(),
- InfoQIE(),
- MixcloudIE(),
- StanfordOpenClassroomIE(),
- MTVIE(),
- YoukuIE(),
- XNXXIE(),
- YouJizzIE(),
- PornotubeIE(),
- YouPornIE(),
- GooglePlusIE(),
- ArteTvIE(),
- NBAIE(),
- WorldStarHipHopIE(),
- JustinTVIE(),
- FunnyOrDieIE(),
- SteamIE(),
- UstreamIE(),
- RBMARadioIE(),
- EightTracksIE(),
- KeekIE(),
- TEDIE(),
- MySpassIE(),
- SpiegelIE(),
- LiveLeakIE(),
- ARDIE(),
- ZDFIE(),
- TumblrIE(),
- BandcampIE(),
- RedTubeIE(),
- InaIE(),
- HowcastIE(),
- VineIE(),
- FlickrIE(),
- TeamcocoIE(),
- XHamsterIE(),
- HypemIE(),
- Vbox7IE(),
- GametrailersIE(),
- StatigramIE(),
- BreakIE(),
- VevoIE(),
- JukeboxIE(),
- TudouIE(),
- CSpanIE(),
- WimpIE(),
- GenericIE()
- ]
+ return [klass() for klass in _ALL_CLASSES]
def get_info_extractor(ie_name):
"""Returns the info extractor class with the given ie_name"""
_VALID_URL = r'^(?:https?://)?(?:(?:www\.)?ardmediathek\.de|mediathek\.daserste\.de)/(?:.*/)(?P<video_id>[^/\?]+)(?:\?.*)?'
_TITLE = r'<h1(?: class="boxTopHeadline")?>(?P<title>.*)</h1>'
_MEDIA_STREAM = r'mediaCollection\.addMediaStream\((?P<media_type>\d+), (?P<quality>\d+), "(?P<rtmp_url>[^"]*)", "(?P<video_url>[^"]*)", "[^"]*"\)'
+ _TEST = {
+ u'url': u'http://www.ardmediathek.de/das-erste/tagesschau-in-100-sek?documentId=14077640',
+ u'file': u'14077640.mp4',
+ u'md5': u'6ca8824255460c787376353f9e20bbd8',
+ u'info_dict': {
+ u"title": u"11.04.2013 09:23 Uhr - Tagesschau in 100 Sekunden"
+ },
+ u'skip': u'Requires rtmpdump'
+ }
def _real_extract(self, url):
# determine video id from url
)
class ArteTvIE(InfoExtractor):
- _VALID_URL = r'(?:http://)?www\.arte.tv/guide/(?:fr|de)/(?:(?:sendungen|emissions)/)?(?P<id>.*?)/(?P<name>.*?)(\?.*)?'
+ """
+ There are two sources of video in arte.tv: videos.arte.tv and
+ www.arte.tv/guide, the extraction process is different for each one.
+ The videos expire in 7 days, so we can't add tests.
+ """
+ _EMISSION_URL = r'(?:http://)?www\.arte.tv/guide/(?:fr|de)/(?:(?:sendungen|emissions)/)?(?P<id>.*?)/(?P<name>.*?)(\?.*)?'
+ _VIDEOS_URL = r'(?:http://)?videos.arte.tv/(?:fr|de)/.*-(?P<id>.*?).html'
_LIVE_URL = r'index-[0-9]+\.html$'
IE_NAME = u'arte.tv'
+ @classmethod
+ def suitable(cls, url):
+ return any(re.match(regex, url) for regex in (cls._EMISSION_URL, cls._VIDEOS_URL))
+
# TODO implement Live Stream
# def extractLiveStream(self, url):
# video_lang = url.split('/')[-4]
# video_url = u'%s/%s' % (info.get('url'), info.get('path'))
def _real_extract(self, url):
- mobj = re.match(self._VALID_URL, url)
- name = mobj.group('name')
- # This is not a real id, it can be for example AJT for the news
- # http://www.arte.tv/guide/fr/emissions/AJT/arte-journal
- video_id = mobj.group('id')
+ mobj = re.match(self._EMISSION_URL, url)
+ if mobj is not None:
+ name = mobj.group('name')
+ # This is not a real id, it can be for example AJT for the news
+ # http://www.arte.tv/guide/fr/emissions/AJT/arte-journal
+ video_id = mobj.group('id')
+ return self._extract_emission(url, video_id)
+
+ mobj = re.match(self._VIDEOS_URL, url)
+ if mobj is not None:
+ id = mobj.group('id')
+ return self._extract_video(url, id)
if re.search(self._LIVE_URL, video_id) is not None:
raise ExtractorError(u'Arte live streams are not yet supported, sorry')
# self.extractLiveStream(url)
# return
+ def _extract_emission(self, url, video_id):
+ """Extract from www.arte.tv/guide"""
webpage = self._download_webpage(url, video_id)
json_url = self._html_search_regex(r'arte_vp_url="(.*?)"', webpage, 'json url')
'description': player_info['VDE'],
'upload_date': unified_strdate(player_info['VDA'].split(' ')[0]),
'thumbnail': player_info['programImage'],
+ 'ext': 'flv',
}
formats = player_info['VSR'].values()
if format_info['mediaType'] == u'rtmp':
info_dict['url'] = format_info['streamer']
info_dict['play_path'] = 'mp4:' + format_info['url']
- info_dict['ext'] = 'mp4'
else:
info_dict['url'] = format_info['url']
- info_dict['ext'] = 'mp4'
return info_dict
+
+ def _extract_video(self, url, video_id):
+ """Extract from videos.arte.tv"""
+ config_xml_url = url.replace('/videos/', '/do_delegate/videos/')
+ config_xml_url = config_xml_url.replace('.html', ',view,asPlayerXml.xml')
+ config_xml = self._download_webpage(config_xml_url, video_id)
+ config_xml_url = self._html_search_regex(r'<video lang=".*?" ref="(.*?)"', config_xml, 'config xml url')
+ config_xml = self._download_webpage(config_xml_url, video_id)
+
+ video_urls = list(re.finditer(r'<url quality="(?P<quality>.*?)">(?P<url>.*?)</url>', config_xml))
+ def _key(m):
+ quality = m.group('quality')
+ if quality == 'hd':
+ return 2
+ else:
+ return 1
+ # We pick the best quality
+ video_urls = sorted(video_urls, key=_key)
+ video_url = list(video_urls)[-1].group('url')
+
+ title = self._html_search_regex(r'<name>(.*?)</name>', config_xml, 'title')
+ thumbnail = self._html_search_regex(r'<firstThumbnailUrl>(.*?)</firstThumbnailUrl>',
+ config_xml, 'thumbnail')
+ return {'id': video_id,
+ 'title': title,
+ 'thumbnail': thumbnail,
+ 'url': video_url,
+ 'ext': 'flv',
+ }
--- /dev/null
+import os.path
+import re
+
+from .common import InfoExtractor
+from ..utils import (
+ compat_urllib_parse,
+ compat_urllib_parse_urlparse,
+)
+
+class AUEngineIE(InfoExtractor):
+ _VALID_URL = r'(?:http://)?(?:www\.)?auengine\.com/embed.php\?.*?file=([^&]+).*?'
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ video_id = mobj.group(1)
+ webpage = self._download_webpage(url, video_id)
+ title = self._html_search_regex(r'<title>(?P<title>.+?)</title>',
+ webpage, u'title')
+ title = title.strip()
+ links = re.findall(r'[^A-Za-z0-9]?(?:file|url):\s*["\'](http[^\'"&]*)', webpage)
+ links = [compat_urllib_parse.unquote(l) for l in links]
+ for link in links:
+ root, pathext = os.path.splitext(compat_urllib_parse_urlparse(link).path)
+ if pathext == '.png':
+ thumbnail = link
+ elif pathext == '.mp4':
+ url = link
+ ext = pathext
+ if ext == title[-len(ext):]:
+ title = title[:-len(ext)]
+ ext = ext[1:]
+ return [{
+ 'id': video_id,
+ 'url': url,
+ 'ext': ext,
+ 'title': title,
+ 'thumbnail': thumbnail,
+ }]
class BandcampIE(InfoExtractor):
_VALID_URL = r'http://.*?\.bandcamp\.com/track/(?P<title>.*)'
+ _TEST = {
+ u'url': u'http://youtube-dl.bandcamp.com/track/youtube-dl-test-song',
+ u'file': u'1812978515.mp3',
+ u'md5': u'cdeb30cdae1921719a3cbcab696ef53c',
+ u'info_dict': {
+ u"title": u"youtube-dl test song \"'/\\\u00e4\u21ad"
+ },
+ u'skip': u'There is a limit of 200 free downloads / month for the test song'
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
_VALID_URL = r'^(?:https?://)?(?:\w+\.)?blip\.tv/((.+/)|(play/)|(api\.swf#))(.+)$'
_URL_EXT = r'^.*\.([a-z0-9]+)$'
IE_NAME = u'blip.tv'
+ _TEST = {
+ u'url': u'http://blip.tv/cbr/cbr-exclusive-gotham-city-imposters-bats-vs-jokerz-short-3-5796352',
+ u'file': u'5779306.m4v',
+ u'md5': u'b2d849efcf7ee18917e4b4d9ff37cafe',
+ u'info_dict': {
+ u"upload_date": u"20111205",
+ u"description": u"md5:9bc31f227219cde65e47eeec8d2dc596",
+ u"uploader": u"Comic Book Resources - CBR TV",
+ u"title": u"CBR EXCLUSIVE: \"Gotham City Imposters\" Bats VS Jokerz Short 3"
+ }
+ }
def report_direct_download(self, title):
"""Report information extraction."""
class BreakIE(InfoExtractor):
_VALID_URL = r'(?:http://)?(?:www\.)?break\.com/video/([^/]+)'
+ _TEST = {
+ u'url': u'http://www.break.com/video/when-girls-act-like-guys-2468056',
+ u'file': u'2468056.mp4',
+ u'md5': u'a3513fb1547fba4fb6cfac1bffc6c46b',
+ u'info_dict': {
+ u"title": u"When Girls Act Like D-Bags"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class ComedyCentralIE(InfoExtractor):
- """Information extractor for The Daily Show and Colbert Report """
-
+ IE_DESC = u'The Daily Show / Colbert Report'
# urls can be abbreviations like :thedailyshow or :colbert
# urls for episodes like:
# or urls for clips like: http://www.thedailyshow.com/watch/mon-december-10-2012/any-given-gun-day
(the-colbert-report-(videos|collections)/(?P<clipID>[0-9]+)/[^/]*/(?P<cntitle>.*?))
|(watch/(?P<date>[^/]*)/(?P<tdstitle>.*)))))
$"""
+ _TEST = {
+ u'url': u'http://www.thedailyshow.com/watch/thu-december-13-2012/kristen-stewart',
+ u'file': u'422212.mp4',
+ u'md5': u'4e2f5cb088a83cd8cdb7756132f9739d',
+ u'info_dict': {
+ u"upload_date": u"20121214",
+ u"description": u"Kristen Stewart",
+ u"uploader": u"thedailyshow",
+ u"title": u"thedailyshow-kristen-stewart part 1"
+ }
+ }
_available_formats = ['3500', '2200', '1700', '1200', '750', '400']
location: Physical location of the video.
player_url: SWF Player URL (used for rtmpdump).
subtitles: The subtitle file contents.
+ view_count: How many users have watched the video on the platform.
urlhandle: [internal] The urlHandle to be used to download the file,
like returned by urllib.request.urlopen
def _get_n_results(self, query, n):
"""Get a specified number of results for a query"""
raise NotImplementedError("This method must be implemented by sublclasses")
+
+ @property
+ def SEARCH_KEY(self):
+ return self._SEARCH_KEY
class CSpanIE(InfoExtractor):
_VALID_URL = r'http://www.c-spanvideo.org/program/(.*)'
+ _TEST = {
+ u'url': u'http://www.c-spanvideo.org/program/HolderonV',
+ u'file': u'315139.flv',
+ u'md5': u'74a623266956f69e4df0068ab6c80fe4',
+ u'info_dict': {
+ u"title": u"Attorney General Eric Holder on Voting Rights Act Decision"
+ },
+ u'skip': u'Requires rtmpdump'
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
_VALID_URL = r'(?i)(?:https?://)?(?:www\.)?dailymotion\.[a-z]{2,3}/video/([^/]+)'
IE_NAME = u'dailymotion'
+ _TEST = {
+ u'url': u'http://www.dailymotion.com/video/x33vw9_tutoriel-de-youtubeur-dl-des-video_tech',
+ u'file': u'x33vw9.mp4',
+ u'md5': u'392c4b85a60a90dc4792da41ce3144eb',
+ u'info_dict': {
+ u"uploader": u"Alex and Van .",
+ u"title": u"Tutoriel de Youtubeur\"DL DES VIDEO DE YOUTUBE\""
+ }
+ }
def _real_extract(self, url):
# Extract id and simplified title from URL
class EightTracksIE(InfoExtractor):
IE_NAME = '8tracks'
_VALID_URL = r'https?://8tracks.com/(?P<user>[^/]+)/(?P<id>[^/#]+)(?:#.*)?$'
+ _TEST = {
+ u"name": u"EightTracks",
+ u"url": u"http://8tracks.com/ytdl/youtube-dl-test-tracks-a",
+ u"playlist": [
+ {
+ u"file": u"11885610.m4a",
+ u"md5": u"96ce57f24389fc8734ce47f4c1abcc55",
+ u"info_dict": {
+ u"title": u"youtue-dl project<>\"' - youtube-dl test track 1 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ },
+ {
+ u"file": u"11885608.m4a",
+ u"md5": u"4ab26f05c1f7291ea460a3920be8021f",
+ u"info_dict": {
+ u"title": u"youtube-dl project - youtube-dl test track 2 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ },
+ {
+ u"file": u"11885679.m4a",
+ u"md5": u"d30b5b5f74217410f4689605c35d1fd7",
+ u"info_dict": {
+ u"title": u"youtube-dl project as well - youtube-dl test track 3 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ },
+ {
+ u"file": u"11885680.m4a",
+ u"md5": u"4eb0a669317cd725f6bbd336a29f923a",
+ u"info_dict": {
+ u"title": u"youtube-dl project as well - youtube-dl test track 4 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ },
+ {
+ u"file": u"11885682.m4a",
+ u"md5": u"1893e872e263a2705558d1d319ad19e8",
+ u"info_dict": {
+ u"title": u"PH - youtube-dl test track 5 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ },
+ {
+ u"file": u"11885683.m4a",
+ u"md5": u"b673c46f47a216ab1741ae8836af5899",
+ u"info_dict": {
+ u"title": u"PH - youtube-dl test track 6 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ },
+ {
+ u"file": u"11885684.m4a",
+ u"md5": u"1d74534e95df54986da7f5abf7d842b7",
+ u"info_dict": {
+ u"title": u"phihag - youtube-dl test track 7 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ },
+ {
+ u"file": u"11885685.m4a",
+ u"md5": u"f081f47af8f6ae782ed131d38b9cd1c0",
+ u"info_dict": {
+ u"title": u"phihag - youtube-dl test track 8 \"'/\\\u00e4\u21ad",
+ u"uploader_id": u"ytdl"
+ }
+ }
+ ]
+ }
+
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class EscapistIE(InfoExtractor):
_VALID_URL = r'^(https?://)?(www\.)?escapistmagazine\.com/videos/view/(?P<showname>[^/]+)/(?P<episode>[^/?]+)[/?]?.*$'
+ _TEST = {
+ u'url': u'http://www.escapistmagazine.com/videos/view/the-escapist-presents/6618-Breaking-Down-Baldurs-Gate',
+ u'file': u'6618-Breaking-Down-Baldurs-Gate.mp4',
+ u'md5': u'c6793dbda81388f4264c1ba18684a74d',
+ u'info_dict': {
+ u"description": u"Baldur's Gate: Original, Modded or Enhanced Edition? I'll break down what you can expect from the new Baldur's Gate: Enhanced Edition.",
+ u"uploader": u"the-escapist-presents",
+ u"title": u"Breaking Down Baldur's Gate"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
_LOGIN_URL = 'https://login.facebook.com/login.php?m&next=http%3A%2F%2Fm.facebook.com%2Fhome.php&'
_NETRC_MACHINE = 'facebook'
IE_NAME = u'facebook'
+ _TEST = {
+ u'url': u'https://www.facebook.com/photo.php?v=120708114770723',
+ u'file': u'120708114770723.mp4',
+ u'md5': u'48975a41ccc4b7a581abd68651c1a5a8',
+ u'info_dict': {
+ u"duration": 279,
+ u"title": u"PEOPLE ARE AWESOME 2013"
+ }
+ }
def report_login(self):
"""Report attempt to log in."""
class FlickrIE(InfoExtractor):
"""Information Extractor for Flickr videos"""
_VALID_URL = r'(?:https?://)?(?:www\.)?flickr\.com/photos/(?P<uploader_id>[\w\-_@]+)/(?P<id>\d+).*'
+ _TEST = {
+ u'url': u'http://www.flickr.com/photos/forestwander-nature-pictures/5645318632/in/photostream/',
+ u'file': u'5645318632.mp4',
+ u'md5': u'6fdc01adbc89d72fc9c4f15b4a4ba87b',
+ u'info_dict': {
+ u"description": u"Waterfalls in the Springtime at Dark Hollow Waterfalls. These are located just off of Skyline Drive in Virginia. They are only about 6/10 of a mile hike but it is a pretty steep hill and a good climb back up.",
+ u"uploader_id": u"forestwander-nature-pictures",
+ u"title": u"Dark Hollow Waterfalls"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class FunnyOrDieIE(InfoExtractor):
_VALID_URL = r'^(?:https?://)?(?:www\.)?funnyordie\.com/videos/(?P<id>[0-9a-f]+)/.*$'
+ _TEST = {
+ u'url': u'http://www.funnyordie.com/videos/0732f586d7/heart-shaped-box-literal-video-version',
+ u'file': u'0732f586d7.mp4',
+ u'md5': u'f647e9e90064b53b6e046e75d0241fbd',
+ u'info_dict': {
+ u"description": u"Lyrics changed to match the video. Spoken cameo by Obscurus Lupa (from ThatGuyWithTheGlasses.com). Based on a concept by Dustin McLean (DustFilms.com). Performed, edited, and written by David A. Scott.",
+ u"title": u"Heart-Shaped Box: Literal Video Version"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
--- /dev/null
+import re
+import xml.etree.ElementTree
+
+from .common import InfoExtractor
+from ..utils import (
+ unified_strdate,
+)
+
+class GameSpotIE(InfoExtractor):
+ _VALID_URL = r'(?:http://)?(?:www\.)?gamespot\.com/([^/]+)/videos/([^/]+)-([^/d]+)/'
+ _TEST = {
+ u"url": u"http://www.gamespot.com/arma-iii/videos/arma-iii-community-guide-sitrep-i-6410818/",
+ u"file": u"6410818.mp4",
+ u"md5": u"5569d64ca98db01f0177c934fe8c1e9b",
+ u"info_dict": {
+ u"title": u"Arma III - Community Guide: SITREP I",
+ u"upload_date": u"20130627",
+ }
+ }
+
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ video_id = mobj.group(3).split("-")[-1]
+ info_url = "http://www.gamespot.com/pages/video_player/xml.php?id="+str(video_id)
+ info_xml = self._download_webpage(info_url, video_id)
+ doc = xml.etree.ElementTree.fromstring(info_xml)
+ clip_el = doc.find('./playList/clip')
+
+ video_url = clip_el.find('./URI').text
+ title = clip_el.find('./title').text
+ ext = video_url.rpartition('.')[2]
+ thumbnail_url = clip_el.find('./screenGrabURI').text
+ view_count = int(clip_el.find('./views').text)
+ upload_date = unified_strdate(clip_el.find('./postDate').text)
+
+ return [{
+ 'id' : video_id,
+ 'url' : video_url,
+ 'ext' : ext,
+ 'title' : title,
+ 'thumbnail' : thumbnail_url,
+ 'upload_date' : upload_date,
+ 'view_count' : view_count,
+ }]
class GametrailersIE(InfoExtractor):
_VALID_URL = r'http://www.gametrailers.com/(?P<type>videos|reviews|full-episodes)/(?P<id>.*?)/(?P<title>.*)'
+ _TEST = {
+ u'url': u'http://www.gametrailers.com/videos/zbvr8i/mirror-s-edge-2-e3-2013--debut-trailer',
+ u'file': u'zbvr8i.flv',
+ u'md5': u'c3edbc995ab4081976e16779bd96a878',
+ u'info_dict': {
+ u"title": u"E3 2013: Debut Trailer"
+ },
+ u'skip': u'Requires rtmpdump'
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
)
class GenericIE(InfoExtractor):
- """Generic last-resort information extractor."""
-
+ IE_DESC = u'Generic downloader that works on some sites'
_VALID_URL = r'.*'
IE_NAME = u'generic'
+ _TEST = {
+ u'url': u'http://www.hodiho.fr/2013/02/regis-plante-sa-jeep.html',
+ u'file': u'13601338388002.mp4',
+ u'md5': u'85b90ccc9d73b4acd9138d3af4c27f89',
+ u'info_dict': {
+ u"uploader": u"www.hodiho.fr",
+ u"title": u"R\u00e9gis plante sa Jeep"
+ }
+ }
def report_download_webpage(self, video_id):
"""Report webpage download."""
mobj = re.search(r'[^A-Za-z0-9]?(?:file|source)=(http[^\'"&]*)', webpage)
if mobj is None:
# Broaden the search a little bit: JWPlayer JS loader
- mobj = re.search(r'[^A-Za-z0-9]?file:\s*["\'](http[^\'"&]*)', webpage)
+ mobj = re.search(r'[^A-Za-z0-9]?file["\']?:\s*["\'](http[^\'"&]*)', webpage)
if mobj is None:
# Try to find twitter cards info
mobj = re.search(r'<meta (?:property|name)="twitter:player:stream" (?:content|value)="(.+?)"', webpage)
# Video Title - Tagline | Site Name
# and so on and so forth; it's just not practical
video_title = self._html_search_regex(r'<title>(.*)</title>',
- webpage, u'video title')
+ webpage, u'video title', default=u'video', flags=re.DOTALL)
# video uploader is domain name
video_uploader = self._search_regex(r'(?:https?://)?([^/]*)/.*',
+# coding: utf-8
+
import datetime
import re
class GooglePlusIE(InfoExtractor):
- """Information extractor for plus.google.com."""
-
+ IE_DESC = u'Google Plus'
_VALID_URL = r'(?:https://)?plus\.google\.com/(?:[^/]+/)*?posts/(\w+)'
IE_NAME = u'plus.google'
+ _TEST = {
+ u"url": u"https://plus.google.com/u/0/108897254135232129896/posts/ZButuJc6CtH",
+ u"file": u"ZButuJc6CtH.flv",
+ u"info_dict": {
+ u"upload_date": u"20120613",
+ u"uploader": u"井上ヨシマサ",
+ u"title": u"嘆きの天使 降臨"
+ }
+ }
def _real_extract(self, url):
# Extract id from URL
class GoogleSearchIE(SearchInfoExtractor):
- """Information Extractor for Google Video search queries."""
+ IE_DESC = u'Google Video search'
_MORE_PAGES_INDICATOR = r'id="pnnext" class="pn"'
_MAX_RESULTS = 1000
IE_NAME = u'video.google:search'
--- /dev/null
+import re
+import base64
+
+from .common import InfoExtractor
+
+
+class HotNewHipHopIE(InfoExtractor):
+ _VALID_URL = r'http://www\.hotnewhiphop.com/.*\.(?P<id>.*)\.html'
+ _TEST = {
+ u'url': u"http://www.hotnewhiphop.com/freddie-gibbs-lay-it-down-song.1435540.html'",
+ u'file': u'1435540.mp3',
+ u'md5': u'2c2cd2f76ef11a9b3b581e8b232f3d96',
+ u'info_dict': {
+ u"title": u"Freddie Gibbs Songs - Lay It Down"
+ }
+ }
+
+ def _real_extract(self, url):
+ m = re.match(self._VALID_URL, url)
+ video_id = m.group('id')
+
+ webpage_src = self._download_webpage(url, video_id)
+
+ video_url_base64 = self._search_regex(r'data-path="(.*?)"',
+ webpage_src, u'video URL', fatal=False)
+
+ if video_url_base64 == None:
+ video_url = self._search_regex(r'"contentUrl" content="(.*?)"', webpage_src,
+ u'video URL')
+ return self.url_result(video_url, ie='Youtube')
+
+ video_url = base64.b64decode(video_url_base64).decode('utf-8')
+
+ video_title = self._html_search_regex(r"<title>(.*)</title>",
+ webpage_src, u'title')
+
+ # Getting thumbnail and if not thumbnail sets correct title for WSHH candy video.
+ thumbnail = self._html_search_regex(r'"og:image" content="(.*)"',
+ webpage_src, u'thumbnail', fatal=False)
+
+ results = [{
+ 'id': video_id,
+ 'url' : video_url,
+ 'title' : video_title,
+ 'thumbnail' : thumbnail,
+ 'ext' : 'mp3',
+ }]
+ return results
\ No newline at end of file
class HowcastIE(InfoExtractor):
_VALID_URL = r'(?:https?://)?(?:www\.)?howcast\.com/videos/(?P<id>\d+)'
+ _TEST = {
+ u'url': u'http://www.howcast.com/videos/390161-How-to-Tie-a-Square-Knot-Properly',
+ u'file': u'390161.mp4',
+ u'md5': u'1d7ba54e2c9d7dc6935ef39e00529138',
+ u'info_dict': {
+ u"description": u"The square knot, also known as the reef knot, is one of the oldest, most basic knots to tie, and can be used in many different ways. Here's the proper way to tie a square knot.",
+ u"title": u"How to Tie a Square Knot Properly"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class HypemIE(InfoExtractor):
"""Information Extractor for hypem"""
_VALID_URL = r'(?:http://)?(?:www\.)?hypem\.com/track/([^/]+)/([^/]+)'
+ _TEST = {
+ u'url': u'http://hypem.com/track/1v6ga/BODYWORK+-+TAME',
+ u'file': u'1v6ga.mp3',
+ u'md5': u'b9cc91b5af8995e9f0c1cee04c575828',
+ u'info_dict': {
+ u"title": u"Tame"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class InaIE(InfoExtractor):
"""Information Extractor for Ina.fr"""
_VALID_URL = r'(?:http://)?(?:www\.)?ina\.fr/video/(?P<id>I[0-9]+)/.*'
+ _TEST = {
+ u'url': u'www.ina.fr/video/I12055569/francois-hollande-je-crois-que-c-est-clair-video.html',
+ u'file': u'I12055569.mp4',
+ u'md5': u'a667021bf2b41f8dc6049479d9bb38a3',
+ u'info_dict': {
+ u"title": u"Fran\u00e7ois Hollande \"Je crois que c'est clair\""
+ }
+ }
def _real_extract(self,url):
mobj = re.match(self._VALID_URL, url)
class InfoQIE(InfoExtractor):
_VALID_URL = r'^(?:https?://)?(?:www\.)?infoq\.com/[^/]+/[^/]+$'
+ _TEST = {
+ u"name": u"InfoQ",
+ u"url": u"http://www.infoq.com/presentations/A-Few-of-My-Favorite-Python-Things",
+ u"file": u"12-jan-pythonthings.mp4",
+ u"info_dict": {
+ u"description": u"Mike Pirnat presents some tips and tricks, standard libraries and third party packages that make programming in Python a richer experience.",
+ u"title": u"A Few of My Favorite [Python] Things"
+ },
+ u"params": {
+ u"skip_download": True
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
--- /dev/null
+import re
+
+from .common import InfoExtractor
+
+class InstagramIE(InfoExtractor):
+ _VALID_URL = r'(?:http://)?instagram.com/p/(.*?)/'
+ _TEST = {
+ u'url': u'http://instagram.com/p/aye83DjauH/#',
+ u'file': u'aye83DjauH.mp4',
+ u'md5': u'0d2da106a9d2631273e192b372806516',
+ u'info_dict': {
+ u"uploader_id": u"naomipq",
+ u"title": u"Video by naomipq"
+ }
+ }
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ video_id = mobj.group(1)
+ webpage = self._download_webpage(url, video_id)
+ video_url = self._html_search_regex(
+ r'<meta property="og:video" content="(.+?)"',
+ webpage, u'video URL')
+ thumbnail_url = self._html_search_regex(
+ r'<meta property="og:image" content="(.+?)" />',
+ webpage, u'thumbnail URL', fatal=False)
+ html_title = self._html_search_regex(
+ r'<title>(.+?)</title>',
+ webpage, u'title', flags=re.DOTALL)
+ title = re.sub(u'(?: *\(Videos?\))? \u2022 Instagram$', '', html_title).strip()
+ uploader_id = self._html_search_regex(r'content="(.*?)\'s video on Instagram',
+ webpage, u'uploader name', fatal=False)
+ ext = 'mp4'
+
+ return [{
+ 'id': video_id,
+ 'url': video_url,
+ 'ext': ext,
+ 'title': title,
+ 'thumbnail': thumbnail_url,
+ 'uploader_id' : uploader_id
+ }]
"""
_JUSTIN_PAGE_LIMIT = 100
IE_NAME = u'justin.tv'
+ _TEST = {
+ u'url': u'http://www.twitch.tv/thegamedevhub/b/296128360',
+ u'file': u'296128360.flv',
+ u'md5': u'ecaa8a790c22a40770901460af191c9a',
+ u'info_dict': {
+ u"upload_date": u"20110927",
+ u"uploader_id": 25114803,
+ u"uploader": u"thegamedevhub",
+ u"title": u"Beginner Series - Scripting With Python Pt.1"
+ }
+ }
def report_download_page(self, channel, offset):
"""Report attempt to download a single page of videos."""
class KeekIE(InfoExtractor):
_VALID_URL = r'http://(?:www\.)?keek\.com/(?:!|\w+/keeks/)(?P<videoID>\w+)'
IE_NAME = u'keek'
+ _TEST = {
+ u'url': u'http://www.keek.com/ytdl/keeks/NODfbab',
+ u'file': u'NODfbab.mp4',
+ u'md5': u'9b0636f8c0f7614afa4ea5e4c6e57e83',
+ u'info_dict': {
+ u"uploader": u"ytdl",
+ u"title": u"test chars: \"'/\\\u00e4<>This is a test video for youtube-dl.For more information, contact phihag@phihag.de ."
+ }
+ }
def _real_extract(self, url):
m = re.match(self._VALID_URL, url)
_VALID_URL = r'^(?:http?://)?(?:\w+\.)?liveleak\.com/view\?(?:.*?)i=(?P<video_id>[\w_]+)(?:.*)'
IE_NAME = u'liveleak'
+ _TEST = {
+ u'url': u'http://www.liveleak.com/view?i=757_1364311680',
+ u'file': u'757_1364311680.mp4',
+ u'md5': u'0813c2430bea7a46bf13acf3406992f4',
+ u'info_dict': {
+ u"description": u"extremely bad day for this guy..!",
+ u"uploader": u"ljfriel2",
+ u"title": u"Most unlucky car accident"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
_DISCLAIMER = 'http://www.metacafe.com/family_filter/'
_FILTER_POST = 'http://www.metacafe.com/f/index.php?inputType=filter&controllerGroup=user'
IE_NAME = u'metacafe'
+ _TEST = {
+ u"add_ie": ["Youtube"],
+ u"url": u"http://metacafe.com/watch/yt-_aUehQsCQtM/the_electric_company_short_i_pbs_kids_go/",
+ u"file": u"_aUehQsCQtM.flv",
+ u"info_dict": {
+ u"upload_date": u"20090102",
+ u"title": u"The Electric Company | \"Short I\" | PBS KIDS GO!",
+ u"description": u"md5:2439a8ef6d5a70e380c22f5ad323e5a8",
+ u"uploader": u"PBS",
+ u"uploader_id": u"PBS"
+ }
+ }
+
def report_disclaimer(self):
"""Report disclaimer retrieval."""
class MySpassIE(InfoExtractor):
_VALID_URL = r'http://www.myspass.de/.*'
+ _TEST = {
+ u'url': u'http://www.myspass.de/myspass/shows/tvshows/absolute-mehrheit/Absolute-Mehrheit-vom-17022013-Die-Highlights-Teil-2--/11741/',
+ u'file': u'11741.mp4',
+ u'md5': u'0b49f4844a068f8b33f4b7c88405862b',
+ u'info_dict': {
+ u"description": u"Wer kann in die Fu\u00dfstapfen von Wolfgang Kubicki treten und die Mehrheit der Zuschauer hinter sich versammeln? Wird vielleicht sogar die Absolute Mehrheit geknackt und der Jackpot von 200.000 Euro mit nach Hause genommen?",
+ u"title": u"Absolute Mehrheit vom 17.02.2013 - Die Highlights, Teil 2"
+ }
+ }
def _real_extract(self, url):
META_DATA_URL_TEMPLATE = 'http://www.myspass.de/myspass/includes/apps/video/getvideometadataxml.php?id=%s'
_VALID_URL = r'(?:http://)?(?:www\.)?myvideo\.de/watch/([0-9]+)/([^?/]+).*'
IE_NAME = u'myvideo'
+ _TEST = {
+ u'url': u'http://www.myvideo.de/watch/8229274/bowling_fail_or_win',
+ u'file': u'8229274.flv',
+ u'md5': u'2d2753e8130479ba2cb7e0a37002053e',
+ u'info_dict': {
+ u"title": u"bowling-fail-or-win"
+ }
+ }
# Original Code from: https://github.com/dersphere/plugin.video.myvideo_de.git
# Released into the Public Domain by Tristan Fischer on 2013-05-19
class NBAIE(InfoExtractor):
_VALID_URL = r'^(?:https?://)?(?:watch\.|www\.)?nba\.com/(?:nba/)?video(/[^?]*?)(?:/index\.html)?(?:\?.*)?$'
+ _TEST = {
+ u'url': u'http://www.nba.com/video/games/nets/2012/12/04/0021200253-okc-bkn-recap.nba/index.html',
+ u'file': u'0021200253-okc-bkn-recap.nba.mp4',
+ u'md5': u'c0edcfc37607344e2ff8f13c378c88a4',
+ u'info_dict': {
+ u"description": u"Kevin Durant scores 32 points and dishes out six assists as the Thunder beat the Nets in Brooklyn.",
+ u"title": u"Thunder vs. Nets"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
# Check if it's necessary to keep the old extracion process
_VALID_URL = r'(?:http://)?(?:[a-z0-9]+\.)?photobucket\.com/.*(([\?\&]current=)|_)(?P<id>.*)\.(?P<ext>(flv)|(mp4))'
IE_NAME = u'photobucket'
+ _TEST = {
+ u'url': u'http://media.photobucket.com/user/rachaneronas/media/TiredofLinkBuildingTryBacklinkMyDomaincom_zpsc0c3b9fa.mp4.html?filters[term]=search&filters[primary]=videos&filters[secondary]=images&sort=1&o=0',
+ u'file': u'zpsc0c3b9fa.mp4',
+ u'md5': u'7dabfb92b0a31f6c16cebc0f8e60ff99',
+ u'info_dict': {
+ u"upload_date": u"20130504",
+ u"uploader": u"rachaneronas",
+ u"title": u"Tired of Link Building? Try BacklinkMyDomain.com!"
+ }
+ }
def _real_extract(self, url):
# Extract id from URL
class PornotubeIE(InfoExtractor):
_VALID_URL = r'^(?:https?://)?(?:\w+\.)?pornotube\.com(/c/(?P<channel>[0-9]+))?(/m/(?P<videoid>[0-9]+))(/(?P<title>.+))$'
+ _TEST = {
+ u'url': u'http://pornotube.com/c/173/m/1689755/Marilyn-Monroe-Bathing',
+ u'file': u'1689755.flv',
+ u'md5': u'374dd6dcedd24234453b295209aa69b6',
+ u'info_dict': {
+ u"upload_date": u"20090708",
+ u"title": u"Marilyn-Monroe-Bathing"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class RBMARadioIE(InfoExtractor):
_VALID_URL = r'https?://(?:www\.)?rbmaradio\.com/shows/(?P<videoID>[^/]+)$'
+ _TEST = {
+ u'url': u'http://www.rbmaradio.com/shows/ford-lopatin-live-at-primavera-sound-2011',
+ u'file': u'ford-lopatin-live-at-primavera-sound-2011.mp3',
+ u'md5': u'6bc6f9bcb18994b4c983bc3bf4384d95',
+ u'info_dict': {
+ u"uploader_id": u"ford-lopatin",
+ u"location": u"Spain",
+ u"description": u"Joel Ford and Daniel \u2019Oneohtrix Point Never\u2019 Lopatin fly their midified pop extravaganza to Spain. Live at Primavera Sound 2011.",
+ u"uploader": u"Ford & Lopatin",
+ u"title": u"Live at Primavera Sound 2011"
+ }
+ }
def _real_extract(self, url):
m = re.match(self._VALID_URL, url)
class RedTubeIE(InfoExtractor):
_VALID_URL = r'(?:http://)?(?:www\.)?redtube\.com/(?P<id>[0-9]+)'
+ _TEST = {
+ u'url': u'http://www.redtube.com/66418',
+ u'file': u'66418.mp4',
+ u'md5': u'7b8c22b5e7098a3e1c09709df1126d2d',
+ u'info_dict': {
+ u"title": u"Sucked on a toilet"
+ }
+ }
def _real_extract(self,url):
mobj = re.match(self._VALID_URL, url)
--- /dev/null
+import re
+
+from .common import InfoExtractor
+
+
+class RingTVIE(InfoExtractor):
+ _VALID_URL = r'(?:http://)?(?:www\.)?ringtv\.craveonline\.com/videos/video/([^/]+)'
+ _TEST = {
+ u"url": u"http://ringtv.craveonline.com/videos/video/746619-canelo-alvarez-talks-about-mayweather-showdown",
+ u"file": u"746619.mp4",
+ u"md5": u"7c46b4057d22de32e0a539f017e64ad3",
+ u"info_dict": {
+ u"title": u"Canelo Alvarez talks about Mayweather showdown",
+ u"description": u"Saul \\\"Canelo\\\" Alvarez spoke to the media about his Sept. 14 showdown with Floyd Mayweather after their kick-off presser in NYC. Canelo is motivated and confident that he will have the speed and gameplan to beat the pound-for-pound king."
+ }
+ }
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ video_id = mobj.group(1).split('-')[0]
+ webpage = self._download_webpage(url, video_id)
+ title = self._search_regex(r'<title>(.+?)</title>',
+ webpage, 'video title').replace(' | RingTV','')
+ description = self._search_regex(r'<div class="blurb">(.+?)</div>',
+ webpage, 'Description')
+ final_url = "http://ringtv.craveonline.springboardplatform.com/storage/ringtv.craveonline.com/conversion/%s.mp4" %(str(video_id))
+ thumbnail_url = "http://ringtv.craveonline.springboardplatform.com/storage/ringtv.craveonline.com/snapshots/%s.jpg" %(str(video_id))
+ ext = final_url.split('.')[-1]
+ return [{
+ 'id' : video_id,
+ 'url' : final_url,
+ 'ext' : ext,
+ 'title' : title,
+ 'thumbnail' : thumbnail_url,
+ 'description' : description,
+ }]
+
of the stream token and uid
"""
- _VALID_URL = r'^(?:https?://)?(?:www\.)?soundcloud\.com/([\w\d-]+)/([\w\d-]+)'
+ _VALID_URL = r'^(?:https?://)?(?:www\.)?soundcloud\.com/([\w\d-]+)/([\w\d-]+)(?:[?].*)?$'
IE_NAME = u'soundcloud'
+ _TEST = {
+ u'url': u'http://soundcloud.com/ethmusic/lostin-powers-she-so-heavy',
+ u'file': u'62986583.mp3',
+ u'md5': u'ebef0a451b909710ed1d7787dddbf0d7',
+ u'info_dict': {
+ u"upload_date": u"20121011",
+ u"description": u"No Downloads untill we record the finished version this weekend, i was too pumped n i had to post it , earl is prolly gonna b hella p.o'd",
+ u"uploader": u"E.T. ExTerrestrial Music",
+ u"title": u"Lostin Powers - She so Heavy (SneakPreview) Adrian Ackers Blueprint 1"
+ }
+ }
def report_resolve(self, video_id):
"""Report information extraction."""
of the stream token and uid
"""
- _VALID_URL = r'^(?:https?://)?(?:www\.)?soundcloud\.com/([\w\d-]+)/sets/([\w\d-]+)'
+ _VALID_URL = r'^(?:https?://)?(?:www\.)?soundcloud\.com/([\w\d-]+)/sets/([\w\d-]+)(?:[?].*)?$'
IE_NAME = u'soundcloud:set'
+ _TEST = {
+ u"url":"https://soundcloud.com/the-concept-band/sets/the-royal-concept-ep",
+ u"playlist": [
+ {
+ u"file":"30510138.mp3",
+ u"md5":"f9136bf103901728f29e419d2c70f55d",
+ u"info_dict": {
+ u"upload_date": u"20111213",
+ u"description": u"The Royal Concept from Stockholm\r\nFilip / Povel / David / Magnus\r\nwww.royalconceptband.com",
+ u"uploader": u"The Royal Concept",
+ u"title": u"D-D-Dance"
+ }
+ },
+ {
+ u"file":"47127625.mp3",
+ u"md5":"09b6758a018470570f8fd423c9453dd8",
+ u"info_dict": {
+ u"upload_date": u"20120521",
+ u"description": u"The Royal Concept from Stockholm\r\nFilip / Povel / David / Magnus\r\nwww.royalconceptband.com",
+ u"uploader": u"The Royal Concept",
+ u"title": u"The Royal Concept - Gimme Twice"
+ }
+ },
+ {
+ u"file":"47127627.mp3",
+ u"md5":"154abd4e418cea19c3b901f1e1306d9c",
+ u"info_dict": {
+ u"upload_date": u"20120521",
+ u"uploader": u"The Royal Concept",
+ u"title": u"Goldrushed"
+ }
+ },
+ {
+ u"file":"47127629.mp3",
+ u"md5":"2f5471edc79ad3f33a683153e96a79c1",
+ u"info_dict": {
+ u"upload_date": u"20120521",
+ u"description": u"The Royal Concept from Stockholm\r\nFilip / Povel / David / Magnus\r\nwww.royalconceptband.com",
+ u"uploader": u"The Royal Concept",
+ u"title": u"In the End"
+ }
+ },
+ {
+ u"file":"47127631.mp3",
+ u"md5":"f9ba87aa940af7213f98949254f1c6e2",
+ u"info_dict": {
+ u"upload_date": u"20120521",
+ u"description": u"The Royal Concept from Stockholm\r\nFilip / David / Povel / Magnus\r\nwww.theroyalconceptband.com",
+ u"uploader": u"The Royal Concept",
+ u"title": u"Knocked Up"
+ }
+ },
+ {
+ u"file":"75206121.mp3",
+ u"md5":"f9d1fe9406717e302980c30de4af9353",
+ u"info_dict": {
+ u"upload_date": u"20130116",
+ u"description": u"The unreleased track World on Fire premiered on the CW's hit show Arrow (8pm/7pm central). \r\nAs a gift to our fans we would like to offer you a free download of the track! ",
+ u"uploader": u"The Royal Concept",
+ u"title": u"World On Fire"
+ }
+ }
+ ]
+ }
def report_resolve(self, video_id):
"""Report information extraction."""
class SpiegelIE(InfoExtractor):
_VALID_URL = r'https?://(?:www\.)?spiegel\.de/video/[^/]*-(?P<videoID>[0-9]+)(?:\.html)?(?:#.*)?$'
+ _TEST = {
+ u'url': u'http://www.spiegel.de/video/vulkan-tungurahua-in-ecuador-ist-wieder-aktiv-video-1259285.html',
+ u'file': u'1259285.mp4',
+ u'md5': u'2c2754212136f35fb4b19767d242f66e',
+ u'info_dict': {
+ u"title": u"Vulkanausbruch in Ecuador: Der \"Feuerschlund\" ist wieder aktiv"
+ }
+ }
def _real_extract(self, url):
m = re.match(self._VALID_URL, url)
class StanfordOpenClassroomIE(InfoExtractor):
- """Information extractor for Stanford's Open ClassRoom"""
-
- _VALID_URL = r'^(?:https?://)?openclassroom.stanford.edu(?P<path>/?|(/MainFolder/(?:HomePage|CoursePage|VideoPage)\.php([?]course=(?P<course>[^&]+)(&video=(?P<video>[^&]+))?(&.*)?)?))$'
IE_NAME = u'stanfordoc'
+ IE_DESC = u'Stanford Open ClassRoom'
+ _VALID_URL = r'^(?:https?://)?openclassroom.stanford.edu(?P<path>/?|(/MainFolder/(?:HomePage|CoursePage|VideoPage)\.php([?]course=(?P<course>[^&]+)(&video=(?P<video>[^&]+))?(&.*)?)?))$'
+ _TEST = {
+ u'url': u'http://openclassroom.stanford.edu/MainFolder/VideoPage.php?course=PracticalUnix&video=intro-environment&speed=100',
+ u'file': u'PracticalUnix_intro-environment.mp4',
+ u'md5': u'544a9468546059d4e80d76265b0443b8',
+ u'info_dict': {
+ u"title": u"Intro Environment"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class StatigramIE(InfoExtractor):
_VALID_URL = r'(?:http://)?(?:www\.)?statigr\.am/p/([^/]+)'
+ _TEST = {
+ u'url': u'http://statigr.am/p/484091715184808010_284179915',
+ u'file': u'484091715184808010_284179915.mp4',
+ u'md5': u'deda4ff333abe2e118740321e992605b',
+ u'info_dict': {
+ u"uploader_id": u"videoseconds",
+ u"title": u"Instagram photo by @videoseconds"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
html_title = self._html_search_regex(
r'<title>(.+?)</title>',
webpage, u'title')
- title = html_title.rpartition(u' | Statigram')[0]
+ title = re.sub(r'(?: *\(Videos?\))? \| Statigram$', '', html_title)
uploader_id = self._html_search_regex(
r'@([^ ]+)', title, u'uploader name', fatal=False)
ext = 'mp4'
"""
_VIDEO_PAGE_TEMPLATE = 'http://store.steampowered.com/video/%s/'
_AGECHECK_TEMPLATE = 'http://store.steampowered.com/agecheck/video/%s/?snr=1_agecheck_agecheck__age-gate&ageDay=1&ageMonth=January&ageYear=1970'
+ _TEST = {
+ u"url": u"http://store.steampowered.com/video/105600/",
+ u"playlist": [
+ {
+ u"file": u"81300.flv",
+ u"md5": u"f870007cee7065d7c76b88f0a45ecc07",
+ u"info_dict": {
+ u"title": u"Terraria 1.1 Trailer"
+ }
+ },
+ {
+ u"file": u"80859.flv",
+ u"md5": u"61aaf31a5c5c3041afb58fb83cbb5751",
+ u"info_dict": {
+ u"title": u"Terraria Trailer"
+ }
+ }
+ ]
+ }
+
@classmethod
def suitable(cls, url):
class TeamcocoIE(InfoExtractor):
_VALID_URL = r'http://teamcoco\.com/video/(?P<url_title>.*)'
+ _TEST = {
+ u'url': u'http://teamcoco.com/video/louis-ck-interview-george-w-bush',
+ u'file': u'19705.mp4',
+ u'md5': u'27b6f7527da5acf534b15f21b032656e',
+ u'info_dict': {
+ u"description": u"Louis C.K. got starstruck by George W. Bush, so what? Part one.",
+ u"title": u"Louis C.K. Interview Pt. 1 11/3/11"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
(/lang/(.*?))? # The url may contain the language
/(?P<name>\w+) # Here goes the name and then ".html"
'''
+ _TEST = {
+ u'url': u'http://www.ted.com/talks/dan_dennett_on_our_consciousness.html',
+ u'file': u'102.mp4',
+ u'md5': u'2d76ee1576672e0bd8f187513267adf6',
+ u'info_dict': {
+ u"description": u"md5:c6fa72e6eedbd938c9caf6b2702f5922",
+ u"title": u"Dan Dennett: The illusion of consciousness"
+ }
+ }
@classmethod
def suitable(cls, url):
--- /dev/null
+# coding: utf-8
+
+import json
+import re
+
+from .common import InfoExtractor
+
+class TF1IE(InfoExtractor):
+ """
+ TF1 uses the wat.tv player, currently it can only download videos with the
+ html5 player enabled, it cannot download HD videos.
+ """
+ _VALID_URL = r'http://videos.tf1.fr/.*-(.*?).html'
+ _TEST = {
+ u'url': u'http://videos.tf1.fr/auto-moto/citroen-grand-c4-picasso-2013-presentation-officielle-8062060.html',
+ u'file': u'10635995.mp4',
+ u'md5': u'66789d3e91278d332f75e1feb7aea327',
+ u'info_dict': {
+ u'title': u'Citroën Grand C4 Picasso 2013 : présentation officielle',
+ u'description': u'Vidéo officielle du nouveau Citroën Grand C4 Picasso, lancé à l\'automne 2013.',
+ }
+ }
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ id = mobj.group(1)
+ webpage = self._download_webpage(url, id)
+ embed_url = self._html_search_regex(r'"(https://www.wat.tv/embedframe/.*?)"',
+ webpage, 'embed url')
+ embed_page = self._download_webpage(embed_url, id, u'Downloading embed player page')
+ wat_id = self._search_regex(r'UVID=(.*?)&', embed_page, 'wat id')
+ wat_info = self._download_webpage('http://www.wat.tv/interface/contentv3/%s' % wat_id, id, u'Downloading Wat info')
+ wat_info = json.loads(wat_info)['media']
+ wat_url = wat_info['url']
+ return self.url_result(wat_url, 'Wat')
--- /dev/null
+import re
+
+from .common import InfoExtractor
+
+
+class TrailerAddictIE(InfoExtractor):
+ _VALID_URL = r'(?:http://)?(?:www\.)?traileraddict\.com/trailer/([^/]+)/(?:trailer|feature-trailer)'
+ _TEST = {
+ u'url': u'http://www.traileraddict.com/trailer/prince-avalanche/trailer',
+ u'file': u'76184.mp4',
+ u'md5': u'41365557f3c8c397d091da510e73ceb4',
+ u'info_dict': {
+ u"title": u"Prince Avalanche Trailer",
+ u"description": u"Trailer for Prince Avalanche.Two highway road workers spend the summer of 1988 away from their city lives. The isolated landscape becomes a place of misadventure as the men find themselves at odds with each other and the women they left behind."
+ }
+ }
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ video_id = mobj.group(1)
+ webpage = self._download_webpage(url, video_id)
+
+ title = self._search_regex(r'<title>(.+?)</title>',
+ webpage, 'video title').replace(' - Trailer Addict','')
+ view_count = self._search_regex(r'Views: (.+?)<br />',
+ webpage, 'Views Count')
+ description = self._search_regex(r'<meta property="og:description" content="(.+?)" />',
+ webpage, 'video description')
+ video_id = self._search_regex(r'<meta property="og:video" content="(.+?)" />',
+ webpage, 'Video id').split('=')[1]
+
+ info_url = "http://www.traileraddict.com/fvar.php?tid=%s" %(str(video_id))
+ info_webpage = self._download_webpage(info_url, video_id , "Downloading the info webpage")
+
+ final_url = self._search_regex(r'&fileurl=(.+)',
+ info_webpage, 'Download url').replace('%3F','?')
+ thumbnail_url = self._search_regex(r'&image=(.+?)&',
+ info_webpage, 'thumbnail url')
+ ext = final_url.split('.')[-1].split('?')[0]
+
+ return [{
+ 'id' : video_id,
+ 'url' : final_url,
+ 'ext' : ext,
+ 'title' : title,
+ 'thumbnail' : thumbnail_url,
+ 'description' : description,
+ 'view_count' : view_count,
+ }]
class TudouIE(InfoExtractor):
_VALID_URL = r'(?:http://)?(?:www\.)?tudou\.com/(?:listplay|programs)/(?:view|(.+?))/(?:([^/]+)|([^/]+)\.html)'
+ _TEST = {
+ u'url': u'http://www.tudou.com/listplay/zzdE77v6Mmo/2xN2duXMxmw.html',
+ u'file': u'159447792.f4v',
+ u'md5': u'ad7c358a01541e926a1e413612c6b10a',
+ u'info_dict': {
+ u"title": u"\u5361\u9a6c\u4e54\u56fd\u8db3\u5f00\u5927\u811a\u957f\u4f20\u51b2\u540a\u96c6\u9526"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class TumblrIE(InfoExtractor):
_VALID_URL = r'http://(?P<blog_name>.*?)\.tumblr\.com/((post)|(video))/(?P<id>\d*)/(.*?)'
+ _TEST = {
+ u'url': u'http://tatianamaslanydaily.tumblr.com/post/54196191430/orphan-black-dvd-extra-behind-the-scenes',
+ u'file': u'54196191430.mp4',
+ u'md5': u'479bb068e5b16462f5176a6828829767',
+ u'info_dict': {
+ u"title": u"tatiana maslany news"
+ }
+ }
def _real_extract(self, url):
m_url = re.match(self._VALID_URL, url)
# The only place where you can get a title, it's not complete,
# but searching in other places doesn't work for all videos
- video_title = self._html_search_regex(r'<title>(?P<title>.*?)</title>',
+ video_title = self._html_search_regex(r'<title>(?P<title>.*?)(?: \| Tumblr)?</title>',
webpage, u'title', flags=re.DOTALL)
return [{'id': video_id,
--- /dev/null
+import base64
+import re
+
+from .common import InfoExtractor
+from ..utils import (
+ compat_parse_qs,
+)
+
+class TutvIE(InfoExtractor):
+ _VALID_URL=r'https?://(?:www\.)?tu\.tv/videos/(?P<id>[^/?]+)'
+ _TEST = {
+ u'url': u'http://tu.tv/videos/noah-en-pabellon-cuahutemoc',
+ u'file': u'2742556.flv',
+ u'md5': u'5eb766671f69b82e528dc1e7769c5cb2',
+ u'info_dict': {
+ u"title": u"Noah en pabellon cuahutemoc"
+ }
+ }
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ video_id = mobj.group('id')
+
+ webpage = self._download_webpage(url, video_id)
+ title = self._html_search_regex(
+ r'<meta property="og:title" content="(.*?)">', webpage, u'title')
+ internal_id = self._search_regex(r'codVideo=([0-9]+)', webpage, u'internal video ID')
+
+ data_url = u'http://tu.tv/flvurl.php?codVideo=' + str(internal_id)
+ data_content = self._download_webpage(data_url, video_id, note=u'Downloading video info')
+ data = compat_parse_qs(data_content)
+ video_url = base64.b64decode(data['kpt'][0]).decode('utf-8')
+ ext = video_url.partition(u'?')[0].rpartition(u'.')[2]
+
+ info = {
+ 'id': internal_id,
+ 'url': video_url,
+ 'ext': ext,
+ 'title': title,
+ }
+ return [info]
class UstreamIE(InfoExtractor):
_VALID_URL = r'https?://www\.ustream\.tv/recorded/(?P<videoID>\d+)'
IE_NAME = u'ustream'
+ _TEST = {
+ u'url': u'http://www.ustream.tv/recorded/20274954',
+ u'file': u'20274954.flv',
+ u'md5': u'088f151799e8f572f84eb62f17d73e5c',
+ u'info_dict': {
+ u"uploader": u"Young Americans for Liberty",
+ u"title": u"Young Americans for Liberty February 7, 2012 2:28 AM"
+ }
+ }
def _real_extract(self, url):
m = re.match(self._VALID_URL, url)
class Vbox7IE(InfoExtractor):
"""Information Extractor for Vbox7"""
_VALID_URL = r'(?:http://)?(?:www\.)?vbox7\.com/play:([^/]+)'
+ _TEST = {
+ u'url': u'http://vbox7.com/play:249bb972c2',
+ u'file': u'249bb972c2.flv',
+ u'md5': u'9c70d6d956f888bdc08c124acc120cfe',
+ u'info_dict': {
+ u"title": u"\u0421\u043c\u044f\u0445! \u0427\u0443\u0434\u043e - \u0447\u0438\u0441\u0442 \u0437\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u0438 - \u0421\u043a\u0440\u0438\u0442\u0430 \u043a\u0430\u043c\u0435\u0440\u0430"
+ }
+ }
def _real_extract(self,url):
mobj = re.match(self._VALID_URL, url)
(currently used by MTVIE)
"""
_VALID_URL = r'((http://www.vevo.com/watch/.*?/.*?/)|(vevo:))(?P<id>.*)$'
+ _TEST = {
+ u'url': u'http://www.vevo.com/watch/hurts/somebody-to-die-for/GB1101300280',
+ u'file': u'GB1101300280.mp4',
+ u'md5': u'06bea460acb744eab74a9d7dcb4bfd61',
+ u'info_dict': {
+ u"upload_date": u"20130624",
+ u"uploader": u"Hurts",
+ u"title": u"Somebody To Die For"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
"""Information extractor for vimeo.com."""
# _VALID_URL matches Vimeo URLs
- _VALID_URL = r'(?P<proto>https?://)?(?:(?:www|player)\.)?vimeo(?P<pro>pro)?\.com/(?:(?:(?:groups|album)/[^/]+)|(?:.*?)/)?(?P<direct_link>play_redirect_hls\?clip_id=)?(?:videos?/)?(?P<id>[0-9]+)'
+ _VALID_URL = r'(?P<proto>https?://)?(?:(?:www|player)\.)?vimeo(?P<pro>pro)?\.com/(?:(?:(?:groups|album)/[^/]+)|(?:.*?)/)?(?P<direct_link>play_redirect_hls\?clip_id=)?(?:videos?/)?(?P<id>[0-9]+)(?:[?].*)?$'
IE_NAME = u'vimeo'
+ _TEST = {
+ u'url': u'http://vimeo.com/56015672',
+ u'file': u'56015672.mp4',
+ u'md5': u'8879b6cc097e987f02484baf890129e5',
+ u'info_dict': {
+ u"upload_date": u"20121220",
+ u"description": u"This is a test case for youtube-dl.\nFor more information, see github.com/rg3/youtube-dl\nTest chars: \u2605 \" ' \u5e78 / \\ \u00e4 \u21ad \U0001d550",
+ u"uploader_id": u"user7108434",
+ u"uploader": u"Filippo Valsorda",
+ u"title": u"youtube-dl test video - \u2605 \" ' \u5e78 / \\ \u00e4 \u21ad \U0001d550"
+ }
+ }
def _verify_video_password(self, url, video_id, webpage):
password = self._downloader.params.get('videopassword', None)
class VineIE(InfoExtractor):
_VALID_URL = r'(?:https?://)?(?:www\.)?vine\.co/v/(?P<id>\w+)'
+ _TEST = {
+ u'url': u'https://vine.co/v/b9KOOWX7HUx',
+ u'file': u'b9KOOWX7HUx.mp4',
+ u'md5': u'2f36fed6235b16da96ce9b4dc890940d',
+ u'info_dict': {
+ u"uploader": u"Jack Dorsey",
+ u"title": u"Chicken."
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
--- /dev/null
+# coding: utf-8
+
+import json
+import re
+
+from .common import InfoExtractor
+
+from ..utils import (
+ compat_urllib_parse,
+ unified_strdate,
+)
+
+
+class WatIE(InfoExtractor):
+ _VALID_URL=r'http://www.wat.tv/.*-(?P<shortID>.*?)_.*?.html'
+ IE_NAME = 'wat.tv'
+ _TEST = {
+ u'url': u'http://www.wat.tv/video/world-war-philadelphia-vost-6bv55_2fjr7_.html',
+ u'file': u'10631273.mp4',
+ u'md5': u'0a4fe7870f31eaeabb5e25fd8da8414a',
+ u'info_dict': {
+ u'title': u'World War Z - Philadelphia VOST',
+ u'description': u'La menace est partout. Que se passe-t-il à Philadelphia ?\r\nWORLD WAR Z, avec Brad Pitt, au cinéma le 3 juillet.\r\nhttp://www.worldwarz.fr',
+ }
+ }
+
+ def download_video_info(self, real_id):
+ # 'contentv4' is used in the website, but it also returns the related
+ # videos, we don't need them
+ info = self._download_webpage('http://www.wat.tv/interface/contentv3/' + real_id, real_id, 'Downloading video info')
+ info = json.loads(info)
+ return info['media']
+
+
+ def _real_extract(self, url):
+ def real_id_for_chapter(chapter):
+ return chapter['tc_start'].split('-')[0]
+ mobj = re.match(self._VALID_URL, url)
+ short_id = mobj.group('shortID')
+ webpage = self._download_webpage(url, short_id)
+ real_id = self._search_regex(r'xtpage = ".*-(.*?)";', webpage, 'real id')
+
+ video_info = self.download_video_info(real_id)
+ chapters = video_info['chapters']
+ first_chapter = chapters[0]
+
+ if real_id_for_chapter(first_chapter) != real_id:
+ self.to_screen('Multipart video detected')
+ chapter_urls = []
+ for chapter in chapters:
+ chapter_id = real_id_for_chapter(chapter)
+ # Yes, when we this chapter is processed by WatIE,
+ # it will download the info again
+ chapter_info = self.download_video_info(chapter_id)
+ chapter_urls.append(chapter_info['url'])
+ entries = [self.url_result(chapter_url) for chapter_url in chapter_urls]
+ return self.playlist_result(entries, real_id, video_info['title'])
+
+ # Otherwise we can continue and extract just one part, we have to use
+ # the short id for getting the video url
+ player_data = compat_urllib_parse.urlencode({'shortVideoId': short_id,
+ 'html5': '1'})
+ player_info = self._download_webpage('http://www.wat.tv/player?' + player_data,
+ real_id, u'Downloading player info')
+ player = json.loads(player_info)['player']
+ html5_player = self._html_search_regex(r'iframe src="(.*?)"', player,
+ 'html5 player')
+ player_webpage = self._download_webpage(html5_player, real_id,
+ u'Downloading player webpage')
+
+ video_url = self._search_regex(r'urlhtml5 : "(.*?)"', player_webpage,
+ 'video url')
+ info = {'id': real_id,
+ 'url': video_url,
+ 'ext': 'mp4',
+ 'title': first_chapter['title'],
+ 'thumbnail': first_chapter['preview'],
+ 'description': first_chapter['description'],
+ 'view_count': video_info['views'],
+ }
+ if 'date_diffusion' in first_chapter:
+ info['upload_date'] = unified_strdate(first_chapter['date_diffusion'])
+
+ return info
class WimpIE(InfoExtractor):
_VALID_URL = r'(?:http://)?(?:www\.)?wimp\.com/([^/]+)/'
+ _TEST = {
+ u'url': u'http://www.wimp.com/deerfence/',
+ u'file': u'deerfence.flv',
+ u'md5': u'8b215e2e0168c6081a1cf84b2846a2b5',
+ u'info_dict': {
+ u"title": u"Watch Till End: Herd of deer jump over a fence."
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class WorldStarHipHopIE(InfoExtractor):
_VALID_URL = r'https?://(?:www|m)\.worldstar(?:candy|hiphop)\.com/videos/video\.php\?v=(?P<id>.*)'
- IE_NAME = u'WorldStarHipHop'
+ _TEST = {
+ "url": "http://www.worldstarhiphop.com/videos/video.php?v=wshh6a7q1ny0G34ZwuIO",
+ "file": "wshh6a7q1ny0G34ZwuIO.mp4",
+ "md5": "9d04de741161603bf7071bbf4e883186",
+ "info_dict": {
+ "title": "Video: KO Of The Week: MMA Fighter Gets Knocked Out By Swift Head Kick!"
+ }
+ }
+
def _real_extract(self, url):
m = re.match(self._VALID_URL, url)
class XHamsterIE(InfoExtractor):
"""Information Extractor for xHamster"""
_VALID_URL = r'(?:http://)?(?:www.)?xhamster\.com/movies/(?P<id>[0-9]+)/.*\.html'
+ _TEST = {
+ u'url': u'http://xhamster.com/movies/1509445/femaleagent_shy_beauty_takes_the_bait.html',
+ u'file': u'1509445.flv',
+ u'md5': u'9f48e0e8d58e3076bb236ff412ab62fa',
+ u'info_dict': {
+ u"upload_date": u"20121014",
+ u"uploader_id": u"Ruseful2011",
+ u"title": u"FemaleAgent Shy beauty takes the bait"
+ }
+ }
def _real_extract(self,url):
mobj = re.match(self._VALID_URL, url)
VIDEO_URL_RE = r'flv_url=(.*?)&'
VIDEO_TITLE_RE = r'<title>(.*?)\s+-\s+XNXX.COM'
VIDEO_THUMB_RE = r'url_bigthumb=(.*?)&'
+ _TEST = {
+ u'url': u'http://video.xnxx.com/video1135332/lida_naked_funny_actress_5_',
+ u'file': u'1135332.flv',
+ u'md5': u'0831677e2b4761795f68d417e0b7b445',
+ u'info_dict': {
+ u"title": u"lida \u00bb Naked Funny Actress (5)"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
class XVideosIE(InfoExtractor):
_VALID_URL = r'^(?:https?://)?(?:www\.)?xvideos\.com/video([0-9]+)(?:.*)'
+ _TEST = {
+ u'url': u'http://www.xvideos.com/video939581/funny_porns_by_s_-1',
+ u'file': u'939581.flv',
+ u'md5': u'1d0c835822f0a71a7bf011855db929d0',
+ u'info_dict': {
+ u"title": u"Funny Porns By >>>>S<<<<<< -1"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
)
class YahooIE(InfoExtractor):
- """Information extractor for screen.yahoo.com."""
+ IE_DESC = u'Yahoo screen'
_VALID_URL = r'http://screen\.yahoo\.com/.*?-(?P<id>\d*?)\.html'
+ _TEST = {
+ u'url': u'http://screen.yahoo.com/julian-smith-travis-legg-watch-214727115.html',
+ u'file': u'214727115.flv',
+ u'md5': u'2e717f169c1be93d84d3794a00d4a325',
+ u'info_dict': {
+ u"title": u"Julian Smith & Travis Legg Watch Julian Smith"
+ },
+ u'skip': u'Requires rtmpdump'
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
return info_dict
class YahooSearchIE(SearchInfoExtractor):
- """Information Extractor for Yahoo! Video search queries."""
-
+ IE_DESC = u'Yahoo screen search'
_MAX_RESULTS = 1000
IE_NAME = u'screen.yahoo:search'
_SEARCH_KEY = 'yvsearch'
class YouJizzIE(InfoExtractor):
_VALID_URL = r'^(?:https?://)?(?:\w+\.)?youjizz\.com/videos/(?P<videoid>[^.]+).html$'
+ _TEST = {
+ u'url': u'http://www.youjizz.com/videos/zeichentrick-1-2189178.html',
+ u'file': u'2189178.flv',
+ u'md5': u'07e15fa469ba384c7693fd246905547c',
+ u'info_dict': {
+ u"title": u"Zeichentrick 1"
+ }
+ }
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
+# coding: utf-8
+
import json
import math
import random
class YoukuIE(InfoExtractor):
_VALID_URL = r'(?:http://)?v\.youku\.com/v_show/id_(?P<ID>[A-Za-z0-9]+)\.html'
+ _TEST = {
+ u"url": u"http://v.youku.com/v_show/id_XNDgyMDQ2NTQw.html",
+ u"file": u"XNDgyMDQ2NTQw_part00.flv",
+ u"md5": u"ffe3f2e435663dc2d1eea34faeff5b5b",
+ u"params": { u"test": False },
+ u"info_dict": {
+ u"title": u"youtube-dl test video \"'/\\ä↭𝕐"
+ }
+ }
+
def _gen_sid(self):
nowTime = int(time.time() * 1000)
class YouPornIE(InfoExtractor):
_VALID_URL = r'^(?:https?://)?(?:\w+\.)?youporn\.com/watch/(?P<videoid>[0-9]+)/(?P<title>[^/]+)'
+ _TEST = {
+ u'url': u'http://www.youporn.com/watch/505835/sex-ed-is-it-safe-to-masturbate-daily/',
+ u'file': u'505835.mp4',
+ u'md5': u'c37ddbaaa39058c76a7e86c6813423c1',
+ u'info_dict': {
+ u"upload_date": u"20101221",
+ u"description": u"Love & Sex Answers: http://bit.ly/DanAndJenn -- Is It Unhealthy To Masturbate Daily?",
+ u"uploader": u"Ask Dan And Jennifer",
+ u"title": u"Sex Ed: Is It Safe To Masturbate Daily?"
+ }
+ }
def _print_formats(self, formats):
"""Print all available formats"""
class YoutubeIE(InfoExtractor):
- """Information extractor for youtube.com."""
-
+ IE_DESC = u'YouTube.com'
_VALID_URL = r"""^
(
(?:https?://)? # http(s):// (optional)
(?: # the various things that can precede the ID:
(?:(?:v|embed|e)/) # v/ or embed/ or e/
|(?: # or the v= param in all its forms
- (?:watch(?:_popup)?(?:\.php)?)? # preceding watch(_popup|.php) or nothing (like /?v=xxxx)
+ (?:watch|movie(?:_popup)?(?:\.php)?)? # preceding watch(_popup|.php) or nothing (like /?v=xxxx)
(?:\?|\#!?) # the params delimiter ? or # or #!
(?:.*?&)? # any other preceding param (like /?s=tuff&v=xxxx)
v=
'46': '1080x1920',
}
IE_NAME = u'youtube'
+ _TESTS = [
+ {
+ u"url": u"http://www.youtube.com/watch?v=BaW_jenozKc",
+ u"file": u"BaW_jenozKc.mp4",
+ u"info_dict": {
+ u"title": u"youtube-dl test video \"'/\\ä↭𝕐",
+ u"uploader": u"Philipp Hagemeister",
+ u"uploader_id": u"phihag",
+ u"upload_date": u"20121002",
+ u"description": u"test chars: \"'/\\ä↭𝕐\n\nThis is a test video for youtube-dl.\n\nFor more information, contact phihag@phihag.de ."
+ }
+ },
+ {
+ u"url": u"http://www.youtube.com/watch?v=1ltcDfZMA3U",
+ u"file": u"1ltcDfZMA3U.flv",
+ u"note": u"Test VEVO video (#897)",
+ u"info_dict": {
+ u"upload_date": u"20070518",
+ u"title": u"Maps - It Will Find You",
+ u"description": u"Music video by Maps performing It Will Find You.",
+ u"uploader": u"MuteUSA",
+ u"uploader_id": u"MuteUSA"
+ }
+ },
+ {
+ u"url": u"http://www.youtube.com/watch?v=UxxajLWwzqY",
+ u"file": u"UxxajLWwzqY.mp4",
+ u"note": u"Test generic use_cipher_signature video (#897)",
+ u"info_dict": {
+ u"upload_date": u"20120506",
+ u"title": u"Icona Pop - I Love It (feat. Charli XCX) [OFFICIAL VIDEO]",
+ u"description": u"md5:b085c9804f5ab69f4adea963a2dceb3c",
+ u"uploader": u"IconaPop",
+ u"uploader_id": u"IconaPop"
+ }
+ }
+ ]
+
@classmethod
def suitable(cls, url):
self.to_screen(u'RTMP download detected')
def _decrypt_signature(self, s):
- """Decrypt the key the two subkeys must have a length of 43"""
+ """Turn the encrypted s field into a working signature"""
if len(s) == 88:
return s[48] + s[81:67:-1] + s[82] + s[66:62:-1] + s[85] + s[61:48:-1] + s[67] + s[47:12:-1] + s[3] + s[11:3:-1] + s[2] + s[12]
return s[36] + s[79:67:-1] + s[81] + s[66:40:-1] + s[33] + s[39:36:-1] + s[40] + s[35] + s[0] + s[67] + s[32:0:-1] + s[34]
else:
- raise ExtractorError(u'Unable to decrypt signature, subkeys length %d not supported; retrying might work' % (len(s)))
+ raise ExtractorError(u'Unable to decrypt signature, key length %d not supported; retrying might work' % (len(s)))
def _get_available_subtitles(self, video_id):
self.report_video_subtitles_download(video_id)
return video_id
def _real_extract(self, url):
+ if re.match(r'(?:https?://)?[^/]+/watch\?feature=[a-z_]+$', url):
+ self._downloader.report_warning(u'Did you forget to quote the URL? Remember that & is a meta-character in most shells, so you want to put the URL in quotes, like youtube-dl \'http://www.youtube.com/watch?feature=foo&v=BaW_jenozKc\' (or simply youtube-dl BaW_jenozKc ).')
+
# Extract original video URL from URL with redirection, like age verification, using next_url parameter
mobj = re.search(self._NEXT_URL_RE, url)
if mobj:
break
if 'token' not in video_info:
if 'reason' in video_info:
- raise ExtractorError(u'YouTube said: %s' % video_info['reason'][0])
+ raise ExtractorError(u'YouTube said: %s' % video_info['reason'][0], expected=True)
else:
raise ExtractorError(u'"token" parameter not in video info for unknown reason')
if req_format is None or req_format == 'best':
video_url_list = [(existing_formats[0], url_map[existing_formats[0]])] # Best quality
elif req_format == 'worst':
- video_url_list = [(existing_formats[len(existing_formats)-1], url_map[existing_formats[len(existing_formats)-1]])] # worst quality
+ video_url_list = [(existing_formats[-1], url_map[existing_formats[-1]])] # worst quality
elif req_format in ('-1', 'all'):
video_url_list = [(f, url_map[f]) for f in existing_formats] # All formats
else:
return results
class YoutubePlaylistIE(InfoExtractor):
- """Information Extractor for YouTube playlists."""
-
+ IE_DESC = u'YouTube.com playlists'
_VALID_URL = r"""(?:
(?:https?://)?
(?:\w+\.)?
class YoutubeChannelIE(InfoExtractor):
- """Information Extractor for YouTube channels."""
-
+ IE_DESC = u'YouTube.com channels'
_VALID_URL = r"^(?:https?://)?(?:youtu\.be|(?:\w+\.)?youtube(?:-nocookie)?\.com)/channel/([0-9A-Za-z_-]+)"
_TEMPLATE_URL = 'http://www.youtube.com/channel/%s/videos?sort=da&flow=list&view=0&page=%s&gl=US&hl=en'
_MORE_PAGES_INDICATOR = 'yt-uix-load-more'
class YoutubeUserIE(InfoExtractor):
- """Information Extractor for YouTube users."""
-
+ IE_DESC = u'YouTube.com user videos (URL or "ytuser" keyword)'
_VALID_URL = r'(?:(?:(?:https?://)?(?:\w+\.)?youtube\.com/user/)|ytuser:)([A-Za-z0-9_-]+)'
_TEMPLATE_URL = 'http://gdata.youtube.com/feeds/api/users/%s'
_GDATA_PAGE_SIZE = 50
return [self.playlist_result(url_results, playlist_title = username)]
class YoutubeSearchIE(SearchInfoExtractor):
- """Information Extractor for YouTube search queries."""
+ IE_DESC = u'YouTube.com searches'
_API_URL = 'https://gdata.youtube.com/feeds/api/videos?q=%s&start-index=%i&max-results=50&v=2&alt=jsonc'
_MAX_RESULTS = 1000
IE_NAME = u'youtube:search'
video_ids = video_ids[:n]
videos = [self.url_result('http://www.youtube.com/watch?v=%s' % id, 'Youtube') for id in video_ids]
return self.playlist_result(videos, query)
+
+
+class YoutubeShowIE(InfoExtractor):
+ IE_DESC = u'YouTube.com (multi-season) shows'
+ _VALID_URL = r'https?://www\.youtube\.com/show/(.*)'
+ IE_NAME = u'youtube:show'
+
+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ show_name = mobj.group(1)
+ webpage = self._download_webpage(url, show_name, u'Downloading show webpage')
+ # There's one playlist for each season of the show
+ m_seasons = list(re.finditer(r'href="(/playlist\?list=.*?)"', webpage))
+ self.to_screen(u'%s: Found %s seasons' % (show_name, len(m_seasons)))
+ return [self.url_result('https://www.youtube.com' + season.group(1), 'YoutubePlaylist') for season in m_seasons]
if not isinstance(globals().get('__loader__'), zipimporter) and not hasattr(sys, "frozen"):
- to_screen(u'It looks like you installed youtube-dl with pip, setup.py or a tarball. Please use that to update.')
+ to_screen(u'It looks like you installed youtube-dl with a package manager, pip, setup.py or a tarball. Please use that to update.')
return
# Check if there is a new version
class ExtractorError(Exception):
"""Error during info extraction."""
- def __init__(self, msg, tb=None):
- """ tb, if given, is the original traceback (so that it can be printed out). """
-
- if not sys.exc_info()[0] in (compat_urllib_error.URLError, socket.timeout, UnavailableVideoError):
- msg = msg + u'; please report this issue on http://yt-dl.org/bug'
+ def __init__(self, msg, tb=None, expected=False):
+ """ tb, if given, is the original traceback (so that it can be printed out).
+ If expected is set, this is a normal error message and most likely not a bug in youtube-dl.
+ """
+
+ if sys.exc_info()[0] in (compat_urllib_error.URLError, socket.timeout, UnavailableVideoError):
+ expected = True
+ if not expected:
+ msg = msg + u'; please report this issue on https://yt-dl.org/bug . Be sure to call youtube-dl with the --verbose flag and include its complete output.'
super(ExtractorError, self).__init__(msg)
self.traceback = tb
-__version__ = '2013.06.34'
+__version__ = '2013.07.02'