Compare commits

..

22 Commits

Author SHA1 Message Date
Philipp Hagemeister
81b42336ad release 2013.06.33 2013-06-25 22:42:02 +02:00
Jaime Marquínez Ferrándiz
c6c1974672 Add "--video-password" option (related #889)
Used only for accessing a private video

Restore the error when the account is missing
2013-06-25 22:22:32 +02:00
Jaime Marquínez Ferrándiz
a545d1d262 Merge pull request #922 from JohnyMoSwag/master
Added embedded youtube detection to WorldstarIE
2013-06-25 22:08:58 +02:00
Jaime Marquínez Ferrándiz
037fcd0047 JukeboxIE: support more countries 2013-06-25 22:04:44 +02:00
Philipp Hagemeister
318452bc0c Sort IEs alphabetically 2013-06-25 21:11:57 +02:00
Philipp Hagemeister
d746cd88c2 Merge remote-tracking branch 'yasoob/master' 2013-06-25 21:09:15 +02:00
Philipp Hagemeister
9c42603b5a release 2013.06.32 2013-06-25 20:55:47 +02:00
Philipp Hagemeister
ea93cce4f6 Directly call update_latest 2013-06-25 20:50:54 +02:00
M.Yasoob Khalid
f4daa18152 added test for tudou.com 2013-06-25 22:52:21 +05:00
M.Yasoob Khalid
9caa687d81 Added an IE for todou 2013-06-25 22:48:08 +05:00
Philipp Hagemeister
3b58c6fb54 Update latest files on release 2013-06-25 18:48:57 +02:00
Philipp Hagemeister
5926c10690 release 2013.06.31 2013-06-25 18:40:58 +02:00
Philipp Hagemeister
df725153d2 Credit mc2avr for JukeboxIE (#924) 2013-06-25 17:57:47 +02:00
Philipp Hagemeister
d662896090 [googleplus] Adapt to new detail URL format 2013-06-25 17:52:32 +02:00
Philipp Hagemeister
db241e8645 Add encoding to jukebox IE and simplify it a little bit 2013-06-25 17:16:38 +02:00
Philipp Hagemeister
ead28ff30a Make upload atomic (#925) 2013-06-25 17:14:25 +02:00
Philipp Hagemeister
515d7a5e73 Add Jukebox IE 2013-06-25 17:12:35 +02:00
mc2avr
14fbdc9cdd [jukebox] call YoutubeIE if necessary 2013-06-25 16:51:09 +02:00
Filippo Valsorda
98bcd2834a improve generic and encrypted signature error messages 2013-06-25 16:47:16 +02:00
Filippo Valsorda
f7ab6cbe16 add tests for use_cipher_signature videos (#897) and the ability to test multiple videos per IE 2013-06-25 14:38:00 +02:00
mc2avr
28ef06f7c2 add JukeboxIE 2013-06-25 13:28:59 +02:00
Johny Mo Swag
d18596baf4 added Youtube embed detection to WorldstarIE 2013-06-24 18:58:49 -07:00
16 changed files with 164 additions and 17 deletions

View File

@@ -130,6 +130,7 @@ which means you can modify it, redistribute it or use it however you like.
-u, --username USERNAME account username
-p, --password PASSWORD account password
-n, --netrc use .netrc authentication data
--video-password PASSWORD video password (vimeo only)
## Post-processing Options:
-x, --extract-audio convert video files to audio-only files (requires

View File

@@ -69,7 +69,9 @@ git checkout HEAD -- youtube-dl youtube-dl.exe
/bin/echo -e "\n### Signing and uploading the new binaries to youtube-dl.org..."
for f in $RELEASE_FILES; do gpg --detach-sig "build/$version/$f"; done
scp -r "build/$version" ytdl@youtube-dl.org:html/downloads/
scp -r "build/$version" ytdl@yt-dl.org:html/tmp/
ssh ytdl@yt-dl.org "mv html/tmp/$version html/downloads/"
ssh ytdl@yt-dl.org "sh html/update_latest.sh $version"
/bin/echo -e "\n### Now switching to gh-pages..."
git clone --branch gh-pages --single-branch . build/gh-pages

View File

@@ -153,9 +153,11 @@ def generator(test_case):
return test_template
### And add them to TestDownload
for test_case in defs:
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)
setattr(TestDownload, test_method.__name__, test_method)
del test_method

View File

@@ -11,6 +11,32 @@
"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",
@@ -660,5 +686,14 @@
"upload_date": "20130624",
"uploader": "Hurts"
}
},
{
"name": "Tudou",
"url": "http://www.tudou.com/listplay/zzdE77v6Mmo/2xN2duXMxmw.html",
"file": "159447792.f4v",
"md5": "ad7c358a01541e926a1e413612c6b10a",
"info_dict": {
"title": "卡马乔国足开大脚长传冲吊集锦"
}
}
]

View File

@@ -46,6 +46,7 @@ class YoutubeDL(object):
username: Username for authentication purposes.
password: Password for authentication purposes.
videopassword: Password for acces a video.
usenetrc: Use netrc for authentication instead.
verbose: Print additional info to stdout.
quiet: Do not print messages to stdout.

View File

@@ -25,6 +25,7 @@ __authors__ = (
'M. Yasoob Ullah Khalid',
'Julien Fraichard',
'Johny Mo Swag',
'Axel Noack',
)
__license__ = 'Public Domain'
@@ -172,6 +173,8 @@ def parseOpts(overrideArguments=None):
dest='password', metavar='PASSWORD', help='account password')
authentication.add_option('-n', '--netrc',
action='store_true', dest='usenetrc', help='use .netrc authentication data', default=False)
authentication.add_option('--video-password',
dest='videopassword', metavar='PASSWORD', help='video password (vimeo only)')
video_format.add_option('-f', '--format',
@@ -421,7 +424,7 @@ def _real_main(argv=None):
if opts.usenetrc and (opts.username is not None or opts.password is not None):
parser.error(u'using .netrc conflicts with giving username/password')
if opts.password is not None and opts.username is None:
sys.stderr.write(u'WARNING: account username missing\n')
parser.error(u' account username missing\n')
if opts.outtmpl is not None and (opts.usetitle or opts.autonumber or opts.useid):
parser.error(u'using output template conflicts with using title, video ID or auto number')
if opts.usetitle and opts.useid:
@@ -498,6 +501,7 @@ def _real_main(argv=None):
'usenetrc': opts.usenetrc,
'username': opts.username,
'password': opts.password,
'videopassword': opts.videopassword,
'quiet': (opts.quiet or opts.geturl or opts.gettitle or opts.getid or opts.getthumbnail or opts.getdescription or opts.getfilename or opts.getformat),
'forceurl': opts.geturl,
'forcetitle': opts.gettitle,

View File

@@ -4,8 +4,8 @@ from .arte import ArteTvIE
from .bandcamp import BandcampIE
from .bliptv import BlipTVIE, BlipTVUserIE
from .breakcom import BreakIE
from .comedycentral import ComedyCentralIE
from .collegehumor import CollegeHumorIE
from .comedycentral import ComedyCentralIE
from .dailymotion import DailymotionIE
from .depositfiles import DepositFilesIE
from .eighttracks import EightTracksIE
@@ -21,6 +21,7 @@ from .howcast import HowcastIE
from .hypem import HypemIE
from .ina import InaIE
from .infoq import InfoQIE
from .jukebox import JukeboxIE
from .justintv import JustinTVIE
from .keek import KeekIE
from .liveleak import LiveLeakIE
@@ -30,7 +31,6 @@ from .mtv import MTVIE
from .myspass import MySpassIE
from .myvideo import MyVideoIE
from .nba import NBAIE
from .statigram import StatigramIE
from .photobucket import PhotobucketIE
from .pornotube import PornotubeIE
from .rbmaradio import RBMARadioIE
@@ -38,9 +38,11 @@ from .redtube import RedTubeIE
from .soundcloud import SoundcloudIE, SoundcloudSetIE
from .spiegel import SpiegelIE
from .stanfordoc import StanfordOpenClassroomIE
from .statigram import StatigramIE
from .steam import SteamIE
from .teamcoco import TeamcocoIE
from .ted import TEDIE
from .tudou import TudouIE
from .tumblr import TumblrIE
from .ustream import UstreamIE
from .vbox7 import Vbox7IE
@@ -48,8 +50,8 @@ from .vevo import VevoIE
from .vimeo import VimeoIE
from .vine import VineIE
from .worldstarhiphop import WorldStarHipHopIE
from .xnxx import XNXXIE
from .xhamster import XHamsterIE
from .xnxx import XNXXIE
from .xvideos import XVideosIE
from .yahoo import YahooIE, YahooSearchIE
from .youjizz import YouJizzIE
@@ -58,6 +60,7 @@ from .youporn import YouPornIE
from .youtube import YoutubeIE, YoutubePlaylistIE, YoutubeSearchIE, YoutubeUserIE, YoutubeChannelIE
from .zdf import ZDFIE
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.
@@ -127,6 +130,8 @@ def gen_extractors():
StatigramIE(),
BreakIE(),
VevoIE(),
JukeboxIE(),
TudouIE(),
GenericIE()
]

