Merge remote-tracking branch 'upstream/master'

This commit is contained in:
rupertbaxter2 2014-08-08 07:14:54 -07:00
commit 04b89c9026
4 changed files with 122 additions and 47 deletions

View file

@ -384,6 +384,7 @@ from .wistia import WistiaIE
from .worldstarhiphop import WorldStarHipHopIE from .worldstarhiphop import WorldStarHipHopIE
from .wrzuta import WrzutaIE from .wrzuta import WrzutaIE
from .xbef import XBefIE from .xbef import XBefIE
from .xboxclips import XboxClipsIE
from .xhamster import XHamsterIE from .xhamster import XHamsterIE
from .xnxx import XNXXIE from .xnxx import XNXXIE
from .xvideos import XVideosIE from .xvideos import XVideosIE

View file

@ -1,3 +1,4 @@
# encoding: utf-8
from __future__ import unicode_literals from __future__ import unicode_literals
import re import re
@ -8,19 +9,34 @@ from ..utils import ExtractorError
class NownessIE(InfoExtractor): class NownessIE(InfoExtractor):
_VALID_URL = r'https?://(?:www\.)?nowness\.com/[^?#]*?/(?P<id>[0-9]+)/(?P<slug>[^/]+?)(?:$|[?#])' _VALID_URL = r'https?://(?:(?:www|cn)\.)?nowness\.com/[^?#]*?/(?P<id>[0-9]+)/(?P<slug>[^/]+?)(?:$|[?#])'
_TEST = { _TESTS = [
'url': 'http://www.nowness.com/day/2013/6/27/3131/candor--the-art-of-gesticulation', {
'md5': '068bc0202558c2e391924cb8cc470676', 'url': 'http://www.nowness.com/day/2013/6/27/3131/candor--the-art-of-gesticulation',
'info_dict': { 'md5': '068bc0202558c2e391924cb8cc470676',
'id': '2520295746001', 'info_dict': {
'ext': 'mp4', 'id': '2520295746001',
'description': 'Candor: The Art of Gesticulation', 'ext': 'mp4',
'uploader': 'Nowness', 'title': 'Candor: The Art of Gesticulation',
'title': 'Candor: The Art of Gesticulation', 'description': 'Candor: The Art of Gesticulation',
} 'thumbnail': 're:^https?://.*\.jpg',
} 'uploader': 'Nowness',
}
},
{
'url': 'http://cn.nowness.com/day/2014/8/7/4069/kasper-bj-rke-ft-jaakko-eino-kalevi--tnr',
'md5': 'e79cf125e387216f86b2e0a5b5c63aa3',
'info_dict': {
'id': '3716354522001',
'ext': 'mp4',
'title': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR',
'description': 'Kasper Bjørke ft. Jaakko Eino Kalevi: TNR',
'thumbnail': 're:^https?://.*\.jpg',
'uploader': 'Nowness',
}
},
]
def _real_extract(self, url): def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url) mobj = re.match(self._VALID_URL, url)

View file

