def set_reuselanguageinvoker(): try: addon_xml = control.joinPath(control.addonPath('plugin.video.dg'), 'addon.xml') tree = ET.parse(addon_xml) root = tree.getroot() for item in root.iter('reuselanguageinvoker'): current_value = str(item.text) if current_value: new_value = 'true' if current_value == 'false' else 'false' if not control.yesnoDialog( control.lang(33018) % (current_value, new_value), '', ''): return control.openSettings(query='12.6') if new_value == 'true': if not control.yesnoDialog(control.lang(33019), '', ''): return item.text = new_value hash_start = gen_file_hash(addon_xml) tree.write(addon_xml) hash_end = gen_file_hash(addon_xml) if hash_start != hash_end: control.setSetting('reuse.languageinvoker', new_value) control.okDialog( message='%s\n%s' % (control.lang(33017) % new_value, control.lang(33020))) else: return control.okDialog(message=33021) current_profile = control.infoLabel('system.profilename') control.execute('LoadProfile(%s)' % current_profile) except: from resources.lib.modules import log_utils log_utils.error()
def revoke_auth(self): try: control.setSetting('alldebrid.token', '') control.setSetting('alldebrid.username', '') control.okDialog(title=40059, message=40009) except: log_utils.error()
def poll_token(self, device_code): data = { 'client_id': CLIENT_ID, 'code': device_code, 'grant_type': 'device_code' } token = requests.post('https://www.premiumize.me/token', data=data, timeout=15).json() if 'error' in token: if token['error'] == "access_denied": control.okDialog(title='default', message=control.lang(40020)) return False, False return True, False self.token = token['access_token'] self.headers = { 'User-Agent': 'Venom for Kodi', 'Authorization': 'Bearer %s' % self.token } control.sleep(500) account_info = self.account_info() control.setSetting('premiumize.token', token['access_token']) control.setSetting('premiumize.username', str(account_info['customer_id'])) return False, True
def add_uncached_torrent(self, magnet_url, pack=False): def _return_failed(message=control.lang(33586)): try: control.progressDialog.close() except: pass self.delete_transfer(transfer_id) control.hide() control.sleep(500) control.okDialog(title=control.lang(40018), message=message) return False control.busy() transfer_id = self.create_transfer(magnet_url) if not transfer_id: return _return_failed() transfer_info = self.list_transfer(transfer_id) if not transfer_info: return _return_failed() if pack: control.hide() control.okDialog(title='default', message=control.lang(40017) % control.lang(40059)) return True interval = 5 line1 = '%s...' % (control.lang(40017) % control.lang(40059)) line2 = transfer_info['filename'] line3 = transfer_info['status'] control.progressDialog.create(control.lang(40018), line1, line2, line3) while not transfer_info['statusCode'] == 4: control.sleep(1000 * interval) transfer_info = self.list_transfer(transfer_id) file_size = transfer_info['size'] line2 = transfer_info['filename'] if transfer_info['statusCode'] == 1: download_speed = round(float(transfer_info['downloadSpeed']) / (1000**2), 2) progress = int(float(transfer_info['downloaded']) / file_size * 100) if file_size > 0 else 0 line3 = control.lang(40016) % (download_speed, transfer_info['seeders'], progress, round(float(file_size) / (1000 ** 3), 2)) elif transfer_info['statusCode'] == 3: upload_speed = round(float(transfer_info['uploadSpeed']) / (1000 ** 2), 2) progress = int(float(transfer_info['uploaded']) / file_size * 100) if file_size > 0 else 0 line3 = control.lang(40015) % (upload_speed, progress, round(float(file_size) / (1000 ** 3), 2)) else: line3 = transfer_info['status'] progress = 0 control.progressDialog.update(progress, line2=line2, line3=line3) if control.monitor.abortRequested(): return sys.exit() try: if control.progressDialog.iscanceled(): if control.yesnoDialog('Delete AD download also?', 'No will continue the download', 'but close dialog'): return _return_failed(control.lang(40014)) else: control.progressDialog.close() control.hide() return False except: pass if 5 <= transfer_info['statusCode'] <= 10: return _return_failed() control.sleep(1000 * interval) try: control.progressDialog.close() except: pass control.hide() return True
def _return_failed(message=control.lang(33586)): try: control.progressDialog.close() except: pass self.delete_transfer(transfer_id) control.hide() control.sleep(500) control.okDialog(title=control.lang(40018), message=message) return False
def _return_failed(message=getLS(33586)): try: control.progressDialog.close() except: pass self.delete_torrent(torrent_id) control.hide() control.sleep(500) control.okDialog(title=getLS(40018), message=message) return False
def get_live_channels(): try: credentials = login() return get_live_channels_user_only(credentials) except Exception as ex: control.log(traceback.format_exc(), control.LOGERROR) control.okDialog(u'Now Online', str(ex)) return []
def done(title, dest, downloaded): try: playing = control.player.isPlaying() text = control.homeWindow.getProperty('GEN-DOWNLOADED') if len(text) > 0: text += '[CR]' if downloaded: text += '%s : %s' % (dest.rsplit(os.sep)[-1], '[COLOR forestgreen]Download succeeded[/COLOR]') else: text += '%s : %s' % (dest.rsplit(os.sep)[-1], '[COLOR red]Download failed[/COLOR]') control.homeWindow.setProperty('GEN-DOWNLOADED', text) if (not downloaded) or (not playing): control.okDialog(title, text) control.homeWindow.clearProperty('GEN-DOWNLOADED') except: log_utils.error()
def run(self): if control.getKodiVersion() < 18: return xbmc.log( '[ plugin.video.venom ] ReuseLanguageInvokerCheck Service Starting...', 2) try: import xml.etree.ElementTree as ET addon_xml = control.joinPath( control.addonPath('plugin.video.venom'), 'addon.xml') tree = ET.parse(addon_xml) root = tree.getroot() current_addon_setting = control.addon( 'plugin.video.venom').getSetting('reuse.languageinvoker') try: current_xml_setting = [ str(i.text) for i in root.iter('reuselanguageinvoker') ][0] except: return xbmc.log( '[ plugin.video.venom ] ReuseLanguageInvokerCheck failed to get settings.xml value', 2) if current_addon_setting == '': current_addon_setting = 'true' control.setSetting('reuse.languageinvoker', current_addon_setting) if current_xml_setting == current_addon_setting: return xbmc.log( '[ plugin.video.venom ] ReuseLanguageInvokerCheck Service Finished', 2) control.okDialog(message='%s\n%s' % (control.lang(33023), control.lang(33020))) for item in root.iter('reuselanguageinvoker'): item.text = current_addon_setting hash_start = control.gen_file_hash(addon_xml) tree.write(addon_xml) hash_end = control.gen_file_hash(addon_xml) xbmc.log( '[ plugin.video.venom ] ReuseLanguageInvokerCheck Service Finished', 2) if hash_start != hash_end: current_profile = control.infoLabel('system.profilename') control.execute('LoadProfile(%s)' % current_profile) else: control.okDialog(title='default', message=33022) return except: log_utils.error() pass
def auth_loop(self): control.sleep(self.auth_step * 1000) url = 'client_id=%s&code=%s' % (self.client_ID, self.device_code) url = oauth_base_url + credentials_url % url response = json.loads(requests.get(url).text) if 'error' in response: return control.okDialog(title='default', message=40019) else: try: control.progressDialog.close() self.client_ID = response['client_id'] self.secret = response['client_secret'] except: log_utils.error() control.okDialog(title='default', message=40019) return
def run(self): if control.getKodiVersion() < 18: return try: import xml.etree.ElementTree as ET addon_dir = control.transPath( control.addon('plugin.video.venom').getAddonInfo('path')) addon_xml = control.joinPath(addon_dir, 'addon.xml') tree = ET.parse(addon_xml) root = tree.getroot() current_addon_setting = control.addon( 'plugin.video.venom').getSetting('reuse.languageinvoker') if current_addon_setting == '': return try: current_xml_setting = [ str(i.text) for i in root.iter('reuselanguageinvoker') ][0] except: return if current_xml_setting == current_addon_setting: return if not control.yesnoDialog( '[B]Reuse Language Invoker[/B] SETTING/XML mismatch.\nRestore correct status(RECOMMENDED)?', '', ''): return for item in root.iter('reuselanguageinvoker'): item.text = current_addon_setting hash_start = control.gen_file_hash(addon_xml) tree.write(addon_xml) hash_end = control.gen_file_hash(addon_xml) if hash_start != hash_end: control.okDialog( 'Kodi must close and be restarted for the change to take effect.' ) else: control.okDialog('Venom', 'Error setting correct value.') return except: log_utils.error() pass
def poll_token(self, device_code): data = { 'client_id': CLIENT_ID, 'code': device_code, 'grant_type': 'device_code' } token = requests.post('https://www.premiumize.me/token', data=data, timeout=15).json() if 'error' in token: if token['error'] == "access_denied": control.okDialog(title='default', message=control.lang(40020)) return False, False return True, False control.addon('script.module.resolveurl').setSetting( 'PremiumizeMeResolver_token', token['access_token']) control.addon('script.module.resolveurl').setSetting( 'PremiumizeMeResolver_auth', 'true') self.headers = { 'User-Agent': 'Venom for Kodi', 'Authorization': 'Bearer %s' % token['access_token'] } return False, True
def playlive(self, path, meta): control.log("Telecine Play - play_stream: path=%s | meta=%s" % (path, meta)) if path is None: return if not control.is_inputstream_available(): control.okDialog('Telecine Play', control.lang(34103).encode('utf-8')) return try: url, license_url = self.get_stream(path) except: control.log(traceback.format_exc(), control.LOGERROR) exc_type, exc_value, exc_traceback = sys.exc_info() control.okDialog('Telecine Play', str(exc_value)) return if '.mpd' not in url: response = requests.get(url, proxies=proxy) url = response.url control.log("media url: %s" % url) control.log("license url: %s" % license_url) try: meta = json.loads(meta) except: meta = { "playcount": 0, "overlay": 6, "mediatype": "video", } if control.supports_offscreen: item = control.item(path=url, offscreen=True) else: item = control.item(path=url) art = meta.get('art', {}) or {} item.setArt(art) properties = meta.get('properties', {}) or {} item.setProperties(properties) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=control.filter_info_labels(meta)) item.setContentLookup(False) item.setMimeType('application/dash+xml') item.setProperty('inputstream.adaptive.manifest_type', 'mpd') if license_url: headers = { 'user-agent': 'Telecine_iOS/2.5.10 (br.com.telecineplay; build:37; iOS 14.1.0) Alamofire/5.2.2', 'x-device': 'Mobile-iOS', 'x-version': '2.5.10', 'content-type': 'application/octet-stream' } item.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') item.setProperty( 'inputstream.adaptive.license_key', "%s|%s|R{SSM}|" % (license_url, urllib.urlencode(headers))) item.setProperty('inputstreamaddon', 'inputstream.adaptive') # if 'subtitles' in info and info['subtitles'] and len(info['subtitles']) > 0: # control.log("FOUND SUBTITLES: %s" % repr([sub['url'] for sub in info['subtitles']])) # item.setSubtitles([sub['url'] for sub in info['subtitles']]) syshandle = int(sys.argv[1]) control.resolve(syshandle, True, item) control.log("Done playing. Quitting...")
def revoke_auth(self): # control.addon('script.module.resolveurl').setSetting('AllDebridResolver_username', '') # not used by resolveURL control.addon('script.module.resolveurl').setSetting('AllDebridResolver_token', '') control.okDialog(title=40059, message=control.lang(40009))
def __get_list_item(self, meta, info, pick_bandwidth=True): hash_token = info['hash'] user = info['user'] query_string = re.sub(r'{{(\w*)}}', r'%(\1)s', info['query_string_template']) query_string = query_string % { 'hash': hash_token, 'key': 'app', 'openClosed': 'F' if info['subscriber_only'] and user else 'A', 'user': user if info['subscriber_only'] and user else '', 'token': hash_token } url = '?'.join([info['url'], query_string]) control.log("live media url: %s" % url) parsed_url = urlparse(url) if parsed_url.path.endswith(".m3u8"): if pick_bandwidth: url, mime_type, stop_event, cookies = hlshelper.pick_bandwidth( url) else: mime_type, stop_event, cookies = None, None, None elif parsed_url.path.endswith(".mpd"): proxy_handler = MediaProxy() url = proxy_handler.resolve(url) stop_event = proxy_handler.stop_event mime_type = None cookies = None else: mime_type, stop_event, cookies = 'video/mp4', None, None if url is None: if stop_event: control.log("Setting stop event for proxy player") stop_event.set() control.infoDialog(message=control.lang(34100).encode('utf-8'), icon='ERROR') return None, None, None control.log("Resolved URL: %s" % repr(url)) if control.supports_offscreen: item = control.item(path=url, offscreen=True) else: item = control.item(path=url) item.setInfo(type='video', infoLabels=control.filter_info_labels(meta)) item.setArt(meta.get('art', {})) item.setProperty('IsPlayable', 'true') item.setContentLookup(False) user_agent = 'User-Agent=Globo Play/0 (iPhone)' if parsed_url.path.endswith(".mpd"): mime_type = 'application/dash+xml' if control.enable_inputstream_adaptive: control.log("Using inputstream.adaptive MPD") item.setProperty('inputstream.adaptive.manifest_type', 'mpd') item.setProperty('inputstream.adaptive.stream_headers', user_agent) item.setProperty('inputstreamaddon', 'inputstream.adaptive') if mime_type: item.setMimeType(mime_type) elif not cookies: item.setMimeType('application/vnd.apple.mpegurl') if control.enable_inputstream_adaptive: control.log("Using inputstream.adaptive HLS") item.setProperty('inputstream.adaptive.manifest_type', 'hls') item.setProperty('inputstream.adaptive.stream_headers', user_agent) item.setProperty('inputstreamaddon', 'inputstream.adaptive') encrypted = info.get('encrypted', False) if encrypted and not control.is_inputstream_available(): control.okDialog(control.lang(31200), control.lang(34103).encode('utf-8')) return if encrypted: control.log("DRM: %s" % info['drm_scheme']) licence_url = info['protection_url'] item.setProperty('inputstream.adaptive.license_type', info['drm_scheme']) if info['drm_scheme'] == 'com.widevine.alpha' or info[ 'drm_scheme'] == 'com.microsoft.playready': item.setProperty('inputstream.adaptive.license_key', licence_url + "||R{SSM}|") # if self.offset > 0: # duration = float(meta['duration']) if 'duration' in meta else 0 # if duration > 0: # item.setProperty('StartPercent', str((self.offset / duration) * 100)) # if self.offset > 0: # item.setProperty('resumetime', str(self.offset)) # duration = float(meta['duration']) if 'duration' in meta else self.offset # duration = duration * 1000.0 # item.setProperty('totaltime', str(duration)) if 'subtitles' in info and info['subtitles'] and len( info['subtitles']) > 0: item.setSubtitles([sub['url'] for sub in info['subtitles']]) return item, url, stop_event
def add_uncached_torrent(self, magnet_url, pack=False): def _return_failed(message=getLS(33586)): try: control.progressDialog.close() except: pass self.delete_torrent(torrent_id) control.hide() control.sleep(500) control.okDialog(title=getLS(40018), message=message) return False control.busy() try: active_count = self.torrents_activeCount() if active_count['nb'] >= active_count['limit']: return _return_failed() except: pass interval = 5 stalled = ['magnet_error', 'error', 'virus', 'dead'] extensions = supported_video_extensions() torrent_id = self.add_magnet(magnet_url) if not torrent_id: return _return_failed() torrent_info = self.torrent_info(torrent_id) if 'error_code' in torrent_info: return _return_failed() status = torrent_info['status'] line = '%s\n%s\n%s' if status == 'magnet_conversion': line1 = getLS(40013) line2 = torrent_info['filename'] line3 = getLS(40012) % str(torrent_info['seeders']) timeout = 100 control.progressDialog.create(getLS(40018), line % (line1, line2, line3)) while status == 'magnet_conversion' and timeout > 0: control.progressDialog.update(timeout, line % (line1, line2, line3)) if control.monitor.abortRequested(): return sysexit() try: if control.progressDialog.iscanceled(): return _return_failed(getLS(40014)) except: pass timeout -= interval control.sleep(1000 * interval) torrent_info = self.torrent_info(torrent_id) status = torrent_info['status'] if any(x in status for x in stalled): return _return_failed() line3 = getLS(40012) % str(torrent_info['seeders']) try: control.progressDialog.close() except: pass if status == 'downloaded': control.busy() return True if status == 'magnet_conversion': return _return_failed() if any(x in status for x in stalled): return _return_failed(status) if status == 'waiting_files_selection': video_files = [] append = video_files.append all_files = torrent_info['files'] for item in all_files: if any(item['path'].lower().endswith(x) for x in extensions): append(item) if pack: try: if len(video_files) == 0: return _return_failed() video_files.sort(key=lambda x: x['path']) torrent_keys = [str(i['id']) for i in video_files] if not torrent_keys: return _return_failed(getLS(40014)) torrent_keys = ','.join(torrent_keys) self.add_torrent_select(torrent_id, torrent_keys) control.okDialog(title='default', message=getLS(40017) % getLS(40058)) control.hide() return True # returning true here causes "success" to be returned and resolve runs on non valid link except: return _return_failed() else: try: video = max(video_files, key=lambda x: x['bytes']) file_id = video['id'] except ValueError: return _return_failed() self.add_torrent_select(torrent_id, str(file_id)) control.sleep(2000) torrent_info = self.torrent_info(torrent_id) status = torrent_info['status'] if status == 'downloaded': control.hide() control.notification(message=getLS(32057), icon=rd_icon) return True file_size = round(float(video['bytes']) / (1000 ** 3), 2) line1 = '%s...' % (getLS(40017) % getLS(40058)) line2 = torrent_info['filename'] line3 = status control.progressDialog.create(getLS(40018), line % (line1, line2, line3)) while not status == 'downloaded': control.sleep(1000 * interval) torrent_info = self.torrent_info(torrent_id) status = torrent_info['status'] if status == 'downloading': line3 = getLS(40011) % (file_size, round(float(torrent_info['speed']) / (1000**2), 2), torrent_info['seeders'], torrent_info['progress']) else: line3 = status control.progressDialog.update(int(float(torrent_info['progress'])), line % (line1, line2, line3)) if control.monitor.abortRequested(): return sysexit() try: if control.progressDialog.iscanceled(): if control.yesnoDialog('Delete RD download also?', 'No will continue the download', 'but close dialog'): return _return_failed(getLS(40014)) else: control.progressDialog.close() control.hide() return False except: pass if any(x in status for x in stalled): return _return_failed() try: control.progressDialog.close() except: pass control.hide() return True control.hide() return False
def doDownload(url, dest, title, image, headers): file = dest.rsplit(os.sep, 1)[-1] resp = getResponse(url, headers, 0) if not resp: control.hide() return control.okDialog( title, dest + 'Download failed: No response from server') try: content = int(resp.headers['Content-Length']) except: content = 0 try: resumable = 'bytes' in resp.headers['Accept-Ranges'].lower() except: resumable = False if content < 1: control.hide() return control.okDialog(title, file + 'Unknown filesize: Unable to download') size = 1024 * 1024 gb = str(round(content / float(1073741824), 2)) if content < size: size = content total = 0 notify = 0 errors = 0 count = 0 resume = 0 sleep = 0 control.hide() if control.yesnoDialog('File Size: %sGB' % gb, 'Path: %s' % dest, 'Continue with download?', '[B]Confirm Download[/B]', 'Confirm', 'Cancel') == 1: return f = control.openFile(dest, 'w') chunk = None chunks = [] while True: downloaded = total for c in chunks: downloaded += len(c) percent = min(100 * downloaded / content, 100) if percent >= notify: control.notification( title=str(int(percent)) + '%', message=title, icon=image, time=3000 ) #xbmcgui.Dialog().notification() auto scroll time to complete supercedes allowed "time=" to run in Silvo, removed dest notify += 20 chunk = None error = False try: chunk = resp.read(size) if not chunk: if percent < 99: error = True else: while len(chunks) > 0: c = chunks.pop(0) f.write(c) del c f.close() log_utils.log('Download Complete: %s' % (dest), level=log_utils.LOGDEBUG) return done(title, dest, True) except: log_utils.error('DOWNNLOADER EXCEPTION: ') error = True sleep = 10 errno = 0 if hasattr(e, 'errno'): errno = e.errno if errno == 10035: # 'A non-blocking socket operation could not be completed immediately' pass if errno == 10054: #'An existing connection was forcibly closed by the remote host' errors = 10 #force resume sleep = 30 if errno == 11001: # 'getaddrinfo failed' errors = 10 #force resume sleep = 30 if chunk: errors = 0 chunks.append(chunk) if len(chunks) > 5: c = chunks.pop(0) f.write(c) total += len(c) del c if error: errors += 1 count += 1 control.sleep(sleep * 1000) if (resumable and errors > 0) or errors >= 10: if (not resumable and resume >= 50) or resume >= 500: # Give up! log_utils.log( 'Download Canceled: %s - too many errors whilst downloading' % (dest), level=log_utils.LOGWARNING) return done(title, dest, False) resume += 1 errors = 0 if resumable: chunks = [] resp = getResponse(url, headers, total) # create new response else: pass
def playlive(self, id, meta): meta = meta or {} control.log("Now Online - play_stream: id=%s | meta=%s" % (id, meta)) if id is None: return self.isLive = meta.get('livefeed', False) try: url, avs_cookie, login_info, xsrf, device_id, sc_id, cdn_token = self.get_cdn( id, self.isLive) except Exception as ex: control.log(traceback.format_exc(), control.LOGERROR) control.okDialog(u'Now Online', ex.message) return encrypted = True if encrypted and not control.is_inputstream_available(): control.okDialog(u'Now Online', control.lang(34103).encode('utf-8')) return control.log("live media url: %s" % url) thumb = meta['thumb'] if 'thumb' in meta else None self.url = url if control.supports_offscreen: item = control.item(path=self.url, offscreen=True) else: item = control.item(path=self.url) item.setArt({'icon': thumb, 'thumb': thumb}) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=control.filter_info_labels(meta)) item.setContentLookup(False) item.setProperty('inputstream.adaptive.manifest_type', 'mpd') # if self.isLive: # item.setProperty('inputstream.adaptive.manifest_update_parameter', 'full') if encrypted: item.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') licence_url = 'https://proxy.claro01.verspective.net/multirights/widevine?deviceId={deviceId}'.format( deviceId=base64.urlsafe_b64encode(device_id)) key_headers = { 'Referer': 'https://www.nowonline.com.br/', 'Origin': 'https://www.nowonline.com.br', } video_type = 'LIVE' if self.isLive else 'VOD' if not self.isLive: url_id = 'https://www.nowonline.com.br/avsclient/contents/product/{id}?channel={platform}'.format( id=id, platform=PLATFORM) header = { 'referer': 'https://www.nowonline.com.br/', } if PLATFORM == 'PCTV': header['x-xsrf-token'] = xsrf cookies = {'avs_cookie': avs_cookie, 'LoginInfo': login_info} control.log('GET VOD ID: %s' % url_id) response = requests.get(url_id, headers=header, cookies=cookies, proxies=proxy).json() control.log(response) available = response.get('response', {}).get('watch', {}).get('available', False) if not available: control.okDialog(u'Now Online', 'Content not available') return cp_id = response.get('response', {}).get('cpId', -1) else: cp_id = id if PLATFORM == 'PCTV': account_device_id = '|accountDeviceId=1234567' if not self.isLive else '' key_headers[ 'privateData'] = 'cookie={avs_cookie}|avs_id={id}|platform={platform}|videoType={videoType}|session={cdn_token}|x-xsrf-token={xsrf}{account_device_id}'.format( avs_cookie=avs_cookie, id=cp_id, xsrf=xsrf, platform=PLATFORM, videoType=video_type, account_device_id=account_device_id, cdn_token=cdn_token) user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36' else: key_headers[ 'privateData'] = 'cookie={avs_cookie}|avs_id={id}|platform={platform}|videoType={videoType}|accountDeviceId={deviceId}||isDownload=Y'.format( avs_cookie=avs_cookie, id=cp_id, deviceId=device_id, platform=PLATFORM, videoType=video_type) user_agent = 'NOW/1 CFNetwork/1197 Darwin/20.0.0' key_headers['User-Agent'] = user_agent key_headers['content-type'] = 'application/octet-stream' license_key = '%s|%s|R{SSM}|' % (licence_url, urllib.urlencode(key_headers)) item.setProperty('inputstream.adaptive.license_key', license_key) item.setProperty('inputstream.adaptive.stream_headers', user_agent) control.log('license_key: %s' % license_key) if control.is_inputstream_available(): item.setProperty('inputstreamaddon', 'inputstream.adaptive') control.resolve(int(sys.argv[1]), True, item) control.log("Done playing. Quitting...")
def __get_list_item(self, meta, info, pick_bandwidth=True): hash = info['hash'] user = info['user'] title = info['title'] # or meta['title'] if 'title' in meta else None query_string = re.sub(r'{{(\w*)}}', r'%(\1)s', info['query_string_template']) query_string = query_string % { 'hash': hash, 'key': 'app', 'openClosed': 'F' if info['subscriber_only'] else 'A', 'user': user if info['subscriber_only'] else '' } url = '?'.join([info['url'], query_string]) control.log("live media url: %s" % url) meta.update({ "genre": info["category"], "plot": info["title"], "plotoutline": info["title"], "title": title }) poster = meta['poster'] if 'poster' in meta else control.addonPoster() thumb = meta['thumb'] if 'thumb' in meta else info["thumbUri"] parsed_url = urlparse(url) if parsed_url.path.endswith(".m3u8"): if pick_bandwidth: url, mime_type, stopEvent, cookies = hlshelper.pick_bandwidth( url) else: mime_type, stopEvent, cookies = None, None, None else: # self.url = url mime_type, stopEvent, cookies = 'video/mp4', None, None if url is None: if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.infoDialog(message=control.lang(34100).encode('utf-8'), icon='ERROR') return None, None, None control.log("Resolved URL: %s" % repr(url)) item = control.item(path=url) item.setInfo(type='video', infoLabels=meta) item.setArt({ 'icon': thumb, 'thumb': thumb, 'poster': poster, 'tvshow.poster': poster, 'season.poster': poster }) item.setProperty('IsPlayable', 'true') item.setContentLookup(False) if parsed_url.path.endswith(".mpd"): mime_type = 'application/dash+xml' if not control.disable_inputstream_adaptive: control.log("Using inputstream.adaptive MPD") item.setProperty('inputstream.adaptive.manifest_type', 'mpd') item.setProperty('inputstreamaddon', 'inputstream.adaptive') if mime_type: item.setMimeType(mime_type) elif not cookies: item.setMimeType('application/vnd.apple.mpegurl') if not control.disable_inputstream_adaptive: control.log("Using inputstream.adaptive HLS") item.setProperty('inputstream.adaptive.manifest_type', 'hls') item.setProperty('inputstreamaddon', 'inputstream.adaptive') encrypted = 'encrypted' in info and info['encrypted'] if encrypted and not control.is_inputstream_available(): control.okDialog(control.lang(31200), control.lang(34103).encode('utf-8')) return if encrypted: control.log("DRM: %s" % info['drm_scheme']) licence_url = info['protection_url'] item.setProperty('inputstream.adaptive.license_type', info['drm_scheme']) if info['drm_scheme'] == 'com.widevine.alpha' or info[ 'drm_scheme'] == 'com.microsoft.playready': item.setProperty('inputstream.adaptive.license_key', licence_url + "||R{SSM}|") # if self.offset > 0: # duration = float(meta['duration']) if 'duration' in meta else 0 # if duration > 0: # item.setProperty('StartPercent', str((self.offset / duration) * 100)) # if self.offset > 0: # item.setProperty('resumetime', str(self.offset)) # duration = float(meta['duration']) if 'duration' in meta else self.offset # duration = duration * 1000.0 # item.setProperty('totaltime', str(duration)) if 'subtitles' in info and info['subtitles'] and len( info['subtitles']) > 0: item.setSubtitles([sub['url'] for sub in info['subtitles']]) return item, url, stopEvent
def playlive(self, id, meta, encrypted=False): meta = meta or {} control.log("TNT Play - play_stream: id=%s | meta=%s" % (id, meta)) if id is None: return try: url = self.geturl(id, encrypted=encrypted) except Exception as ex: control.log(traceback.format_exc(), control.LOGERROR) control.okDialog(u'TNT Play', str(ex)) return if encrypted and not control.is_inputstream_available(): control.okDialog(u'TNT Play', control.lang(34103).encode('utf-8')) self.stop_content(id, encrypted=encrypted) return control.log("media url: %s" % url) self.offset = float(meta['milliseconds_watched']) / 1000.0 if 'milliseconds_watched' in meta else 0 self.isLive = not encrypted parsed_url = urlparse(url) # if ".m3u8" in parsed_url.path: # self.url, mime_type, stop_event, cookies = hlshelper.pick_bandwidth(url) # else: # self.url = url # mime_type, stop_event, cookies = None, None, None proxy_handler = MediaProxy(control.proxy_url) self.url = proxy_handler.resolve(url) stop_event = proxy_handler.stop_event mime_type = None cookies = None if self.url is None: if stop_event: control.log("Setting stop event for proxy player") stop_event.set() control.infoDialog(control.lang(34100).encode('utf-8'), icon='ERROR') return control.log("Resolved URL: %s" % repr(self.url)) control.log("Parsed URL: %s" % repr(parsed_url)) if control.supports_offscreen: item = control.item(path=self.url, offscreen=True) else: item = control.item(path=self.url) item.setArt(meta.get('art', {})) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=control.filter_info_labels(meta)) item.setContentLookup(False) manifest_type = 'hls' if parsed_url.path.endswith(".m3u8") else 'mpd' if encrypted: control.log("DRM: com.widevine.alpha") licence_url = 'https://widevine.license.istreamplanet.com/widevine/api/license/7837c2c6-8fe4-4db0-9900-1bd66c21ffa3' item.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') item.setProperty('inputstream.adaptive.manifest_type', manifest_type) cookie = get_token() retry = 1 token = '' while retry >= 0: retry = retry - 1 headers = { 'Accept': 'application/json', 'cookie': 'avs_cookie=' + cookie, 'User-Agent': 'Tnt/2.2.13.1908061505 CFNetwork/1107.1 Darwin/19.0.0' } drm_url = 'https://api.tntgo.tv/AGL/1.0/A/{lang}/{platform}/TNTGO_LATAM_BR/CONTENT/GETDRMTOKEN/{id}'.format(lang=LANGUAGE, platform=vod_platform, id=id) control.log('TNT DRM GET %s' % drm_url) control.log(headers) drm_response = requests.get(drm_url, headers=headers, proxies=proxy).json() or {} control.log(drm_response) if drm_response.get('resultCode', 'KO') == u'OK': token = drm_response.get('resultObj') break if drm_response.get('message', '') == 'Token not valid': cookie = get_token(True) else: logout() control.infoDialog(drm_response.get('message', u'DRM ERROR'), icon='ERROR') self.stop_content(id, encrypted=encrypted) return headers = { 'user-agent': 'Tnt/2.2.13.1908061505 CFNetwork/1107.1 Darwin/19.0.0', 'x-isp-token': token, 'Origin': 'https://www.tntgo.tv', 'content-type': 'application/octet-stream' } license_key = '%s|%s|R{SSM}|' % (licence_url, urllib.urlencode(headers)) item.setProperty('inputstream.adaptive.license_key', license_key) stream_headers = { 'user-agent': 'Tnt/2.2.13.1908061505 CFNetwork/1107.1 Darwin/19.0.0', 'Origin': 'https://www.tntgo.tv' } item.setProperty('inputstream.adaptive.stream_headers', urllib.urlencode(stream_headers)) else: item.setProperty('inputstream.adaptive.manifest_type', 'hls') # mime_type = 'application/vnd.apple.mpegurl' # item.setProperty('inputstream.adaptive.manifest_update_parameter', 'full') if mime_type: item.setMimeType(mime_type) control.log("MIME TYPE: %s" % repr(mime_type)) if control.is_inputstream_available(): item.setProperty('inputstreamaddon', 'inputstream.adaptive') item.setProperty('inputstream', 'inputstream.adaptive') # Kodi 19 control.resolve(int(sys.argv[1]), True, item) self.stopPlayingEvent = threading.Event() self.stopPlayingEvent.clear() while not self.stopPlayingEvent.isSet(): if control.monitor.abortRequested(): control.log("Abort requested") break if self.isPlaying(): self.current_time = self.getTime() control.sleep(100) if stop_event: control.log("Setting stop event for proxy player") stop_event.set() self.stop_content(id, encrypted=encrypted) control.log("Done playing. Quitting...")
def playlive(self, id, meta): meta = meta or {} control.log("Globosat Play - play_stream: id=%s | meta=%s" % (id, meta)) if id is None: return self.isLive = meta.get('livefeed', False) cdn = control.setting('globosat_cdn') if cdn: cdn = cdn.lower() if cdn.lower() != 'auto' else None if meta.get('geofencing') and meta.get('lat') and meta.get('long'): info = resourceshelper.get_geofence_video_info( id, meta.get('lat'), meta.get('long'), auth_helper.get_credentials(), cdn) elif not meta.get('router', True) or cdn: info = resourceshelper.get_video_info(id, cdn=cdn) else: info = resourceshelper.get_video_router(id, self.isLive, cdn) if not info: info = resourceshelper.get_video_info(id, cdn=cdn) control.log("INFO: %s" % repr(info)) if not info or info is None or 'channel' not in info: return try: hash_token = info.get('hash_token') user = info.get('user') if not hash_token: control.log('Signing resource: %s' % info['resource_id']) hash_token, user, credentials = self.sign_resource( info['provider_id'], info['resource_id'], id, info['player'], info['version'], cdn) except Exception as ex: control.log(traceback.format_exc(), control.LOGERROR) control.log("PLAYER ERROR: %s" % repr(ex)) return encrypted = 'encrypted' in info and info['encrypted'] if encrypted and not control.is_inputstream_available(): control.okDialog(control.lang(31200), control.lang(34103).encode('utf-8')) return query_string = re.sub(r'{{(\w*)}}', r'%(\1)s', info['query_string_template']) query_string = query_string % { 'hash': hash_token, 'key': 'app', 'openClosed': 'F' if info['subscriber_only'] and user else 'A', 'user': user if info['subscriber_only'] and user else '', 'token': hash_token } url = '?'.join([info['url'], query_string]) control.log("live media url: %s" % url) self.offset = float(meta['milliseconds_watched'] ) / 1000.0 if 'milliseconds_watched' in meta else 0 parsed_url = urlparse(url) if parsed_url.path.endswith(".m3u8"): self.url, mime_type, stop_event, cookies = hlshelper.pick_bandwidth( url) elif parsed_url.path.endswith(".mpd") and not self.isLive: proxy_handler = MediaProxy() self.url = proxy_handler.resolve(url) stop_event = proxy_handler.stop_event mime_type = None cookies = None else: self.url = url mime_type, stop_event, cookies = 'video/mp4', None, None if self.url is None: if stop_event: control.log("Setting stop event for proxy player") stop_event.set() control.infoDialog(control.lang(34100).encode('utf-8'), icon='ERROR') return control.log("Resolved URL: %s" % repr(self.url)) control.log("Parsed URL: %s" % repr(parsed_url)) if control.supports_offscreen: item = control.item(path=self.url, offscreen=True) else: item = control.item(path=self.url) item.setArt(meta.get('art', {})) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=control.filter_info_labels(meta)) item.setContentLookup(False) if parsed_url.path.endswith(".mpd"): mime_type = 'application/dash+xml' item.setProperty('inputstream.adaptive.manifest_type', 'mpd') if self.isLive: item.setProperty( 'inputstream.adaptive.manifest_update_parameter', 'full') elif parsed_url.path.endswith(".ism/manifest"): mime_type = 'application/vnd.ms-sstr+xml' item.setProperty('inputstream.adaptive.manifest_type', 'ism') else: item.setProperty('inputstream.adaptive.manifest_type', 'hls') if encrypted: control.log("DRM: %s" % info['drm_scheme']) licence_url = info['protection_url'] item.setProperty('inputstream.adaptive.license_type', info['drm_scheme']) if info['drm_scheme'] == 'com.widevine.alpha' or info[ 'drm_scheme'] == 'com.microsoft.playready': item.setProperty('inputstream.adaptive.license_key', licence_url + "||R{SSM}|") if mime_type: item.setMimeType(mime_type) control.log("MIME TYPE: %s" % repr(mime_type)) if not cookies and control.is_inputstream_available(): item.setProperty('inputstreamaddon', 'inputstream.adaptive') # reqCookies = client.request(url=self.url,output='cookiejar',headRequest=True) # cookie_string = "; ".join([str(x) + "=" + str(y) for x, y in reqCookies.items()]) # item.setProperty('inputstream.adaptive.stream_headers', 'cookie=%s' % cookie_string) # control.log("COOKIE STRING: %s" % cookie_string) if 'subtitles' in info and info['subtitles'] and len( info['subtitles']) > 0: control.log("FOUND SUBTITLES: %s" % repr([sub['url'] for sub in info['subtitles']])) item.setSubtitles([sub['url'] for sub in info['subtitles']]) control.resolve(int(sys.argv[1]), True, item) self.stopPlayingEvent = threading.Event() self.stopPlayingEvent.clear() self.token = auth_helper.get_globosat_token() self.video_id = info['id'] if 'id' in info else None first_run = True last_time = 0.0 while not self.stopPlayingEvent.isSet(): if control.monitor.abortRequested(): control.log("Abort requested") break if self.isPlaying(): if first_run: self.showSubtitles(False) first_run = False if not self.isLive: current_time = self.getTime() if current_time - last_time > 5 or (last_time == 0 and current_time > 1): last_time = current_time self.save_video_progress(self.token, self.video_id, current_time) control.sleep(1000) if stop_event: control.log("Setting stop event for proxy player") stop_event.set() control.log("Done playing. Quitting...")
def playlive(self, id, meta): control.log("Globosat Play - play_stream: id=%s | meta=%s" % (id, meta)) if id is None: return info = resourceshelper.get_video_info(id) control.log("INFO: %s" % repr(info)) if not info or info is None or 'channel' not in info: return try: hash, user, credentials = self.sign_resource( info['provider_id'], info['resource_id'], id, info['player'], info['version']) except Exception as ex: control.log("ERROR: %s" % repr(ex)) return encrypted = 'encrypted' in info and info['encrypted'] if encrypted and not control.is_inputstream_available(): control.okDialog(control.lang(31200), control.lang(34103).encode('utf-8')) return title = info['channel'] query_string = re.sub(r'{{(\w*)}}', r'%(\1)s', info['query_string_template']) query_string = query_string % { 'hash': hash, 'key': 'app', 'openClosed': 'F' if info['subscriber_only'] else 'A', 'user': user if info['subscriber_only'] else '' } url = '?'.join([info['url'], query_string]) control.log("live media url: %s" % url) try: meta = json.loads(meta) except: meta = { "playcount": 0, "overlay": 6, "title": title, "thumb": info["thumbUri"], "mediatype": "video", "aired": info["exhibited_at"] } meta.update({ "genre": info["category"], "plot": info["title"], "plotoutline": info["title"] }) poster = meta['poster'] if 'poster' in meta else control.addonPoster() thumb = meta['thumb'] if 'thumb' in meta else info["thumbUri"] self.offset = float(meta['milliseconds_watched'] ) / 1000.0 if 'milliseconds_watched' in meta else 0 self.isLive = 'livefeed' in meta and meta['livefeed'] == 'true' parsed_url = urlparse(url) if parsed_url.path.endswith(".m3u8"): self.url, mime_type, stopEvent, cookies = hlshelper.pick_bandwidth( url) else: self.url = url mime_type, stopEvent, cookies = 'video/mp4', None, None if self.url is None: if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.infoDialog(control.lang(34100).encode('utf-8'), icon='ERROR') return control.log("Resolved URL: %s" % repr(self.url)) control.log("Parsed URL: %s" % repr(parsed_url)) item = control.item(path=self.url) item.setArt({ 'icon': thumb, 'thumb': thumb, 'poster': poster, 'tvshow.poster': poster, 'season.poster': poster }) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=meta) item.setContentLookup(False) if parsed_url.path.endswith(".mpd"): mime_type = 'application/dash+xml' item.setProperty('inputstream.adaptive.manifest_type', 'mpd') if self.isLive: item.setProperty( 'inputstream.adaptive.manifest_update_parameter', 'full') elif parsed_url.path.endswith(".ism/manifest"): mime_type = 'application/vnd.ms-sstr+xml' item.setProperty('inputstream.adaptive.manifest_type', 'ism') else: item.setProperty('inputstream.adaptive.manifest_type', 'hls') if encrypted: control.log("DRM: %s" % info['drm_scheme']) licence_url = info['protection_url'] item.setProperty('inputstream.adaptive.license_type', info['drm_scheme']) if info['drm_scheme'] == 'com.widevine.alpha' or info[ 'drm_scheme'] == 'com.microsoft.playready': item.setProperty('inputstream.adaptive.license_key', licence_url + "||R{SSM}|") if mime_type: item.setMimeType(mime_type) control.log("MIME TYPE: %s" % repr(mime_type)) if not cookies and control.is_inputstream_available(): item.setProperty('inputstreamaddon', 'inputstream.adaptive') # reqCookies = client.request(url=self.url,output='cookiejar',headRequest=True) # cookie_string = "; ".join([str(x) + "=" + str(y) for x, y in reqCookies.items()]) # item.setProperty('inputstream.adaptive.stream_headers', 'cookie=%s' % cookie_string) # control.log("COOKIE STRING: %s" % cookie_string) if 'subtitles' in info and info['subtitles'] and len( info['subtitles']) > 0: control.log("FOUND SUBTITLES: %s" % repr([sub['url'] for sub in info['subtitles']])) item.setSubtitles([sub['url'] for sub in info['subtitles']]) control.resolve(int(sys.argv[1]), True, item) self.stopPlayingEvent = threading.Event() self.stopPlayingEvent.clear() self.token = auth_helper.get_globosat_token() self.video_id = info['id'] if 'id' in info else None first_run = True last_time = 0.0 while not self.stopPlayingEvent.isSet(): if control.monitor.abortRequested(): control.log("Abort requested") break if self.isPlaying(): if first_run: self.showSubtitles(False) first_run = False if not self.isLive: current_time = self.getTime() if current_time - last_time > 5 or (last_time == 0 and current_time > 1): last_time = current_time self.save_video_progress(self.token, self.video_id, current_time) control.sleep(1000) if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.log("Done playing. Quitting...")
def playlive(self, id, meta): meta = meta or {} control.log("Oi Play - play_stream: id=%s | meta=%s" % (id, meta)) if id is None: return provider = meta.get('provider') self.isLive = meta.get('livefeed', False) data = self.individualize(self.isLive, id, provider) if not data or 'individualization' not in data: error_message = '%s: %s' % ( data.get('reason'), data.get('detail')) if data and data.get( 'reason') else control.lang(34100).encode('utf-8') control.infoDialog(error_message, icon='ERROR') return encrypted = 'drm' in data and 'licenseUrl' in data['drm'] if encrypted and not control.is_inputstream_available(): control.okDialog(u'Oi Play', control.lang(34103).encode('utf-8')) return url = data['individualization']['url'] # info = data.get('token', {}).get('cmsChannelItem') or data.get('token', {}).get('cmsContentItem') control.log("live media url: %s" % url) self.offset = float(meta['milliseconds_watched'] ) / 1000.0 if 'milliseconds_watched' in meta else 0 parsed_url = urlparse(url) if ".m3u8" in parsed_url.path: self.url, mime_type, stopEvent, cookies = hlshelper.pick_bandwidth( url) else: self.url = url mime_type, stopEvent, cookies = 'video/mp4', None, None if self.url is None: if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.infoDialog(control.lang(34100).encode('utf-8'), icon='ERROR') return control.log("Resolved URL: %s" % repr(self.url)) control.log("Parsed URL: %s" % repr(parsed_url)) if control.supports_offscreen: item = control.item(path=self.url, offscreen=True) else: item = control.item(path=self.url) item.setArt(meta.get('art', {})) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=control.filter_info_labels(meta)) item.setContentLookup(False) if ".mpd" in parsed_url.path: mime_type = 'application/dash+xml' item.setProperty('inputstream.adaptive.manifest_type', 'mpd') if self.isLive: item.setProperty( 'inputstream.adaptive.manifest_update_parameter', 'full') else: item.setProperty('inputstream.adaptive.manifest_type', 'hls') if encrypted: control.log("DRM: com.widevine.alpha") # licence_url = data['drm']['licenseUrl'] + '&token=' + data['drm']['jwtToken'] if data.get('drm', {}).get('jwtToken'): licence_url = '%s&token=%s' % (data.get( 'drm', {}).get('licenseUrl'), data.get('drm', {}).get('jwtToken')) else: licence_url = data.get('drm', {}).get('licenseUrl') item.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') item.setProperty('inputstream.adaptive.license_key', licence_url + "||R{SSM}|") if mime_type: item.setMimeType(mime_type) control.log("MIME TYPE: %s" % repr(mime_type)) if not cookies and control.is_inputstream_available(): item.setProperty('inputstreamaddon', 'inputstream.adaptive') # if 'subtitles' in info and info['subtitles'] and len(info['subtitles']) > 0: # control.log("FOUND SUBTITLES: %s" % repr([sub['url'] for sub in info['subtitles']])) # item.setSubtitles([sub['url'] for sub in info['subtitles']]) control.resolve(int(sys.argv[1]), True, item) self.stopPlayingEvent = threading.Event() self.stopPlayingEvent.clear() first_run = True # last_time = 0.0 while not self.stopPlayingEvent.isSet(): if control.monitor.abortRequested(): control.log("Abort requested") break if self.isPlaying(): if first_run: self.showSubtitles(False) first_run = False # if not self.isLive: # current_time = self.getTime() # if current_time - last_time > 5 or (last_time == 0 and current_time > 1): # last_time = current_time # self.save_video_progress(self.token, self.video_id, current_time) control.sleep(1000) if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.log("Done playing. Quitting...")
def playlive(self, id, meta, encrypted=False): control.log("TNT Play - play_stream: id=%s | meta=%s" % (id, meta)) if id is None: return try: url = self.geturl(id, encrypted=encrypted) except Exception as ex: control.log(traceback.format_exc(), control.LOGERROR) control.okDialog(u'TNT Play', str(ex)) return if encrypted and not control.is_inputstream_available(): control.okDialog(u'TNT Play', control.lang(34103).encode('utf-8')) return control.log("live media url: %s" % url) try: meta = json.loads(meta) except: meta = { "playcount": 0, "overlay": 6, } poster = meta['poster'] if 'poster' in meta else None thumb = meta['thumb'] if 'thumb' in meta else None self.offset = float(meta['milliseconds_watched'] ) / 1000.0 if 'milliseconds_watched' in meta else 0 self.isLive = not encrypted parsed_url = urlparse(url) if ".m3u8" in parsed_url.path: self.url, mime_type, stopEvent, cookies = hlshelper.pick_bandwidth( url) else: self.url = url mime_type, stopEvent, cookies = None, None, None if self.url is None: if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.infoDialog(control.lang(34100).encode('utf-8'), icon='ERROR') return control.log("Resolved URL: %s" % repr(self.url)) control.log("Parsed URL: %s" % repr(parsed_url)) item = control.item(path=self.url) item.setArt({'icon': thumb, 'thumb': thumb, 'poster': poster}) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=control.filter_info_labels(meta)) item.setContentLookup(False) manifest_type = 'hls' if parsed_url.path.endswith(".m3u8") else 'mpd' if encrypted: control.log("DRM: com.widevine.alpha") licence_url = 'https://widevine.license.istreamplanet.com/widevine/api/license/7837c2c6-8fe4-4db0-9900-1bd66c21ffa3' item.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') item.setProperty('inputstream.adaptive.manifest_type', manifest_type) cookie = get_token() retry = 1 token = '' while retry >= 0: retry = retry - 1 headers = { 'Accept': 'application/json', 'cookie': 'avs_cookie=' + cookie, 'User-Agent': 'Tnt/2.2.13.1908061505 CFNetwork/1107.1 Darwin/19.0.0' } drm_url = 'https://api.tntgo.tv/AGL/1.0/A/{lang}/{platform}/TNTGO_LATAM_BR/CONTENT/GETDRMTOKEN/{id}'.format( lang=LANGUAGE, platform=vod_platform, id=id) control.log('TNT DRM GET %s' % drm_url) control.log(headers) drm_response = requests.get( drm_url, headers=headers, proxies=proxy).json() or {} control.log(drm_response) if drm_response.get('resultCode', 'KO') == u'OK': token = drm_response.get('resultObj') break if drm_response.get('message', '') == 'Token not valid': cookie = get_token(True) else: logout() control.infoDialog(drm_response.get( 'message', u'DRM ERROR'), icon='ERROR') return key_headers = 'x-isp-token=%s&Origin=https://www.tntgo.tv' % token license_key = '%s|%s|R{SSM}|' % (licence_url, key_headers) item.setProperty('inputstream.adaptive.license_key', license_key) else: item.setProperty('inputstream.adaptive.manifest_type', 'hls') # mime_type = 'application/vnd.apple.mpegurl' # item.setProperty('inputstream.adaptive.manifest_update_parameter', 'full') if mime_type: item.setMimeType(mime_type) control.log("MIME TYPE: %s" % repr(mime_type)) if not cookies and control.is_inputstream_available(): item.setProperty('inputstreamaddon', 'inputstream.adaptive') item.setProperty('inputstream', 'inputstream.adaptive') # Kodi 19 control.resolve(int(sys.argv[1]), True, item) control.log("Done playing. Quitting...")
def add_uncached_torrent(self, magnet_url, pack=False): def _transfer_info(transfer_id): info = self.list_transfer() if 'status' in info and info['status'] == 'success': for item in info['transfers']: if item['id'] == transfer_id: return item return {} def _return_failed(message=control.lang(33586)): try: control.progressDialog.close() except: pass self.delete_transfer(transfer_id) control.hide() control.sleep(500) control.okDialog(title=control.lang(40018), message=message) return False control.busy() extensions = supported_video_extensions() transfer_id = self.create_transfer(magnet_url) if not transfer_id: return control.hide() if not transfer_id['status'] == 'success': return _return_failed() transfer_id = transfer_id['id'] transfer_info = _transfer_info(transfer_id) if not transfer_info: return _return_failed() if pack: control.hide() control.okDialog(title='default', message=control.lang(40017) % control.lang(40057)) return True interval = 5 line1 = '%s...' % (control.lang(40017) % control.lang(40057)) line2 = transfer_info['name'] line3 = transfer_info['message'] control.progressDialog.create(control.lang(40018), line1, line2, line3) while not transfer_info['status'] == 'seeding': control.sleep(1000 * interval) transfer_info = _transfer_info(transfer_id) line3 = transfer_info['message'] control.progressDialog.update(int( float(transfer_info['progress']) * 100), line3=line3) if control.monitor.abortRequested(): return sysexit() try: if control.progressDialog.iscanceled(): if control.yesnoDialog('Delete PM download also?', 'No will continue the download', 'but close dialog'): return _return_failed(control.lang(40014)) else: control.progressDialog.close() control.hide() return False except: pass if transfer_info.get('status') == 'stalled': return _return_failed() control.sleep(1000 * interval) try: control.progressDialog.close() except: log_utils.error() control.hide() return True
def playlive(self, id, meta): control.log("Oi Play - play_stream: id=%s | meta=%s" % (id, meta)) if id is None: return data = self.individualize(id) encrypted = 'drm' in data and 'licenseUrl' in data['drm'] if encrypted and not control.is_inputstream_available(): control.okDialog(u'Oi Play', control.lang(34103).encode('utf-8')) return url = data['individualization']['url'] url = url.replace('https://', 'http://') # hack info = data['token']['cmsChannelItem'] title = info['title'] control.log("live media url: %s" % url) try: meta = json.loads(meta) except: meta = { "playcount": 0, "overlay": 6, "title": title, "thumb": info['positiveLogoUrl'], "mediatype": "video", "aired": None, "genre": info["categoryName"], "plot": title, "plotoutline": title } # meta.update({ # "genre": info["categoryName"], # "plot": title, # "plotoutline": title # }) # poster = meta['poster'] if 'poster' in meta else control.addonPoster() thumb = meta['thumb'] if 'thumb' in meta else info['positiveLogoUrl'] self.offset = float(meta['milliseconds_watched'] ) / 1000.0 if 'milliseconds_watched' in meta else 0 self.isLive = info['isLive'] parsed_url = urlparse(url) if ".m3u8" in parsed_url.path: self.url, mime_type, stopEvent, cookies = hlshelper.pick_bandwidth( url) else: self.url = url mime_type, stopEvent, cookies = 'video/mp4', None, None if self.url is None: if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.infoDialog(control.lang(34100).encode('utf-8'), icon='ERROR') return control.log("Resolved URL: %s" % repr(self.url)) control.log("Parsed URL: %s" % repr(parsed_url)) item = control.item(path=self.url) item.setArt({'icon': thumb, 'thumb': thumb}) item.setProperty('IsPlayable', 'true') item.setInfo(type='Video', infoLabels=control.filter_info_labels(meta)) item.setContentLookup(False) if ".mpd" in parsed_url.path: mime_type = 'application/dash+xml' item.setProperty('inputstream.adaptive.manifest_type', 'mpd') if self.isLive: item.setProperty( 'inputstream.adaptive.manifest_update_parameter', 'full') else: item.setProperty('inputstream.adaptive.manifest_type', 'hls') if encrypted: control.log("DRM: com.widevine.alpha") licence_url = data['drm']['licenseUrl'] + '&token=' + data['drm'][ 'jwtToken'] item.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') item.setProperty('inputstream.adaptive.license_key', licence_url + "||R{SSM}|") if mime_type: item.setMimeType(mime_type) control.log("MIME TYPE: %s" % repr(mime_type)) if not cookies and control.is_inputstream_available(): item.setProperty('inputstreamaddon', 'inputstream.adaptive') # if 'subtitles' in info and info['subtitles'] and len(info['subtitles']) > 0: # control.log("FOUND SUBTITLES: %s" % repr([sub['url'] for sub in info['subtitles']])) # item.setSubtitles([sub['url'] for sub in info['subtitles']]) control.resolve(int(sys.argv[1]), True, item) self.stopPlayingEvent = threading.Event() self.stopPlayingEvent.clear() first_run = True # last_time = 0.0 while not self.stopPlayingEvent.isSet(): if control.monitor.abortRequested(): control.log("Abort requested") break if self.isPlaying(): if first_run: self.showSubtitles(False) first_run = False # if not self.isLive: # current_time = self.getTime() # if current_time - last_time > 5 or (last_time == 0 and current_time > 1): # last_time = current_time # self.save_video_progress(self.token, self.video_id, current_time) control.sleep(1000) if stopEvent: control.log("Setting stop event for proxy player") stopEvent.set() control.log("Done playing. Quitting...")
def search(query, page=1): if not query: yield control.run_plugin_url() return print('[BRplay] - search: %s | %s' % (query, page)) threads = [] if control.is_globoplay_available(): threads.append( workers.Thread(convert_to_list, globoplay.search, query, page)) if control.is_globosat_available(): threads.append( workers.Thread(convert_to_list, globosat.search, query, page)) if control.is_telecine_available(): threads.append( workers.Thread(convert_to_list, telecine.search, query, page)) if control.is_oiplay_available(): threads.append( workers.Thread(convert_to_list, oiplay.search, query, page)) if control.is_nowonline_available(): threads.append( workers.Thread(convert_to_list, netnow.search, query, page)) if control.is_tntplay_available(): threads.append( workers.Thread(convert_to_list, tnt_vod.search, query, page)) [i.start() for i in threads] [i.join() for i in threads] random.shuffle(threads) all_results = (thread.get_result() for thread in threads) control.log(all_results) combined = list(roundrobin(*all_results)) # combined = chain(*all_results) has_next_page = False if not combined: control.okDialog(line1=control.lang(34141).encode('utf-8'), heading=control.lang(32010).encode('utf-8')) yield control.run_plugin_url() return rank = 1 for result in combined: if result.get('page'): has_next_page = True continue result.update({ 'sort': [(control.SORT_METHOD_UNSORTED, '%U'), control.SORT_METHOD_STUDIO], # 'sort': [(control.SORT_METHOD_TRACKNUM, '%U'), control.SORT_METHOD_STUDIO, (control.SORT_METHOD_LABEL_IGNORE_FOLDERS, '%U')], 'tracknumber': rank, 'sorttitle': '%04d' % (rank, ), 'content': 'episodes', 'mediatype': 'video' }) rank += 1 yield result if has_next_page: yield { 'handler': __name__, 'method': 'search', 'query': query, 'page': page + 1, 'label': '%s (%s)' % (control.lang(34136).encode('utf-8'), page + 1), 'art': { 'poster': control.addonNext(), 'fanart': control.addonFanart() }, 'properties': { 'SpecialSort': 'bottom' } }
def revoke_auth(self): control.setSetting('alldebrid.token', '') control.setSetting('alldebrid.username', '') control.okDialog(title=40059, message=40009) # # from resolveURL # def get_all_hosters(self): # hosters = [] # url = '{0}/user/hosts?agent={1}&apikey={2}'.format(api_url, urllib_parse.quote_plus(AGENT), self.get_setting('token')) # try: # result = self.net.http_GET(url, headers=self.headers).content # js_data = jsloads(result) # if js_data.get('status', False) == "success": # js_data = js_data.get('data') # regexes = [value.get('regexp') for _, value in js_data.get('hosts', {}).items() # if value.get('status', False)] # hosters = [re.compile(regex) for regex in regexes] # logger.log_debug('AllDebrid hosters : {0}'.format(len(hosters))) # regexes = [value.get('regexp') for _, value in js_data.get('streams', {}).items()] # streamers = [] # for regex in regexes: # try: # streamers.append(re.compile(regex)) # except: # pass # logger.log_debug('AllDebrid Streamers : {0}'.format(len(streamers))) # hosters.extend(streamers) # logger.log_debug('AllDebrid Total hosters : {0}'.format(len(hosters))) # else: # logger.log_error('Error getting AD Hosters') # except Exception as e: # log_utils.log('Error getting AD hosts: %s' % e, __name__, log_utils.LOGDEBUG) # return hosters # # from resolveURL # def get_hosts(self): # hosts = [] # url = '{0}/hosts/domains?agent={1}&apikey={2}'.format(api_url, urllib_parse.quote_plus(AGENT), self.get_setting('token')) # try: # js_result = self.net.http_GET(url, headers=self.headers).content # js_data = jsloads(js_result) # if js_data.get('status', False) == "success": # # hosts = [host.replace('www.', '') for host in js_data.get('hosts', [])] # hosts = js_data.get('data').get('hosts') # hosts.extend(js_data.get('data').get('streams')) # if self.get_setting('torrents') == 'true': # hosts.extend(['torrent', 'magnet']) # logger.log_debug('AllDebrid hosts : {0}'.format(hosts)) # else: # logger.log_error('Error getting AD Hosts') # except Exception as e: # log_utils.log('Error getting AD hosts: %s' % e, __name__, log_utils.LOGDEBUG) # return hosts # # from resolveURL # def valid_url(self, url, host): # logger.log_debug('in valid_url {0} : {1}'.format(url, host)) # if url: # if url.lower().startswith('magnet:') and self.get_setting('torrents') == 'true': # return True # if self.hosters is None: # self.hosters = self.get_all_hosters() # for regexp in self.hosters: # if re.search(regexp, url): # logger.log_debug('AllDebrid Match found') # return True # elif host: # if self.hosts is None: # self.hosts = self.get_hosts() # if any(host in item for item in self.hosts): # return True # return False
def add_uncached_torrent(self, magnet_url, pack=False): def _return_failed(message=control.lang(33586)): try: control.progressDialog.close() except: pass self.delete_torrent(torrent_id) control.hide() control.sleep(500) control.okDialog(title=control.lang(40018), message=message) return False control.busy() try: active_count = self.torrents_activeCount() if active_count['nb'] >= active_count['limit']: return _return_failed() except: pass interval = 5 stalled = ['magnet_error', 'error', 'virus', 'dead'] extensions = supported_video_extensions() torrent = self.add_magnet(magnet_url) # if not transfer_id: # check if this is needed # control.hide() # return torrent_id = torrent['id'] if not torrent_id: return _return_failed() torrent_info = self.torrent_info(torrent_id) if 'error_code' in torrent_info: # log_utils.log('torrent_info = %s' % torrent_info, __name__, log_utils.LOGDEBUG) return _return_failed() status = torrent_info['status'] if status == 'magnet_conversion': line1 = control.lang(40013) line2 = torrent_info['filename'] line3 = control.lang(40012) % str(torrent_info['seeders']) timeout = 100 control.progressDialog.create(control.lang(40018), line1, line2, line3) while status == 'magnet_conversion' and timeout > 0: control.progressDialog.update(timeout, line3=line3) if control.monitor.abortRequested(): return sys.exit() try: if control.progressDialog.iscanceled(): return _return_failed(control.lang(40014)) except: pass if any(x in status for x in stalled): return _return_failed() timeout -= interval control.sleep(1000 * interval) torrent_info = self.torrent_info(torrent_id) status = torrent_info['status'] line3 = control.lang(40012) % str(torrent_info['seeders']) try: control.progressDialog.close() except: pass if status == 'magnet_conversion': return _return_failed() if status == 'waiting_files_selection': video_files = [] all_files = torrent_info['files'] for item in all_files: if any(item['path'].lower().endswith(x) for x in extensions): video_files.append(item) if pack: try: if len(video_files) == 0: return _return_failed() video_files = sorted(video_files, key=lambda x: x['path']) torrent_keys = [str(i['id']) for i in video_files] if not torrent_keys: return _return_failed(control.lang(40014)) torrent_keys = ','.join(torrent_keys) self.select_file(torrent_id, torrent_keys) control.okDialog(title='default', message=control.lang(40017) % control.lang(40058)) # self.clear_cache() control.hide() return True except: return _return_failed() else: try: video = max(video_files, key=lambda x: x['bytes']) file_id = video['id'] except ValueError: return _return_failed() self.select_file(torrent_id, str(file_id)) control.sleep(2000) torrent_info = self.torrent_info(torrent_id) status = torrent_info['status'] if status == 'downloaded': return True file_size = round(float(video['bytes']) / (1000**3), 2) line1 = '%s...' % (control.lang(40017) % control.lang(40058)) line2 = torrent_info['filename'] line3 = status control.progressDialog.create(ls(40018), line1, line2, line3) while not status == 'downloaded': control.sleep(1000 * interval) torrent_info = self.torrent_info(torrent_id) status = torrent_info['status'] if status == 'downloading': line3 = control.lang(40011) % ( file_size, round(float(torrent_info['speed']) / (1000**2), 2), torrent_info['seeders'], torrent_info['progress']) else: line3 = status control.progressDialog.update(int( float(torrent_info['progress'])), line3=line3) if control.monitor.abortRequested(): return sys.exit() try: if control.progressDialog.iscanceled(): return _return_failed(control.lang(40011)) except: pass if any(x in status for x in stalled): return _return_failed() try: control.progressDialog.close() except Exception: pass control.hide() return True control.hide() return False
def doDownload(url, dest, title, image, headers): file = dest.rsplit(os.sep, 1)[-1] resp = getResponse(url, headers, 0) if not resp: control.hide() control.okDialog(title, dest + 'Download failed: No response from server') return try: content = int(resp.headers['Content-Length']) except: content = 0 try: resumable = 'bytes' in resp.headers['Accept-Ranges'].lower() except: resumable = False if content < 1: control.hide() control.okDialog(title, file + 'Unknown filesize: Unable to download') return size = 1024 * 1024 # mb = content / (1024 * 1024) gb = str(round(content / float(1073741824), 2)) if content < size: size = content total = 0 notify = 0 errors = 0 count = 0 resume = 0 sleep = 0 control.hide() if control.yesnoDialog('Name to save: %s' % file, 'File Size: %sGB' % gb, 'Continue with download?', 'Confirm Download', 'Confirm', 'Cancel') == 1: return #f = open(dest, mode='wb') f = control.openFile(dest, 'w') chunk = None chunks = [] while True: downloaded = total for c in chunks: downloaded += len(c) percent = min(100 * downloaded / content, 100) if percent >= notify: control.notification(title=title + ' - Download Progress - ' + str(percent)+'%', message=dest, icon=image, time=10000) notify += 10 chunk = None error = False try: chunk = resp.read(size) if not chunk: if percent < 99: error = True else: while len(chunks) > 0: c = chunks.pop(0) f.write(c) del c f.close() return done(title, dest, True) except Exception as e: log_utils.log('DOWNNLOADER EXCEPTION | %s' % str(e), __name__, log_utils.LOGDEBUG) error = True sleep = 10 errno = 0 if hasattr(e, 'errno'): errno = e.errno if errno == 10035: # 'A non-blocking socket operation could not be completed immediately' pass if errno == 10054: #'An existing connection was forcibly closed by the remote host' errors = 10 #force resume sleep = 30 if errno == 11001: # 'getaddrinfo failed' errors = 10 #force resume sleep = 30 if chunk: errors = 0 chunks.append(chunk) if len(chunks) > 5: c = chunks.pop(0) f.write(c) total += len(c) del c if error: errors += 1 count += 1 control.sleep(sleep*1000) if (resumable and errors > 0) or errors >= 10: if (not resumable and resume >= 50) or resume >= 500: #Give up! return done(title, dest, False) resume += 1 errors = 0 if resumable: chunks = [] #create new response resp = getResponse(url, headers, total) else: pass