Skip to content

Commit

Permalink
improve streamservice (#170)
Browse files Browse the repository at this point in the history
* improve streamservice

* Add different fail scenarios

* Fix typos caused by online editing :-(

* fixed log error

* Add Sporza live stream
  • Loading branch information
mediaminister authored and dagwieers committed May 1, 2019
1 parent d28a0d9 commit bf3c63c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 35 deletions.
8 changes: 4 additions & 4 deletions resources/lib/vrtplayer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,23 @@
name='Eén',
studio='Een',
live_stream='https://www.vrt.be/vrtnu/kanalen/een/',
live_stream_id='vualto_een',
live_stream_id='vualto_een_geo',
),
'canvas': dict(
id='1H',
type='tv',
name='Canvas',
studio='Canvas',
live_stream='https://www.vrt.be/vrtnu/kanalen/canvas/',
live_stream_id='vualto_canvas',
live_stream_id='vualto_canvas_geo',
),
'ketnet': dict(
id='O9',
type='tv',
name='Ketnet',
studio='Ketnet',
live_stream='https://www.vrt.be/vrtnu/kanalen/ketnet/',
live_stream_id='vualto_ketnet',
live_stream_id='vualto_ketnet_geo',
),
'ketnet-jr': dict(
id='1H',
Expand All @@ -61,7 +61,7 @@
type='radio+tv',
name='Sporza',
studio='Sporza',
live_stream_id='vualto_sporza',
live_stream_id='vualto_sporza_geo',
),
'vrtnxt': dict(
id='',
Expand Down
68 changes: 38 additions & 30 deletions resources/lib/vrtplayer/streamservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,37 +78,58 @@ def _get_license_key(self, key_url, key_type='R', key_headers=None, key_value=No

return '%s|%s|%s|' % (key_url, header, key_value)

def _get_api_data(self, video_url, video_id=None):
def _get_api_data(self, video):
'''Get and prepare api data object'''
video_url = video.get('video_url')
video_id = video.get('video_id')
publication_id = video.get('publication_id')
# Prepare api_data for on demand streams by video_id and publication_id
if video_id and publication_id:
xvrttoken = self.token_resolver.get_xvrttoken()
api_data = apidata.ApiData(self._CLIENT, self._VUALTO_API_URL, video_id, publication_id + requests.utils.quote('$'), xvrttoken, False)
# Prepare api_data for livestreams by video_id, e.g. vualto_strubru, vualto_mnm
elif video_id and not video_url:
api_data = apidata.ApiData(self._CLIENT, self._VUALTO_API_URL, video_id, '', None, True)
# Webscrape api_data with video_id fallback
elif video_url:
api_data = self._webscrape_api_data(video_url) or apidata.ApiData(self._CLIENT, self._VUALTO_API_URL, video_id, '', None, True)
return api_data

def _webscrape_api_data(self, video_url):
'''Scrape api data from VRT NU html page'''
html_page = requests.get(video_url, proxies=self._proxies).text
strainer = SoupStrainer('div', {'class': 'cq-dd-vrtvideo'})
soup = BeautifulSoup(html_page, 'html.parser', parse_only=strainer)
try:
video_data = soup.find(lambda tag: tag.name == 'div' and tag.get('class') == ['vrtvideo']).attrs
except Exception:
# Web scraping failed
video_data = None
except Exception as e:
# Web scraping failed, log error
self._kodi_wrapper.log_error('Web scraping api data failed: %s' % e)
return None

# Web scraping failed, fall back to using video_id only
if not video_data and video_id:
return apidata.ApiData(self._CLIENT, self._VUALTO_API_URL, video_id, '', None, True)
# Web scraping failed, log error
if not video_data:
self._kodi_wrapper.log_error('Web scraping api data failed, empty video_data')
return None

# Store required data attributes
# Store required html data attributes
client = video_data.get('data-client')
media_api_url = video_data.get('data-mediaapiurl')

video_id = video_data.get('data-videoid')
# Is this a livestream instead ?
publication_id = video_data.get('data-publicationid', '')
# Live stream or on demand
if video_id is None:
is_live_stream = True
xvrttoken = None
video_id = video_data.get('data-livestream')
xvrttoken = None
else:
is_live_stream = False
publication_id += requests.utils.quote('$')
xvrttoken = self.token_resolver.get_xvrttoken()

publication_id = video_data.get('data-publicationid', '')
if publication_id:
publication_id += requests.utils.quote('$')
if client is None or media_api_url is None or (video_id is None and publication_id is None):
self._kodi_wrapper.log_error('Web scraping api data failed, required attributes missing')
return None

return apidata.ApiData(client, media_api_url, video_id, publication_id, xvrttoken, is_live_stream)

Expand Down Expand Up @@ -156,22 +177,9 @@ def _fix_virtualsubclip(stream_dict, duration):
return stream_dict

def get_stream(self, video, retry=False, api_data=None):
video_url = video.get('video_url')
video_id = video.get('video_id')
publication_id = video.get('publication_id')
# Prepare api_data for on demand streams by video_id and publication_id
if video_id and publication_id and not retry:
xvrttoken = self.token_resolver.get_xvrttoken()
api_data = apidata.ApiData(self._CLIENT, self._VUALTO_API_URL, video_id, publication_id + requests.utils.quote('$'), xvrttoken, False)
# Prepare api_data for livestreams by video_id, e.g. vualto_strubru, vualto_mnm
elif video_id and not video_url:
api_data = apidata.ApiData(self._CLIENT, self._VUALTO_API_URL, video_id, '', None, True)
# Support .mpd streams directly (only works on Kodi 18+ with inputstream.adaptive)
elif video_url.endswith('.mpd'):
return streamurls.StreamURLS(video_url, use_inputstream_adaptive=True)
# Webscrape api_data from html video_url
else:
api_data = api_data or self._get_api_data(video_url, video_id)
'''Main streamservice function'''
if not api_data:
api_data = self._get_api_data(video)

vudrm_token = None
video_json = self._get_video_json(api_data)
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/vrtplayer/vrtplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def show_category_menu_items(self):

def show_livestream_items(self):
livestream_items = []
for channel in ['een', 'canvas', 'ketnet', 'stubru', 'mnm']:
for channel in ['een', 'canvas', 'ketnet', 'sporza', 'stubru', 'mnm']:
if channel in ['een', 'canvas', 'ketnet']:
thumbnail = self.__get_media(channel + '.png')
fanart = self._api_helper.get_live_screenshot(channel)
Expand Down

0 comments on commit bf3c63c

Please sign in to comment.