@ -1,10 +1,12 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import json
import re import re
from .common import InfoExtractor from .common import InfoExtractor
from ..utils import int_or_none from ..utils import (
int_or_none,
compat_str,
)
class VubeIE(InfoExtractor): class VubeIE(InfoExtractor):
@ -29,6 +31,7 @@ class VubeIE(InfoExtractor):
'like_count': int, 'like_count': int,
'dislike_count': int, 'dislike_count': int,
'comment_count': int, 'comment_count': int,
'categories': ['pop', 'music', 'cover', 'singing', 'jessie j', 'price tag', 'chiara grispo'],
} }
}, },
{ {
@ -47,6 +50,7 @@ class VubeIE(InfoExtractor):
'like_count': int, 'like_count': int,
'dislike_count': int, 'dislike_count': int,
'comment_count': int, 'comment_count': int,
'categories': ['seraina', 'jessica', 'krewella', 'alive'],
} }
}, { }, {
'url': 'http://vube.com/vote/Siren+Gene/0nmsMY5vEq?n=2&t=s', 'url': 'http://vube.com/vote/Siren+Gene/0nmsMY5vEq?n=2&t=s',
@ -56,13 +60,15 @@ class VubeIE(InfoExtractor):
'ext': 'mp4', 'ext': 'mp4',
'title': 'Frozen - Let It Go Cover by Siren Gene', 'title': 'Frozen - Let It Go Cover by Siren Gene',
'description': 'My rendition of "Let It Go" originally sung by Idina Menzel.', 'description': 'My rendition of "Let It Go" originally sung by Idina Menzel.',
'uploader': 'Siren Gene',
'uploader_id': 'Siren',
'thumbnail': 're:^http://frame\.thestaticvube\.com/snap/[0-9x]+/10283ab622a-86c9-4681-51f2-30d1f65774af\.jpg$', 'thumbnail': 're:^http://frame\.thestaticvube\.com/snap/[0-9x]+/10283ab622a-86c9-4681-51f2-30d1f65774af\.jpg$',
'uploader': 'Siren',
'timestamp': 1395448018,
'upload_date': '20140322',
'duration': 221.788, 'duration': 221.788,
'like_count': int, 'like_count': int,
'dislike_count': int, 'dislike_count': int,
'comment_count': int, 'comment_count': int,
'categories': ['let it go', 'cover', 'idina menzel', 'frozen', 'singing', 'disney', 'siren gene'],
} }
} }
] ]
@ -71,47 +77,40 @@ class VubeIE(InfoExtractor):
mobj = re.match(self._VALID_URL, url) mobj = re.match(self._VALID_URL, url)
video_id = mobj.group('id') video_id = mobj.group('id')
webpage = self._download_webpage(url, video_id) video = self._download_json(
data_json = self._search_regex( 'http://vube.com/t-api/v1/video/%s' % video_id, video_id, 'Downloading video JSON')
r'(?s)window\["(?:tapiVideoData|vubeOriginalVideoData)"\]\s*=\s*(\{.*?\n});\n',
webpage, 'video data'
)
data = json.loads(data_json)
video = (
data.get('video') or
data)
assert isinstance(video, dict)
public_id = video['public_id'] public_id = video['public_id']
formats = [ formats = []
{
'url': 'http://video.thestaticvube.com/video/%s/%s.mp4' % (fmt['media_resolution_id'], public_id), for media in video['media'].get('video', []) + video['media'].get('audio', []):
'height': int(fmt['height']), if media['transcoding_status'] != 'processed':
'abr': int(fmt['audio_bitrate']), continue
'vbr': int(fmt['video_bitrate']), fmt = {
'format_id': fmt['media_resolution_id'] 'url': 'http://video.thestaticvube.com/video/%s/%s.mp4' % (media['media_resolution_id'], public_id),
} for fmt in video['mtm'] if fmt['transcoding_status'] == 'processed' 'abr': int(media['audio_bitrate']),
] 'format_id': compat_str(media['media_resolution_id']),
}
vbr = int(media['video_bitrate'])
if vbr:
fmt.update({
'vbr': vbr,
'height': int(media['height']),
})
formats.append(fmt)
self._sort_formats(formats) self._sort_formats(formats)
title = video['title'] title = video['title']
description = video.get('description') description = video.get('description')
thumbnail = self._proto_relative_url( thumbnail = self._proto_relative_url(video.get('thumbnail_src'), scheme='http:')
video.get('thumbnail') or video.get('thumbnail_src'), uploader = video.get('user_alias') or video.get('channel')
scheme='http:')
uploader = data.get('user', {}).get('channel', {}).get('name') or video.get('user_alias')
uploader_id = data.get('user', {}).get('name')
timestamp = int_or_none(video.get('upload_time')) timestamp = int_or_none(video.get('upload_time'))
duration = video['duration'] duration = video['duration']
view_count = video.get('raw_view_count') view_count = video.get('raw_view_count')
like_count = video.get('rlikes') like_count = video.get('total_likes')
if like_count is None: dislike_count = video.get('total_hates')
like_count = video.get('total_likes')
dislike_count = video.get('rhates')
if dislike_count is None:
dislike_count = video.get('total_hates')
comments = video.get('comments') comments = video.get('comments')
comment_count = None comment_count = None
@ -124,6 +123,8 @@ class VubeIE(InfoExtractor):
else: else:
comment_count = len(comments) comment_count = len(comments)
categories = [tag['text'] for tag in video['tags']]
return { return {
'id': video_id, 'id': video_id,
'formats': formats, 'formats': formats,
@ -131,11 +132,11 @@ class VubeIE(InfoExtractor):
'description': description, 'description': description,
'thumbnail': thumbnail, 'thumbnail': thumbnail,
'uploader': uploader, 'uploader': uploader,
'uploader_id': uploader_id,
'timestamp': timestamp, 'timestamp': timestamp,
'duration': duration, 'duration': duration,
'view_count': view_count, 'view_count': view_count,
'like_count': like_count, 'like_count': like_count,
'dislike_count': dislike_count, 'dislike_count': dislike_count,
'comment_count': comment_count, 'comment_count': comment_count,
'categories': categories,
} }

View file

@ -0,0 +1,57 @@
# encoding: utf-8
from __future__ import unicode_literals
import re
from .common import InfoExtractor
from ..utils import (
parse_iso8601,
float_or_none,
int_or_none,
)
class XboxClipsIE(InfoExtractor):
_VALID_URL = r'https?://(?:www\.)?xboxclips\.com/video\.php\?.*vid=(?P<id>[\w-]{36})'
_TEST = {
'url': 'https://xboxclips.com/video.php?uid=2533274823424419&gamertag=Iabdulelah&vid=074a69a9-5faf-46aa-b93b-9909c1720325',
'md5': 'fbe1ec805e920aeb8eced3c3e657df5d',
'info_dict': {
'id': '074a69a9-5faf-46aa-b93b-9909c1720325',
'ext': 'mp4',
'title': 'Iabdulelah playing Upload Studio',
'filesize_approx': 28101836.8,
'timestamp': 1407388500,
'upload_date': '20140807',
'duration': 56,
}
}
def _real_extract(self, url):
mobj = re.match(self._VALID_URL, url)
video_id = mobj.group('id')
webpage = self._download_webpage(url, video_id)
video_url = self._html_search_regex(
r'>Link: <a href="([^"]+)">', webpage, 'video URL')
title = self._html_search_regex(
r'<title>XboxClips \| ([^<]+)</title>', webpage, 'title')
timestamp = parse_iso8601(self._html_search_regex(
r'>Recorded: ([^<]+)<', webpage, 'upload date', fatal=False))
filesize = float_or_none(self._html_search_regex(
r'>Size: ([\d\.]+)MB<', webpage, 'file size', fatal=False), invscale=1024 * 1024)
duration = int_or_none(self._html_search_regex(
r'>Duration: (\d+) Seconds<', webpage, 'duration', fatal=False))
view_count = int_or_none(self._html_search_regex(
r'>Views: (\d+)<', webpage, 'view count', fatal=False))
return {
'id': video_id,
'url': video_url,
'title': title,
'timestamp': timestamp,
'filesize_approx': filesize,
'duration': duration,
'view_count': view_count,
}