Skip to content

Commit

Permalink
Include list of channels
Browse files Browse the repository at this point in the history
A central database of all channels is very useful, and opens up the
possibility to fall back when web scraping fails.

It also makes it possible to start adding audio streams, or studio
translations.
  • Loading branch information
dagwieers committed May 1, 2019
1 parent bf3c63c commit 8b1575f
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 4 deletions.
5 changes: 5 additions & 0 deletions addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def router(params_string):
api_helper = vrtapihelper.VRTApiHelper(kodi_wrapper)
vrt_player = vrtplayer.VRTPlayer(addon.getAddonInfo('path'), kodi_wrapper, stream_service, api_helper)
params = dict(parse_qsl(params_string))
content_type = params.get('content_type')
action = params.get('action')
if action == actions.LISTING_AZ_TVSHOWS:
vrt_player.show_tvshow_menu_items(path=None)
Expand All @@ -45,6 +46,10 @@ def router(params_string):
tv_guide.show_tvguide(params)
elif action == actions.PLAY:
vrt_player.play(params)
elif action == actions.PLAY_RADIO:
vrt_player.play_radio(params)
elif content_type == 'audio':
vrt_player.show_radio_menu_items()
else:
vrt_player.show_main_menu_items()

Expand Down
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</requires>

<extension point="xbmc.python.pluginsource" library="addon.py">
<provides>video</provides>
<provides>video audio</provides>
</extension>
<extension point="xbmc.service" library="service.py"/>
<extension point="xbmc.addon.metadata">
Expand Down
15 changes: 13 additions & 2 deletions resources/lib/kodiwrappers/kodiwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, handle, url, addon):
self._addon = addon
self._addon_id = addon.getAddonInfo('id')

def show_listing(self, list_items, sort='unsorted', ascending=True, content_type='episodes', cache=True):
def show_listing(self, list_items, sort='unsorted', ascending=True, content_type='episodes', list_type='video', cache=True):
listing = []

