def prepare(self): info = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url, 'http://\w+.yinyuetai.com/video/(\d+)') data = json.loads( get_content( 'http://ext.yinyuetai.com/main/get-h-mv-info?json=true&videoId={}' .format(self.vid))) assert not data['error'], 'some error happens' video_data = data['videoInfo']['coreVideoInfo'] info.title = video_data['videoName'] info.artist = video_data['artistNames'] for s in video_data['videoUrlModels']: stream_id = self.types_2_id[s['qualityLevel']] stream_profile = self.types_2_profile[s['qualityLevel']] info.stream_types.append(stream_id) info.streams[stream_id] = { 'container': 'flv', 'video_profile': stream_profile, 'src': [s['videoUrl']], 'size': s['fileSize'] } info.stream_types = sorted(info.stream_types, key=self.ids.index) return info
def prepare(self): handlers = [HTTPCookieProcessor()] if default_proxy_handler: handlers += default_proxy_handler install_opener(build_opener(*handlers)) info = VideoInfo(self.name, True) html = get_content(self.url) self.vid = match1(html, '"userNum":(\d+)') live_id = match1(html, '"liveId":\s*(\d+)') assert live_id, u"主播正在休息" info.stream_types.append('current') info.streams['current'] = { 'container': 'mp4', 'src': [ 'http://extapi.live.netease.com/redirect/video/{}'.format( self.vid) ], 'size': float('inf') } info.artist = match1(html, '"nick":"([^"]+)') info.title = match1(html, '<title>([^<]+)').split('-')[0] return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) raw_data = match1(html, '<script id="__NEXT_DATA__".*?>(.*?)</script>') data = json.loads(raw_data) self.vid = data['props']['pageProps']['roomInfoInitData']['live'][ 'ccid'] assert self.vid != 0, 'live video is offline' info.title = data['props']['pageProps']['roomInfoInitData'][ 'live']['title'] info.artist = data['props']['pageProps']['roomInfoInitData'][ 'micfirst']['nickname'] data = json.loads( get_content("http://cgi.v.cc.163.com/video_play_url/{}".format( self.vid))) info.stream_types.append("current") info.streams["current"] = { 'container': 'flv', 'video_profile': "current", 'src': [data["videourl"]], 'size': 0 } return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) json_stream = match1(html, '"stream": ({.+?})\s*};') assert json_stream, "live video is offline" data = json.loads(json_stream) assert data['status'] == 200, data['msg'] room_info = data['data'][0]['gameLiveInfo'] info.title = u'{}「{} - {}」'.format(room_info['roomName'], room_info['nick'], room_info['introduction']) info.artist = room_info['nick'] stream_info = random.choice(data['data'][0]['gameStreamInfoList']) sHlsUrl = stream_info['sHlsUrl'] sStreamName = stream_info['sStreamName'] sHlsUrlSuffix = stream_info['sHlsUrlSuffix'] sHlsAntiCode = stream_info['sHlsAntiCode'] hls_url = u'{}/{}.{}?{}'.format(sHlsUrl, sStreamName, sHlsUrlSuffix, sHlsAntiCode) info.stream_types.append("current") info.streams["current"] = { 'container': 'm3u8', 'video_profile': 'current', 'src': [unescape(hls_url)], 'size': float('inf') } return info
def prepare(self): info = VideoInfo(self.name) add_header("Referer", "http://music.163.com/") if not self.vid: self.vid = match1(self.url, 'song/(\d+)', '\?id=(.*)') api_url = self.api_url.format(self.vid, self.vid) music = self.get_music(json.loads(get_content(api_url))) self.logger.debug("music info >" + str(music)) info.title = music['name'] info.artist = music['artists'][0]['name'] real_id = music["id"] snd_key = random_string() if sys.version_info[0] == 3: encSecKey = RSA_string(snd_key) else: encSecKey = RSA_string(snd_key)[:-1] payload = netease_req(real_id, snd_key, encSecKey) mp3_info = json.loads(get_content(self.mp3_api, data=compact_bytes(urlencode(payload), 'utf-8')))['data'][0] self.logger.debug("mp3 > " + str(mp3_info)) info.stream_types.append('current') info.streams['current'] = {'container': mp3_info['type'], 'video_profile': 'current', 'src' : [mp3_info['url']], 'size': mp3_info['size']} return info
def prepare(self): info = VideoInfo(self.name) add_header("Referer", "http://music.163.com/") if not self.vid: self.vid = match1(self.url, 'song/(\d+)', '\?id=(.*)') api_url = self.api_url.format(self.vid, self.vid) music = self.get_music(json.loads(get_content(api_url))) self.logger.debug("music info >" + str(music)) info.title = music['name'] info.artist = music['artists'][0]['name'] real_id = music["id"] snd_key = random_string() if sys.version_info[0] == 3: encSecKey = RSA_string(snd_key) else: encSecKey = RSA_string(snd_key)[:-1] payload = netease_req(real_id, snd_key, encSecKey) mp3_info = json.loads( get_content(self.mp3_api, data=compact_bytes(urlencode(payload), 'utf-8')))['data'][0] self.logger.debug("mp3 > " + str(mp3_info)) info.stream_types.append('current') info.streams['current'] = { 'container': mp3_info['type'], 'video_profile': 'current', 'src': [mp3_info['url']], 'size': mp3_info['size'] } return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, 'panda.tv/(\w+)') content = get_content(self.api_url.format(self.vid, int(time.time()))) stream_data = json.loads(content) errno = stream_data['errno'] errmsg = stream_data['errmsg'] assert not errno, "Errno: {}, Errmsg: {}".format(errno, errmsg) assert stream_data['data']['videoinfo'][ 'status'] == '2', u"error: (⊙o⊙)主播暂时不在家,看看其他精彩直播吧!" room_key = stream_data['data']['videoinfo']['room_key'] plflag = stream_data['data']['videoinfo']['plflag'].split('_')[1] info.title = stream_data['data']['roominfo']['name'] info.artist = stream_data['data']['hostinfo']['name'] data2 = json.loads(stream_data['data']["videoinfo"]["plflag_list"]) rid = data2["auth"]["rid"] sign = data2["auth"]["sign"] ts = data2["auth"]["time"] info.stream_types.append('current') info.streams['current'] = { 'container': 'flv', 'video_profile': 'current', 'src': [self.live_base.format(plflag, room_key, sign, ts, rid)], 'size': float('inf') } return info
def parser_list(self, url): add_header("Referer", "http://music.163.com/") vid = match1(url, 'id=(.*)') if "album" in url: api_url = "http://music.163.com/api/album/{}?id={}&csrf_token=".format(vid, vid) listdata = json.loads(get_content(api_url)) playlist = listdata['album']['songs'] elif "playlist" in url: api_url = "http://music.163.com/api/playlist/detail?id={}&csrf_token=".format(vid) listdata = json.loads(get_content(api_url)) playlist = listdata['result']['tracks'] elif "toplist" in url: api_url = "http://music.163.com/api/playlist/detail?id={}&csrf_token=".format(vid) listdata = json.loads(get_content(api_url)) playlist = listdata['result']['tracks'] elif "artist" in url: api_url = "http://music.163.com/api/artist/{}?id={}&csrf_token=".format(vid, vid) listdata = json.loads(get_content(api_url)) playlist = listdata['hotSongs'] info_list = [] for music in playlist: info = VideoInfo(self.name) info.title = music['name'] info.artist = music['artists'][0]['name'] self.mp3_host = music['mp3Url'][8] for st in self.supported_stream_types: if st in music and music[st]: info.stream_types.append(st) self.song_date[st] = music[st] self.extract_song(info) info_list.append(info) return info_list
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, '/(\d+)') if not self.vid: html = get_content(self.url) self.vid = match1(html, '"room_id":(\d+)') #from upstream!! api_url = 'http://www.qie.tv/api/v1/room/{}'.format(self.vid) data = json.loads(get_content(api_url)) self.logger.debug('data:\n%s', data) assert data['error'] == 0, 'error {}: {}'.format( data['error'], data['data']) livedata = data['data'] assert livedata[ 'show_status'] == '1', 'error: live show is not on line!!' info.title = livedata['room_name'] info.artist = livedata['nickname'] info.stream_types.append('current') info.streams['current'] = { 'container': 'flv', 'video_profile': 'current', 'src': ['{}/{}'.format(livedata['rtmp_url'], livedata['rtmp_live'])], 'size': float('inf') } return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) self.vid = match1(html, '"room_id.?":(\d+)') or match1( html, 'data-onlineid=(\d+)') cdn = 'ws' authstr = 'room/{0}?aid=wp&cdn={1}&client_sys=wp&time={2}'.format( self.vid, cdn, int(time.time())) authmd5 = hashlib.md5((authstr + APPKEY).encode()).hexdigest() api_url = 'https://capi.douyucdn.cn/api/v1/{0}&auth={1}'.format( authstr, authmd5) html_content = get_content(api_url) live_data = json.loads(html_content) assert live_data["error"] == 0, "server error!!" live_data = live_data["data"] assert live_data['show_status'] == '1', "the show is not online!!" info.title = live_data['room_name'] info.artist = live_data['nickname'] real_url = '/'.join([live_data['rtmp_url'], live_data['rtmp_live']]) info.stream_types.append('TD') info.streams['TD'] = { 'container': 'flv', 'video_profile': self.id_2_profile['TD'], 'src': [real_url], 'size': float('inf') } return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) t_a = match1(html, '"keywords" content="([^"]+)') info.title = t_a.split(',')[0] info.artist = t_a.split(',')[1] replay_url = match1(html, '"m3u8":"([^"]+)') if replay_url: replay_url = replay_url.replace('\/','/') info.live = False info.stream_types.append('current') info.streams['current'] = {'container': 'm3u8', 'video_profile': 'current', 'src' : [replay_url], 'size': float('inf')} return info self.vid = match1(html, '"sn":"([^"]+)') channel = match1(html, '"channel":"([^"]+)') api_url = 'http://g2.live.360.cn/liveplay?stype=flv&channel={}&bid=huajiao&sn={}&sid={}&_rate=xd&ts={}&r={}&_ostype=flash&_delay=0&_sign=null&_ver=13'.format(channel, self.vid, SID, time.time(),random.random()) encoded_json = get_content(api_url) decoded_json = base64.decodestring(compact_bytes(encoded_json[0:3]+ encoded_json[6:], 'utf-8')).decode('utf-8') video_data = json.loads(decoded_json) live_url = video_data['main'] info.live = True info.stream_types.append('current') info.streams['current'] = {'container': 'flv', 'video_profile': 'current', 'src' : [live_url], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) self.vid = match1(html, 'roomid: (\d+)') info.title = match1(html, '"title":"([^"]+)') info.artist = match1(html, '"Name":"([^"]+)') api_url = 'http://livestream.plu.cn/live/getlivePlayurl?roomId={}&{}'.format( self.vid, int(time.time())) data = json.loads( get_content(api_url))['playLines'][0]['urls'] #don't know index 1 for i in data: if i['ext'] == 'flv': stream_id = self.supported_stream_types[i['rateLevel'] - 1] info.stream_types.append(stream_id) info.streams[stream_id] = { 'container': 'flv', 'video_profile': self.types_2_profile[stream_id], 'src': [i['securityUrl']], 'size': 0 } #sort stream_types types = self.supported_stream_types types.reverse() info.stream_types = sorted(info.stream_types, key=types.index) return info
def prepare(self): assert self.url, "please provide valid url" info = VideoInfo(self.name, True) html = get_content(self.url) Alias = match1(html, 'initAlias:\'([^\']+)') Token = match1(html, 'initToken: \'([^\']+)') info.artist = match1(html, 'anchorName:\'([^\']+)') info.title = info.artist + u'的直播房间' api_url = "http://lapi.xiu.youku.com/v1/get_playlist?app_id=101&alias={}&token={}&player_type=flash&sdkversion=0.1.0&playerversion=3.1.0&rd={}".format( Alias, Token, randint(0, 9999)) data1 = json.loads(get_content(api_url)) assert data1['error_code'] == 0 url_data = data1['url_list'][0] stream_url = json.loads(get_content(url_data['url']))['u'] info.stream_types.append('current') info.streams['current'] = { 'container': url_data["format"], 'video_profile': 'current', 'src': [stream_url], 'size': float('inf') } return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, '/(\d+)') if not self.vid: html = get_content(self.url) self.vid = match1(html, '"room_id":(\d+)') #from upstream!! api_url = 'http://www.qie.tv/api/v1/room/{}'.format(self.vid) metadata = json.loads(get_content(api_url)) assert metadata['error'] == 0, 'error {}: {}'.format(metadata['error'], metadata['data']) livedata = metadata['data'] assert livedata['show_status'] == '1', 'error: live show is not on line!!' info.title = livedata['room_name'] info.artist = livedata['nickname'] base_url = livedata['rtmp_url'] if 'hls_url' in livedata: info.stream_types.append('BD') info.streams['BD'] = {'container': 'm3u8', 'video_profile': u'原画', 'src' : [livedata['hls_url']], 'size': float('inf')} mutli_stream = livedata['rtmp_multi_bitrate'] for i in self.mutli_bitrate: if i in mutli_stream: info.stream_types.append(self.bitrate_2_type[i]) info.streams[self.bitrate_2_type[i]] = {'container': 'flv', 'video_profile': self.bitrate_2_profile[i], 'src' : [base_url + '/' + mutli_stream[i]], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name, True) if self.vid is None: self.vid = match1(self.url, 'room/(\d+)') tt = int(time.time() * 1000) url = 'https://data.live.126.net/liveAll/{}.json?{}'.format( self.vid, tt) data = json.loads(get_content(url)) self.logger.debug('video_data: \n%s', data) assert 'liveVideoUrl' in data, 'live video is offline' info.title = data['roomName'] try: info.artist = data['sourceinfo']['tname'] except KeyError: pass url = data['liveVideoUrl'] info.stream_types.append('current') info.streams['current'] = { 'container': url.split('.')[-1], 'video_profile': 'current', 'src': [url], 'size': 0 } return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, '/(\d+)') if not self.vid: html = get_content(self.url) self.vid = match1(html, '"liveAddr":"([0-9\_]+)"') self.pid = self.vid # from upstream!! serverDataTxt = match1(html, 'serverData = {([\S\ ]+)};') serverDataTxt = '{%s}' % (serverDataTxt) self.logger.debug("serverDataTxt => %s" % (serverDataTxt)) serverData = json.loads(serverDataTxt) self.logger.debug(serverData) assert serverData["liveInfo"]["data"]["profileInfo"]["isLive"] == 1, 'error: live show is not on line!!' info.title = serverData["liveInfo"]["data"]["videoInfo"]["title"] info.artist = serverData["liveInfo"]["data"]["profileInfo"]["nickName"] for data in serverData["liveInfo"]["data"]["videoInfo"]["streamInfos"]: info.stream_types.append(self.bitrate_2_type[data["bitrate"]]) info.streams[self.bitrate_2_type[data["bitrate"]]] = {'container': 'flv', 'video_profile': data["desc"], 'src': ["%s&_t=%s000"%(unescape(data["playUrl"]),int(time.time()))], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) room = match1(html, 'var $ROOM = ([^;]+)') self.vid = match1(html, '"room_id.?":(\d+)') info.title = json.loads("{\"room_name\" : \"" + match1(html, '"room_name.?":"([^"]+)') + "\"}")['room_name'] info.artist = json.loads("{\"name\" : \"" + match1(html, '"owner_name.?":"([^"]+)') + "\"}")['name'] api_url = 'https://www.douyu.com/lapi/live/getPlay/{}'.format(self.vid) tt = str(int(time.time() / 60)) rnd_md5 = hashlib.md5(str(random.random()).encode('utf8')) did = rnd_md5.hexdigest().upper() to_sign = ''.join([self.vid, did, API_KEY, tt]) sign = stupidMD5(to_sign) for stream in self.stream_ids: rate = self.stream_id_2_rate[stream] params = {"ver" : VER, "sign" : sign, "did" : did, "rate" : rate, "tt" : tt, "cdn" : "ws"} form = urlencode(params) html_content = get_content(api_url, data=compact_bytes(form, 'utf-8')) live_data = json.loads(html_content) assert live_data["error"] == 0, "live show is offline" live_data = live_data["data"] real_url = '/'.join([live_data['rtmp_url'], live_data['rtmp_live']]) info.stream_types.append(stream) info.streams[stream] = {'container': 'flv', 'video_profile': self.id_2_profile[stream], 'src' : [real_url], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name) if self.data is None: self.prepare_data() data = self.data if self.vid is None: movie = data['state']['movie']['moiveList'][0] else: for movie in data['state']['movie']['moiveList']: mid = movie['mid'] if mid == self.vid: break assert mid == self.vid, 'can not found mid %r' % mid title = data['data'][0]['title'] mtitle = movie['title'] school = data['data'][0]['school'] director = data['data'][0]['director'] if mtitle.startswith(title): title = mtitle elif mtitle != title: title = '{} - {}'.format(title, mtitle) if school not in title: title = '{} - {}'.format(title, school) info.title = title info.artist = director for stream, tp, profile in self.sopported_stream_types: for ext in ['mp4', 'm3u8']: for orig in ['', 'Orign']: if stream in info.streams: continue url = movie['{}{}Url{}'.format(ext, tp, orig)] if not url: continue size = movie['{}{}Size{}'.format(ext, tp, orig)] info.stream_types.append(stream) info.streams[stream] = { 'container': ext, 'video_profile': profile, 'src': [url], 'size': size } if movie['subList']: url = movie['mp4ShareUrl'] if url: info.stream_types.insert(0, 'subtitle') info.streams['subtitle'] = { 'container': 'mp4', 'video_profile': '有字幕', 'src': [url], 'size': 0 } return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) json_stream = match1(html, '"stream": "([a-zA-Z0-9+=/]+)"') assert json_stream, 'live video is offline' data = json.loads(base64.b64decode(json_stream).decode()) self.logger.debug('data:\n%s', data) assert data['status'] == 200, data['msg'] room_info = data['data'][0]['gameLiveInfo'] info.title = '{}「{} - {}」'.format(room_info['roomName'], room_info['nick'], room_info['introduction']) info.artist = room_info['nick'] stream_info = random.choice(data['data'][0]['gameStreamInfoList']) sUrl = stream_info['sFlvUrl'] sStreamName = stream_info['sStreamName'] sUrlSuffix = stream_info['sFlvUrlSuffix'] sAntiCode = unquote(unescape(stream_info['sFlvAntiCode'])) params = dict(p.split('=', 1) for p in sAntiCode.split('&') if p) params.update({ 'ctype': 'huya_webh5', 'uid': '0', 'seqid': str(int(os.urandom(5).hex(), 16)), 'ver': '1', 't': '100' # 102 }) fm = base64.b64decode(params['fm']).decode().split('_', 1)[0] ss = md5('|'.join([params['seqid'], params['ctype'], params['t']])) def link_url(rate): if rate: streamname = '{}_{}'.format(sStreamName, rate) else: streamname = sStreamName params['wsSecret'] = md5('_'.join( [fm, params['uid'], streamname, ss, params['wsTime']])) return '{}/{}.{}?{}'.format(sUrl, streamname, sUrlSuffix, urlencode(params, safe='*')) for si in data['vMultiStreamInfo']: video_profile = si['sDisplayName'] stream, _rate = self.profile_2_id_rate(video_profile) rate = si['iBitRate'] or _rate info.stream_types.append(stream) info.streams[stream] = { 'container': 'flv', 'video_profile': video_profile, 'src': [link_url(rate)], 'size': float('inf') } return info
def build_videoinfo(self, title, artist, size, urls): info = VideoInfo(self.name) info.title = title info.artist = artist info.stream_types.append('current') info.streams['current'] = { 'container': 'm3u8', 'src': urls, 'size': size } self.video_info['info'] = info
def prepare(self): info = VideoInfo(self.name) info.live = True self.vid = self.url[self.url.rfind('/')+1:].split(".")[0] json_request_url = 'http://www.yizhibo.com/live/h5api/get_basic_live_info?scid={}'.format(self.vid) content = json.loads(get_content(json_request_url)) assert content['result'] == 1, "Error : {}".format(content['result']) info.title = content['data']['live_title'] info.artist = content['data']['nickname'] info.streams['current'] = {'container': 'm3u8', 'video_profile': 'current', 'src' : [content['data']['play_url']], 'size': float('inf')} info.stream_types.append('current') return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) self.vid = match1(html, '"user_id":"([^"]+)",') title = json.loads(match1(html, '"room_name":("[^"]*"),')) artist = json.loads(match1(html, '"nick_name":("[^"]+"),')) info.title = u'{} - {}'.format(title, artist) info.artist = artist def get_live_info(rate='source'): data = getlive(self.vid, rate) self.logger.debug('data:\n' + str(data)) if data['code'] != 'A00000': return data.get('msg') data = data['data'] url = data.get('https_flv') or data.get('flv') or data.get('rtmp') if url: url = url.replace('rtmp://', 'http://') ran = random.randrange(1e4) if '?' in url: url = '{}&ran={}'.format(url, ran) else: url = '{}?ran={}'.format(url, ran) stream_profile = self.rate_2_profile[rate] stream_id = self.rate_2_id[rate] info.stream_types.append(stream_id) info.streams[stream_id] = { 'video_profile': stream_profile, 'container': 'flv', 'src' : [url], 'size': float('inf') } error_msges = [] if rate == 'source': rate_list = data['rate_list'] if 'source' in rate_list: rate_list.remove('source') for rate in rate_list: error_msg = get_live_info(rate) if error_msg: error_msges.append(error_msg) if error_msges: return ', '.join(error_msges) error_msg = get_live_info() if error_msg: self.logger.debug('error_msg:\n' + error_msg) assert len(info.stream_types), error_msg or 'can\'t play this live video!!' info.stream_types = sorted(info.stream_types, key=self.ids.index) return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) self.vid = match1(html, "anchorCcId : \'([^\']+)") info.title = match1(html, "title: \'([^\']+)") info.artist = match1(html, "anchorName : \'([^\']+)") data = json.loads(get_content("http://cgi.v.cc.163.com/video_play_url/{}".format(self.vid))) info.stream_types.append("current") info.streams["current"] = {'container': 'flv', 'video_profile': "current", 'src' : [data["videourl"]], 'size': 0} return info
def prepare(self): info = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url, 'yinyue/(\d+)') html = get_content("http://player.kuwo.cn/webmusic/st/getNewMuiseByRid?rid=MUSIC_{}".format(self.vid)) info.title = match1(html, "<name>(.*)</name>") info.artist = match1(html, "<artist>(.*)</artist>") for t in self.supported_stream_types: url=get_content("http://antiserver.kuwo.cn/anti.s?format={}&rid=MUSIC_{}&type=convert_url&response=url".format(t, self.vid)) info.stream_types.append(t) info.streams[t] = {'container': t, 'video_profile': 'current', 'src' : [url], 'size': 0} return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, 'quanmin.tv/(\w+)') content = get_content(self.api_url.format(self.vid)) stream_data = json.loads(content) assert stream_data['status'], u"error: (⊙o⊙)主播暂时不在家,看看其他精彩直播吧!" info.title = stream_data["title"] info.artist = stream_data['nick'] info.stream_types.append('current') info.streams['current'] = {'container': 'flv', 'video_profile': 'current', 'src' : [self.live_base.format(self.vid)], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url, 'http://music.baidu.com/song/([\d]+)') param = urlencode({'songIds': self.vid}) song_data = json.loads(get_content('http://play.baidu.com/data/music/songlink', data=compact_bytes(param, 'utf-8')))['data']['songList'][0] info.title = song_data['songName'] info.artist = song_data['artistName'] info.stream_types.append('current') info.streams['current'] = {'container': song_data['format'], 'video_profile': 'current', 'src' : [song_data['songLink']], 'size': song_data['size']} return info
def prepare(self): info = VideoInfo(self.name) self.vid = match1(self.url, 'video/(\d+)') api_url = 'https://api.vc.bilibili.com/clip/v1/video/detail?video_id={}'.format(self.vid) video_data = json.loads(get_content(api_url)) info.title = video_data['data']['item']['description'] info.artist = video_data['data']['user']['name'] info.stream_types.append('current') info.streams['current'] = {'container': 'mp4', 'src' : [video_data['data']['item']['video_playurl']], 'size': int(video_data['data']['item']['video_size'])} return info
def prepare(self): handlers = [HTTPCookieProcessor()] if default_proxy_handler: handlers += default_proxy_handler install_opener(build_opener(*handlers)) info = VideoInfo(self.name, True) html = get_content(self.url) self.vid = match1(html, '"userNum":(\d+)') live_id = match1(html, '"liveId":\s*(\d+)') assert live_id, u"主播正在休息" info.stream_types.append('current') info.streams['current'] = {'container': 'mp4', 'src': ['http://extapi.live.netease.com/redirect/video/{}'.format(self.vid)], 'size' : float('inf')} info.artist = match1(html, '"nick":"([^"]+)') info.title = match1(html, '<title>([^<]+)').split('-')[0] return info
def prepare(self): add_header("Referer", "http://music.163.com/") video = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url, 'id=(.*)') api_url = "http://music.163.com/api/mv/detail/?id={}&ids=[{}]&csrf_token=".format(self.vid, self.vid) mv = json.loads(get_content(api_url))['data'] video.title = mv['name'] video.artist = mv['artistName'] for code in self.supported_stream_code: if code in mv['brs']: stream_id = self.code_2_id[code] stream_profile = self.code_2_profile[code] video.stream_types.append(stream_id) video.streams[stream_id] = {'container': 'mp4', 'video_profile': stream_profile, 'src' : [mv['brs'][code]], 'size': 0} return video
def prepare(self): assert self.url, "please provide valid url" info = VideoInfo(self.name, True) html = get_content(self.url) Alias = match1(html, 'initAlias:\'([^\']+)' ,'"ln":\s*"([^"]+)"') Token = match1(html, 'initToken: \'([^\']+)', '"tk":\s*"([^"]+)"') info.artist = match1(html, 'anchorName:\s*\'([^\']+)', '"anchorName":\s*"([^"]+)"') info.title = info.artist + u'的直播房间' t = datetime.datetime.utcnow().isoformat().split('.')[0] + 'Z' api_url = "http://lapi.lcloud.laifeng.com/Play?AppId=101&StreamName={}&Action=Schedule&Token={}&Version=2.0&CallerVersion=3.3&Caller=flash&Format=HttpFlv&Timestamp={}&Format=HttpFlv&rd={}".format(Alias, Token, t, randint(10000, 99999) ) data1 = json.loads(get_content(api_url)) assert data1['Code'] == 'Success', data1['Message'] stream_url = data1['HttpFlv'][0]['Url'] info.stream_types.append('current') info.streams['current'] = {'container': 'flv', 'video_profile': 'current', 'src' : [stream_url], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) self.vid = match1(html, 'cid=([^&]+)') t = match1(html, '<title>([^<]+)').split('-') info.title = t[0] info.artist = t[1] data = get_content('http://live.bilibili.com/api/playurl?cid={}'.format(self.vid)) urls = [matchall(data, ['CDATA\[([^\]]+)'])[1]] size = float('inf') ext = 'flv' info.stream_types.append('current') info.streams['current'] = {'container': ext, 'video_profile': 'current', 'src' : urls, 'size': size} return info
def prepare(self): add_header("Referer", "http://music.163.com/") video = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url, '\?id=(.*)', 'mv/(\d+)') api_url = "http://music.163.com/api/mv/detail/?id={}&ids=[{}]&csrf_token=".format(self.vid, self.vid) mv = json.loads(get_content(api_url))['data'] video.title = mv['name'] video.artist = mv['artistName'] for code in self.supported_stream_code: if code in mv['brs']: stream_id = self.code_2_id[code] stream_profile = self.code_2_profile[code] video.stream_types.append(stream_id) video.streams[stream_id] = {'container': 'mp4', 'video_profile': stream_profile, 'src' : [mv['brs'][code]], 'size': 0} return video
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) self.vid = match1(html, '"qipuId":(\d+),') title = match1(html, '"roomTitle":"([^"]+)",') artist = match1(html, '"anchorNickname":"([^"]+)",') info.title = u'{} - {}'.format(title, artist) info.artist = artist data = getlive(self.vid) self.logger.debug('data:\n' + str(data)) assert data['code'] == 'A00000', data.get( 'msg', 'can\'t play this live video!!') data = data['data'] for stream in data['streams']: # TODO: parse more format types. # Streams which use formatType 'TS' are slow, # and rolling playback use formatType 'HLFLV' with scheme 'hcdnlive://'. # Its host and path encoded as like: # 'AMAAAAD3PV2R2QI7MXRQ4L2BD5Y...' # the real url is: # 'https://hlslive.video.iqiyi.com/live/{hl_slid}.flv?{params}' # Request it, the response is a json data which contains CDN informations. if stream['formatType'] == 'TS': m3u8 = stream['url'] # miswrote 'streamType' to 'steamType' stream_type = stream['steamType'] stream_profile = stream['screenSize'] stream_id = self.type_2_id[stream_type] info.stream_types.append(stream_id) info.streams[stream_id] = { 'video_profile': stream_profile, 'container': 'm3u8', 'src': [m3u8], 'size': float('inf') } assert info.stream_types, 'can\'t play this live video!!' if len(info.stream_types) == 1: info.streams['current'] = info.streams.pop(info.stream_types[0]) info.stream_types[0] = 'current' else: info.stream_types = sorted(info.stream_types, key=self.ids.index) return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) self.vid = match1(html, '"qipuId":(\d+),') title = match1(html, '"roomTitle":"([^"]+)",') artist = match1(html, '"anchorNickname":"([^"]+)",') info.title = u'{} - {}'.format(title, artist) info.artist = artist data = getlive(self.vid) self.logger.debug('data:\n' + str(data)) assert data['code'] == 'A00000', data.get('msg', 'can\'t play this live video!!') data = data['data'] for stream in data['streams']: # TODO: parse more format types. # Streams which use formatType 'TS' are slow, # and rolling playback use formatType 'HLFLV' with scheme 'hcdnlive://'. # Its host and path encoded as like: # 'AMAAAAD3PV2R2QI7MXRQ4L2BD5Y...' # the real url is: # 'https://hlslive.video.iqiyi.com/live/{hl_slid}.flv?{params}' # Request it, the response is a json data which contains CDN informations. if stream['formatType'] == 'TS': m3u8 = stream['url'] # miswrote 'streamType' to 'steamType' stream_type = stream['steamType'] stream_profile = stream['screenSize'] stream_id = self.type_2_id[stream_type] info.stream_types.append(stream_id) info.streams[stream_id] = { 'video_profile': stream_profile, 'container': 'm3u8', 'src' : [m3u8], 'size': float('inf') } assert info.stream_types, 'can\'t play this live video!!' if len(info.stream_types) == 1: info.streams['current'] = info.streams.pop(info.stream_types[0]) info.stream_types[0] = 'current' else: info.stream_types = sorted(info.stream_types, key=self.ids.index) return info
def prepare(self): info = VideoInfo(self.name) info.live = True self.vid = self.url[self.url.rfind('/') + 1:].split(".")[0] json_request_url = 'http://www.yizhibo.com/live/h5api/get_basic_live_info?scid={}'.format( self.vid) content = json.loads(get_content(json_request_url)) assert content['result'] == 1, "Error : {}".format(content['result']) info.title = content['data']['live_title'] info.artist = content['data']['nickname'] info.streams['current'] = { 'container': 'm3u8', 'video_profile': 'current', 'src': [content['data']['play_url']], 'size': float('inf') } info.stream_types.append('current') return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, '/(\d+)') if not self.vid: html = get_content(self.url) self.vid = match1(html, '"room_id":(\d+)') #from upstream!! api_url = 'http://www.qie.tv/api/v1/room/{}'.format(self.vid) metadata = json.loads(get_content(api_url)) assert metadata['error'] == 0, 'error {}: {}'.format( metadata['error'], metadata['data']) livedata = metadata['data'] assert livedata[ 'show_status'] == '1', 'error: live show is not on line!!' info.title = livedata['room_name'] info.artist = livedata['nickname'] base_url = livedata['rtmp_url'] if 'hls_url' in livedata: info.stream_types.append('BD') info.streams['BD'] = { 'container': 'm3u8', 'video_profile': u'原画', 'src': [livedata['hls_url']], 'size': float('inf') } mutli_stream = livedata['rtmp_multi_bitrate'] for i in self.mutli_bitrate: if i in mutli_stream: info.stream_types.append(self.bitrate_2_type[i]) info.streams[self.bitrate_2_type[i]] = { 'container': 'flv', 'video_profile': self.bitrate_2_profile[i], 'src': [base_url + '/' + mutli_stream[i]], 'size': float('inf') } return info
def prepare(self): info = VideoInfo(self.name) add_header("Referer", "http://music.163.com/") if not self.vid: self.vid = match1(self.url, 'song/(\d+)', '\?id=(.*)') api_url = self.api_url.format(self.vid, self.vid) music = self.get_music(json.loads(get_content(api_url))) info.title = music['name'] info.artist = music['artists'][0]['name'] self.mp3_host = music['mp3Url'][8] for st in self.supported_stream_types: if st in music and music[st]: info.stream_types.append(st) self.song_date[st] = music[st] self.extract_song(info) return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) self.vid = match1(self.url, 'vid=(\d+)') video_data = json.loads("[" + match1(html, '_DATA.list = \[([^\[]+)];') + "]") if self.vid: for data in video_data: if data['vid'] == self.vid: break else: data = video_data[0] assert 'video_url' in data, "No video found!!" info.artist = data['user_name'] info.title = data['video_name'] info.stream_types.append('current') info.streams['current'] = {'container': 'mp4', 'src': [data['video_url']], 'size' : 0} return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) self.vid = match1(html, "anchorCcId\s*:\s*\'([^\']+)") info.title = match1(html, "title:\s*\'([^\']+)") info.artist = match1(html, "anchorName\s*:\s*\'([^\']+)") data = json.loads( get_content("http://cgi.v.cc.163.com/video_play_url/{}".format( self.vid))) info.stream_types.append("current") info.streams["current"] = { 'container': 'flv', 'video_profile': "current", 'src': [data["videourl"]], 'size': 0 } return info
def prepare(self): info = VideoInfo(self.name) add_header("Referer", "http://music.163.com/") if not self.vid: self.vid = match1(self.url, 'id=(.*)') api_url = self.api_url.format(self.vid, self.vid) music = self.get_music(json.loads(get_content(api_url))) info.title = music['name'] info.artist = music['artists'][0]['name'] self.mp3_host = music['mp3Url'][8] for st in self.supported_stream_types: if st in music and music[st]: info.stream_types.append(st) self.song_date[st] = music[st] self.extract_song(info) return info
def prepare(self): self.live = True info = VideoInfo(self.name, True) page = get_content(self.url) page_meta = match1(page, r'window\.HOSTINFO=(.+?);<') page_meta = json.loads(page_meta) info.title = page_meta['roominfo']['name'] info.artist = page_meta['hostinfo']['nickName'] info.stream_types.append('current') stream_url = page_meta['videoinfo']['streamurl'] assert int(page_meta['roominfo']['playstatus']), 'live show is offline' info.streams['current'] = dict(container='flv', video_profile='current', src=[stream_url], size=float('inf')) return info
def prepare(self): info = VideoInfo(self.name) vid = match1(self.url, '(?:video/|vid=)(\d+)') self.logger.debug('URL: ' + self.url) data = get_content('https://www.douyin.com/web/api/v2/aweme/iteminfo/?item_ids=' + vid) data = json.loads(data) video_info = data['item_list'][0] title = video_info['desc'] nickName = video_info['author'].get('nickname', '') uid = video_info['author'].get('unique_id') or video_info['author']['short_id'] info.title = '{title} - {nickName}(@{uid})'.format(**vars()) info.artist = nickName info.stream_types.append('current') info.streams['current'] = { 'container': 'mp4', 'video_profile': 'current', 'src' : [video_info['video']['play_addr']['url_list'][0].replace('playwm', 'play')], } return info
def prepare(self): info = VideoInfo(self.name) self.vid = match1(self.url, 'video/(\d+)') api_url = 'https://api.vc.bilibili.com/clip/v1/video/detail?video_id={}'.format( self.vid) video_data = json.loads(get_content(api_url)) info.title = video_data['data']['item']['description'] info.artist = video_data['data']['user']['name'] info.stream_types.append('current') info.streams['current'] = { 'container': 'mp4', 'src': [video_data['data']['item']['video_playurl']], 'size': int(video_data['data']['item']['video_size']) } return info
def prepare(self): assert self.url, "please provide valid url" info = VideoInfo(self.name, True) html = get_content(self.url) Alias = match1(html, 'initAlias:\'([^\']+)') Token = match1(html, 'initToken: \'([^\']+)') info.artist = match1(html, 'anchorName:\'([^\']+)') info.title = info.artist + u'的直播房间' api_url = "http://lapi.xiu.youku.com/v1/get_playlist?app_id=101&alias={}&token={}&player_type=flash&sdkversion=0.1.0&playerversion=3.1.0&rd={}".format(Alias, Token, randint(0,9999)) data1 = json.loads(get_content(api_url)) assert data1['error_code'] == 0 url_data = data1['url_list'][0] stream_url = json.loads(get_content(url_data['url']))['u'] info.stream_types.append('current') info.streams['current'] = {'container': url_data["format"], 'video_profile': 'current', 'src' : [stream_url], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url, 'http://\w+.yinyuetai.com/video/(\d+)') data = json.loads(get_content('http://ext.yinyuetai.com/main/get-h-mv-info?json=true&videoId={}'.format(self.vid))) assert not data['error'], 'some error happens' video_data = data['videoInfo']['coreVideoInfo'] info.title = video_data['videoName'] info.artist = video_data['artistNames'] for s in video_data['videoUrlModels']: stream_id = self.types_2_id[s['qualityLevel']] stream_profile = self.types_2_profile[s['qualityLevel']] info.stream_types.append(stream_id) info.streams[stream_id] = {'container': 'flv', 'video_profile': stream_profile, 'src' : [s['videoUrl']], 'size': s['fileSize']} info.stream_types = sorted(info.stream_types, key = self.ids.index) return info
def prepare(self): info = VideoInfo(self.name, True) if self.url: self.vid = match1(self.url, '/(\d+)') if not self.vid: html = get_content(self.url) self.vid = match1(html, '"room_id":(\d+)') json_request_url = "http://m.douyu.com/html5/live?roomId={}".format(self.vid) content = json.loads(get_content(json_request_url)) assert content['error'] == 0, '%s: %s' % (self.name, content['msg']) data = content['data'] info.title = data.get('room_name') info.artist= data.get('nickname') show_status = data.get('show_status') assert show_status == "1", "The live stream is not online! (Errno:%s)" % show_status real_url = data.get('hls_url') info.stream_types.append('current') info.streams['current'] = {'container': 'm3u8', 'video_profile': 'current', 'src' : [real_url], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name, True) if self.url: self.vid = self.url[self.url.rfind('/')+1:] suffix = 'room/%s?aid=android&client_sys=android&time=%d' % (self.vid, int(time.time())) sign = hashlib.md5((suffix + '1231').encode('ascii')).hexdigest() json_request_url = "http://www.douyutv.com/api/v1/%s&auth=%s" % (suffix, sign) content = get_content(json_request_url) data = json.loads(content)['data'] server_status = data.get('error',0) if server_status is not 0: raise ValueError("Server returned error:%s" % server_status) info.title = data.get('room_name') info.artist= data.get('nickname') show_status = data.get('show_status') assert show_status == "1", "The live stream is not online! (Errno:%s)" % show_status real_url = data.get('rtmp_url')+'/'+data.get('rtmp_live') info.stream_types.append('current') info.streams['current'] = {'container': 'flv', 'video_profile': 'current', 'src' : [real_url], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, 'panda.tv/(\w+)') content = get_content(self.api_url.format(self.vid, int(time.time()))) stream_data = json.loads(content) errno = stream_data['errno'] errmsg = stream_data['errmsg'] assert not errno, "Errno: {}, Errmsg: {}".format(errno, errmsg) assert stream_data['data']['videoinfo']['status'] == '2', u"error: (⊙o⊙)主播暂时不在家,看看其他精彩直播吧!" room_key = stream_data['data']['videoinfo']['room_key'] plflag = stream_data['data']['videoinfo']['plflag'].split('_')[1] info.title = stream_data['data']['roominfo']['name'] info.artist = stream_data['data']['hostinfo']['name'] data2 = json.loads(stream_data['data']["videoinfo"]["plflag_list"]) rid = data2["auth"]["rid"] sign = data2["auth"]["sign"] ts = data2["auth"]["time"] info.stream_types.append('current') info.streams['current'] = {'container': 'flv', 'video_profile': 'current', 'src' : [self.live_base.format(plflag, room_key, sign, ts, rid)], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) t_a = match1(html, '"keywords" content="([^"]+)') info.title = t_a.split(',')[0] info.artist = t_a.split(',')[1] replay_url = match1(html, '"m3u8":"([^"]+)') if replay_url: replay_url = replay_url.replace('\/', '/') info.live = False info.stream_types.append('current') info.streams['current'] = { 'container': 'm3u8', 'video_profile': 'current', 'src': [replay_url], 'size': float('inf') } return info self.vid = match1(html, '"sn":"([^"]+)') channel = match1(html, '"channel":"([^"]+)') api_url = 'http://g2.live.360.cn/liveplay?stype=flv&channel={}&bid=huajiao&sn={}&sid={}&_rate=xd&ts={}&r={}&_ostype=flash&_delay=0&_sign=null&_ver=13'.format( channel, self.vid, SID, time.time(), random.random()) encoded_json = get_content(api_url) decoded_json = base64.decodestring( compact_bytes(encoded_json[0:3] + encoded_json[6:], 'utf-8')).decode('utf-8') video_data = json.loads(decoded_json) live_url = video_data['main'] info.stream_types.append('current') info.streams['current'] = { 'container': 'flv', 'video_profile': 'current', 'src': [live_url], 'size': float('inf') } return info
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) self.vid = match1(html, 'roomid: (\d+)', '__ROOMID = \'(\d+)\';', '"RoomId":(\d+)') info.title = match1(html, '"title":"([^"]+)', '<title>([^>]+)<') info.artist = match1(html, '"Name":"([^"]+)') api_url = 'http://livestream.plu.cn/live/getlivePlayurl?roomId={}&{}'.format(self.vid, int(time.time())) data = json.loads(get_content(api_url))['playLines'][0]['urls'] #don't know index 1 for i in data: if i['ext'] == 'flv': stream_id = self.supported_stream_types[i['rateLevel'] -1] info.stream_types.append(stream_id) info.streams[stream_id] = {'container': 'flv', 'video_profile': self.types_2_profile[stream_id], 'src' : [i['securityUrl']], 'size': 0} #sort stream_types types = self.supported_stream_types types.reverse() info.stream_types = sorted(info.stream_types, key=types.index) return info
def prepare(self): assert javascript_is_supported, "No JS Interpreter found, can't parse douyu live!" info = VideoInfo(self.name, True) add_header("Referer", 'https://www.douyu.com') title = None artist = None html_room_info = None self.vid = match1(self.url, 'douyu.com/(\d+)') if self.vid: try: html_room_info = get_content('https://open.douyucdn.cn/api/RoomApi/room/' + self.vid) except: self.vid = None if not self.vid: html = get_content(self.url) self.vid = match1(html, 'room_id\s*=\s*(\d+)', '"room_id.?":(\d+)', 'data-onlineid=(\d+)') title = match1(html, 'Title-headlineH2">([^<]+)<') artist = match1(html, 'Title-anchorName" title="([^"]+)"') if not artist: html_room_info = html_room_info or get_content('https://open.douyucdn.cn/api/RoomApi/room/' + self.vid) data = json.loads(html_room_info) if data['error'] == 0: title = data['data']['room_name'] artist = data['data']['owner_name'] info.title = u'{} - {}'.format(title, artist) info.artist = artist html_h5enc = get_content('https://www.douyu.com/swf_api/homeH5Enc?rids=' + self.vid) data = json.loads(html_h5enc) assert data['error'] == 0, data['msg'] js_enc = data['data']['room' + self.vid] try: # try load local .js file first # from https://cdnjs.com/libraries/crypto-js from pkgutil import get_data js_md5 = get_data(__name__, 'crypto-js-md5.min.js') if isinstance(js_md5, bytes): js_md5 = js_md5.decode() except IOError: js_md5 = get_content('https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js') js_ctx = JSEngine(js_md5) js_ctx.eval(js_enc) did = uuid.uuid4().hex tt = str(int(time.time())) ub98484234 = js_ctx.call('ub98484234', self.vid, did, tt) self.logger.debug('ub98484234: ' + ub98484234) params = { 'v': match1(ub98484234, 'v=(\d+)'), 'did': did, 'tt': tt, 'sign': match1(ub98484234, 'sign=(\w{32})'), 'cdn': '', 'iar': 0, 'ive': 0 } def get_live_info(rate=0): params['rate'] = rate data = urlencode(params) if not isinstance(data, bytes): data = data.encode() html_content = get_content('https://www.douyu.com/lapi/live/getH5Play/{}'.format(self.vid), data=data) self.logger.debug(html_content) live_data = json.loads(html_content) if live_data['error']: return live_data['msg'] live_data = live_data["data"] real_url = '{}/{}'.format(live_data['rtmp_url'], live_data['rtmp_live']) rate_2_profile = dict((rate['rate'], rate['name']) for rate in live_data['multirates']) video_profile = rate_2_profile[live_data['rate']] stream = self.profile_2_id[video_profile] if stream in info.streams: return info.stream_types.append(stream) info.streams[stream] = { 'container': 'flv', 'video_profile': video_profile, 'src' : [real_url], 'size': float('inf') } error_msges = [] if rate == 0: rate_2_profile.pop(0, None) rate_2_profile.pop(live_data['rate'], None) for rate in rate_2_profile: error_msg = get_live_info(rate) if error_msg: error_msges.append(error_msg) if error_msges: return ', '.join(error_msges) error_msg = get_live_info() assert len(info.stream_types), error_msg info.stream_types = sorted(info.stream_types, key=self.stream_ids.index) return info