def _by_regex(self, reg_exp, xml_contents): match = re.search(reg_exp, xml_contents, re.IGNORECASE) if match: language = match.group('language') fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug( 'Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) result = self._write_file( fname, bytearray(HTMLParser.HTMLParser().unescape( result.text.decode('utf8')), encoding='utf8', errors='ignore')) if result: return [fname] else: return [] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: self.context.log_debug('No subtitles found for: %s' % reg_exp) return []
def _process_manifest(_url): try: headers = { 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.38 Safari/537.36', 'DNT': '1', 'Accept-Encoding': 'gzip, deflate, sdch', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } _result = requests.get(_url, headers=headers, verify=False) _xml = ElementTree.fromstring(_result.text) _url = '' _last_bit_rate = 0 for _media in _xml: _bit_rate = int(_media.get('bitrate')) if _bit_rate > _last_bit_rate: _url = _media.get('href') _last_bit_rate = _bit_rate pass pass if _url: return _url except: raise UnsupportedStreamException pass
def update_watch_history(self, video_id): headers = {'Host': 'www.youtube.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept': 'image/webp,*/*;q=0.8', 'DNT': '1', 'Referer': 'https://www.youtube.com/tv', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} params = {'noflv': '1', 'html5': '1', 'video_id': video_id, 'referrer': '', 'eurl': 'https://www.youtube.com/tv#/watch?v=%s' % video_id, 'skl': 'false', 'ns': 'yt', 'el': 'leanback', 'ps': 'leanback'} if self._access_token: params['access_token'] = self._access_token pass url = 'https://www.youtube.com/user_watch' result = requests.get(url, params=params, headers=headers, verify=False, allow_redirects=True) pass
def _load_manifest(self, url, video_id): headers = {'Host': 'manifest.googlevideo.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36', 'Accept': '*/*', 'DNT': '1', 'Referer': 'https://www.youtube.com/watch?v=%s' % video_id, 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} result = requests.get(url, headers=headers, verify=False, allow_redirects=True) lines = result.text.splitlines() streams = [] re_line = re.compile(r'RESOLUTION=(?P<width>\d+)x(?P<height>\d+)') re_itag = re.compile(r'/itag/(?P<itag>\d+)') for i in range(len(lines)): re_match = re.search(re_line, lines[i]) if re_match: line = lines[i + 1] re_itag_match = re.search(re_itag, line) if re_itag_match: itag = re_itag_match.group('itag') yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) width = int(re_match.group('width')) height = int(re_match.group('height')) video_stream = {'url': line} video_stream.update(yt_format) streams.append(video_stream) pass pass pass return streams
def update_watch_history(self, video_id): headers = { "Host": "www.youtube.com", "Connection": "keep-alive", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36", "Accept": "image/webp,*/*;q=0.8", "DNT": "1", "Referer": "https://www.youtube.com/tv", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.8,de;q=0.6", } params = { "noflv": "1", "html5": "1", "video_id": video_id, "referrer": "", "eurl": "https://www.youtube.com/tv#/watch?v=%s" % video_id, "skl": "false", "ns": "yt", "el": "leanback", "ps": "leanback", } if self._access_token: params["access_token"] = self._access_token pass url = "https://www.youtube.com/user_watch" result = requests.get(url, params=params, headers=headers, verify=False, allow_redirects=True) pass
def _load_manifest(self, url, video_id): headers = {'Host': 'manifest.googlevideo.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept': '*/*', 'DNT': '1', 'Referer': 'https://www.youtube.com/watch?v=%s' % video_id, 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} result = requests.get(url, headers=headers, verify=False, allow_redirects=True) lines = result.text.splitlines() streams = [] re_line = re.compile(r'RESOLUTION=(?P<width>\d+)x(?P<height>\d+)') re_itag = re.compile(r'/itag/(?P<itag>\d+)') for i in range(len(lines)): re_match = re.search(re_line, lines[i]) if re_match: line = lines[i + 1] re_itag_match = re.search(re_itag, line) if re_itag_match: itag = re_itag_match.group('itag') yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) width = int(re_match.group('width')) height = int(re_match.group('height')) video_stream = {'url': line} video_stream.update(yt_format) streams.append(video_stream) pass pass pass return streams
def _get_subtitles(self): languages = self._languages() if languages == self.LANG_NONE: return [] subtitle_list_url = self.SUBTITLE_LIST_URL % self.video_id result = requests.get(subtitle_list_url, headers=self.headers, verify=False, allow_redirects=True) if result.text: if languages == self.LANG_ALL: return self._get_all(result.text) elif languages == self.LANG_CURR: return self._get_current(result.text) elif languages == self.LANG_CURR_EN: list_of_subs = [] list_of_subs.extend(self._get_current(result.text)) list_of_subs.extend(self._get_en(result.text)) return list(set(list_of_subs)) elif languages == self.LANG_EN: return self._get_en(result.text) elif languages == self.LANG_PROMPT: return self._prompt(result.text) else: self.context.log_debug( 'Unknown language_enum: %s for subtitles' % str(languages)) else: self.context.log_debug('Failed to retrieve subtitle list') return []
def _get_subtitles(self): languages = self._languages() if languages == self.LANG_NONE: return [] subtitle_list_url = self.SUBTITLE_LIST_URL % self.video_id result = requests.get(subtitle_list_url, headers=self.headers, verify=False, allow_redirects=True) if result.text: if languages == self.LANG_ALL: return self._get_all(result.text) elif languages == self.LANG_CURR: return self._get_current(result.text) elif languages == self.LANG_CURR_EN: list_of_subs = [] list_of_subs.extend(self._get_current(result.text)) list_of_subs.extend(self._get_en(result.text)) return list(set(list_of_subs)) elif languages == self.LANG_EN: return self._get_en(result.text) elif languages == self.LANG_PROMPT: return self._prompt(result.text) else: self.context.log_debug('Unknown language_enum: %s for subtitles' % str(languages)) else: self.context.log_debug('Failed to retrieve subtitle list') return []
def get_format_videos(self, version, channel_id, format_id, clip_type='full', page=1, per_page=50): result = {} try: # http://contentapi.sim-technik.de/mega-app/v2/tablet/videos/format/pro7:505?clip_type=full&page=1&per_page=50 url = 'http://contentapi.sim-technik.de/mega-app/v2/%s/videos/format/%s:%s' % ( self._device, channel_id, format_id) params = { 'clip_type': clip_type, 'page': str(page), 'per_page': str(per_page) } data = requests.get(url, headers=self._header, params=params).json() return data except: # do nothing pass return result
def _by_regex(self, reg_exp, xml_contents): match = re.search(reg_exp, xml_contents, re.IGNORECASE) if match: language = match.group('language') fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug( 'Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) self._write_file(fname, result.text) return [fname] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: self.context.log_debug('No subtitles found for: %s' % reg_exp) return []
def _get_all(self, xml_contents): return_list = [] for match in re.finditer('lang_code="(?P<language>[^"]+?)"', xml_contents, re.IGNORECASE): language = match.group('language') fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug('Subtitle exists for: %s, filename: %s' % (language, fname)) return_list.append(fname) continue result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) result = self._write_file(fname, bytearray(HTMLParser.HTMLParser().unescape(result.text.decode('utf8')), encoding='utf8', errors='ignore')) if result: return_list.append(fname) continue else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) continue if not return_list: self.context.log_debug('No subtitles found') return return_list
def _get_all(self, xml_contents): return_list = [] for match in re.finditer('lang_code="(?P<language>[^"]+?)"', xml_contents, re.IGNORECASE): language = match.group('language') fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug( 'Subtitle exists for: %s, filename: %s' % (language, fname)) return_list.append(fname) continue result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) self._write_file(fname, result.text) return_list.append(fname) continue else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) continue if not return_list: self.context.log_debug('No subtitles found') return return_list
def _process_manifest(_url): try: headers = {'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.38 Safari/537.36', 'DNT': '1', 'Accept-Encoding': 'gzip, deflate, sdch', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} _result = requests.get(_url, headers=headers, verify=False) _xml = ElementTree.fromstring(_result.text) _url = '' _last_bit_rate = 0 for _media in _xml: _bit_rate = int(_media.get('bitrate')) if _bit_rate > _last_bit_rate: _url = _media.get('href') _last_bit_rate = _bit_rate pass pass if _url: return _url except: raise UnsupportedStreamException pass
def _get_current(self, xml_contents): language = self.language fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug('Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] if xml_contents.find('lang_code="%s"' % language) > -1: result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) self._write_file(fname, result.text) return [fname] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: if '-' not in self.language: self.context.log_debug('No subtitles found for: %s' % language) return [] language = language.split('-')[0] fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug( 'Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] if xml_contents.find('lang_code="%s"' % language) > -1: result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) self._write_file(fname, result.text) return [fname] else: self.context.log_debug( 'Failed to retrieve subtitles for: %s' % language) return [] else: self.context.log_debug('No subtitles found for: %s' % language) return []
def _perform_v3_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True, quota_optimized=True): # first set the config for the corresponding system (Frodo, Gotham, Helix, ...) yt_config = self._config # in any case of these APIs we change the config to a common key to save some quota # if quota_optimized and path in ['channels', 'search']: # yt_config = self.CONFIGS['youtube-for-kodi-quota'] # pass # params if not params: params = {} pass _params = {'key': yt_config['key']} _params.update(params) # headers if not headers: headers = {} pass _headers = {'Host': 'www.googleapis.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept-Encoding': 'gzip, deflate'} # a config can decide if a token is allowed if self._access_token and yt_config.get('token-allowed', True): _headers['Authorization'] = 'Bearer %s' % self._access_token pass _headers.update(headers) # url _url = 'https://www.googleapis.com/youtube/v3/%s' % path.strip('/') result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': _headers['content-type'] = 'application/json' result = requests.post(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': _headers['content-type'] = 'application/json' result = requests.put(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} if result.headers.get('content-type', '').startswith('application/json'): return result.json() pass
def _perform_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True, json=None): # params if not params: params = {} pass _params = {} _params.update(params) # headers if not headers: headers = {} pass _headers = { 'Host': 'api.breakmedia.com', 'Connection': 'Keep-Alive', 'User-Agent': '' } _headers.update(headers) # url _url = 'http://api.breakmedia.com/%s' % path.strip('/') result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) elif method == 'POST': if post_data: result = requests.post(_url, data=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif json: result = requests.post(_url, json=json, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} return result.json()
def _get_current(self, xml_contents): language = self.language fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug('Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] if xml_contents.find('lang_code="%s"' % language) > -1: result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) result = self._write_file(fname, bytearray(HTMLParser.HTMLParser().unescape(result.text.decode('utf8')), encoding='utf8', errors='ignore')) if result: return [fname] else: return [] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: if '-' not in self.language: self.context.log_debug('No subtitles found for: %s' % language) return [] language = language.split('-')[0] fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug('Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] if xml_contents.find('lang_code="%s"' % language) > -1: result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) result = self._write_file(fname, bytearray(HTMLParser.HTMLParser().unescape(result.text.decode('utf8')), encoding='utf8', errors='ignore')) if result: return [fname] else: return [] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: self.context.log_debug('No subtitles found for: %s' % language) return []
def _perform_request(self, channel_config=None, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params _params = {} if not params: params = {} pass _params.update(params) # headers if not headers: headers = {} pass _headers = { 'Accept': 'application/json', 'Origin': 'http://www.nowtv.de', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36', 'DNT': '1', 'Referer': 'http://www.nowtv.de/', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } if channel_config: _headers['Referer'] = 'http://www.nowtv.de/%s' % channel_config['id'] pass # set the login token if self._token: _headers['X-AUTH-TOKEN'] = self._token pass _headers.update(headers) # url _url = 'https://api.nowtv.de/v3/' if path: _url = _url + path.strip('/') pass result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects,timeout=100) pass elif method == 'POST': result = requests.post(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects,timeout=100) pass elif method == 'OPTIONS': requests.options(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects,timeout=100) return {} elif method == 'DELETE': requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects,timeout=100) return {} if result is None: return {} return result.json()
def _perform_v1_tv_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = {'key': self._config_tv['key']} _params.update(params) # headers if not headers: headers = {} pass _headers = {'Host': 'www.googleapis.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36', 'Origin': 'https://www.youtube.com', 'Accept': '*/*', 'DNT': '1', 'Referer': 'https://www.youtube.com/tv', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} if self._access_token_tv: _headers['Authorization'] = 'Bearer %s' % self._access_token_tv pass _headers.update(headers) # url _url = 'https://www.googleapis.com/youtubei/v1/%s' % path.strip('/') result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': _headers['content-type'] = 'application/json' result = requests.post(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': _headers['content-type'] = 'application/json' result = requests.put(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} if result.headers.get('content-type', '').startswith('application/json'): return result.json() pass
def get_video_url(self, stream_id): """ Returns the url for the given id :param stream_id: :return: """ content = requests.get('http://www.netzkino.de/adconf/android-new.php') json_data = content.json() streamer_url = json_data.get('streamer', 'http://netzkino_and-vh.akamaihd.net/i/') return streamer_url + urllib.quote(stream_id.encode('utf-8')) + '.mp4/master.m3u8'
def _browse(_url): headers = {'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.38 Safari/537.36', 'DNT': '1', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} _result = requests.get(_url, headers=headers, verify=False) return _result.text
def get_new_videos(self, version, format_ids=None): if not format_ids: format_ids = [] pass result = {} format_id_string = ','.join(format_ids) format_id_string = '[' + format_id_string + ']' url = 'http://contentapi.sim-technik.de/mega-app/v2/tablet/videos/favourites' params = {'ids': format_id_string} data = requests.get(url, headers=self._header, params=params).json() return data
def get_homepage(self, version, channel_id): result = {} try: # http://contentapi.sim-technik.de/mega-app/v2/pro7/phone/homepage url = "http://contentapi.sim-technik.de/mega-app/v2/%s/%s/homepage" % (channel_id, self._device) data = requests.get(url, headers=self._header).json() return data except: # do nothing pass return result
def get_new_videos(self, version, format_ids=None): if not format_ids: format_ids = [] pass result = {} format_id_string = ",".join(format_ids) format_id_string = "[" + format_id_string + "]" url = "http://contentapi.sim-technik.de/mega-app/v2/tablet/videos/favourites" params = {"ids": format_id_string} data = requests.get(url, headers=self._header, params=params).json() return data
def get_video_url(self, video_id): result = {} try: url = "http://vas.sim-technik.de/video/video.json" params = {"clipid": video_id, "app": "megapp", "method": str(self._video_method)} data = requests.get(url, headers=self._header, params=params).json() return data except: # do nothing pass return result
def _perform_v3_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = {'key': self._key} _params.update(params) # headers if not headers: headers = {} pass _headers = {'Host': 'www.googleapis.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept-Encoding': 'gzip, deflate', 'X-JavaScript-User-Agent': 'Google APIs Explorer'} if self._access_token: _headers['Authorization'] = 'Bearer %s' % self._access_token pass _headers.update(headers) # url _url = 'https://www.googleapis.com/youtube/v3/%s' % path.strip('/') result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': _headers['content-type'] = 'application/json' result = requests.post(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': _headers['content-type'] = 'application/json' result = requests.put(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} if result.headers.get('content-type', '').startswith('application/json'): return result.json() pass
def _get_current(self, xml_contents): language = self.language fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug('Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] if xml_contents.find('lang_code="%s"' % language) > -1: result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) self._write_file(fname, result.text) return [fname] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: if '-' not in self.language: self.context.log_debug('No subtitles found for: %s' % language) return [] language = language.split('-')[0] fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug('Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] if xml_contents.find('lang_code="%s"' % language) > -1: result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) self._write_file(fname, result.text) return [fname] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: self.context.log_debug('No subtitles found for: %s' % language) return []
def get_formats(self, version, channel_id): result = {} try: # http://contentapi.sim-technik.de/mega-app/v2/pro7/phone/format url = 'http://contentapi.sim-technik.de/mega-app/v2/%s/%s/format' % ( channel_id, self._device) data = requests.get(url, headers=self._header).json() return data except: # do nothing pass return result
def search(self, version, query): result = {} try: # http://contentapi.sim-technik.de/mega-app/v2/phone/search?query=halligalli url = "http://contentapi.sim-technik.de/mega-app/v2/tablet/search" params = {"query": query} data = requests.get(url, headers=self._header, params=params).json() return data except: # do nothing pass return result
def search(self, version, query): result = {} try: # http://contentapi.sim-technik.de/mega-app/v2/phone/search?query=halligalli url = 'http://contentapi.sim-technik.de/mega-app/v2/tablet/search' params = {'query': query} data = requests.get(url, headers=self._header, params=params).json() return data except: # do nothing pass return result
def _perform_v1_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = {} _params.update(params) # headers if not headers: headers = {} pass _headers = {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 5.0.1; GT-I9505 Build/LRX22C)', 'Host': 'api.redbull.tv', 'Connection': 'Keep-Alive', 'Accept-Encoding': 'gzip'} _headers.update(headers) # url _url = 'https://api.redbull.tv/v1/%s' % path.strip('/') result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': _headers['content-type'] = 'application/json' result = requests.post(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': _headers['content-type'] = 'application/json' result = requests.put(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} if result.headers.get('content-type', '').startswith('application/json'): return result.json() pass
def _perform_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass if self._client_id: params['client_id'] = self._client_id pass # basic header _headers = {'Accept-Encoding': 'gzip', 'Host': 'api.soundcloud.com:443', 'Connection': 'Keep-Alive', 'User-Agent': 'SoundCloud-Android/14.10.01-27 (Android 4.4.4; samsung GT-I9100'} # set access token if self._access_token: _headers['Authorization'] = 'OAuth %s' % self._access_token pass if not headers: headers = {} pass _headers.update(headers) # url _url = 'https://api.soundcloud.com:443/%s' % path result = None if method == 'GET': result = requests.get(_url, params=params, headers=_headers, verify=False, allow_redirects=allow_redirects) elif method == 'POST': result = requests.post(_url, data=post_data, params=params, headers=_headers, verify=False, allow_redirects=allow_redirects) elif method == 'PUT': result = requests.put(_url, data=post_data, params=params, headers=_headers, verify=False, allow_redirects=allow_redirects) elif method == 'DELETE': result = requests.delete(_url, data=post_data, params=params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} if result.status_code == requests.codes.unauthorized: raise ClientException(status_code=result.status_code) return result.json()
def _load_json_script(self, java_script_url): headers = {'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'DNT': '1', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} url = java_script_url if not url.startswith('http'): url = 'http://' + url pass result = requests.get(url, headers=headers, verify=False, allow_redirects=True) java_script = result.text return self._load_java_script(java_script)
def _perform_v2_request(self, url, method='GET', headers=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = {} _params.update(params) # headers if not headers: headers = {} pass _headers = { 'User-Agent': 'VimeoAndroid/1.1.42 (Android ver=4.4.2 sdk=19; Model samsung GT-I9505; Linux 3.4.0-3423977 armv7l)', 'Host': 'vimeo.com', 'Accept-Encoding': 'gzip, deflate'} _headers.update(headers) oauth_parms = post_data or params _headers.update(self._create_authorization(url, method, oauth_parms)) # url _url = url result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': result = requests.post(_url, data=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': result = requests.put(_url, data=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} return result.text
def get_video_url(self, video_id): result = {} try: url = 'http://vas.sim-technik.de/video/video.json' params = { 'clipid': video_id, 'app': 'megapp', 'method': str(self._video_method) } data = requests.get(url, headers=self._header, params=params).json() return data except: # do nothing pass return result
def get_format_videos(self, version, channel_id, format_id, clip_type="full", page=1, per_page=50): result = {} try: # http://contentapi.sim-technik.de/mega-app/v2/tablet/videos/format/pro7:505?clip_type=full&page=1&per_page=50 url = "http://contentapi.sim-technik.de/mega-app/v2/%s/videos/format/%s:%s" % ( self._device, channel_id, format_id, ) params = {"clip_type": clip_type, "page": str(page), "per_page": str(per_page)} data = requests.get(url, headers=self._header, params=params).json() return data except: # do nothing pass return result
def _load_json_script(self, java_script_url): headers = { "Connection": "keep-alive", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "DNT": "1", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.8,de;q=0.6", } url = java_script_url if not url.startswith("http"): url = "http://" + url pass result = requests.get(url, headers=headers, verify=False, allow_redirects=True) java_script = result.text return self._load_java_script(java_script)
def get_format_content(self, version, channel_id, format_id): result = {} try: # http://contentapi.sim-technik.de/mega-app/v2/pro7/phone/format/show/pro7:789 url = "http://contentapi.sim-technik.de/mega-app/v2/%s/%s/format/show/%s:%s" % ( channel_id, self._device, channel_id, format_id, ) data = requests.get(url, headers=self._header).json() return data except: # do nothing pass return result
def _perform_request(self, channel_config, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params _params = {} if not params: params = {} pass _params.update(params) # headers if not headers: headers = {} pass _headers = { 'Accept': 'application/json, text/plain, */*', 'Origin': 'http://www.nowtv.de', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36', 'DNT': '1', 'Referer': 'http://www.nowtv.de/', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } if channel_config: _headers['Referer'] = 'http://www.nowtv.de/%s' % channel_config['id'] pass _headers.update(headers) # url _url = 'https://api.nowtv.de/v3/' if path: _url = _url + path.strip('/') pass result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} return result.json()
def _perform_request(self, url, method='GET', headers=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = {} _params.update(params) # headers if not headers: headers = {} pass _headers = { 'User-Agent': 'Dalvik/1.6.0 (Linux; U; Android 4.4.2; GT-I9505 Build/KOT49H)', 'Accept-Encoding': 'gzip'} _headers.update(headers) # url _url = url result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': result = requests.post(_url, data=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': result = requests.put(_url, data=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} return result.json()
def _by_regex(self, reg_exp, xml_contents): match = re.search(reg_exp, xml_contents, re.IGNORECASE) if match: language = match.group('language') fname = self.srt_filename(language) if xbmcvfs.exists(fname): self.context.log_debug('Subtitle exists for: %s, filename: %s' % (language, fname)) return [fname] result = requests.get(self.subtitle_url(language), headers=self.headers, verify=False, allow_redirects=True) if result.text: self.context.log_debug('Subtitle found for: %s' % language) self._write_file(fname, result.text) return [fname] else: self.context.log_debug('Failed to retrieve subtitles for: %s' % language) return [] else: self.context.log_debug('No subtitles found for: %s' % reg_exp) return []
def _perform_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = { 'd': 'wwww', 'l': 'de-DE' } _params.update(self._config.get('param', {})) _params.update(params) # headers if not headers: headers = {} pass _headers = {'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'Accept': 'application/json, text/javascript, */*; q=0.01', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36', 'DNT': '1', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'} _headers.update(self._config['header']) _headers.update(headers) # url _url = self._config['url'] % path.strip('/') result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} return result.json()
def _perform_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params _params = {} if not params: params = {} pass # always set the id params['id'] = self._config['id'] _params.update(params) _params['_key'] = self._config['key_tablet'] timestamp = str(int(time.time())) _params['_ts'] = timestamp _params['_tk'] = self._calculate_token(timestamp, params) _params['_auth'] = 'integrity' # headers if not headers: headers = {} pass _headers = self._config['http-header'] _headers.update(headers) # url _url = self._config['url'] if path: _url = _url + path.strip('/') pass result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} return result.json()
def _perform_v2_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = {'key': self._config['key']} _params.update(params) # headers if not headers: headers = {} pass _headers = {'Host': 'gdata.youtube.com', 'X-GData-Key': 'key=%s' % self._config['key'], 'GData-Version': '2.1', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36'} if self._access_token: _headers['Authorization'] = 'Bearer %s' % self._access_token pass _headers.update(headers) # url url = 'https://gdata.youtube.com/%s/' % path.strip('/') result = None if method == 'GET': result = requests.get(url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} if method != 'DELETE' and result.text: return result.json() pass
def _load_json_script(self, java_script_url): headers = { 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'DNT': '1', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } url = java_script_url if not url.startswith('http'): url = 'http://' + url pass result = requests.get(url, headers=headers, verify=False, allow_redirects=True) java_script = result.text return self._load_java_script(java_script)
def _method_watch(self, video_id, reason=u''): stream_list = [] headers = { 'Host': 'www.youtube.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept': '*/*', 'DNT': '1', 'Referer': 'https://www.youtube.com', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } params = {'v': video_id} url = 'https://www.youtube.com/watch' result = requests.get(url, params=params, headers=headers, verify=False, allow_redirects=True) html = result.text """ This will almost double the speed for the regular expressions, because we only must match a small portion of the whole html. And only if we find positions, we cut down the html. """ pos = html.find('ytplayer.config') if pos >= 0: html2 = html[pos:] pos = html2.find('</script>') if pos: html = html2[:pos] pass pass """ itag_map = {} itag_map.update(self.DEFAULT_ITAG_MAP) re_match = re.match('.+\"fmt_list\": \"(?P<fmt_list>.+?)\".+', html) if re_match: fmt_list = re_match.group('fmt_list') fmt_list = fmt_list.split(',') for value in fmt_list: value = value.replace('\/', '|') try: attr = value.split('|') sizes = attr[1].split('x') itag_map[attr[0]] = {'width': int(sizes[0]), 'height': int(sizes[1])} except: # do nothing pass pass pass """ re_match_js = re.search(r'\"js\"[^:]*:[^"]*\"(?P<js>.+?)\"', html) js = '' cipher = None if re_match_js: js = re_match_js.group('js').replace('\\', '').strip('//') cipher = Cipher(self._context, java_script_url=js) pass re_match_hlsvp = re.search(r'\"hlsvp\"[^:]*:[^"]*\"(?P<hlsvp>[^"]*\")', html) if re_match_hlsvp: hlsvp = urllib.unquote(re_match_hlsvp.group('hlsvp')).replace( '\/', '/') return self._load_manifest(hlsvp, video_id) re_match = re.search( r'\"url_encoded_fmt_stream_map\"[^:]*:[^"]*\"(?P<url_encoded_fmt_stream_map>[^"]*\")', html) if re_match: url_encoded_fmt_stream_map = re_match.group( 'url_encoded_fmt_stream_map') url_encoded_fmt_stream_map = url_encoded_fmt_stream_map.split(',') for value in url_encoded_fmt_stream_map: value = value.replace('\\u0026', '&') attr = dict(urlparse.parse_qsl(value)) try: url = attr.get('url', None) conn = attr.get('conn', None) if url: url = urllib.unquote(attr['url']) signature = '' if attr.get('s', ''): signature = cipher.get_signature(attr['s']) pass elif attr.get('sig', ''): signature = attr.get('sig', '') pass if signature: url += '&signature=%s' % signature pass itag = attr['itag'] yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) # this format is discontinued if yt_format.get('discontinued', False): continue pass video_stream = {'url': url} video_stream.update(yt_format) stream_list.append(video_stream) pass elif conn: # rtmpe url = '%s?%s' % (conn, urllib.unquote(attr['stream'])) itag = attr['itag'] yt_format = self.FORMAT.get(itag, None) yt_format['rtmpe'] = True if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) video_stream = {'url': url} video_stream.update(yt_format) stream_list.append(video_stream) pass except Exception, ex: x = 0 pass pass pass
def _perform_v3_request(self, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True, quota_optimized=True): # first set the config for the corresponding system (Frodo, Gotham, Helix, ...) yt_config = self._config # in any case of these APIs we change the config to a common key to save some quota if quota_optimized and path in ['channels', 'search']: yt_config = self.CONFIGS['youtube-for-kodi-quota'] pass # params if not params: params = {} pass _params = {'key': yt_config['key']} _params.update(params) # headers if not headers: headers = {} pass _headers = { 'Host': 'www.googleapis.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept-Encoding': 'gzip, deflate' } # a config can decide if a token is allowed if self._access_token and yt_config.get('token-allowed', True): _headers['Authorization'] = 'Bearer %s' % self._access_token pass _headers.update(headers) # url _url = 'https://www.googleapis.com/youtube/v3/%s' % path.strip('/') result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': _headers['content-type'] = 'application/json' result = requests.post(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': _headers['content-type'] = 'application/json' result = requests.put(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} if result.headers.get('content-type', '').startswith('application/json'): return result.json() pass
def _perform_request(self, channel_config=None, method='GET', headers=None, path=None, post_data=None, params=None, allow_redirects=True): # params _params = {} if not params: params = {} pass _params.update(params) # headers if not headers: headers = {} pass _headers = { 'Accept': 'application/json', 'Origin': 'http://www.nowtv.de', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36', 'DNT': '1', 'Referer': 'http://www.nowtv.de/', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } if channel_config: _headers[ 'Referer'] = 'http://www.nowtv.de/%s' % channel_config['id'] pass # set the login token if self._token: _headers['X-AUTH-TOKEN'] = self._token pass _headers.update(headers) # url _url = 'https://api.nowtv.de/v3/' if path: _url = _url + path.strip('/') pass result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects, timeout=100) pass elif method == 'POST': result = requests.post(_url, json=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects, timeout=100) pass elif method == 'OPTIONS': requests.options(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects, timeout=100) return {} elif method == 'DELETE': requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects, timeout=100) return {} if result is None: return {} return result.json()
def _method_get_video_info(self, video_id): headers = { 'Host': 'www.youtube.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36', 'Accept': '*/*', 'DNT': '1', 'Referer': 'https://www.youtube.com/tv', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } params = { 'video_id': video_id, 'hl': self._language, 'cbr': 'Chrome', 'cbrver': '40.0.2214.115', 'cos': 'Windows', 'cosver': '6.1' } if self._access_token: params['access_token'] = self._access_token pass url = 'https://www.youtube.com/get_video_info' result = requests.get(url, params=params, headers=headers, verify=False, allow_redirects=True) stream_list = [] data = result.text params = dict(urlparse.parse_qsl(data)) if params.get('status', '') == 'fail': return self._method_watch(video_id, reason=params.get('reason', 'UNKNOWN')) if params.get('live_playback', '0') == '1': url = params.get('hlsvp', '') if url: return self._load_manifest(url, video_id) pass meta_info = {'video': {}, 'channel': {}, 'images': {}} meta_info['video']['id'] = params.get('vid', params.get('video_id', '')) meta_info['video']['title'] = params.get('title', '').decode('utf-8') meta_info['channel']['author'] = params.get('author', '').decode('utf-8') meta_info['channel']['id'] = 'UC%s' % params.get('uid', '') image_data_list = [{ 'from': 'iurlhq', 'to': 'high' }, { 'from': 'iurlmq', 'to': 'medium' }, { 'from': 'iurlsd', 'to': 'standard' }, { 'from': 'thumbnail_url', 'to': 'default' }] for image_data in image_data_list: image_url = params.get(image_data['from'], '') if image_url: meta_info['images'][image_data['to']] = image_url pass pass """ fmt_list = params.get('fmt_list', '') if fmt_list: fmt_list = fmt_list.split(',') for item in fmt_list: data = item.split('/') size = data[1].split('x') pass pass """ # read adaptive_fmts """ adaptive_fmts = params['adaptive_fmts'] adaptive_fmts = adaptive_fmts.split(',') for item in adaptive_fmts: stream_map = dict(urlparse.parse_qsl(item)) if stream_map['itag'] != '140' and stream_map['itag'] != '171': video_stream = {'url': stream_map['url'], 'yt_format': itag_map[stream_map['itag']]} stream_list.append(video_stream) pass pass """ # extract streams from map dash_manifest = urllib.unquote(params.get('dashmpd', '')) if dash_manifest: self._context.log_debug('>>> MPD manifest: "%s"' % dash_manifest) video_stream = {'url': dash_manifest, 'meta': meta_info} yt_format = self.FORMAT.get("dashmpd", None) video_stream.update(yt_format) stream_list.append(video_stream) url_encoded_fmt_stream_map = params.get('url_encoded_fmt_stream_map', '') if url_encoded_fmt_stream_map: url_encoded_fmt_stream_map = url_encoded_fmt_stream_map.split(',') for item in url_encoded_fmt_stream_map: stream_map = dict(urlparse.parse_qsl(item)) url = stream_map.get('url', None) conn = stream_map.get('conn', None) if url: if 'sig' in stream_map: url += '&signature=%s' % stream_map['sig'] elif 's' in stream_map: # f**k!!! in this case we must call the web page return self._method_watch(video_id) itag = stream_map['itag'] yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) if yt_format.get('discontinued', False): continue pass video_stream = {'url': url, 'meta': meta_info} video_stream.update(yt_format) stream_list.append(video_stream) pass elif conn: url = '%s?%s' % (conn, urllib.unquote( stream_map['stream'])) itag = stream_map['itag'] yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) yt_format['video']['rtmpe'] = True video_stream = {'url': url, 'meta': meta_info} video_stream.update(yt_format) stream_list.append(video_stream) pass pass pass # last fallback if not stream_list: return self._method_watch(video_id) return stream_list
def _method_get_video_info(self, video_id): headers = { 'Host': 'www.youtube.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36', 'Accept': '*/*', 'DNT': '1', 'Referer': 'https://www.youtube.com/tv', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } params = { 'video_id': video_id, 'hl': self.language, 'gl': self.region, 'eurl': 'https://youtube.googleapis.com/v/' + video_id, 'ssl_stream': '1', 'ps': 'default', 'el': 'default' } if self._access_token: params['access_token'] = self._access_token pass url = 'https://www.youtube.com/get_video_info' result = requests.get(url, params=params, headers=headers, verify=False, allow_redirects=True) stream_list = [] data = result.text params = dict(urlparse.parse_qsl(data)) meta_info = {'video': {}, 'channel': {}, 'images': {}, 'subtitles': []} meta_info['video']['id'] = params.get('vid', params.get('video_id', '')) meta_info['video']['title'] = params.get('title', '').decode('utf-8') meta_info['channel']['author'] = params.get('author', '').decode('utf-8') meta_info['channel']['id'] = 'UC%s' % params.get('uid', '') image_data_list = [{ 'from': 'iurlhq', 'to': 'high' }, { 'from': 'iurlmq', 'to': 'medium' }, { 'from': 'iurlsd', 'to': 'standard' }, { 'from': 'thumbnail_url', 'to': 'default' }] for image_data in image_data_list: image_url = params.get(image_data['from'], '') if image_url: meta_info['images'][image_data['to']] = image_url pass pass if params.get('status', '') == 'fail': return self._method_watch(video_id, reason=params.get('reason', 'UNKNOWN'), meta_info=meta_info) if params.get('live_playback', '0') == '1': url = params.get('hlsvp', '') if url: return self._load_manifest(url, video_id, meta_info=meta_info) pass """ fmt_list = params.get('fmt_list', '') if fmt_list: fmt_list = fmt_list.split(',') for item in fmt_list: data = item.split('/') size = data[1].split('x') pass pass """ # read adaptive_fmts """ adaptive_fmts = params['adaptive_fmts'] adaptive_fmts = adaptive_fmts.split(',') for item in adaptive_fmts: stream_map = dict(urlparse.parse_qsl(item)) if stream_map['itag'] != '140' and stream_map['itag'] != '171': video_stream = {'url': stream_map['url'], 'yt_format': itag_map[stream_map['itag']]} stream_list.append(video_stream) pass pass """ if self._context.get_settings().use_dash(): major_version = self._context.get_system_version().get_version()[0] if major_version >= 17: use_dash = True if not self._context.addon_enabled('inputstream.mpd'): use_dash = self._context.set_addon_enabled( 'inputstream.mpd' ) # already 'enabled' this in youtube settings else: use_dash = False self._context.get_settings().set_bool( 'kodion.video.quality.mpd', False) if use_dash: mpd_url = params.get('dashmpd', None) use_cipher_signature = 'True' == params.get( 'use_cipher_signature', None) if mpd_url: if use_cipher_signature or re.search( '/s/[0-9A-F\.]+', mpd_url): # in this case we must call the web page self._context.log_info( 'Unable to use mpeg-dash for %s, unable to decipher signature. Attempting fallback play method...' % video_id) return self._method_watch(video_id, meta_info=meta_info) meta_info['subtitles'] = Subtitles(self._context, video_id).get() video_stream = { 'url': mpd_url, 'title': meta_info['video'].get('title', ''), 'meta': meta_info } video_stream.update(self.FORMAT.get('9999')) stream_list.append(video_stream) return stream_list added_subs = False # avoid repeat calls from loop or cipher signature # extract streams from map url_encoded_fmt_stream_map = params.get('url_encoded_fmt_stream_map', '') if url_encoded_fmt_stream_map: url_encoded_fmt_stream_map = url_encoded_fmt_stream_map.split(',') for item in url_encoded_fmt_stream_map: stream_map = dict(urlparse.parse_qsl(item)) url = stream_map.get('url', None) conn = stream_map.get('conn', None) if url: if 'sig' in stream_map: url += '&signature=%s' % stream_map['sig'] elif 's' in stream_map: # in this case we must call the web page return self._method_watch(video_id, meta_info=meta_info) itag = stream_map['itag'] yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) if yt_format.get('discontinued', False): continue pass if not added_subs: added_subs = True meta_info['subtitles'] = Subtitles( self._context, video_id).get() video_stream = {'url': url, 'meta': meta_info} video_stream.update(yt_format) stream_list.append(video_stream) pass elif conn: url = '%s?%s' % (conn, urllib.unquote( stream_map['stream'])) itag = stream_map['itag'] yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) yt_format['video']['rtmpe'] = True if not added_subs: added_subs = True meta_info['subtitles'] = Subtitles( self._context, video_id).get() video_stream = {'url': url, 'meta': meta_info} video_stream.update(yt_format) stream_list.append(video_stream) pass pass pass # last fallback if not stream_list: return self._method_watch(video_id) return stream_list
def _method_watch(self, video_id, reason=u'', meta_info=None): stream_list = [] headers = { 'Host': 'www.youtube.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36', 'Accept': '*/*', 'DNT': '1', 'Referer': 'https://www.youtube.com', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.8,de;q=0.6' } params = {'v': video_id, 'hl': self.language, 'gl': self.region} url = 'https://www.youtube.com/watch' result = requests.get(url, params=params, headers=headers, verify=False, allow_redirects=True) html = result.text """ This will almost double the speed for the regular expressions, because we only must match a small portion of the whole html. And only if we find positions, we cut down the html. """ pos = html.find('ytplayer.config') if pos >= 0: html2 = html[pos:] pos = html2.find('</script>') if pos: html = html2[:pos] pass pass _meta_info = { 'video': {}, 'channel': {}, 'images': {}, 'subtitles': [] } meta_info = meta_info if meta_info else _meta_info re_match_hlsvp = re.search(r'\"hlsvp\"[^:]*:[^"]*\"(?P<hlsvp>[^"]*\")', html) if re_match_hlsvp: hlsvp = urllib.unquote(re_match_hlsvp.group('hlsvp')).replace( '\/', '/') return self._load_manifest(hlsvp, video_id, meta_info=meta_info) re_match_js = re.search(r'\"js\"[^:]*:[^"]*\"(?P<js>.+?)\"', html) cipher = None if re_match_js: js = re_match_js.group('js').replace('\\', '').strip('//') cipher = Cipher(self._context, java_script_url=js) pass meta_info['subtitles'] = Subtitles(self._context, video_id).get() re_match = re.search( r'\"url_encoded_fmt_stream_map\"[^:]*:[^"]*\"(?P<url_encoded_fmt_stream_map>[^"]*\")', html) if re_match: url_encoded_fmt_stream_map = re_match.group( 'url_encoded_fmt_stream_map') url_encoded_fmt_stream_map = url_encoded_fmt_stream_map.split(',') for value in url_encoded_fmt_stream_map: value = value.replace('\\u0026', '&') attr = dict(urlparse.parse_qsl(value)) try: url = attr.get('url', None) conn = attr.get('conn', None) if url: url = urllib.unquote(attr['url']) signature = '' if attr.get('s', ''): signature = cipher.get_signature(attr['s']) pass elif attr.get('sig', ''): signature = attr.get('sig', '') pass if signature: url += '&signature=%s' % signature pass itag = attr['itag'] yt_format = self.FORMAT.get(itag, None) if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) # this format is discontinued if yt_format.get('discontinued', False): continue pass video_stream = {'url': url, 'meta': meta_info} video_stream.update(yt_format) stream_list.append(video_stream) pass elif conn: # rtmpe url = '%s?%s' % (conn, urllib.unquote(attr['stream'])) itag = attr['itag'] yt_format = self.FORMAT.get(itag, None) yt_format['rtmpe'] = True if not yt_format: raise Exception('unknown yt_format for itag "%s"' % itag) video_stream = {'url': url, 'meta': meta_info} video_stream.update(yt_format) stream_list.append(video_stream) pass except Exception as ex: pass # try to find the reason of this page if we've only got 'UNKNOWN' if len(stream_list) == 0 and reason.lower() == 'unknown': reason_match = re.search(r'<h1[^>]*>(?P<reason>[^<]+)', html) if reason_match: reason = reason_match.group('reason').strip() pass pass # this is a reason from get_video_info. We should at least display the reason why the video couldn't be loaded if len(stream_list) == 0 and reason: raise YouTubeException(reason) return stream_list
def _perform_v2_request(self, url, method='GET', headers=None, post_data=None, params=None, allow_redirects=True): # params if not params: params = {} pass _params = {} _params.update(params) # headers if not headers: headers = {} pass _headers = { 'User-Agent': 'VimeoAndroid/1.1.42 (Android ver=4.4.2 sdk=19; Model samsung GT-I9505; Linux 3.4.0-3423977 armv7l)', 'Host': 'vimeo.com', 'Accept-Encoding': 'gzip, deflate' } _headers.update(headers) oauth_parms = post_data or params _headers.update(self._create_authorization(url, method, oauth_parms)) # url _url = url result = None if method == 'GET': result = requests.get(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'POST': result = requests.post(_url, data=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'PUT': result = requests.put(_url, data=post_data, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass elif method == 'DELETE': result = requests.delete(_url, params=_params, headers=_headers, verify=False, allow_redirects=allow_redirects) pass if result is None: return {} return result.text