xbmcplugin.setContent(self._handle, content=content_type)
Expand Down Expand Up @@ -90,7 +90,7 @@ def show_listing(self, list_items, sort='unsorted', ascending=True, content_type
list_item.setArt(title_item.art_dict)

if title_item.video_dict:
list_item.setInfo(type='video', infoLabels=title_item.video_dict)
list_item.setInfo(type=list_type, infoLabels=title_item.video_dict)

listing.append((url, list_item, not title_item.is_playable))

Expand Down Expand Up @@ -121,6 +121,17 @@ def play(self, video):
xbmc.sleep(100)
xbmc.Player().showSubtitles(subtitles_visible)

def play_radio(self, stream):
play_item = xbmcgui.ListItem(path=stream)
if stream.endswith('.mpd'):
play_item.setProperty('inputstreamaddon', 'inputstream.adaptive')
play_item.setProperty('inputstream.adaptive.manifest_type', 'mpd')
play_item.setMimeType('application/dash+xml')
play_item.setContentLookup(False)
xbmcplugin.setResolvedUrl(self._handle, True, listitem=play_item)
while not xbmc.Player().isPlaying() and not xbmc.Monitor().abortRequested():
xbmc.sleep(100)

def show_ok_dialog(self, title, message):
xbmcgui.Dialog().ok(self._addon.getAddonInfo('name'), title, message)

Expand Down
189 changes: 188 additions & 1 deletion resources/lib/vrtplayer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,54 @@
id='O8',
type='tv',
name='Eén',
tagline='',
studio='Een',
website='https://een.be/',
live_stream='https://www.vrt.be/vrtnu/kanalen/een/',
live_stream_id='vualto_een_geo',
),
'canvas': dict(
id='1H',
type='tv',
name='Canvas',
tagline='',
studio='Canvas',
website='https://canvas.be/',
live_stream='https://www.vrt.be/vrtnu/kanalen/canvas/',
live_stream_id='vualto_canvas_geo',
),
'ketnet': dict(
id='O9',
type='tv',
name='Ketnet',
tagline='',
studio='Ketnet',
website='https://ketnet.be/',
live_stream='https://www.vrt.be/vrtnu/kanalen/ketnet/',
live_stream_id='vualto_ketnet_geo',
),
'ketnet-jr': dict(
id='1H',
type='tv',
name='Ketnet Junior',
tagline='',
studio='Ketnet Junior',
website='https://ketnet.be/',
),
'sporza': dict(
id='12',
type='radio+tv',
name='Sporza',
tagline='Kristalheldere sportverslaggeving',
studio='Sporza',
live_stream_id='vualto_sporza_geo',
website='https://sporza.be/',
live_stream='https://live-aka.vrtcdn.be/groupa/live/bf2f7c79-1d77-4cdc-80e8-47ae024f30ba/live.isml/.mpd',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/a1211b31-541b-43ce-b6e2-489d9a8995ad/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/a1211b31-541b-43ce-b6e2-489d9a8995ad/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/sporza-high.mp3',
mp3_64='http://icecast.vrtcdn.be/sporza-mid.mp3',
aac_128='http://icecast.vrtcdn.be/sporza.aac',
),
'vrtnxt': dict(
id='',
Expand All @@ -73,42 +89,213 @@
id='11',
type='radio',
name='Radio 1',
tagline='Altijd Benieuwd',
studio='Radio 1',
website='https://radio1.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/47303075-8243-434b-8199-2e62cf4dd97a/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/47303075-8243-434b-8199-2e62cf4dd97a/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/radio1-high.mp3',
mp3_64='http://icecast.vrtcdn.be/radio1-mid.mp3',
aac_128='http://icecast.vrtcdn.be/radio1.aac',
),
'radio2-antwerpen': dict(
id='21',
type='radio',
name='Radio 2 Antwerpen',
tagline='De grootste familie',
studio='Radio 2',
website='https://radio2.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/033d312d-31f7-400a-b81a-61195f0b79c5/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/033d312d-31f7-400a-b81a-61195f0b79c5/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/ra2ant-high.mp3',
mp3_64='http://icecast.vrtcdn.be/ra2ant-mid.mp3',
aac_128='http://icecast.vrtcdn.be/ra2ant.aac',
),
'radio2-vlaams-brabant': dict(
id='22',
type='radio',
name='Radio 2 Vlaams-Brabant',
tagline='De grootste familie',
studio='Radio 2',
website='https://radio2.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/1e08f370-1f20-4807-aaa3-051c7f0d8359/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/1e08f370-1f20-4807-aaa3-051c7f0d8359/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/ra2vlb-high.mp3',
mp3_64='http://icecast.vrtcdn.be/ra2vlb-mid.mp3',
aac_128='http://icecast.vrtcdn.be/ra2vlb.aac',
),
'radio2-limburg': dict(
id='23',
type='radio',
name='Radio 2 Limburg',
tagline='De grootste familie',
studio='Radio 2',
website='https://radio2.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/d9c49923-b49f-4ab3-8532-4e9bd850b4e2/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/d9c49923-b49f-4ab3-8532-4e9bd850b4e2/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/ra2lim-high.mp3',
mp3_64='http://icecast.vrtcdn.be/ra2lim-mid.mp3',
aac_128='http://icecast.vrtcdn.be/ra2lim.aac',
),
'radio2': dict(
id='24',
type='radio',
name='Radio 2',
name='Radio 2 Oost-Vlaanderen',
tagline='De grootste familie',
studio='Radio 2',
website='https://radio2.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/93a8a402-9008-4a97-b473-bc107be7524d/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/93a8a402-9008-4a97-b473-bc107be7524d/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/ra2ovl-high.mp3',
mp3_64='http://icecast.vrtcdn.be/ra2ovl-mid.mp3',
aac_128='http://icecast.vrtcdn.be/ra2ovl.aac',
),
'radio2-west-vlaanderen': dict(
id='25',
type='radio',
name='Radio 2 West-Vlaanderen',
tagline='De grootste familie',
studio='Radio 2',
website='https://radio2.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/604e4a0e-22e8-4f99-ad5e-4f62d27dfec4/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/604e4a0e-22e8-4f99-ad5e-4f62d27dfec4/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/ra2wvl-high.mp3',
mp3_64='http://icecast.vrtcdn.be/ra2wvl-mid.mp3',
aac_128='http://icecast.vrtcdn.be/ra2wvl.aac',
),
'klara': dict(
id='31',
type='radio',
tagline='Blijf verwonderd',
name='Klara',
studio='Klara',
website='https://klara.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/a9f36fda-cb3c-4b4e-9405-a5bba55654c0/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/a9f36fda-cb3c-4b4e-9405-a5bba55654c0/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/klara-high.mp3',
mp3_64='http://icecast.vrtcdn.be/klara-mid.mp3',
aac_128='http://icecast.vrtcdn.be/klara.aac',
),
'klara-continuo': dict(
id='32',
type='radio',
tagline='Non-stop klassieke muziek',
name='Klara Continuo',
studio='Klara Continuo',
website='https://klara.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/0d06dbbe-92d4-4cfe-a0b3-ccc6b7a32ec4/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/0d06dbbe-92d4-4cfe-a0b3-ccc6b7a32ec4/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/klaracontinuo-high.mp3',
mp3_64='http://icecast.vrtcdn.be/klaracontinuo-mid.mp3',
aac_128='http://icecast.vrtcdn.be/klaracontinuo.aac',
),
'stubru': dict(
id='41',
type='radio+tv',
name='Studio Brussel',
tagline='Life is Music',
studio='Studio Brussel',
website='https://stubru.be/',
# live_stream='https://stubru.be/live',
live_stream_id='vualto_stubru',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/f404f0f3-3917-40fd-80b6-a152761072fe/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/f404f0f3-3917-40fd-80b6-a152761072fe/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/stubru-high.mp3',
mp3_64='http://icecast.vrtcdn.be/stubru-mid.mp3',
aac_128='http://icecast.vrtcdn.be/stubru.aac',
),
'stubru-tijdloze': dict(
id='44',
type='radio',
name='Studio Brussel, De Tijdloze',
tagline='Altijd en overal de beste Tijdloze muziek',
studio='Studio Brussel',
website='https://stubru.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/582109ca-1e71-4330-93fc-e9affee94d7d/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupc/live/582109ca-1e71-4330-93fc-e9affee94d7d/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/stubru_tijdloze-high.mp3',
mp3_64='http://icecast.vrtcdn.be/stubru_tijdloze-mid.mp3',
aac_128='http://icecast.vrtcdn.be/stubru_tijdloze.aac',
),
'mnm': dict(
id='55',
type='radio+tv',
name='MNM',
tagline='Music and More',
studio='MNM',
website='https://mnm.be/',
# live_stream='https://mnm.be/kijk/live',
live_stream_id='vualto_mnm',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/68dc3b80-040e-4a75-a394-72f3bb7aff9a/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/68dc3b80-040e-4a75-a394-72f3bb7aff9a/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/mnm-high.mp3',
mp3_64='http://icecast.vrtcdn.be/mnm-mid.mp3',
aac_128='http://icecast.vrtcdn.be/mnm.aac',
),
'mnm-hits': dict(
id='56',
type='radio',
name='MNM Hits',
tagline='Music and More - The Hits',
studio='MNM',
website='https://mnm.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/35dd91de-0352-4865-8632-17e5af8dc6ba/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupb/live/35dd91de-0352-4865-8632-17e5af8dc6ba/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/mnm_hits-high.mp3',
mp3_64='http://icecast.vrtcdn.be/mnm_hits-mid.mp3',
aac_128='http://icecast.vrtcdn.be/mnm_hits.aac',
),
'mnm-urbanice': dict(
id='57',
type='radio',
name='MNM UrbaNice',
tagline='De Online Urban Stream van MNM',
studio='MNM',
website='https://mnm.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/da0b681c-73db-4c9e-af32-7921591d3fbd/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/da0b681c-73db-4c9e-af32-7921591d3fbd/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/mnm_urb-high.mp3',
mp3_64='http://icecast.vrtcdn.be/mnm_urb-mid.mp3',
aac_128='http://icecast.vrtcdn.be/mnm_urb.aac',
),
'ketnet-hits': dict(
id='O3',
type='radio',
name='Ketnet Hits',
tagline='De hipste, de coolste én de plezantste hits op een rijtje',
studio='Ketnet',
website='https://ketnet.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/014a9eea-af85-4da6-aab2-c472ca8d0149/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/014a9eea-af85-4da6-aab2-c472ca8d0149/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/ketnetradio-high.mp3',
mp3_64='http://icecast.vrtcdn.be/ketnetradio-mid.mp3',
aac_128='http://icecast.vrtcdn.be/ketnetradio.aac',
>>>>>>> Include list of channels
),
'vrtnws': dict(
id='13',
type='radio+tv',
name='VRT NWS',
tagline='Ieder moment het meest recente nieuws',
studio='VRT NWS',
live_stream_id='vualto_nieuws',
# live_stream_id='vualto_journaal',
website='https://www.vrtnieuws.be/',
hls_128='https://ondemand-radio-cf-vrt.akamaized.net/audioonly/content/fixed/11_11niws-snip_hi.mp4/.m3u8',
mpeg_dash_128='https://ondemand-radio-cf-vrt.akamaized.net/audioonly/content/fixed/11_11niws-snip_hi.mp4/.mpd',
mp3_128='https://progressive-audio.lwc.vrtcdn.be/content/fixed/11_11niws-snip_hi.mp3',
),
'vrt-event': dict(
id='71',
type='radio',
name='VRT Event',
tagline='',
studio='VRT',
website='https://vrt.be/',
hls_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/779d53fc-9472-4fe8-b62a-1d38c5878c60/live.isml/.m3u8',
mpeg_dash_128='https://live-radio-cf-vrt.akamaized.net/groupa/live/779d53fc-9472-4fe8-b62a-1d38c5878c60/live.isml/.mpd',
mp3_128='http://icecast.vrtcdn.be/vrtevent-high.mp3',
mp3_64='http://icecast.vrtcdn.be/vrtevent-mid.mp3',
aac_128='http://icecast.vrtcdn.be/vrtevent.aac',
),
}
1 change: 1 addition & 0 deletions resources/lib/vrtplayer/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
LISTING_TVGUIDE = 'listingtvguide'

