X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=youtube_dl%2Fextractor%2Fyouku.py;h=349ce09414b765060ac5f06121b87b529e287a12;hb=401d147893366a638b64872c4011e73f6f23fc67;hp=2a65ae6279f4ca032c460d697f1ddee84db9d39e;hpb=c683454e7e35a67a901526071136f8932adab3ea;p=youtube-dl diff --git a/youtube_dl/extractor/youku.py b/youtube_dl/extractor/youku.py index 2a65ae627..349ce0941 100644 --- a/youtube_dl/extractor/youku.py +++ b/youtube_dl/extractor/youku.py @@ -2,10 +2,13 @@ from __future__ import unicode_literals import base64 +import random +import string +import time from .common import InfoExtractor from ..compat import ( - compat_urllib_parse, + compat_urllib_parse_urlencode, compat_ord, ) from ..utils import ( @@ -42,6 +45,7 @@ class YoukuIE(InfoExtractor): 'title': '武媚娘传奇 85', }, 'playlist_count': 11, + 'skip': 'Available in China only', }, { 'url': 'http://v.youku.com/v_show/id_XMTI1OTczNDM5Mg==.html', 'info_dict': { @@ -49,7 +53,6 @@ class YoukuIE(InfoExtractor): 'title': '花千骨 04', }, 'playlist_count': 13, - 'skip': 'Available in China only', }, { 'url': 'http://v.youku.com/v_show/id_XNjA1NzA2Njgw.html', 'note': 'Video protected with password', @@ -61,6 +64,14 @@ class YoukuIE(InfoExtractor): 'params': { 'videopassword': '100600', }, + }, { + # /play/get.json contains streams with "channel_type":"tail" + 'url': 'http://v.youku.com/v_show/id_XOTUxMzg4NDMy.html', + 'info_dict': { + 'id': 'XOTUxMzg4NDMy', + 'title': '我的世界☆明月庄主☆车震猎杀☆杀人艺术Minecraft', + }, + 'playlist_count': 6, }] def construct_video_urls(self, data): @@ -89,6 +100,8 @@ class YoukuIE(InfoExtractor): fileid_dict = {} for stream in data['stream']: + if stream.get('channel_type') == 'tail': + continue format = stream.get('stream_type') fileid = stream['stream_fileid'] fileid_dict[format] = fileid @@ -114,6 +127,8 @@ class YoukuIE(InfoExtractor): # generate video_urls video_urls_dict = {} for stream in data['stream']: + if stream.get('channel_type') == 'tail': + continue format = stream.get('stream_type') video_urls = [] for dt in stream['segs']: @@ -135,38 +150,44 @@ class YoukuIE(InfoExtractor): '_00' + \ '/st/' + self.parse_ext_l(format) + \ '/fileid/' + get_fileid(format, n) + '?' + \ - compat_urllib_parse.urlencode(param) + compat_urllib_parse_urlencode(param) video_urls.append(video_url) video_urls_dict[format] = video_urls return video_urls_dict + @staticmethod + def get_ysuid(): + return '%d%s' % (int(time.time()), ''.join([ + random.choice(string.ascii_letters) for i in range(3)])) + def get_hd(self, fm): hd_id_dict = { - 'flv': '0', - 'mp4': '1', - 'hd2': '2', - 'hd3': '3', '3gp': '0', '3gphd': '1', + 'flv': '0', 'flvhd': '0', + 'mp4': '1', 'mp4hd': '1', - 'mp4hd2': '1' + 'mp4hd2': '1', + 'mp4hd3': '1', + 'hd2': '2', + 'hd3': '3', } return hd_id_dict[fm] def parse_ext_l(self, fm): ext_dict = { + '3gp': 'flv', + '3gphd': 'mp4', 'flv': 'flv', + 'flvhd': 'flv', 'mp4': 'mp4', 'mp4hd': 'mp4', 'mp4hd2': 'flv', 'mp4hd3': 'flv', 'hd2': 'flv', 'hd3': 'flv', - '3gp': 'flv', - '3gphd': 'mp4', - 'flvhd': 'flv' } return ext_dict[fm] @@ -174,20 +195,22 @@ class YoukuIE(InfoExtractor): _dict = { '3gp': 'h6', '3gphd': 'h5', - 'flvhd': 'h4', 'flv': 'h4', + 'flvhd': 'h4', 'mp4': 'h3', - 'hd2': 'h2', - 'hd3': 'h1', 'mp4hd': 'h3', + 'mp4hd2': 'h4', 'mp4hd3': 'h4', - 'mp4hd2': 'h4' + 'hd2': 'h2', + 'hd3': 'h1', } return _dict[fm] def _real_extract(self, url): video_id = self._match_id(url) + self._set_cookie('youku.com', '__ysuid', self.get_ysuid()) + def retrieve_data(req_url, note): headers = { 'Referer': req_url, @@ -203,16 +226,14 @@ class YoukuIE(InfoExtractor): return raw_data['data'] - video_password = self._downloader.params.get('videopassword', None) + video_password = self._downloader.params.get('videopassword') # request basic data - basic_data_url = "http://play.youku.com/play/get.json?vid=%s&ct=12" % video_id + basic_data_url = 'http://play.youku.com/play/get.json?vid=%s&ct=12' % video_id if video_password: basic_data_url += '&pwd=%s' % video_password - data = retrieve_data( - basic_data_url, - 'Downloading JSON metadata 1') + data = retrieve_data(basic_data_url, 'Downloading JSON metadata') error = data.get('error') if error: @@ -220,9 +241,12 @@ class YoukuIE(InfoExtractor): if error_note is not None and '因版权原因无法观看此视频' in error_note: raise ExtractorError( 'Youku said: Sorry, this video is available in China only', expected=True) + elif error_note and '该视频被设为私密' in error_note: + raise ExtractorError( + 'Youku said: Sorry, this video is private', expected=True) else: msg = 'Youku server reported error %i' % error.get('code') - if error is not None: + if error_note is not None: msg += ': ' + error_note raise ExtractorError(msg) @@ -241,6 +265,8 @@ class YoukuIE(InfoExtractor): # which one has all } for i in range(max(len(v.get('segs')) for v in data['stream']))] for stream in data['stream']: + if stream.get('channel_type') == 'tail': + continue fm = stream.get('stream_type') video_urls = video_urls_dict[fm] for video_url, seg, entry in zip(video_urls, stream['segs'], entries):