def resolve_video_url(self, video_id): # get video info data = self._get_video_info(video_id) self.plugin.log.debug('resolving video: %s' % video_id) # this method assumes there's no children if 'children' in data: raise Exception('Invalid video id: %s' % video_id) # find playlist in resources list for res in data['resources']: if '.m3u8' in res['url']: break # get hashes hashes, data_hashes = self._get_hashes(video_id, [res['_id']]) signed_hashes = util.get_signed_hashes(hashes) # resolve query string template query_string = re.sub(r'{{(\w*)}}', r'%(\1)s', res['query_string_template']) try: query_string = query_string % { 'hash': signed_hashes[0], 'key': 'html5' } except KeyError: # live videos query_string = query_string % { 'hash': signed_hashes[0], 'key': 'html5', 'openClosed': 'F', 'user': data_hashes['user'] } # build resolved url url = '?'.join([res['url'], query_string]) self.plugin.log.debug('video url: %s' % url) return url
def resolve_video_url_mp4(self, video_id): # which index to look in the list heights = [360, 480, 720] video_res = int(self.plugin.get_setting('video_quality') or 0) # get video info data = self._get_video_info(video_id) self.plugin.log.debug('resolving video: %s' % video_id) # this method assumes there's no children if 'children' in data: raise Exception('Invalid video id: %s' % video_id) # build resources dict based on heights resources = dict((d['height'], d) for d in data['resources'] if 'players' in d and 'desktop' in d['players']) # get resource based on video quality setting while True: try: r = resources[heights[video_res]] break except: video_res -= 1 # get hashes hashes, data_hashes = self._get_hashes(video_id, [r['_id']], 'html5') signed_hashes = util.get_signed_hashes(hashes) query_string = re.sub(r'{{([a-z]*)}}', r'%(\1)s', r['query_string_template']) % { 'hash': signed_hashes[0], 'key': 'html5' } # build resolved url url = '?'.join([r['url'], query_string]) self.plugin.log.debug('video playlist url: %s' % url) return url
def resolve_video_url_m3u8(self, video_id): #import rpdb2; rpdb2.start_embedded_debugger('pw') # get video info data = self._get_video_info(video_id) self.plugin.log.debug('resolving video: %s' % video_id) # this method assumes there's no children if 'children' in data: raise Exception('Invalid video id: %s' % video_id) # check if resources is empty if len(data['resources']) == 0: # get hashes hashes, data_hashes = self._get_hashes(video_id, [], 'html5') url = data_hashes['url'] template = 'h={{hash}}&k={{key}}&a={{openClosed}}&u={{user}}' else: # find playlist in resources list reslist = [resource for resource in data['resources'] if 'players' in resource and 'desktop' in resource['players'] and '.m3u8' in resource['url']] # don't have a m3u8 video available if len(reslist) == 0: return self.resolve_video_url_mp4(video_id) res = reslist[0] url = res['url'] # get hashes hashes, data_hashes = self._get_hashes(video_id, [res['_id']], 'html5') template = res['query_string_template'] signed_hashes = util.get_signed_hashes(hashes) # resolve query string template query_string = re.sub(r'{{(\w*)}}', r'%(\1)s', template) try: query_string = query_string % { 'hash': signed_hashes[0], 'key': 'html5' } except KeyError: # live videos query_string = query_string % { 'hash': signed_hashes[0], 'key': 'html5', 'openClosed': 'F' if data['subscriber_only'] else 'A', 'user': data_hashes['user'] if data['subscriber_only'] else '' } # build resolved url url = '?'.join([url, query_string]) self.plugin.log.debug('video playlist url: %s' % url) return url
def resolve_video_url(self, video_id): # get video info data = self._get_video_info(video_id) self.plugin.log.debug('resolving video: %s' % video_id) # this method assumes there's no children if 'children' in data: raise Exception('Invalid video id: %s' % video_id) # find playlist in resources list for res in data['resources']: if '.m3u8' in res['url']: break # get hashes hashes, data_hashes = self._get_hashes(video_id, [res['_id']], 'html5') signed_hashes = util.get_signed_hashes(hashes) # resolve query string template query_string = re.sub(r'{{(\w*)}}', r'%(\1)s', res['query_string_template']) try: query_string = query_string % { 'hash': signed_hashes[0], 'key': 'html5' } except KeyError: # live videos query_string = query_string % { 'hash': signed_hashes[0], 'key': 'html5', 'openClosed': 'F', 'user': data_hashes['user'] } # build resolved url url = '?'.join([res['url'], query_string]) self.plugin.log.debug('video playlist url: %s' % url) session = requests.Session() req = session.get(url) m3u8_header = { 'Cookie': '; '.join(['%s=%s' % (key, value) for (key, value) in req.cookies.items()]) } m3u8_obj = m3u8.loads(req.text.strip()) streams = {} if m3u8_obj.is_variant: # if this m3u8 contains links to other m3u8s for playlist in m3u8_obj.playlists: bitrate = str(int(playlist.stream_info.bandwidth[:playlist.stream_info.bandwidth.find(' ')])/100) streams[bitrate] = url[:url.rfind('/') + 1] + playlist.uri + '?' + url.split('?')[1] + '|' + urllib.urlencode(m3u8_header) else: return url return util.getBestBitrateUrl(self.plugin, streams)
def resolve_video_url_mp4(self, video_id): #import rpdb2; rpdb2.start_embedded_debugger('pw') # which index to look in the list heights = [360, 480, 720] video_res = int(self.plugin.get_setting('video_quality') or 0) # get video info data = self._get_video_info(video_id) self.plugin.log.debug('resolving video: %s' % video_id) # this method assumes there's no children if 'children' in data: raise Exception('Invalid video id: %s' % video_id) # build resources dict based on heights resources = dict((d['height'], d) for d in data['resources'] if 'players' in d and 'height' in d and 'desktop' in d['players']) # No height info, skip to m3u8 if len(resources) == 0: return self.resolve_video_url_m3u8(video_id) # get resource based on video quality setting while True: try: r = resources[heights[video_res]] break except: video_res -= 1 # get hashes hashes, data_hashes = self._get_hashes(video_id, [r['_id']], 'html5') signed_hashes = util.get_signed_hashes(hashes) query_string = re.sub(r'{{([a-z]*)}}', r'%(\1)s', r['query_string_template']) % { 'hash': signed_hashes[0], 'key': 'html5' } # build resolved url url = '?'.join([r['url'], query_string]) self.plugin.log.debug('video playlist url: %s' % url) return url