PLAY = 'play'
PLAY_RADIO = 'play_radio'
30 changes: 30 additions & 0 deletions resources/lib/vrtplayer/vrtplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@ def show_livestream_items(self):

self._kodi_wrapper.show_listing(livestream_items, sort='unsorted', content_type='videos', cache=False)

def show_radio_menu_items(self):
radio_items = []
for channel in CHANNELS:
if 'radio' not in CHANNELS[channel].get('type'):
continue
if CHANNELS[channel].get('tagline'):
label = '%(name)s [I][COLOR blue]-- %(tagline)s[/COLOR][/I]' % CHANNELS[channel]
else:
label = CHANNELS[channel].get('name')
radio_items.append(helperobjects.TitleItem(
title=label,
# Only MP3 support includes song information
url_dict=dict(action=actions.PLAY_RADIO, radio_stream=CHANNELS[channel].get('mp3_128')),
is_playable=True,
art_dict=dict(thumb='DefaultAddonMusic.png', icon='DefaultAddonMusic.png', fanart='DefaultAddonMusic.png'),
video_dict=dict(
plot='[B]%(name)s[/B]\n[I]%(tagline)s[/I]\n\n[COLOR yellow]%(website)s[/COLOR]' % CHANNELS[channel],
mediatype='music',
),
))

