def get_desired_zoom_level(): blackbarcomp = None blackbarcomp_raw = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "Settings.GetSettingValue", "params": {"setting": "videoplayer.errorinaspect"}, "id": 1}' ) blackbarcomp_json = json.loads(blackbarcomp_raw) if 'result' in blackbarcomp_json: if 'value' in blackbarcomp_json['result']: blackbarcomp = int(blackbarcomp_json['result']['value']) if blackbarcomp is None: return 0 aspectratio_screen = float(xbmcgui.getScreenWidth()) / float( xbmcgui.getScreenHeight()) aspectratio_video = xbmc.RenderCapture().getAspectRatio() aspectratio_compensation = aspectratio_video - (aspectratio_video * (blackbarcomp / 100.0)) ratio_correction = (aspectratio_compensation / aspectratio_screen) zoomlevel = math.ceil(ratio_correction * 100.0) / 100.0 user_compensation = int(addon.getSetting('user_compensation')) zoomlevel = zoomlevel + (user_compensation / 100.0) maximum_zoom_level = float(1.0 + int(addon.getSetting('maximum_compensation')) / 100.0) if zoomlevel > maximum_zoom_level: zoomlevel = maximum_zoom_level return zoomlevel
def show(self): if self._demolabel is not None: return # FIXME: Using a different font does not seem to have much of an impact self._demolabel = ControlLabel(0, getScreenHeight() // 4, getScreenWidth(), 100, localize(30060) + '\n' + localize(30061), font='font36_title', textColor='0xddee9922', alignment=0x00000002) self.window.addControl(self._demolabel) self.log('show', 0)
def generate_logblobs_params(): """Generate the initial log blog""" # It seems that this log is sent when logging in to a profile the first time # i think it is the easiest to reproduce, the others contain too much data screen_size = str(xbmcgui.getScreenWidth()) + 'x' + str(xbmcgui.getScreenHeight()) timestamp_utc = time.time() timestamp = int(timestamp_utc * 1000) client_ver = g.LOCAL_DB.get_value('asset_core', '', table=TABLE_SESSION) app_id = int(time.time()) * 10000 + random.randint(1, 10001) # Should be used with all log requests if client_ver: result = re.search(r'-([0-9\.]+)\.js$', client_ver) client_ver = result.groups()[0] # Here you have to enter only the real data, falsifying the data would cause repercussions in netflix server logs # therefore since it is possible to exclude data, we avoid entering data that we do not have blob = { 'browserua': common.get_user_agent().replace(' ', '#'), 'browserhref': 'https://www.netflix.com/browse', # 'initstart': 988, # 'initdelay': 268, 'screensize': screen_size, # '1920x1080', 'screenavailsize': screen_size, # '1920x1040', 'clientsize': screen_size, # '1920x944', # 'pt_navigationStart': -1880, # 'pt_fetchStart': -1874, # 'pt_secureConnectionStart': -1880, # 'pt_requestStart': -1853, # 'pt_domLoading': -638, # 'm_asl_start': 990, # 'm_stf_creat': 993, # 'm_idb_open': 993, # 'm_idb_succ': 1021, # 'm_msl_load_no_data': 1059, # 'm_asl_comp': 1256, 'type': 'startup', 'sev': 'info', 'devmod': 'chrome-cadmium', 'clver': client_ver, # e.g. '6.0021.220.051' 'osplatform': g.LOCAL_DB.get_value('browser_info_os_name', '', table=TABLE_SESSION), 'osver': g.LOCAL_DB.get_value('browser_info_os_version', '', table=TABLE_SESSION), 'browsername': 'Chrome', 'browserver': g.LOCAL_DB.get_value('browser_info_version', '', table=TABLE_SESSION), 'appLogSeqNum': 0, 'uniqueLogId': common.get_random_uuid(), 'appId': app_id, 'esn': g.get_esn(), 'lver': '', # 'jssid': '15822792997793', # Same value of appId # 'jsoffms': 1261, 'clienttime': timestamp, 'client_utc': int(timestamp_utc), 'uiver': g.LOCAL_DB.get_value('ui_version', '', table=TABLE_SESSION) } blobs_container = { 'entries': [blob] } blobs_dump = json.dumps(blobs_container) blobs_dump = blobs_dump.replace('"', '\"').replace(' ', '').replace('#', ' ') return {'logblobs': blobs_dump}
def _set_isa_addon_settings(is_4k_capable, hdcp_override): """Method for self-configuring of InputStream Adaptive add-on""" is_helper = inputstreamhelper.Helper('mpd') if not is_helper.check_inputstream(): show_ok_dialog(get_local_string(30154), get_local_string(30046)) return isa_addon = Addon('inputstream.adaptive') isa_addon.setSettingBool('HDCPOVERRIDE', hdcp_override) if isa_addon.getSettingInt('STREAMSELECTION') == 1: # Stream selection must never be set to 'Manual' or cause problems with the streams isa_addon.setSettingInt('STREAMSELECTION', 0) # 'Ignore display' should only be set when Kodi display resolution is not 4K isa_addon.setSettingBool( 'IGNOREDISPLAY', is_4k_capable and (getScreenWidth() != 3840 or getScreenHeight() != 2160))
def settings(self, settings): self.id_teamwatch = settings['twid'] self.id_playerctl = settings['pcid'] self.nickname = settings['nickname'] self.twitter_enabled = settings['twitter_enabled'] self.twitter_language = settings['language'] self.twitter_language = xbmc.convertLanguage(self.twitter_language, xbmc.ISO_639_1) self.twitter_result_type = settings['result_type'] self.facebook_enabled = settings['facebook_enabled'] self.facebook_email = settings['facebook_email'] self.facebook_password = settings['facebook_password'] if settings['imdb_lang'] == 'Italian': self.imdb_translate = 'it' elif settings['imdb_lang'] == 'French': self.imdb_translate = 'fr' elif settings['imdb_lang'] == 'German': self.imdb_translate = 'de' else: self.imdb_translate = None self.email_enabled = settings['email_enabled'] self.email = settings['email'] self.email_password = settings['email_password'] self.email_imap = settings['email_imap'] self.facebook = settings['facebook'] self.show_allways = not (settings['showallways'] == "true") self.screen_height = settings['screen_height'] if self.screen_height == "" or self.screen_height == None: self.screen_height = xbmcgui.getScreenHeight() else: self.screen_height = int(settings['screen_height']) self.screen_width = settings['screen_width'] if self.screen_width == "" or self.screen_width == None: self.screen_width = xbmcgui.getScreenWidth() else: self.screen_width = int(settings['screen_width']) self.bartop = self.screen_height - 75
def _set_isa_addon_settings(is_4k_capable, hdcp_override): """Method for self-configuring of InputStream Adaptive add-on""" try: is_helper = inputstreamhelper.Helper('mpd') if not is_helper.check_inputstream(): show_ok_dialog(get_local_string(30154), get_local_string(30046)) return except Exception as exc: # pylint: disable=broad-except # Captures all types of ISH internal errors import traceback error(G.py2_decode(traceback.format_exc(), 'latin-1')) raise InputStreamHelperError(str(exc)) isa_addon = Addon('inputstream.adaptive') isa_addon.setSettingBool('HDCPOVERRIDE', hdcp_override) if isa_addon.getSettingInt('STREAMSELECTION') == 1: # Stream selection must never be set to 'Manual' or cause problems with the streams isa_addon.setSettingInt('STREAMSELECTION', 0) # 'Ignore display' should only be set when Kodi display resolution is not 4K isa_addon.setSettingBool( 'IGNOREDISPLAY', is_4k_capable and (getScreenWidth() != 3840 or getScreenHeight() != 2160))
def get_stream(self, video_id, video_type): stream = {} screenHeight = xbmcgui.getScreenHeight() screenWidth = xbmcgui.getScreenWidth() if self.us_uhd: hwDecoding = ['H264', 'H265'] platform = 'firetv' else: hwDecoding = [] platform = 'desktop' params = {'usePreAuth': 'true'} # discoveryplus.com (US) if self.locale_suffix == 'us': if video_type == 'channel': jsonPayload = { 'deviceInfo': { 'adBlocker': 'true' }, 'channelId': video_id, 'wisteriaProperties': { 'advertiser': { 'firstPlay': 0, 'fwIsLat': 0 }, 'device': { 'type': 'desktop' }, 'platform': 'desktop', 'product': 'dplus_us', 'sessionId': self.client_id, 'streamProvider': { 'suspendBeaconing': 0, 'hlsVersion': 7, 'pingConfig': 1 } } } url = '{api_url}/playback/v3/channelPlaybackInfo'.format( api_url=self.api_url) else: jsonPayload = { 'deviceInfo': { 'adBlocker': 'true', 'hwDecodingCapabilities': hwDecoding, 'screen': { 'width': screenWidth, 'height': screenHeight }, 'player': { 'width': screenWidth, 'height': screenHeight } }, 'videoId': video_id, 'wisteriaProperties': { 'platform': platform, 'product': 'dplus_us' } } url = '{api_url}/playback/v3/videoPlaybackInfo'.format( api_url=self.api_url) data_dict = json.loads( self.make_request(url, 'post', params=params, headers=self.site_headers, payload=json.dumps(jsonPayload)))['data'] else: if video_type == 'channel': url = '{api_url}/playback/v2/channelPlaybackInfo/{video_id}'.format( api_url=self.api_url, video_id=video_id) else: url = '{api_url}/playback/v2/videoPlaybackInfo/{video_id}'.format( api_url=self.api_url, video_id=video_id) data_dict = json.loads( self.make_request(url, 'get', params=params, headers=self.site_headers))['data'] # discoveryplus.com (US) if self.locale_suffix == 'us': # use hls proxy to change framerate from 30.000 to 29.970 path = "/dplus_proxy.m3u8" hls_params = {} hls_params["hls_origin_url"] = data_dict['attributes'][ 'streaming'][0]['url'] hls_params["old_framerate"] = "30.000" hls_params["new_framerate"] = "29.970" hls_proxy = (urlparse("http://127.0.0.1:48201/")._replace( path=path, query=urlencode(hls_params), ).geturl()) stream['hls_url'] = hls_proxy stream['drm_enabled'] = data_dict['attributes']['streaming'][0][ 'protection']['drmEnabled'] else: stream['hls_url'] = data_dict['attributes']['streaming']['hls'][ 'url'] stream['mpd_url'] = data_dict['attributes']['streaming']['dash'][ 'url'] if data_dict['attributes']['protection']['drmEnabled']: if data_dict['attributes']['protection']['schemes'].get( 'widevine'): stream['license_url'] = data_dict['attributes'][ 'protection']['schemes']['widevine']['licenseUrl'] stream['drm_token'] = data_dict['attributes'][ 'protection']['drmToken'] stream['drm_enabled'] = data_dict['attributes']['protection'][ 'drmEnabled'] return stream
class TeamWatch(): __addon__ = xbmcaddon.Addon() __resources__ = os.path.join(__addon__.getAddonInfo('path'), 'resources') monitor = xbmc.Monitor() window = None background = None feedtext = None id_teamwatch = __addon__.getSetting('twid') id_playerctl = __addon__.getSetting('pcid') nickname = __addon__.getSetting('nickname') twitter_enabled = __addon__.getSetting('twitter_enabled') twitter_language = __addon__.getSetting('language') twitter_language = xbmc.convertLanguage(twitter_language, xbmc.ISO_639_1) twitter_result_type = __addon__.getSetting('result_type') show_allways = not (__addon__.getSetting('showallways') == "true") screen_height = __addon__.getSetting('screen_height') if screen_height == "": screen_height = xbmcgui.getScreenHeight() screen_width = __addon__.getSetting('screen_width') if screen_width == "": screen_width = xbmcgui.getScreenWidth() bartop = screen_height - 75 id_chat = -1 id_twitter = -1 id_invite = "" show_enable = True feed_show_time = None feed_name = ['#teamwatch'] feed_is_shown = False show_disable_after = False start_time = time.time() player = None log_prog = 1 def __init__(self): self.id_teamwatch = self.__addon__.getSetting('twid') for feed in self.__addon__.getSetting('feed').split(":"): if feed not in self.feed_name: self.feed_name.append(feed) self.id_chat = -1 self.id_twitter = -1 self.id_invite = "" self.show_enable = True self.feed_show_time = time.time() self.feed_is_shown = False self.show_disable_after = False self.bartop = self.screen_height - 75 self.player = xbmc.Player() self._log("start [" + ":".join(self.feed_name) + "]") self._log(self.show_allways) self.bartop = self.screen_height - 75 self.background = xbmcgui.ControlImage( 0, self.bartop, self.screen_width, 75, os.path.join(self.__resources__, '1280_settings.png')) self.background.setVisible(False) self.feedtext = xbmcgui.ControlLabel(80, self.bartop + 5, self.screen_width - 90, 75, '', font='font45', textColor='0xFFFFFFFF') self.feedtext.setVisible(False) def _log(self, text): xbmc.log('%d service.maxxam.teamwatch: %s' % (self.log_prog, text)) self.log_prog = self.log_prog + 1 def loop(self): twpath = os.path.join(xbmc.translatePath('special://home'), 'userdata', 'addon_data', 'service.maxxam.teamwatch', 'tw.ini') while not self.monitor.abortRequested(): # after DISPLAY_TIME_SECS elapsed hide the message bar if self.monitor.waitForAbort(REFRESH_TIME_SECS): self.hide_message() self._log("stop") break if self.feed_is_shown and time.time( ) - self.feed_show_time > DISPLAY_TIME_SECS: self.hide_message() if self.show_disable_after: self.hide_message() self.show_enable = False self.show_disable_after = False if (time.time() - self.start_time) < REFRESH_TIME_SECS or self.feed_is_shown: continue self.start_time = time.time() try: file = open(twpath, "r") self.id_chat = int(file.read()) file.close() except: self.id_chat = -1 params = { 'idt': self.id_twitter, 'idc': self.id_chat, 'twid': self.id_teamwatch, 'pcid': self.id_playerctl, 'nickname': self.nickname } if self.feed_name: params['q'] = ":".join(self.feed_name) else: params['q'] = "#teamwatch" if self.twitter_enabled: params['tqp'] = "&lang=%s&result_type=%s" % ( self.twitter_language, self.twitter_result_type) params['tl'] = self.twitter_language else: params[' notweet'] = 1 url = 'http://www.teamwatch.it/get.php?%s' % urllib.urlencode( params) if DEBUG > 1: self._log("id_chat: " + str(self.id_chat)) self._log(url) try: jresult = {} jresult = json.loads(urllib.urlopen(url).read()) except: self._log("error opening %s" % url) finally: if 'id' in jresult: if 'is_twitter' in jresult and jresult['is_twitter'] == 1: self.id_twitter = jresult['id'] else: self.id_chat = jresult['id'] file = open(twpath, "w+") file.write(str(self.id_chat)) file.close() if jresult['status'] == 'ok' and self.show_enable: file = open(twpath, "w") file.write(str(self.id_chat)) file.close() user = jresult['user'].encode('utf-8') text = jresult['text'].encode('utf-8') if self.show_allways or xbmcgui.getCurrentWindowId( ) == WINDOW_FULLSCREEN_VIDEO: if DEBUG > 1: self.show_message(user, text, [ ICON_CHAT, ICON_TWITTER ][jresult['is_twitter']]) #, jresult['id']) else: self.show_message(user, text, [ICON_CHAT, ICON_TWITTER ][jresult['is_twitter']]) elif jresult['status'] == 'settings': param = jresult['param'].encode('utf-8') if param.startswith("#tw:addfeed:"): if not param[12:] in self.feed_name: self.feed_name.append(param[12:]) self.__addon__.setSetting('feed', ":".join(self.feed_name)) self.show_message('TeamWatch', localize(32000, param[12:]), ICON_SETTING) elif param.startswith("#tw:removefeed:"): if param[15:] in self.feed_name: self.feed_name.remove(param[15:]) self.__addon__.setSetting('feed', ":".join(self.feed_name)) self.show_message('TeamWatch', localize(32001, param[15:]), ICON_SETTING) elif param == "#tw:off": self.show_message('TeamWatch', localize(32002), ICON_SETTING) self.show_disable_after = True elif param == "#tw:on": self.show_enable = True self.show_message('TeamWatch', localize(32003), ICON_SETTING) elif param == "#tw:bar:top": self.bartop = 0 self.show_message('TeamWatch', "Bar position set to top", ICON_SETTING) elif param == "#tw:bar:bottom": self.bartop = self.screen_height - 75 self.show_message('TeamWatch', "Bar position set to bottom", ICON_SETTING) elif param == "#tw:id": self.id_chat = jresult['idc'] self.id_twitter = jresult['idt'] file = open(twpath, "w") file.write(str(self.id_chat)) file.close() elif param == "#tw:playerctl:playpause": self._log('esecuzione #tw:playerctl:playpause') xbmc.executebuiltin("Action(PlayPause)") self._log('playpause terminated id_chat: ' + str(self.id_chat)) elif param == "#tw:playerctl:sshot": xbmc.executebuiltin("TakeScreenshot") elif param.startswith("#tw:playerctl:seek:"): t = [ int("0" + filter(str.isdigit, x)) for x in param[19:].split(":") ] if len(t) == 4: xbmc.executeJSONRPC( '{ "jsonrpc": "2.0", "method": "Player.Seek", "params": {"playerid":1, "value": {"hours":%d, "minutes":%d, "seconds":%d, "milliseconds":%d}}, "id": 1 }' % tuple(t)) elif DEBUG: self._log('#tw:playerctl:seek invalid time') elif param.startswith("#tw:playstream:"): self._log('*** playstream received ***') self._log(param[15:]) player = xbmc.Player() player.play(param[15:]) elif param.startswith("#tw:invite:"): # web_pdb.set_trace() if DEBUG: self._log("#tw:invite") invite = param[11:].split(":") if invite[0] == "m": self._log("#tw:invite:m: %s" % invite[1]) movie = xbmc_helpers.search_movie(invite[1]) self._log("after movie search") if movie: # dialog = xbmcgui.Dialog() # res = dialog.yesno(localize(32004), localize(32005, (invite[1], movie["title"]))) if DEBUG: self._log("invite received for movie: %s" % movie["title"]) player = xbmc.Player() player.play(movie["file"]) if player.isPlaying(): self._log('playing...') else: self._log('not playing...') else: if DEBUG: self._log( "invite received for non existent movie %s" % invite[1]) elif invite[0] == "e": episode = xbmc_helpers.search_episode( invite[1], invite[2], invite[3]) if episode: dialog = xbmcgui.Dialog() s_ep = "S[COLOR green][B]%02d[/B][/COLOR]E[COLOR green][B]%02d[/B][/COLOR]" % ( int(episode["season"]), int( episode["episode"])) res = dialog.yesno( localize(32004), localize( 32006, (invite[1], episode["showtitle"], s_ep))) if DEBUG: self._log( "invite received for episode id: %d" % episode["episodeid"]) else: if DEBUG: self._log( "invite received for non existent episode %s %s %s" % (invite[1], invite[2], invite[3])) else: pass else: pass else: if DEBUG and jresult['status'] == "fail" and jresult[ 'reason'] != "no feeds" and not jresult[ 'reason'].startswith('waiting'): self._log(jresult) if DEBUG and jresult['reason'].startswith('json parse error'): self.id_twitter = -1 self.id_chat = -1 def show_message(self, user, text, icon=ICON_CHAT, id=-1): if DEBUG: self._log(user + " " + text) self.window = xbmcgui.Window(xbmcgui.getCurrentWindowId()) self.background.setPosition(0, self.bartop) self.background.setVisible(False) self.window.addControl(self.background) self.feedtext.setPosition(80, self.bartop + 5) self.feedtext.setLabel('') self.feedtext.setVisible(False) self.window.addControl(self.feedtext) if icon == ICON_TWITTER: self.background.setImage( os.path.join(self.__resources__, '1280_tweet.png')) elif icon == ICON_SETTING: self.background.setImage( os.path.join(self.__resources__, '1280_settings.png')) elif icon == ICON_CHAT: self.background.setImage( os.path.join(self.__resources__, '1280_chat.png')) else: self.background.setImage( os.path.join(self.__resources__, '1280_chat.png')) if DEBUG: self.feedtext.setLabel('[COLOR yellow][B]%s[/B][/COLOR]: [%d] %s' % (user, id, text)) else: self.feedtext.setLabel('[COLOR yellow][B]%s[/B][/COLOR]: %s' % (user, text)) self.background.setVisible(True) self.feedtext.setVisible(True) self.feed_is_shown = True self.feed_show_time = time.time() def hide_message(self): if self.feed_is_shown: self.window.removeControls([self.feedtext, self.background]) self.feed_is_shown = False
def get_stream(self, video_id, video_type): stream = {} screenHeight = xbmcgui.getScreenHeight() screenWidth = xbmcgui.getScreenWidth() if self.us_uhd: hwDecoding = ['H264','H265'] platform = 'firetv' else: hwDecoding = [] platform = 'desktop' params = {'usePreAuth': 'true'} # discoveryplus.com (US) if self.locale_suffix == 'us': if video_type == 'channel': jsonPayload = { 'deviceInfo': { 'adBlocker': 'true' }, 'channelId': video_id, 'wisteriaProperties': { 'advertiser': { 'firstPlay': 0, 'fwIsLat': 0 }, 'device': { 'type': 'desktop' }, 'platform': 'desktop', 'product': 'dplus_us', 'sessionId': self.client_id, 'streamProvider': { 'suspendBeaconing': 0, 'hlsVersion': 7, 'pingConfig': 1 } } } url = '{api_url}/playback/v3/channelPlaybackInfo'.format(api_url=self.api_url) else: jsonPayload = { 'deviceInfo': { 'adBlocker': 'true', 'hwDecodingCapabilities': hwDecoding, 'screen':{ 'width':screenWidth, 'height':screenHeight }, 'player':{ 'width':screenWidth, 'height':screenHeight } }, 'videoId': video_id, 'wisteriaProperties':{ 'platform': platform, 'product': 'dplus_us' } } url = '{api_url}/playback/v3/videoPlaybackInfo'.format(api_url=self.api_url) data_dict = json.loads(self.make_request(url, 'post', params=params, headers=self.site_headers, payload=json.dumps(jsonPayload)))['data'] else: if video_type == 'channel': url = '{api_url}/playback/v2/channelPlaybackInfo/{video_id}'.format(api_url=self.api_url, video_id=video_id) else: url = '{api_url}/playback/v2/videoPlaybackInfo/{video_id}'.format(api_url=self.api_url, video_id=video_id) data_dict = json.loads(self.make_request(url, 'get', params=params, headers=self.site_headers))['data'] # discoveryplus.com (US) if self.locale_suffix == 'us': # discoveryplus.com has frame-rate="30.000" even though videos are 29.970 fps. This downloads the m3u8 and changes 30.000 to 29.970 originalm3u8 = requests.get(data_dict['attributes']['streaming'][0]['url']).text updatedm3u8 = originalm3u8.replace("30.000", "29.970") tempm3u8 = open(self.tempdir + "temp.m3u8", "w") tempm3u8.write(updatedm3u8) tempm3u8.close() tempm3u8path = self.tempdir.replace("\\", "/") #replace backslashes in path with frontslashes on windows or ISA fails to load path stream['hls_url'] = tempm3u8path + "temp.m3u8" stream['drm_enabled'] = data_dict['attributes']['streaming'][0]['protection']['drmEnabled'] else: stream['hls_url'] = data_dict['attributes']['streaming']['hls']['url'] stream['mpd_url'] = data_dict['attributes']['streaming']['dash']['url'] if data_dict['attributes']['protection']['drmEnabled']: if data_dict['attributes']['protection']['schemes'].get('widevine'): stream['license_url'] = data_dict['attributes']['protection']['schemes']['widevine']['licenseUrl'] stream['drm_token'] = data_dict['attributes']['protection']['drmToken'] stream['drm_enabled'] = data_dict['attributes']['protection']['drmEnabled'] return stream
def get_stream(self, video_id, video_type): stream = {} screenHeight = xbmcgui.getScreenHeight() screenWidth = xbmcgui.getScreenWidth() # Use drmSupported:false for UHD streams. For now playback is only tested to kinda work when drm and # InputStreamAdaptive is disabled from add-on settings. It is possible that drm/mpd stream also works on Android devices. # Change drmSupported to false from add-on settings if you want to play videos without drm. if self.us_uhd: hwDecoding = ['H264','H265'] platform = 'firetv' drmSupported = 'false' else: hwDecoding = [] platform = 'desktop' if self.drm_supported: drmSupported = 'true' else: drmSupported = 'false' # discoveryplus.com (go=US and Canada) if self.realm == 'go': product = 'dplus_us' elif self.realm == 'dplusindia': # this is maybe wrong or not needed product = 'dplusindia' else: product = 'dplus_emea' jsonPayload = { 'deviceInfo': { 'adBlocker': 'true', 'drmSupported': drmSupported, 'hwDecodingCapabilities': hwDecoding, 'screen':{ 'width':screenWidth, 'height':screenHeight }, 'player':{ 'width':screenWidth, 'height':screenHeight } }, 'wisteriaProperties':{ 'advertiser': { 'firstPlay': 0, 'fwIsLat': 0 }, 'device':{ 'browser':{ 'name': 'chrome', 'version': '96.0.4664.55' }, 'type': platform }, 'platform': platform, 'product': product, 'sessionId': self.client_id, 'streamProvider': { 'suspendBeaconing': 0, 'hlsVersion': 7, 'pingConfig': 1 } } } if video_type == 'channel': jsonPayload['channelId'] = video_id url = '{api_url}/playback/v3/channelPlaybackInfo'.format(api_url=self.api_url) else: jsonPayload['videoId'] = video_id url = '{api_url}/playback/v3/videoPlaybackInfo'.format(api_url=self.api_url) data_dict = json.loads(self.make_request(url, 'post', headers=self.site_headers, payload=json.dumps(jsonPayload)))['data'] stream['url'] = data_dict['attributes']['streaming'][0]['url'] stream['type'] = data_dict['attributes']['streaming'][0]['type'] if data_dict['attributes']['streaming'][0]['protection']['drmEnabled']: stream['license_url'] = data_dict['attributes']['streaming'][0]['protection']['schemes']['widevine']['licenseUrl'] stream['drm_token'] = data_dict['attributes']['streaming'][0]['protection'].get('drmToken') stream['drm_enabled'] = data_dict['attributes']['streaming'][0]['protection']['drmEnabled'] return stream