3737import xbmcaddon
3838import xbmcvfs
3939
40+ import inputstreamhelper
4041import simplecache
4142import youtube_channels
4243
@@ -1010,27 +1011,28 @@ def get_auth_url(self, url, segment_data=None):
10101011 url += ('?' if '?' not in url else '&' ) + auth_params
10111012 return url
10121013
1013- def play_video (self , media_id_or_urn , audio = False ):
1014+ def play_video (self , media_id_or_urn ):
10141015 """
10151016 Gets the stream information starts to play it.
10161017
10171018 Keyword arguments:
10181019 media_id_or_urn -- the urn or id of the media to play
1019- audio -- boolean value to indicate if the content is
1020- audio (default: False)
10211020 """
10221021 if media_id_or_urn .startswith ('urn:' ):
10231022 urn = media_id_or_urn
10241023 media_id = media_id_or_urn .split (':' )[- 1 ]
10251024 else :
1026- media_type = 'audio' if audio else 'video'
1025+ # TODO: Could fail for livestreams
1026+ media_type = 'video'
10271027 urn = 'urn:' + self .bu + ':' + media_type + ':' + media_id_or_urn
10281028 media_id = media_id_or_urn
10291029 self .log ('play_video, urn = ' + urn + ', media_id = ' + media_id )
10301030
10311031 detail_url = ('https://il.srgssr.ch/integrationlayer/2.0/'
10321032 'mediaComposition/byUrn/' + urn )
10331033 json_response = json .loads (self .open_url (detail_url ))
1034+ title = utils .try_get (json_response , ['episode' , 'title' ], str , urn )
1035+
10341036 chapter_list = utils .try_get (
10351037 json_response , 'chapterList' , data_type = list , default = [])
10361038 if not chapter_list :
@@ -1053,27 +1055,22 @@ def play_video(self, media_id_or_urn, audio=False):
10531055 'HD' : '' ,
10541056 }
10551057
1056- if audio :
1057- candidates = [res for res in resource_list if utils .try_get (
1058- res , 'protocol' ) in ('HTTP' , 'HTTPS' , 'HTTP-MP3-STREAM' )]
1059- for candi in candidates :
1060- if utils .try_get (candi , 'quality' ) in ('HD' , 'HQ' ):
1061- stream_url = candi ['url' ]
1062- break
1063- else :
1064- stream_url = candidates [0 ]['url' ]
1065-
1066- play_item = xbmcgui .ListItem (media_id , path = stream_url )
1067- xbmcplugin .setResolvedUrl (self .handle , True , play_item )
1068- return
1069-
10701058 mf_type = 'hls'
1059+ drm = False
10711060 for resource in resource_list :
1061+ if utils .try_get (resource , 'drmList' , data_type = list , default = []):
1062+ drm = True
1063+ break
1064+
10721065 if utils .try_get (resource , 'protocol' ) == 'HLS' :
10731066 for key in ('SD' , 'HD' ):
10741067 if utils .try_get (resource , 'quality' ) == key :
10751068 stream_urls [key ] = utils .try_get (resource , 'url' )
10761069
1070+ if drm :
1071+ self .play_drm (urn , title , resource_list )
1072+ return
1073+
10771074 if not stream_urls ['SD' ] and not stream_urls ['HD' ]:
10781075 self .log ('play_video: no stream URL found.' )
10791076 return
@@ -1121,7 +1118,6 @@ def play_video(self, media_id_or_urn, audio=False):
11211118 new_query , parsed_url .fragment )
11221119 auth_url = surl_result .geturl ()
11231120 self .log (f'play_video, auth_url = { auth_url } ' )
1124- title = utils .try_get (json_response , ['episode' , 'title' ], str , urn )
11251121 play_item = xbmcgui .ListItem (title , path = auth_url )
11261122 if self .subtitles :
11271123 subs = self .get_subtitles (stream_url , urn )
@@ -1134,6 +1130,52 @@ def play_video(self, media_id_or_urn, audio=False):
11341130
11351131 xbmcplugin .setResolvedUrl (self .handle , True , play_item )
11361132
1133+ def play_drm (self , urn , title , resource_list ):
1134+ self .log (f'play_drm: urn = { urn } ' )
1135+ preferred_quality = 'HD' if self .prefer_hd else 'SD'
1136+ resource_data = {
1137+ 'url' : '' ,
1138+ 'lic_url' : '' ,
1139+ }
1140+ for resource in resource_list :
1141+ url = utils .try_get (resource , 'url' )
1142+ if not url :
1143+ continue
1144+ quality = utils .try_get (resource , 'quality' )
1145+ lic_url = ''
1146+ if utils .try_get (resource , 'protocol' ) == 'DASH' :
1147+ drmlist = utils .try_get (
1148+ resource , 'drmList' , data_type = list , default = [])
1149+ for item in drmlist :
1150+ if utils .try_get (item , 'type' ) == 'WIDEVINE' :
1151+ lic_url = utils .try_get (item , 'licenseUrl' )
1152+ resource_data ['url' ] = url
1153+ resource_data ['lic_url' ] = lic_url
1154+ if resource_data ['lic_url' ] and quality == preferred_quality :
1155+ break
1156+
1157+ if not resource_data ['url' ] or not resource_data ['lic_url' ]:
1158+ self .log ('play_drm: No stream found' )
1159+ return
1160+
1161+ manifest_type = 'mpd'
1162+ drm = 'com.widevine.alpha'
1163+ helper = inputstreamhelper .Helper (manifest_type , drm = drm )
1164+ if not helper .check_inputstream ():
1165+ self .log ('play_drm: Unable to setup drm' )
1166+ return
1167+
1168+ play_item = xbmcgui .ListItem (
1169+ title , path = self .get_auth_url (resource_data ['url' ]))
1170+ ia = 'inputstream.adaptive'
1171+ play_item .setProperty ('inputstream' , ia )
1172+ lic_key = f'{ resource_data ["lic_url" ]} |' \
1173+ 'Content-Type=application/octet-stream|R{SSM}|'
1174+ play_item .setProperty (f'{ ia } .manifest_type' , manifest_type )
1175+ play_item .setProperty (f'{ ia } .license_type' , drm )
1176+ play_item .setProperty (f'{ ia } .license_key' , lic_key )
1177+ xbmcplugin .setResolvedUrl (self .handle , True , play_item )
1178+
11371179 def get_subtitles (self , url , name ):
11381180 """
11391181 Returns subtitles from an url
0 commit comments