self._kodi_wrapper.show_listing(radio_items, sort='label', content_type='music', list_type='video')

def show_episodes(self, path):
episode_items, sort, ascending = self._api_helper.get_episode_items(path)
self._kodi_wrapper.show_listing(episode_items, sort=sort, ascending=ascending, content_type='episodes', cache=False)
Expand All @@ -128,6 +151,13 @@ def play(self, params):
if stream is not None:
self._kodi_wrapper.play(stream)

def play_radio(self, params):
if 'channel' in params:
stream = CHANNELS[params.get('channel')].get('mp3_128')
else:
stream = params.get('radio_stream')
self._kodi_wrapper.play_radio(stream)

def __get_media(self, file_name):
return os.path.join(self._addon_path, 'resources', 'media', file_name)

Expand Down
1 change: 1 addition & 0 deletions test/vrtplayertests.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def test_categories_scraping(self):
''' Test to ensure our hardcoded categories conforms to scraped categories '''
# Remove thumbnails from scraped categories first
categories = [dict(id=c['id'], name=c['name']) for c in vrtplayer.get_categories()]
self.assertTrue(categories)
self.assertEqual(categories, CATEGORIES)

def test_random_tvshow_episodes(self):
Expand Down

0 comments on commit 8b1575f

Please sign in to comment.