Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Commit fb07177

Browse files
committed
Play advertisements
1 parent b5e3604 commit fb07177

File tree

4 files changed

+121
-19
lines changed

4 files changed

+121
-19
lines changed

resources/lib/kodiutils.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -190,25 +190,36 @@ def show_listing(title_items, category=None, sort=None, content=None, cache=True
190190
def play(stream, title=None, art_dict=None, info_dict=None, prop_dict=None):
191191
"""Play the given stream"""
192192
from resources.lib.addon import routing
193+
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
194+
playlist.clear()
195+
196+
if not isinstance(stream, list):
197+
stream = [stream]
198+
199+
for i, url in enumerate(stream):
200+
play_item = xbmcgui.ListItem(label=title, path=url)
201+
if art_dict:
202+
play_item.setArt(art_dict)
203+
if info_dict:
204+
play_item.setInfo(type='video', infoLabels=info_dict)
205+
if prop_dict:
206+
play_item.setProperties(prop_dict)
207+
208+
# Setup Inputstream Adaptive
209+
if kodi_version_major() >= 19:
210+
play_item.setProperty('inputstream', 'inputstream.adaptive')
211+
else:
212+
play_item.setProperty('inputstreamaddon', 'inputstream.adaptive')
213+
play_item.setProperty('inputstream.adaptive.manifest_type', 'hls')
214+
play_item.setMimeType('application/vnd.apple.mpegurl')
215+
play_item.setContentLookup(False)
193216

194-
play_item = xbmcgui.ListItem(label=title, path=stream)
195-
if art_dict:
196-
play_item.setArt(art_dict)
197-
if info_dict:
198-
play_item.setInfo(type='video', infoLabels=info_dict)
199-
if prop_dict:
200-
play_item.setProperties(prop_dict)
201-
202-
# Setup Inputstream Adaptive
203-
if kodi_version_major() >= 19:
204-
play_item.setProperty('inputstream', 'inputstream.adaptive')
205-
else:
206-
play_item.setProperty('inputstreamaddon', 'inputstream.adaptive')
207-
play_item.setProperty('inputstream.adaptive.manifest_type', 'hls')
208-
play_item.setMimeType('application/vnd.apple.mpegurl')
209-
play_item.setContentLookup(False)
217+
if i == 0:
218+
first_item = play_item
219+
220+
playlist.add(url=url, listitem=play_item, index=i)
210221

211-
xbmcplugin.setResolvedUrl(routing.handle, True, listitem=play_item)
222+
xbmcplugin.setResolvedUrl(routing.handle, True, listitem=first_item)
212223

213224

214225
def get_search_string(heading='', message=''):

resources/lib/modules/player.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ def play_from_page(self, channel, path):
3434
episode = self._api.get_episode(channel, path)
3535
resolved_stream = None
3636

37+
# Get advertisements
38+
ad_streams = self._api.get_ad_streams(episode.channel, episode.program_title, path, episode.uuid, episode.video_type)
39+
_LOGGER.info('Advertisements: %s', ad_streams)
40+
3741
if episode.stream:
3842
# We already have a resolved stream. Nice!
3943
# We don't need credentials for these streams.
@@ -46,6 +50,8 @@ def play_from_page(self, channel, path):
4650
_LOGGER.debug('Resolved stream: %s', resolved_stream)
4751

4852
if resolved_stream:
53+
ad_streams.append(resolved_stream)
54+
resolved_stream = ad_streams
4955
titleitem = Menu.generate_titleitem(episode)
5056
kodiutils.play(resolved_stream, info_dict=titleitem.info_dict, art_dict=titleitem.art_dict, prop_dict=titleitem.prop_dict)
5157

resources/lib/viervijfzes/content.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,11 @@ def __repr__(self):
9797
class Episode:
9898
""" Defines an Episode. """
9999

100-
def __init__(self, uuid=None, nodeid=None, path=None, channel=None, program_title=None, title=None, description=None, cover=None, background=None,
101-
duration=None, season=None, season_uuid=None, number=None, rating=None, aired=None, expiry=None, stream=None):
100+
def __init__(self, uuid=None, video_type=None, nodeid=None, path=None, channel=None, program_title=None, title=None, description=None, cover=None,
101+
background=None, duration=None, season=None, season_uuid=None, number=None, rating=None, aired=None, expiry=None, stream=None):
102102
"""
103103
:type uuid: str
104+
:type video_type: str
104105
:type nodeid: str
105106
:type path: str
106107
:type channel: str
@@ -119,6 +120,7 @@ def __init__(self, uuid=None, nodeid=None, path=None, channel=None, program_titl
119120
:type stream: string
120121
"""
121122
self.uuid = uuid
123+
self.video_type = video_type
122124
self.nodeid = nodeid
123125
self.path = path
124126
self.channel = channel
@@ -375,6 +377,65 @@ def get_categories(self, channel):
375377

376378
return categories
377379

380+
def get_weather(self, channel):
381+
""" Get a weather dictionary.
382+
:type channel: str
383+
:rtype dict
384+
"""
385+
response = self._get_url(self.SITE_APIS[channel] + '/weather', authentication=True)
386+
weather = json.loads(response)
387+
return weather
388+
389+
def get_ad_streams(self, channel, program, path, uuid, video_type):
390+
""" Get a list of advertisement stream URLs to use for this video.
391+
:type channel: str
392+
:type path: str
393+
:rtype list
394+
"""
395+
ad_streams = []
396+
ad_url = 'https://pubads.g.doubleclick.net/gampad/ads'
397+
weather = self.get_weather(channel)
398+
channel_info = dict(
399+
vier=dict(cmsid='2493239', network_id='21797861328'),
400+
vijf=dict(cmsid='2493512', network_id='21797861328'),
401+
zes=dict(cmsid='2496240', network_id='21797861328')
402+
)
403+
network_id = channel_info.get(channel).get('network_id')
404+
from unicodedata import normalize
405+
program = normalize('NFD', program).replace(' ', '-')
406+
program = re.sub(r'[^A-Za-z0-9-]+', '', program).lower()
407+
if program:
408+
iu_id = '/{}/{}/{}/{}'.format(network_id, channel, 'programmas', program)
409+
else:
410+
iu_id = '/{}/{}/'.format(network_id, channel)
411+
params = dict(ad_rule=1,
412+
cmsid=channel_info.get(channel).get('cmsid'),
413+
correlator=int(round(time.time() * 1000)),
414+
sbs_weather_cond=weather.get('summary'),
415+
sbs_weather_temp=weather.get('temperature'),
416+
description_url=path,
417+
env='vp',
418+
gdfp_req=1,
419+
impl='s',
420+
iu=iu_id,
421+
output='vast',
422+
sz='640x360',
423+
unviewed_position_start=1,
424+
url=path,
425+
vid=uuid,
426+
video_type=video_type)
427+
428+
xml = self._get_url(ad_url, params)
429+
import xml.etree.ElementTree as ET
430+
tree = ET.fromstring(xml)
431+
for item in tree:
432+
if item.tag == 'Preroll':
433+
url = item.find('Ad').text
434+
xml = self._get_url(url)
435+
tree = ET.fromstring(xml)
436+
ad_streams = [item.text for item in tree.findall('.//MediaFile[@delivery="streaming"]') if item.text.endswith('.m3u8')]
437+
return ad_streams
438+
378439
@staticmethod
379440
def _extract_programs(html, channel):
380441
""" Extract Programs from HTML code """
@@ -535,6 +596,7 @@ def _parse_episode_data(data, season_uuid=None):
535596

536597
episode = Episode(
537598
uuid=data.get('videoUuid'),
599+
video_type=data.get('type', {}),
538600
nodeid=data.get('pageInfo', {}).get('nodeId'),
539601
path=data.get('link').lstrip('/'),
540602
channel=data.get('pageInfo', {}).get('site'),

tests/xbmc.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
GLOBAL_SETTINGS = global_settings()
4646
PO = import_language(language=GLOBAL_SETTINGS.get('locale.language'))
4747

48+
PLAYLIST_MUSIC = 0
49+
PLAYLIST_VIDEO = 1
50+
4851

4952
def to_unicode(text, encoding='utf-8'):
5053
""" Force text to unicode """
@@ -135,6 +138,26 @@ def getPlayingFile(self):
135138
return ''
136139

137140

141+
class PlayList(object): # pylint: disable=useless-object-inheritance
142+
""" A stub implementation of the xbmc PlayList class """
143+
144+
def __init__(self, playList):
145+
""" A stub constructor for the xbmc PlayList class """
146+
147+
def getposition(self):
148+
""" A stub implementation for the xbmc PlayList class getposition() method """
149+
return 0
150+
151+
def add(self, url, listitem=None, index=-1):
152+
""" A stub implementation for the xbmc PlayList class add() method """
153+
154+
def clear(self):
155+
""" A stub implementation for the xbmc PlayList class clear() method """
156+
157+
def size(self):
158+
""" A stub implementation for the xbmc PlayList class size() method """
159+
160+
138161
class VideoInfoTag:
139162
""" A stub implementation of the xbmc VideoInfoTag class """
140163

0 commit comments

Comments
 (0)