View File

@@ -211,7 +211,7 @@ class InfoExtractor(object):
raise ExtractorError(u'Unable to extract %s' % _name)
else:
self._downloader.report_warning(u'unable to extract %s; '
u'please report this issue on GitHub.' % _name)
u'please report this issue on http://yt-dl.org/bug' % _name)
return None
def _html_search_regex(self, pattern, string, name, default=None, fatal=True, flags=0):

View File

@@ -46,14 +46,18 @@ class GooglePlusIE(InfoExtractor):
video_title = self._html_search_regex(r'<meta name\=\"Description\" content\=\"(.*?)[\n<"]',
webpage, 'title', default=u'NA')
# Step 2, Stimulate clicking the image box to launch video
video_page = self._search_regex('"(https\://plus\.google\.com/photos/.*?)",,"image/jpeg","video"\]',
# Step 2, Simulate clicking the image box to launch video
DOMAIN = 'https://plus.google.com'
video_page = self._search_regex(r'<a href="((?:%s)?/photos/.*?)"' % re.escape(DOMAIN),
webpage, u'video page URL')
if not video_page.startswith(DOMAIN):
video_page = DOMAIN + video_page
webpage = self._download_webpage(video_page, video_id, u'Downloading video page')
# Extract video links on video page
"""Extract video links of all sizes"""
pattern = '\d+,\d+,(\d+),"(http\://redirector\.googlevideo\.com.*?)"'
pattern = r'\d+,\d+,(\d+),"(http\://redirector\.googlevideo\.com.*?)"'
mobj = re.findall(pattern, webpage)
if len(mobj) == 0:
raise ExtractorError(u'Unable to extract video links')

View File

@@ -0,0 +1,56 @@
# coding: utf-8
import re
from .common import InfoExtractor
from ..utils import (
ExtractorError,
unescapeHTML,
)
class JukeboxIE(InfoExtractor):
_VALID_URL = r'^http://www\.jukebox?\..+?\/.+[,](?P<video_id>[a-z0-9\-]+).html'
_IFRAME = r'<iframe .*src="(?P<iframe>[^"]*)".*>'
_VIDEO_URL = r'"config":{"file":"(?P<video_url>http:[^"]+[.](?P<video_ext>[^.?]+)[?]mdtk=[0-9]+)"'
_TITLE = r'<h1 class="inline">(?P<title>[^<]+)</h1>.*<span id="infos_article_artist">(?P<artist>[^<]+)</span>'
_IS_YOUTUBE = r'config":{"file":"(?P<youtube_url>http:[\\][/][\\][/]www[.]youtube[.]com[\\][/]watch[?]v=[^"]+)"'
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
video_id = mobj.group('video_id')
html = self._download_webpage(url, video_id)
mobj = re.search(self._IFRAME, html)
if mobj is None:
raise ExtractorError(u'Cannot extract iframe url')
iframe_url = unescapeHTML(mobj.group('iframe'))
iframe_html = self._download_webpage(iframe_url, video_id, 'Downloading iframe')
mobj = re.search(r'class="jkb_waiting"', iframe_html)
if mobj is not None:
raise ExtractorError(u'Video is not available(in your country?)!')
self.report_extraction(video_id)
mobj = re.search(self._VIDEO_URL, iframe_html)
if mobj is None:
mobj = re.search(self._IS_YOUTUBE, iframe_html)
if mobj is None:
raise ExtractorError(u'Cannot extract video url')
youtube_url = unescapeHTML(mobj.group('youtube_url')).replace('\/','/')
self.to_screen(u'Youtube video detected')
return self.url_result(youtube_url,ie='Youtube')
video_url = unescapeHTML(mobj.group('video_url')).replace('\/','/')
video_ext = unescapeHTML(mobj.group('video_ext'))
mobj = re.search(self._TITLE, html)
if mobj is None:
raise ExtractorError(u'Cannot extract title')
title = unescapeHTML(mobj.group('title'))
artist = unescapeHTML(mobj.group('artist'))
return [{'id': video_id,
'url': video_url,
'title': artist + '-' + title,
'ext': video_ext
}]

View File

@@ -0,0 +1,32 @@
import re
from .common import InfoExtractor
class TudouIE(InfoExtractor):
_VALID_URL = r'(?:http://)?(?:www\.)?tudou\.com/(?:listplay|programs)/(?:view|(.+?))/(?:([^/]+)|([^/]+)\.html)'
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
video_id = mobj.group(2).replace('.html','')
webpage = self._download_webpage(url, video_id)
video_id = re.search('"k":(.+?),',webpage).group(1)
title = re.search(",kw:\"(.+)\"",webpage)
if title is None:
title = re.search(",kw: \'(.+)\'",webpage)
title = title.group(1)
thumbnail_url = re.search(",pic: \'(.+?)\'",webpage)
if thumbnail_url is None:
thumbnail_url = re.search(",pic:\"(.+?)\"",webpage)
thumbnail_url = thumbnail_url.group(1)
info_url = "http://v2.tudou.com/f?id="+str(video_id)
webpage = self._download_webpage(info_url, video_id, "Opening the info webpage")
final_url = re.search('\>(.+?)\<\/f\>',webpage).group(1)
ext = (final_url.split('?')[0]).split('.')[-1]
return [{
'id': video_id,
'url': final_url,
'ext': ext,
'title': title,
'thumbnail': thumbnail_url,
}]

View File

@@ -20,9 +20,9 @@ class VimeoIE(InfoExtractor):
IE_NAME = u'vimeo'
def _verify_video_password(self, url, video_id, webpage):
password = self._downloader.params.get('password', None)
password = self._downloader.params.get('videopassword', None)
if password is None:
raise ExtractorError(u'This video is protected by a password, use the --password option')
raise ExtractorError(u'This video is protected by a password, use the --video-password option')
token = re.search(r'xsrft: \'(.*?)\'', webpage).group(1)
data = compat_urllib_parse.urlencode({'password': password,
'token': token})

View File

@@ -16,6 +16,10 @@ class WorldStarHipHopIE(InfoExtractor):
video_url = self._search_regex(r'so\.addVariable\("file","(.*?)"\)',
webpage_src, u'video URL')
if 'youtube' in video_url:
self.to_screen(u'Youtube video detected:')
return self.url_result(video_url, ie='Youtube')
if 'mp4' in video_url:
ext = 'mp4'
else:

View File

@@ -129,12 +129,13 @@ class YoutubeIE(InfoExtractor):
"""Indicate the download will use the RTMP protocol."""
self.to_screen(u'RTMP download detected')
@staticmethod
def _decrypt_signature(s):
def _decrypt_signature(self, s):
"""Decrypt the key the two subkeys must have a length of 43"""
(a,b) = s.split('.')
if len(a) != 43 or len(b) != 43:
raise ExtractorError(u'Unable to decrypt signature, subkeys lengths not valid')
raise ExtractorError(u'Unable to decrypt signature, subkeys lengths %d.%d not supported; retrying might work' % (len(a), len(b)))
if self._downloader.params.get('verbose'):
self.to_screen('encrypted signature length %d.%d' % (len(a), len(b)))
b = ''.join([b[:8],a[0],b[9:18],b[-4],b[19:39], b[18]])[0:40]
a = a[-40:]
s_dec = '.'.join((a,b))[::-1]

View File

@@ -474,7 +474,7 @@ class ExtractorError(Exception):
""" 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 GitHub.'
msg = msg + u'; please report this issue on http://yt-dl.org/bug'
super(ExtractorError, self).__init__(msg)
self.traceback = tb

View File

@@ -1,2 +1,2 @@
__version__ = '2013.06.30'
__version__ = '2013.06.33'