Skip to content

Commit

Permalink
Another batch of changes (#257)
Browse files Browse the repository at this point in the history
This PR includes:
- Disable optional inpustream.adaptive dependency
- Change show_ok_dialog() interface
- Avoid unneeded indentation (pythonic style is to avoid indented code)
- Fix streamservice on Python 3
- Enable streamservicetests in Makefile
  • Loading branch information
dagwieers authored May 19, 2019
1 parent 17f77f5 commit 3e5f2df
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 133 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ script:
- tox -e flake8
- pylint *.py resources/lib/ test/
- python test/vrtplayertests.py
#- python test/streamservicetests.py
- python test/apihelpertests.py
- python test/tvguidetests.py
- python test/searchtests.py
#- python test/favoritestests.py
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pylint:
unit:
@echo -e "$(white)=$(blue) Starting unit tests$(reset)"
PYTHONPATH=$(CURDIR) python test/vrtplayertests.py
#PYTHONPATH=$(CURDIR) python test/streamservicetests.py
PYTHONPATH=$(CURDIR) python test/streamservicetests.py
PYTHONPATH=$(CURDIR) python test/apihelpertests.py
PYTHONPATH=$(CURDIR) python test/tvguidetests.py
PYTHONPATH=$(CURDIR) python test/searchtests.py
Expand Down
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<import addon="script.module.beautifulsoup4" version="4.5.3"/>
<import addon="script.module.dateutil" version="2.6.0"/>
<import addon="script.module.inputstreamhelper" version="0.3.3"/>
<import addon="inputstream.adaptive" version="2.0.20" optional="true"/>
<!-- import addon="inputstream.adaptive" version="2.0.20" optional="true"/ -->
<import addon="script.module.pysocks" version="1.6.8" optional="true"/>
<import addon="xbmc.python" version="2.25.0"/>
</requires>
Expand Down
8 changes: 4 additions & 4 deletions resources/lib/kodiwrappers/kodiwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ def get_search_string(self):
search_string = keyboard.getText()
return search_string

def show_ok_dialog(self, title, message):
def show_ok_dialog(self, heading='', message=''):
import xbmcgui
if not title:
title = self._addon.getAddonInfo('name')
xbmcgui.Dialog().ok(title, message)
if not heading:
heading = self._addon.getAddonInfo('name')
xbmcgui.Dialog().ok(heading=heading, message=message)

def show_notification(self, heading='', message='', icon='info', time=4000):
import xbmcgui
Expand Down
132 changes: 68 additions & 64 deletions resources/lib/vrtplayer/streamservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def _get_stream_json(self, api_data):
def _handle_error(self, video_json):
self._kodi.log_error(video_json.get('message'))
message = self._kodi.localize(30954) # Whoops something went wrong
self._kodi.show_ok_dialog('', message)
self._kodi.show_ok_dialog(message=message)
self._kodi.end_of_directory()

@staticmethod
Expand Down Expand Up @@ -194,73 +194,77 @@ def get_stream(self, video, retry=False, api_data=None):
api_data = self._get_api_data(video)

stream_json = self._get_stream_json(api_data)
if stream_json:
if 'targetUrls' in stream_json:
if not stream_json:
return None

# DRM support for ketnet junior/uplynk streaming service
uplynk = 'uplynk.com' in stream_json.get('targetUrls')[0].get('url')
if 'targetUrls' in stream_json:

vudrm_token = stream_json.get('drm')
drm_stream = (vudrm_token or uplynk)
# DRM support for ketnet junior/uplynk streaming service
uplynk = 'uplynk.com' in stream_json.get('targetUrls')[0].get('url')

# Select streaming protocol
if not drm_stream and self._kodi.has_inputstream_adaptive() or drm_stream and self._can_play_drm and self._kodi.get_setting('usedrm') == 'true':
protocol = 'mpeg_dash'
elif vudrm_token:
protocol = 'hls_aes'
else:
protocol = 'hls'

# Get stream manifest url
manifest_url = next(stream.get('url') for stream in stream_json.get('targetUrls') if stream.get('type') == protocol)

# Fix virtual subclip
duration = timedelta(milliseconds=stream_json.get('duration'))
manifest_url = self._fix_virtualsubclip(manifest_url, duration)

# Prepare stream for Kodi player
if protocol == 'mpeg_dash' and drm_stream:
self._kodi.log_notice('Protocol: mpeg_dash drm', 'Verbose')
if vudrm_token:
if self._vualto_license_url is None:
self._get_vualto_license_url()
encryption_json = '{{"token":"{0}","drm_info":[D{{SSM}}],"kid":"{{KID}}"}}'.format(vudrm_token)
license_key = self._get_license_key(key_url=self._vualto_license_url,
key_type='D',
key_value=encryption_json,
key_headers={'Content-Type': 'text/plain;charset=UTF-8'})
else:
license_key = self._get_license_key(key_url=self._UPLYNK_LICENSE_URL, key_type='R')

stream = streamurls.StreamURLS(manifest_url, license_key=license_key, use_inputstream_adaptive=True)
elif protocol == 'mpeg_dash':
stream = streamurls.StreamURLS(manifest_url, use_inputstream_adaptive=True)
self._kodi.log_notice('Protocol: ' + protocol, 'Verbose')
vudrm_token = stream_json.get('drm')
drm_stream = (vudrm_token or uplynk)

# Select streaming protocol
if not drm_stream and self._kodi.has_inputstream_adaptive():
protocol = 'mpeg_dash'
elif drm_stream and self._can_play_drm and self._kodi.get_setting('usedrm') == 'true':
protocol = 'mpeg_dash'
elif vudrm_token:
protocol = 'hls_aes'
else:
protocol = 'hls'

# Get stream manifest url
manifest_url = next(stream.get('url') for stream in stream_json.get('targetUrls') if stream.get('type') == protocol)

# Fix virtual subclip
duration = timedelta(milliseconds=stream_json.get('duration'))
manifest_url = self._fix_virtualsubclip(manifest_url, duration)

# Prepare stream for Kodi player
if protocol == 'mpeg_dash' and drm_stream:
self._kodi.log_notice('Protocol: mpeg_dash drm', 'Verbose')
if vudrm_token:
if self._vualto_license_url is None:
self._get_vualto_license_url()
encryption_json = '{{"token":"{0}","drm_info":[D{{SSM}}],"kid":"{{KID}}"}}'.format(vudrm_token)
license_key = self._get_license_key(key_url=self._vualto_license_url,
key_type='D',
key_value=encryption_json,
key_headers={'Content-Type': 'text/plain;charset=UTF-8'})
else:
# Fix 720p quality for HLS livestreams
manifest_url += '?hd' if '.m3u8?' not in manifest_url else '&hd'
stream = streamurls.StreamURLS(*self._select_hls_substreams(manifest_url))
self._kodi.log_notice('Protocol: ' + protocol, 'Verbose')
return stream

if stream_json.get('code') in ('INCOMPLETE_ROAMING_CONFIG', 'INVALID_LOCATION'):
self._kodi.log_error(stream_json.get('message'))
roaming_xvrttoken = self._tokenresolver.get_xvrttoken(True)
if not retry and roaming_xvrttoken is not None:
# Delete cached playertokens
if api_data.is_live_stream:
self._kodi.delete_file(self._kodi.get_userdata_path() + 'live_vrtPlayerToken')
else:
self._kodi.delete_file(self._kodi.get_userdata_path() + 'ondemand_vrtPlayerToken')
# Update api_data with roaming_xvrttoken and try again
api_data.xvrttoken = roaming_xvrttoken
return self.get_stream(video, retry=True, api_data=api_data)
message = self._kodi.localize(30953) # Cannot be played
self._kodi.show_ok_dialog('', message)
self._kodi.end_of_directory()
license_key = self._get_license_key(key_url=self._UPLYNK_LICENSE_URL, key_type='R')

stream = streamurls.StreamURLS(manifest_url, license_key=license_key, use_inputstream_adaptive=True)
elif protocol == 'mpeg_dash':
stream = streamurls.StreamURLS(manifest_url, use_inputstream_adaptive=True)
self._kodi.log_notice('Protocol: ' + protocol, 'Verbose')
else:
self._handle_error(stream_json)
# Fix 720p quality for HLS livestreams
manifest_url += '?hd' if '.m3u8?' not in manifest_url else '&hd'
stream = streamurls.StreamURLS(*self._select_hls_substreams(manifest_url))
self._kodi.log_notice('Protocol: ' + protocol, 'Verbose')
return stream

if stream_json.get('code') not in ('INCOMPLETE_ROAMING_CONFIG', 'INVALID_LOCATION'):
self._handle_error(stream_json)
return None

self._kodi.log_error(stream_json.get('message'))
roaming_xvrttoken = self._tokenresolver.get_xvrttoken(True)
if not retry and roaming_xvrttoken is not None:
# Delete cached playertokens
if api_data.is_live_stream:
self._kodi.delete_file(self._kodi.get_userdata_path() + 'live_vrtPlayerToken')
else:
self._kodi.delete_file(self._kodi.get_userdata_path() + 'ondemand_vrtPlayerToken')
# Update api_data with roaming_xvrttoken and try again
api_data.xvrttoken = roaming_xvrttoken
return self.get_stream(video, retry=True, api_data=api_data)
message = self._kodi.localize(30953) # Cannot be played
self._kodi.show_ok_dialog(message=message)
self._kodi.end_of_directory()
return None

def _select_hls_substreams(self, master_hls_url):
Expand All @@ -271,7 +275,7 @@ def _select_hls_substreams(self, master_hls_url):
hls_subtitle_id = None
hls_base_url = master_hls_url.split('.m3u8')[0]
self._kodi.log_notice('URL get: ' + unquote(master_hls_url), 'Verbose')
hls_playlist = urlopen(master_hls_url).read()
hls_playlist = urlopen(master_hls_url).read().decode('utf-8')
max_bandwidth = self._kodi.get_max_bandwidth()
stream_bandwidth = None

Expand All @@ -291,7 +295,7 @@ def _select_hls_substreams(self, master_hls_url):

if stream_bandwidth > max_bandwidth and not hls_variant_url:
message = self._kodi.localize(30057).format(max=max_bandwidth, min=stream_bandwidth)
self._kodi.show_ok_dialog('', message)
self._kodi.show_ok_dialog(message=message)
self._kodi.open_settings()

# Get audio url
Expand Down
Loading

0 comments on commit 3e5f2df

Please sign in to comment.