Compare commits
14 Commits
2016.06.22
...
2016.06.23
Author | SHA1 | Date | |
---|---|---|---|
|
96f88e91b7 | ||
|
3331a4644d | ||
|
adf1921dc1 | ||
|
97674f0419 | ||
|
73843ae8ac | ||
|
f2bb8c036a | ||
|
75ca6bcee2 | ||
|
089657ed1f | ||
|
b5eab86c24 | ||
|
c8e3e0974b | ||
|
dfc8f46e1c | ||
|
c143ddce5d | ||
|
169d836feb | ||
|
6ae938b295 |
6
.github/ISSUE_TEMPLATE.md
vendored
6
.github/ISSUE_TEMPLATE.md
vendored
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2016.06.22*. If it's not read [this FAQ entry](https://github.com/rg3/youtube-dl/blob/master/README.md#how-do-i-update-youtube-dl) and update. Issues with outdated version will be rejected.
|
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2016.06.23*. If it's not read [this FAQ entry](https://github.com/rg3/youtube-dl/blob/master/README.md#how-do-i-update-youtube-dl) and update. Issues with outdated version will be rejected.
|
||||||
- [ ] I've **verified** and **I assure** that I'm running youtube-dl **2016.06.22**
|
- [ ] I've **verified** and **I assure** that I'm running youtube-dl **2016.06.23**
|
||||||
|
|
||||||
### Before submitting an *issue* make sure you have:
|
### Before submitting an *issue* make sure you have:
|
||||||
- [ ] At least skimmed through [README](https://github.com/rg3/youtube-dl/blob/master/README.md) and **most notably** [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections
|
- [ ] At least skimmed through [README](https://github.com/rg3/youtube-dl/blob/master/README.md) and **most notably** [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections
|
||||||
@@ -35,7 +35,7 @@ $ youtube-dl -v <your command line>
|
|||||||
[debug] User config: []
|
[debug] User config: []
|
||||||
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
||||||
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
||||||
[debug] youtube-dl version 2016.06.22
|
[debug] youtube-dl version 2016.06.23
|
||||||
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
||||||
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
||||||
[debug] Proxy map: {}
|
[debug] Proxy map: {}
|
||||||
|
@@ -14,15 +14,17 @@ if os.path.exists(lazy_extractors_filename):
|
|||||||
os.remove(lazy_extractors_filename)
|
os.remove(lazy_extractors_filename)
|
||||||
|
|
||||||
from youtube_dl.extractor import _ALL_CLASSES
|
from youtube_dl.extractor import _ALL_CLASSES
|
||||||
from youtube_dl.extractor.common import InfoExtractor
|
from youtube_dl.extractor.common import InfoExtractor, SearchInfoExtractor
|
||||||
|
|
||||||
with open('devscripts/lazy_load_template.py', 'rt') as f:
|
with open('devscripts/lazy_load_template.py', 'rt') as f:
|
||||||
module_template = f.read()
|
module_template = f.read()
|
||||||
|
|
||||||
module_contents = [module_template + '\n' + getsource(InfoExtractor.suitable)]
|
module_contents = [
|
||||||
|
module_template + '\n' + getsource(InfoExtractor.suitable) + '\n',
|
||||||
|
'class LazyLoadSearchExtractor(LazyLoadExtractor):\n pass\n']
|
||||||
|
|
||||||
ie_template = '''
|
ie_template = '''
|
||||||
class {name}(LazyLoadExtractor):
|
class {name}({bases}):
|
||||||
_VALID_URL = {valid_url!r}
|
_VALID_URL = {valid_url!r}
|
||||||
_module = '{module}'
|
_module = '{module}'
|
||||||
'''
|
'''
|
||||||
@@ -34,10 +36,20 @@ make_valid_template = '''
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_name(base):
|
||||||
|
if base is InfoExtractor:
|
||||||
|
return 'LazyLoadExtractor'
|
||||||
|
elif base is SearchInfoExtractor:
|
||||||
|
return 'LazyLoadSearchExtractor'
|
||||||
|
else:
|
||||||
|
return base.__name__
|
||||||
|
|
||||||
|
|
||||||
def build_lazy_ie(ie, name):
|
def build_lazy_ie(ie, name):
|
||||||
valid_url = getattr(ie, '_VALID_URL', None)
|
valid_url = getattr(ie, '_VALID_URL', None)
|
||||||
s = ie_template.format(
|
s = ie_template.format(
|
||||||
name=name,
|
name=name,
|
||||||
|
bases=', '.join(map(get_base_name, ie.__bases__)),
|
||||||
valid_url=valid_url,
|
valid_url=valid_url,
|
||||||
module=ie.__module__)
|
module=ie.__module__)
|
||||||
if ie.suitable.__func__ is not InfoExtractor.suitable.__func__:
|
if ie.suitable.__func__ is not InfoExtractor.suitable.__func__:
|
||||||
@@ -47,12 +59,35 @@ def build_lazy_ie(ie, name):
|
|||||||
s += make_valid_template.format(valid_url=ie._make_valid_url())
|
s += make_valid_template.format(valid_url=ie._make_valid_url())
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
# find the correct sorting and add the required base classes so that sublcasses
|
||||||
|
# can be correctly created
|
||||||
|
classes = _ALL_CLASSES[:-1]
|
||||||
|
ordered_cls = []
|
||||||
|
while classes:
|
||||||
|
for c in classes[:]:
|
||||||
|
bases = set(c.__bases__) - set((object, InfoExtractor, SearchInfoExtractor))
|
||||||
|
stop = False
|
||||||
|
for b in bases:
|
||||||
|
if b not in classes and b not in ordered_cls:
|
||||||
|
if b.__name__ == 'GenericIE':
|
||||||
|
exit()
|
||||||
|
classes.insert(0, b)
|
||||||
|
stop = True
|
||||||
|
if stop:
|
||||||
|
break
|
||||||
|
if all(b in ordered_cls for b in bases):
|
||||||
|
ordered_cls.append(c)
|
||||||
|
classes.remove(c)
|
||||||
|
break
|
||||||
|
ordered_cls.append(_ALL_CLASSES[-1])
|
||||||
|
|
||||||
names = []
|
names = []
|
||||||
for ie in list(sorted(_ALL_CLASSES[:-1], key=lambda cls: cls.ie_key())) + _ALL_CLASSES[-1:]:
|
for ie in ordered_cls:
|
||||||
name = ie.ie_key() + 'IE'
|
name = ie.__name__
|
||||||
src = build_lazy_ie(ie, name)
|
src = build_lazy_ie(ie, name)
|
||||||
module_contents.append(src)
|
module_contents.append(src)
|
||||||
names.append(name)
|
if ie in _ALL_CLASSES:
|
||||||
|
names.append(name)
|
||||||
|
|
||||||
module_contents.append(
|
module_contents.append(
|
||||||
'_ALL_CLASSES = [{0}]'.format(', '.join(names)))
|
'_ALL_CLASSES = [{0}]'.format(', '.join(names)))
|
||||||
|
@@ -146,7 +146,7 @@ class VimeoIE(VimeoBaseInfoExtractor):
|
|||||||
\.
|
\.
|
||||||
)?
|
)?
|
||||||
vimeo(?P<pro>pro)?\.com/
|
vimeo(?P<pro>pro)?\.com/
|
||||||
(?!channels/[^/?#]+/?(?:$|[?#])|[^/]+/review/|(?:album|ondemand)/)
|
(?!(?:channels|album)/[^/?#]+/?(?:$|[?#])|[^/]+/review/|ondemand/)
|
||||||
(?:.*?/)?
|
(?:.*?/)?
|
||||||
(?:
|
(?:
|
||||||
(?:
|
(?:
|
||||||
@@ -227,8 +227,6 @@ class VimeoIE(VimeoBaseInfoExtractor):
|
|||||||
{
|
{
|
||||||
'url': 'http://vimeo.com/channels/keypeele/75629013',
|
'url': 'http://vimeo.com/channels/keypeele/75629013',
|
||||||
'md5': '2f86a05afe9d7abc0b9126d229bbe15d',
|
'md5': '2f86a05afe9d7abc0b9126d229bbe15d',
|
||||||
'note': 'Video is freely available via original URL '
|
|
||||||
'and protected with password when accessed via http://vimeo.com/75629013',
|
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '75629013',
|
'id': '75629013',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
@@ -272,7 +270,7 @@ class VimeoIE(VimeoBaseInfoExtractor):
|
|||||||
{
|
{
|
||||||
# contains original format
|
# contains original format
|
||||||
'url': 'https://vimeo.com/33951933',
|
'url': 'https://vimeo.com/33951933',
|
||||||
'md5': '53c688fa95a55bf4b7293d37a89c5c53',
|
'md5': '2d9f5475e0537f013d0073e812ab89e6',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '33951933',
|
'id': '33951933',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
@@ -284,6 +282,29 @@ class VimeoIE(VimeoBaseInfoExtractor):
|
|||||||
'description': 'md5:ae23671e82d05415868f7ad1aec21147',
|
'description': 'md5:ae23671e82d05415868f7ad1aec21147',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
# only available via https://vimeo.com/channels/tributes/6213729 and
|
||||||
|
# not via https://vimeo.com/6213729
|
||||||
|
'url': 'https://vimeo.com/channels/tributes/6213729',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '6213729',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Vimeo Tribute: The Shining',
|
||||||
|
'uploader': 'Casey Donahue',
|
||||||
|
'uploader_url': 're:https?://(?:www\.)?vimeo\.com/caseydonahue',
|
||||||
|
'uploader_id': 'caseydonahue',
|
||||||
|
'upload_date': '20090821',
|
||||||
|
'description': 'md5:bdbf314014e58713e6e5b66eb252f4a6',
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
'expected_warnings': ['Unable to download JSON metadata'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'url': 'http://vimeo.com/moogaloop.swf?clip_id=2539741',
|
||||||
|
'only_matching': True,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'url': 'https://vimeo.com/109815029',
|
'url': 'https://vimeo.com/109815029',
|
||||||
'note': 'Video not completely processed, "failed" seed status',
|
'note': 'Video not completely processed, "failed" seed status',
|
||||||
@@ -293,6 +314,10 @@ class VimeoIE(VimeoBaseInfoExtractor):
|
|||||||
'url': 'https://vimeo.com/groups/travelhd/videos/22439234',
|
'url': 'https://vimeo.com/groups/travelhd/videos/22439234',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'url': 'https://vimeo.com/album/2632481/video/79010983',
|
||||||
|
'only_matching': True,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
# source file returns 403: Forbidden
|
# source file returns 403: Forbidden
|
||||||
'url': 'https://vimeo.com/7809605',
|
'url': 'https://vimeo.com/7809605',
|
||||||
@@ -369,7 +394,7 @@ class VimeoIE(VimeoBaseInfoExtractor):
|
|||||||
orig_url = url
|
orig_url = url
|
||||||
if mobj.group('pro') or mobj.group('player'):
|
if mobj.group('pro') or mobj.group('player'):
|
||||||
url = 'https://player.vimeo.com/video/' + video_id
|
url = 'https://player.vimeo.com/video/' + video_id
|
||||||
else:
|
elif any(p in url for p in ('play_redirect_hls', 'moogaloop.swf')):
|
||||||
url = 'https://vimeo.com/' + video_id
|
url = 'https://vimeo.com/' + video_id
|
||||||
|
|
||||||
# Retrieve video webpage to extract further information
|
# Retrieve video webpage to extract further information
|
||||||
@@ -630,8 +655,21 @@ class VimeoChannelIE(VimeoBaseInfoExtractor):
|
|||||||
webpage = self._login_list_password(page_url, list_id, webpage)
|
webpage = self._login_list_password(page_url, list_id, webpage)
|
||||||
yield self._extract_list_title(webpage)
|
yield self._extract_list_title(webpage)
|
||||||
|
|
||||||
for video_id in re.findall(r'id="clip_(\d+?)"', webpage):
|
# Try extracting href first since not all videos are available via
|
||||||
yield self.url_result('https://vimeo.com/%s' % video_id, 'Vimeo')
|
# short https://vimeo.com/id URL (e.g. https://vimeo.com/channels/tributes/6213729)
|
||||||
|
clips = re.findall(
|
||||||
|
r'id="clip_(\d+)"[^>]*>\s*<a[^>]+href="(/(?:[^/]+/)*\1)', webpage)
|
||||||
|
if clips:
|
||||||
|
for video_id, video_url in clips:
|
||||||
|
yield self.url_result(
|
||||||
|
compat_urlparse.urljoin(base_url, video_url),
|
||||||
|
VimeoIE.ie_key(), video_id=video_id)
|
||||||
|
# More relaxed fallback
|
||||||
|
else:
|
||||||
|
for video_id in re.findall(r'id=["\']clip_(\d+)', webpage):
|
||||||
|
yield self.url_result(
|
||||||
|
'https://vimeo.com/%s' % video_id,
|
||||||
|
VimeoIE.ie_key(), video_id=video_id)
|
||||||
|
|
||||||
if re.search(self._MORE_PAGES_INDICATOR, webpage, re.DOTALL) is None:
|
if re.search(self._MORE_PAGES_INDICATOR, webpage, re.DOTALL) is None:
|
||||||
break
|
break
|
||||||
@@ -668,7 +706,7 @@ class VimeoUserIE(VimeoChannelIE):
|
|||||||
|
|
||||||
class VimeoAlbumIE(VimeoChannelIE):
|
class VimeoAlbumIE(VimeoChannelIE):
|
||||||
IE_NAME = 'vimeo:album'
|
IE_NAME = 'vimeo:album'
|
||||||
_VALID_URL = r'https://vimeo\.com/album/(?P<id>\d+)'
|
_VALID_URL = r'https://vimeo\.com/album/(?P<id>\d+)(?:$|[?#]|/(?!video))'
|
||||||
_TITLE_RE = r'<header id="page_header">\n\s*<h1>(.*?)</h1>'
|
_TITLE_RE = r'<header id="page_header">\n\s*<h1>(.*?)</h1>'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://vimeo.com/album/2632481',
|
'url': 'https://vimeo.com/album/2632481',
|
||||||
@@ -688,6 +726,13 @@ class VimeoAlbumIE(VimeoChannelIE):
|
|||||||
'params': {
|
'params': {
|
||||||
'videopassword': 'youtube-dl',
|
'videopassword': 'youtube-dl',
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
'url': 'https://vimeo.com/album/2632481/sort:plays/format:thumbnail',
|
||||||
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
# TODO: respect page number
|
||||||
|
'url': 'https://vimeo.com/album/2632481/page:2/sort:plays/format:thumbnail',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def _page_url(self, base_url, pagenum):
|
def _page_url(self, base_url, pagenum):
|
||||||
|
@@ -24,6 +24,7 @@ class VineIE(InfoExtractor):
|
|||||||
'upload_date': '20130519',
|
'upload_date': '20130519',
|
||||||
'uploader': 'Jack Dorsey',
|
'uploader': 'Jack Dorsey',
|
||||||
'uploader_id': '76',
|
'uploader_id': '76',
|
||||||
|
'view_count': int,
|
||||||
'like_count': int,
|
'like_count': int,
|
||||||
'comment_count': int,
|
'comment_count': int,
|
||||||
'repost_count': int,
|
'repost_count': int,
|
||||||
@@ -39,6 +40,7 @@ class VineIE(InfoExtractor):
|
|||||||
'upload_date': '20140815',
|
'upload_date': '20140815',
|
||||||
'uploader': 'Mars Ruiz',
|
'uploader': 'Mars Ruiz',
|
||||||
'uploader_id': '1102363502380728320',
|
'uploader_id': '1102363502380728320',
|
||||||
|
'view_count': int,
|
||||||
'like_count': int,
|
'like_count': int,
|
||||||
'comment_count': int,
|
'comment_count': int,
|
||||||
'repost_count': int,
|
'repost_count': int,
|
||||||
@@ -54,6 +56,7 @@ class VineIE(InfoExtractor):
|
|||||||
'upload_date': '20130430',
|
'upload_date': '20130430',
|
||||||
'uploader': 'Z3k3',
|
'uploader': 'Z3k3',
|
||||||
'uploader_id': '936470460173008896',
|
'uploader_id': '936470460173008896',
|
||||||
|
'view_count': int,
|
||||||
'like_count': int,
|
'like_count': int,
|
||||||
'comment_count': int,
|
'comment_count': int,
|
||||||
'repost_count': int,
|
'repost_count': int,
|
||||||
@@ -71,6 +74,7 @@ class VineIE(InfoExtractor):
|
|||||||
'upload_date': '20150705',
|
'upload_date': '20150705',
|
||||||
'uploader': 'Pimry_zaa',
|
'uploader': 'Pimry_zaa',
|
||||||
'uploader_id': '1135760698325307392',
|
'uploader_id': '1135760698325307392',
|
||||||
|
'view_count': int,
|
||||||
'like_count': int,
|
'like_count': int,
|
||||||
'comment_count': int,
|
'comment_count': int,
|
||||||
'repost_count': int,
|
'repost_count': int,
|
||||||
@@ -109,6 +113,7 @@ class VineIE(InfoExtractor):
|
|||||||
'upload_date': unified_strdate(data.get('created')),
|
'upload_date': unified_strdate(data.get('created')),
|
||||||
'uploader': username,
|
'uploader': username,
|
||||||
'uploader_id': data.get('userIdStr'),
|
'uploader_id': data.get('userIdStr'),
|
||||||
|
'view_count': int_or_none(data.get('loops', {}).get('count')),
|
||||||
'like_count': int_or_none(data.get('likes', {}).get('count')),
|
'like_count': int_or_none(data.get('likes', {}).get('count')),
|
||||||
'comment_count': int_or_none(data.get('comments', {}).get('count')),
|
'comment_count': int_or_none(data.get('comments', {}).get('count')),
|
||||||
'repost_count': int_or_none(data.get('reposts', {}).get('count')),
|
'repost_count': int_or_none(data.get('reposts', {}).get('count')),
|
||||||
|
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..compat import compat_str
|
from ..compat import compat_str
|
||||||
@@ -10,7 +11,6 @@ from ..utils import (
|
|||||||
ExtractorError,
|
ExtractorError,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
orderedSet,
|
orderedSet,
|
||||||
sanitized_Request,
|
|
||||||
str_to_int,
|
str_to_int,
|
||||||
unescapeHTML,
|
unescapeHTML,
|
||||||
unified_strdate,
|
unified_strdate,
|
||||||
@@ -190,7 +190,7 @@ class VKIE(InfoExtractor):
|
|||||||
if username is None:
|
if username is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
login_page = self._download_webpage(
|
login_page, url_handle = self._download_webpage_handle(
|
||||||
'https://vk.com', None, 'Downloading login page')
|
'https://vk.com', None, 'Downloading login page')
|
||||||
|
|
||||||
login_form = self._hidden_inputs(login_page)
|
login_form = self._hidden_inputs(login_page)
|
||||||
@@ -200,11 +200,26 @@ class VKIE(InfoExtractor):
|
|||||||
'pass': password.encode('cp1251'),
|
'pass': password.encode('cp1251'),
|
||||||
})
|
})
|
||||||
|
|
||||||
request = sanitized_Request(
|
# https://new.vk.com/ serves two same remixlhk cookies in Set-Cookie header
|
||||||
'https://login.vk.com/?act=login',
|
# and expects the first one to be set rather than second (see
|
||||||
urlencode_postdata(login_form))
|
# https://github.com/rg3/youtube-dl/issues/9841#issuecomment-227871201).
|
||||||
|
# As of RFC6265 the newer one cookie should be set into cookie store
|
||||||
|
# what actually happens.
|
||||||
|
# We will workaround this VK issue by resetting the remixlhk cookie to
|
||||||
|
# the first one manually.
|
||||||
|
cookies = url_handle.headers.get('Set-Cookie')
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
cookies = cookies.encode('iso-8859-1')
|
||||||
|
cookies = cookies.decode('utf-8')
|
||||||
|
remixlhk = re.search(r'remixlhk=(.+?);.*?\bdomain=(.+?)(?:[,;]|$)', cookies)
|
||||||
|
if remixlhk:
|
||||||
|
value, domain = remixlhk.groups()
|
||||||
|
self._set_cookie(domain, 'remixlhk', value)
|
||||||
|
|
||||||
login_page = self._download_webpage(
|
login_page = self._download_webpage(
|
||||||
request, None, note='Logging in as %s' % username)
|
'https://login.vk.com/?act=login', None,
|
||||||
|
note='Logging in as %s' % username,
|
||||||
|
data=urlencode_postdata(login_form))
|
||||||
|
|
||||||
if re.search(r'onLoginFailed', login_page):
|
if re.search(r'onLoginFailed', login_page):
|
||||||
raise ExtractorError(
|
raise ExtractorError(
|
||||||
|
@@ -6,17 +6,23 @@ from ..compat import compat_urllib_parse_unquote
|
|||||||
|
|
||||||
|
|
||||||
class XNXXIE(InfoExtractor):
|
class XNXXIE(InfoExtractor):
|
||||||
_VALID_URL = r'^https?://(?:video|www)\.xnxx\.com/video(?P<id>[0-9]+)/(.*)'
|
_VALID_URL = r'https?://(?:video|www)\.xnxx\.com/video-?(?P<id>[0-9a-z]+)/'
|
||||||
_TEST = {
|
_TESTS = [{
|
||||||
'url': 'http://video.xnxx.com/video1135332/lida_naked_funny_actress_5_',
|
'url': 'http://www.xnxx.com/video-55awb78/skyrim_test_video',
|
||||||
'md5': '0831677e2b4761795f68d417e0b7b445',
|
'md5': 'ef7ecee5af78f8b03dca2cf31341d3a0',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '1135332',
|
'id': '55awb78',
|
||||||
'ext': 'flv',
|
'ext': 'flv',
|
||||||
'title': 'lida » Naked Funny Actress (5)',
|
'title': 'Skyrim Test Video',
|
||||||
'age_limit': 18,
|
'age_limit': 18,
|
||||||
}
|
},
|
||||||
}
|
}, {
|
||||||
|
'url': 'http://video.xnxx.com/video1135332/lida_naked_funny_actress_5_',
|
||||||
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
'url': 'http://www.xnxx.com/video-55awb78/',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
video_id = self._match_id(url)
|
video_id = self._match_id(url)
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__version__ = '2016.06.22'
|
__version__ = '2016.06.23'
|
||||||
|
Reference in New Issue
Block a user