def download_token(tokenUrl): try: DownloadHeaders = {} DownloadRequest = hybrid.urllib_request(tokenUrl, headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadString = hybrid.string_decode_utf8(DownloadDataHttp.read()) return DownloadString except: notificationIcon = path.addon( 'resources/skins/default/media/common/close.png') xbmcgui.Dialog().notification(var.addonname, 'Token download failure.', notificationIcon, 2500, False) return None
def download_recording_event(forceUpdate=False): #Check if data is already cached if var.ChannelsDataJsonRecordingEvent != [] and forceUpdate == False: return None #Check if user has pvr access if var.RecordingAccess == False: return None #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken } DownloadRequest = hybrid.urllib_request(path.recording_event(), headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson[ 'errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification( var.addonname, 'Opnames download mislukt: ' + resultMessage, notificationIcon, 2500, False) return False var.ChannelsDataJsonRecordingEvent = DownloadDataJson return True except: notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification(var.addonname, 'Opnames download mislukt.', notificationIcon, 2500, False) return False
def download_streams(): try: DownloadHeaders = {} DownloadRequest = hybrid.urllib_request( 'https://raw.githubusercontent.com/dumbie/kodirepo/master/plugin.video.vogelspot/streams/streams.js', headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadString = hybrid.string_decode_utf8(DownloadDataHttp.read()) return DownloadString except: notificationIcon = path.addon( 'resources/skins/default/media/common/close.png') xbmcgui.Dialog().notification(var.addonname, 'Streams download failure.', notificationIcon, 2500, False) return None
def download_search_program(programName): #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken } programName = hybrid.urllib_quote(programName) DownloadRequest = hybrid.urllib_request( path.search_program(programName), headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson[ 'errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/search.png') xbmcgui.Dialog().notification( var.addonname, 'Zoek download mislukt: ' + resultMessage, notificationIcon, 2500, False) return None return DownloadDataJson except: notificationIcon = path.resources( 'resources/skins/default/media/common/search.png') xbmcgui.Dialog().notification(var.addonname, 'Zoek download mislukt.', notificationIcon, 2500, False) return None
def download_channels_radio(forceUpdate=False): #Check if data is already cached if var.ChannelsDataJsonRadio != [] and forceUpdate == False: return None try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent') } DownloadRequest = hybrid.urllib_request(path.channels_list_radio(), headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) var.ChannelsDataJsonRadio = DownloadDataJson return True except: notificationIcon = path.resources( 'resources/skins/default/media/common/radio.png') xbmcgui.Dialog().notification(var.addonname, 'Radio download mislukt.', notificationIcon, 2500, False) return False
def ApiLogin(LoginNotification=False): #Check login retry limit if var.ApiLoginCount > 2: notificationIcon = path.resources( 'resources/skins/default/media/common/error.png') xbmcgui.Dialog().notification( var.addonname, 'Aanmeld poging limiet bereikt, herstart de add-on.', notificationIcon, 2500, False) return False else: var.ApiLoginCount += 1 #Generate the device id ApiGenerateDeviceId() #Check the login type if var.addon.getSetting('LoginType') == 'Abonnementsnummer': #Check login settings if var.addon.getSetting('LoginUsername') == '' or var.addon.getSetting( 'LoginPassword') == '': var.addon.openSettings() return False loginDevice = classes.Class_ApiLogin_deviceRegistrationData() loginDevice.deviceId = var.addon.getSetting('LoginDeviceId120') loginDevice.vendor = "Webbie Player" loginDevice.model = str(var.addonversion) loginDevice.deviceFirmVersion = "Kodi" loginDevice.appVersion = str(var.kodiversion) loginDevice = loginDevice.__dict__ loginAuth = classes.Class_ApiLogin_credentialsStdAuth() loginAuth.username = var.addon.getSetting('LoginUsername') loginAuth.password = var.addon.getSetting('LoginPassword') loginAuth.deviceRegistrationData = loginDevice loginAuth = loginAuth.__dict__ loginData = classes.Class_ApiLogin_stdAuth() loginData.credentialsStdAuth = loginAuth loginData = loginData.__dict__ else: #Check login settings if var.addon.getSetting('LoginEmail') == '' or var.addon.getSetting( 'LoginPasswordEmail') == '': var.addon.openSettings() return False loginDevice = classes.Class_ApiLogin_deviceInfo() loginDevice.deviceId = var.addon.getSetting('LoginDeviceId120') loginDevice.deviceVendor = "Webbie Player" loginDevice.deviceModel = str(var.addonversion) loginDevice.deviceFirmVersion = "Kodi" loginDevice.appVersion = str(var.kodiversion) loginDevice = loginDevice.__dict__ loginCredentials = classes.Class_ApiLogin_credentials() loginCredentials.username = var.addon.getSetting('LoginEmail') loginCredentials.password = var.addon.getSetting('LoginPasswordEmail') loginCredentials = loginCredentials.__dict__ loginAuth = classes.Class_ApiLogin_credentialsExtAuth() loginAuth.deviceInfo = loginDevice loginAuth.credentials = loginCredentials loginAuth = loginAuth.__dict__ loginData = classes.Class_ApiLogin_extAuth() loginData.credentialsExtAuth = loginAuth loginData = loginData.__dict__ #Request login by sending data try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Content-Type": "application/json" } DownloadData = json.dumps(loginData).encode('ascii') DownloadRequest = hybrid.urllib_request(path.api_login(), data=DownloadData, headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) except: notificationIcon = path.resources( 'resources/skins/default/media/common/error.png') xbmcgui.Dialog().notification(var.addonname, 'Aanmelden is mislukt.', notificationIcon, 2500, False) var.ApiLoggedIn = False var.ApiLastLogin = datetime(1970, 1, 1) var.ApiLoginCookie = '' var.ApiLoginToken = '' return False #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson['errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] errorDescription = DownloadDataJson['errorDescription'] if errorDescription == '403-3161': notificationIcon = path.resources( 'resources/skins/default/media/common/error.png') xbmcgui.Dialog().notification(var.addonname, 'Inloggen 24 uur geblokkeerd.', notificationIcon, 2500, False) var.ApiLoggedIn = False var.ApiLastLogin = datetime(1970, 1, 1) var.ApiLoginCookie = '' var.ApiLoginToken = '' return False elif errorDescription == '401-3035': notificationIcon = path.resources( 'resources/skins/default/media/common/error.png') xbmcgui.Dialog().notification( var.addonname, 'Uw account is (tijdelijk) geblokkeerd.', notificationIcon, 2500, False) var.ApiLoggedIn = False var.ApiLastLogin = datetime(1970, 1, 1) var.ApiLoginCookie = '' var.ApiLoginToken = '' return False elif resultCode == 'KO': notificationIcon = path.resources( 'resources/skins/default/media/common/error.png') xbmcgui.Dialog().notification( var.addonname, 'Onjuiste gegevens: ' + resultMessage, notificationIcon, 5000, False) var.ApiLoggedIn = False var.ApiLastLogin = datetime(1970, 1, 1) var.ApiLoginCookie = '' var.ApiLoginToken = '' return False #Read and set the returned token var.ApiLoginToken = hybrid.urllib_getheader(DownloadDataHttp, 'X-Xsrf-Token') #Filter and clone the cookie contents HeaderCookie = hybrid.urllib_getheader(DownloadDataHttp, 'Set-Cookie') var.ApiLoginCookie = '' cookie_split = re.findall(r"([^\s]*?=.*?(?=;|,|$))", HeaderCookie) for cookie in cookie_split: if cookie.startswith('Path') == False and cookie.startswith( 'Expires') == False and cookie.startswith('Max-Age') == False: var.ApiLoginCookie += cookie + ';' var.ApiLoginCookie = var.ApiLoginCookie[:-1] #Show the login notification if LoginNotification == True: xbmcgui.Dialog().notification(var.addonname, 'Aangemeld, veel kijkplezier.', var.addonicon, 2500, False) #Check if user has pvr access ApiCheckPvrAccess(DownloadDataJson) #Check if user has home access ApiCheckHomeAccess(DownloadDataJson) #Update api login variables var.ApiLoginCount = 0 var.ApiLoggedIn = True var.ApiLastLogin = datetime.now() #Start the auto login thread if var.thread_login_auto == None: var.thread_login_auto = Thread(target=thread_login_auto) var.thread_login_auto.start() return True
def download_epg_day(dateStringDay, forceUpdate=False): #Check if data is already cached epgDayCache = None for epgCache in var.EpgCacheArray: try: if epgCache.dateStringDay == dateStringDay: epgDayCache = epgCache break except: continue #Check if update is needed if epgDayCache != None: if forceUpdate == True: var.EpgCacheArray.remove(epgDayCache) else: return epgDayCache.epgJson #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken, 'Content-Type': 'application/json' } #Download epg information DownloadRequest = hybrid.urllib_request(path.epg_day(dateStringDay), headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson[ 'errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/epg.png') xbmcgui.Dialog().notification( var.addonname, 'TV Gids download mislukt: ' + resultMessage, notificationIcon, 2500, False) return None #Update epg information classAdd = classes.Class_EpgCache() classAdd.dateStringDay = dateStringDay classAdd.epgJson = DownloadDataJson var.EpgCacheArray.append(classAdd) return DownloadDataJson except: notificationIcon = path.resources( 'resources/skins/default/media/common/epg.png') xbmcgui.Dialog().notification(var.addonname, 'TV Gids laden mislukt.', notificationIcon, 2500, False) return None
def record_event_remove(RecordId, StartDeltaTime=0): #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Content-Type": "application/json", "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken } DownloadData = json.dumps([{ "recordId": int(RecordId), "startDeltaTime": int(StartDeltaTime) }]).encode('ascii') DownloadRequest = hybrid.urllib_request( path.recording_event_add_remove(), data=DownloadData, headers=DownloadHeaders) DownloadRequest.get_method = lambda: 'DELETE' DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson[ 'errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification( var.addonname, 'Opname annulering mislukt: ' + resultMessage, notificationIcon, 2500, False) return False notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification(var.addonname, 'Opname is geannuleerd of verwijderd.', notificationIcon, 2500, False) #Download the recording event download_recording_event(True) #Update the main page count if var.guiMain != None: var.guiMain.count_recorded_event() var.guiMain.count_recording_event() return True except: notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification(var.addonname, 'Opname annulering mislukt.', notificationIcon, 2500, False) return False
def record_event_add(ProgramId): #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Content-Type": "application/json", "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken } DownloadData = json.dumps({ "externalContentId": ProgramId, "isAutoDeletionEnabled": True }).encode('ascii') DownloadRequest = hybrid.urllib_request( path.recording_event_add_remove(), data=DownloadData, headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson[ 'errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification( var.addonname, 'Opname planning mislukt: ' + resultMessage, notificationIcon, 2500, False) return '' notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification(var.addonname, 'Programma wordt opgenomen.', notificationIcon, 2500, False) #Download the recording event download_recording_event(True) #Update the main page count if var.guiMain != None: var.guiMain.count_recorded_event() var.guiMain.count_recording_event() return str(DownloadDataJson['resultObj']['containers'][0]['metadata'] ['contentId']) except: notificationIcon = path.resources( 'resources/skins/default/media/common/record.png') xbmcgui.Dialog().notification(var.addonname, 'Opname planning mislukt.', notificationIcon, 2500, False) return ''
def record_series_add(ChannelId, liveSeriesId): #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Content-Type": "application/json", "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken } DownloadData = json.dumps({ "channelId": ChannelId, "seriesId": liveSeriesId, "isAutoDeletionEnabled": True, "episodeScope": "ALL", "isChannelBoundEnabled": True }).encode('ascii') DownloadRequest = hybrid.urllib_request( path.recording_series_add_remove(), data=DownloadData, headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson[ 'errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/recordseries.png') xbmcgui.Dialog().notification( var.addonname, 'Serie seizoen planning mislukt: ' + resultMessage, notificationIcon, 2500, False) return False notificationIcon = path.resources( 'resources/skins/default/media/common/recordseries.png') xbmcgui.Dialog().notification(var.addonname, 'Serie seizoen wordt opgenomen.', notificationIcon, 2500, False) #Download the recording series download_recording_series(True) #Download the recording event download_recording_event(True) #Update the main page count if var.guiMain != None: var.guiMain.count_recorded_event() var.guiMain.count_recording_event() var.guiMain.count_recording_series() return True except: notificationIcon = path.resources( 'resources/skins/default/media/common/recordseries.png') xbmcgui.Dialog().notification(var.addonname, 'Serie seizoen planning mislukt.', notificationIcon, 2500, False) return False
def play_stream_recorded(listItem, Windowed): #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) #Download the program stream url try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken } #Get and set the stream asset id ProgramAssetId = listItem.getProperty('ProgramAssetId') ProgramRecordEventId = listItem.getProperty('ProgramRecordEventId') #Check the set stream asset id if func.string_isnullorempty( ProgramAssetId) or func.string_isnullorempty( ProgramRecordEventId): notificationIcon = path.resources( 'resources/skins/default/media/common/recorddone.png') xbmcgui.Dialog().notification( var.addonname, 'Opname is niet speelbaar, wegens stream rechten.', notificationIcon, 2500, False) return DownloadRequest = hybrid.urllib_request(path.stream_url_recording( ProgramRecordEventId, ProgramAssetId), headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) except: notificationIcon = path.resources( 'resources/skins/default/media/common/recorddone.png') xbmcgui.Dialog().notification(var.addonname, 'Opname is niet gevonden.', notificationIcon, 2500, False) return #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson['errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/recorddone.png') xbmcgui.Dialog().notification( var.addonname, 'Opname is niet beschikbaar: ' + resultMessage, notificationIcon, 2500, False) return #Check the target resolution if var.addon.getSetting('StreamResolution') == '2160p': targetResolution = '10000000' elif var.addon.getSetting('StreamResolution') == '1080p': targetResolution = '6000000' elif var.addon.getSetting('StreamResolution') == '720p': targetResolution = '4000000' elif var.addon.getSetting('StreamResolution') == '576p': targetResolution = '2500000' elif var.addon.getSetting('StreamResolution') == '432p': targetResolution = '1600000' elif var.addon.getSetting('StreamResolution') == '360p': targetResolution = '1200000' #Set stream headers dictionary StreamHeadersDict = {"User-Agent": var.addon.getSetting('CustomUserAgent')} #Create stream headers string StreamHeaders = '' for name, value in StreamHeadersDict.items(): StreamHeaders += '&' + name + '=' + hybrid.urllib_quote(value) StreamHeaders = StreamHeaders.replace('&', '', 1) #Get and adjust the stream url try: StreamUrl = DownloadDataJson['resultObj']['src']['sources']['src'] StreamUrl = StreamUrl.replace('&max_bitrate=1200000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=1600000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=2500000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=4000000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=6000000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=10000000', '&max_bitrate=' + targetResolution) StreamUrl += '&drm=clear' except: notificationIcon = path.resources( 'resources/skins/default/media/common/recorddone.png') xbmcgui.Dialog().notification(var.addonname, 'Stream is niet beschikbaar.', notificationIcon, 2500, False) return #Set input adaptive stream listItem.setProperty(hybrid.inputstreamname, 'inputstream.adaptive') listItem.setProperty('inputstream.adaptive.manifest_type', 'mpd') listItem.setProperty('inputstream.adaptive.stream_headers', StreamHeaders) #Get and set stream license key try: AdaptiveLicenseUrl = DownloadDataJson['resultObj']['src']['sources'][ 'contentProtection']['widevine']['licenseAcquisitionURL'] AdaptivePostData = 'R{SSM}' AdaptiveResponse = '' listItem.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') listItem.setProperty( 'inputstream.adaptive.license_key', AdaptiveLicenseUrl + "|" + StreamHeaders + "|" + AdaptivePostData + "|" + AdaptiveResponse) except: pass #Update the list item name label listItem.setLabel(listItem.getProperty('ProgramName')) #Set stream start offset in seconds listItem.setProperty('StartOffset', '120') #Set internet stream property listItem.setProperty("get_stream_details_from_player", 'true') #Start playing the media var.PlayerCustom.PlayCustom(StreamUrl, listItem, Windowed, False)
def play_stream_television(listItem, Windowed): #Get channel settings and variables NewAssetId = listItem.getProperty('AssetId') NewChannelId = listItem.getProperty('ChannelId') NewExternalId = listItem.getProperty('ExternalId') NewChannelName = listItem.getProperty('ChannelName') CurrentAssetId = var.addon.getSetting('CurrentAssetId') CurrentChannelId = var.addon.getSetting('CurrentChannelId') CurrentExternalId = var.addon.getSetting('CurrentExternalId') CurrentChannelName = var.addon.getSetting('CurrentChannelName') #Allow longer back seeking DateTimeUtc = datetime.utcnow() - timedelta( minutes=int(var.addon.getSetting('StreamSeekMinutes'))) StartString = '&time=' + str(func.datetime_to_ticks(DateTimeUtc)) #Check if user is logged in if var.ApiLoggedIn == False: apilogin.ApiLogin(False) #Download the television stream url try: DownloadHeaders = { "User-Agent": var.addon.getSetting('CustomUserAgent'), "Cookie": var.ApiLoginCookie, "X-Xsrf-Token": var.ApiLoginToken } RequestUrl = path.stream_url_tv(NewChannelId, NewAssetId) + StartString DownloadRequest = hybrid.urllib_request(RequestUrl, headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataJson = json.load(DownloadDataHttp) except: notificationIcon = path.resources( 'resources/skins/default/media/common/television.png') xbmcgui.Dialog().notification(var.addonname, 'Zender is niet gevonden.', notificationIcon, 2500, False) return #Check if connection is successful if DownloadDataJson['resultCode'] and DownloadDataJson['errorDescription']: resultCode = DownloadDataJson['resultCode'] resultMessage = DownloadDataJson['message'] if resultCode == 'KO': var.ApiLoggedIn = False notificationIcon = path.resources( 'resources/skins/default/media/common/television.png') xbmcgui.Dialog().notification( var.addonname, 'Zender is niet beschikbaar: ' + resultMessage, notificationIcon, 2500, False) return #Check the target resolution if var.addon.getSetting('StreamResolution') == '2160p': targetResolution = '10000000' elif var.addon.getSetting('StreamResolution') == '1080p': targetResolution = '6000000' elif var.addon.getSetting('StreamResolution') == '720p': targetResolution = '4000000' elif var.addon.getSetting('StreamResolution') == '576p': targetResolution = '2500000' elif var.addon.getSetting('StreamResolution') == '432p': targetResolution = '1600000' elif var.addon.getSetting('StreamResolution') == '360p': targetResolution = '1200000' #Set stream headers dictionary StreamHeadersDict = {"User-Agent": var.addon.getSetting('CustomUserAgent')} #Create stream headers string StreamHeaders = '' for name, value in StreamHeadersDict.items(): StreamHeaders += '&' + name + '=' + hybrid.urllib_quote(value) StreamHeaders = StreamHeaders.replace('&', '', 1) #Get and adjust the stream url try: StreamUrl = DownloadDataJson['resultObj']['src']['sources']['src'] StreamUrl = StreamUrl.replace('&max_bitrate=1200000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=1600000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=2500000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=4000000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=6000000', '&max_bitrate=' + targetResolution) StreamUrl = StreamUrl.replace('&max_bitrate=10000000', '&max_bitrate=' + targetResolution) StreamUrl += '&drm=clear' except: notificationIcon = path.resources( 'resources/skins/default/media/common/television.png') xbmcgui.Dialog().notification(var.addonname, 'Stream is niet beschikbaar.', notificationIcon, 2500, False) return #Update channel settings and variables if CurrentChannelId != NewChannelId: var.addon.setSetting('LastAssetId', CurrentAssetId) var.addon.setSetting('LastChannelId', CurrentChannelId) var.addon.setSetting('LastExternalId', CurrentExternalId) var.addon.setSetting('LastChannelName', CurrentChannelName) var.addon.setSetting('CurrentAssetId', NewAssetId) var.addon.setSetting('CurrentChannelId', NewChannelId) var.addon.setSetting('CurrentExternalId', NewExternalId) var.addon.setSetting('CurrentChannelName', NewChannelName) #Set input adaptive stream listItem.setProperty(hybrid.inputstreamname, 'inputstream.adaptive') listItem.setProperty('inputstream.adaptive.manifest_type', 'mpd') listItem.setProperty('inputstream.adaptive.stream_headers', StreamHeaders) listItem.setProperty('inputstream.adaptive.manifest_update_parameter', 'full') #Get and set stream license key try: AdaptiveLicenseUrl = DownloadDataJson['resultObj']['src']['sources'][ 'contentProtection']['widevine']['licenseAcquisitionURL'] AdaptivePostData = 'R{SSM}' AdaptiveResponse = '' listItem.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') listItem.setProperty( 'inputstream.adaptive.license_key', AdaptiveLicenseUrl + "|" + StreamHeaders + "|" + AdaptivePostData + "|" + AdaptiveResponse) except: pass #Update the list item name label listItem.setLabel(NewChannelName) #Set internet stream property listItem.setProperty("get_stream_details_from_player", 'true') #Start playing the media var.PlayerCustom.PlayCustom(StreamUrl, listItem, Windowed, True)
def enable_widevine_support(forceUpdate=False): #Check if Widevine is already updating if var.WidevineUpdating == True: return var.WidevineUpdating = True #Get InputStream adaptive Widevine path input_addon = xbmcaddon.Addon('inputstream.adaptive') decrypter_path = input_addon.getSetting('DECRYPTERPATH') if func.string_isnullorempty(decrypter_path): widevine_path = hybrid.string_decode_utf8( hybrid.xbmc_translate_path('special://home/cdm')) input_addon.setSetting('DECRYPTERPATH', 'special://home/cdm') else: widevine_path = hybrid.string_decode_utf8( hybrid.xbmc_translate_path(decrypter_path)) #Set the download headers DownloadHeaders = {"User-Agent": var.addon.getSetting('CustomUserAgent')} #Check if newer Widevine version is available RequestUrl = str(path.requirements()) + 'version.txt' DownloadRequest = hybrid.urllib_request(RequestUrl, headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataString = DownloadDataHttp.read().decode() if DownloadDataString != var.addon.getSetting('WidevineVersion'): var.addon.setSetting('WidevineVersion', DownloadDataString) forceUpdate = True #Check if Widevine support is installed if forceUpdate == False: for aRoot, aDirs, aFiles in os.walk(widevine_path): for fileName in aFiles: if 'widevinecdm' in fileName: var.WidevineUpdating = False return #Check the system processor architecture downloadArchitecture = '' systemArchitecture = platform.machine().lower() systemBits = platform.architecture()[0].lower() if 'arm' in systemArchitecture: downloadArchitecture = 'armv7' elif systemBits == '32bit': downloadArchitecture = 'ia32' elif systemBits == '64bit': downloadArchitecture = 'x64' #Check if operating system is supported downloadOperatingSystem = '' if xbmc.getCondVisibility('System.Platform.Android'): var.WidevineUpdating = False return elif xbmc.getCondVisibility('System.Platform.IOS'): var.WidevineUpdating = False return elif xbmc.getCondVisibility('System.Platform.Linux'): downloadOperatingSystem = 'linux' elif xbmc.getCondVisibility('System.Platform.OSX'): downloadOperatingSystem = 'mac' elif xbmc.getCondVisibility('System.Platform.Windows'): downloadOperatingSystem = 'win' else: var.WidevineUpdating = False xbmcgui.Dialog().notification( var.addonname, 'Besturing systeem wordt niet ondersteund.', var.addonicon, 2500, False) return #Notify the user Widevine is installing xbmcgui.Dialog().notification(var.addonname, 'Widevine wordt geinstalleerd.', var.addonicon, 2500, False) #Stop the current playback of any media if xbmc.Player().isPlaying(): xbmc.Player().stop() xbmc.sleep(1000) #Create the Widevine decrypter directory if os.path.exists(widevine_path) == False: os.mkdir(widevine_path) try: #Download the required Widevine files RequestUrl = str(path.requirements()) + 'widevine-' + str( downloadOperatingSystem) + '-' + str(downloadArchitecture) + '.zip' DownloadRequest = hybrid.urllib_request(RequestUrl, headers=DownloadHeaders) DownloadDataHttp = hybrid.urllib_urlopen(DownloadRequest) DownloadDataBytes = DownloadDataHttp.read() #Write the downloaded Widevine zip file download_filename = widevine_path + '/widevine.zip' filewrite = open(download_filename, 'wb') filewrite.write(DownloadDataBytes) filewrite.close() except: var.WidevineUpdating = False notificationIcon = path.resources( 'resources/skins/default/media/common/error.png') xbmcgui.Dialog().notification(var.addonname, 'Mislukt om Widevine te downloaden.', notificationIcon, 2500, False) return try: #Extract the downloaded Widevine zip file downloadZip = ZipFile(download_filename) downloadZip.extractall(widevine_path) downloadZip.close() except: var.WidevineUpdating = False notificationIcon = path.resources( 'resources/skins/default/media/common/error.png') xbmcgui.Dialog().notification(var.addonname, 'Mislukt om Widevine te installeren.', notificationIcon, 2500, False) return #Remove the downloaded Widevine zip file os.remove(download_filename) var.WidevineUpdating = False xbmcgui.Dialog().notification(var.addonname, 'Widevine is succesvol geinstalleerd.', var.addonicon, 2500, False)