Radios de Vigo: Vigo FM dial and UK/US/Portugal news radio for Kodi
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
927195e28d
60 files changed
+488
No files matched your search
+127
@@ -0,0 +1,127 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Keeps an IPTV Simple instance that plays this add-on's radio.m3u.
|
||||
|
||||
Runs when Kodi starts and again after every add-on update. Writes the
|
||||
instance settings, then restarts IPTV Simple (once nothing is playing) if the
|
||||
settings or the station list changed since the last run.
|
||||
"""
|
||||
import glob
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcvfs
|
||||
|
||||
ADDON = xbmcaddon.Addon()
|
||||
ADDON_ID = ADDON.getAddonInfo('id')
|
||||
HOME = 'special://home/addons/{}/resources/'.format(ADDON_ID)
|
||||
FIRST_INSTANCE = 95 # KodiMov+ uses 91 (VAIO) and 93 (.49)
|
||||
|
||||
SETTINGS = '''<settings version="2">
|
||||
<setting id="kodi_addon_instance_name">Radios de Vigo</setting>
|
||||
<setting id="kodi_addon_instance_enabled">true</setting>
|
||||
<setting id="m3uPathType">0</setting>
|
||||
<setting id="m3uPath">{home}radio.m3u</setting>
|
||||
<setting id="m3uUrl" default="true" />
|
||||
<setting id="m3uCache" default="true">true</setting>
|
||||
<setting id="startNum" default="true">1</setting>
|
||||
<setting id="numberByOrder" default="true">false</setting>
|
||||
<setting id="m3uRefreshMode" default="true">0</setting>
|
||||
<setting id="epgPathType">0</setting>
|
||||
<setting id="epgPath" default="true" />
|
||||
<setting id="epgUrl" default="true" />
|
||||
<setting id="logoPathType">0</setting>
|
||||
<setting id="logoPath">{home}logos/</setting>
|
||||
<setting id="useLogosLocalPathOnly" default="true">false</setting>
|
||||
<setting id="logoFromEpg">0</setting>
|
||||
<setting id="useFFmpegReconnect" default="true">true</setting>
|
||||
<setting id="useInputstreamAdaptiveforHls" default="true">false</setting>
|
||||
</settings>
|
||||
'''.format(home=HOME)
|
||||
|
||||
|
||||
def log(msg):
|
||||
xbmc.log('[{}] {}'.format(ADDON_ID, msg), xbmc.LOGINFO)
|
||||
|
||||
|
||||
def rpc(method, **params):
|
||||
return json.loads(xbmc.executeJSONRPC(json.dumps(
|
||||
{'jsonrpc': '2.0', 'id': 1, 'method': method, 'params': params})))
|
||||
|
||||
|
||||
def read(path):
|
||||
try:
|
||||
with io.open(path, 'r', encoding='utf-8') as f:
|
||||
return f.read()
|
||||
except (IOError, OSError):
|
||||
return None
|
||||
|
||||
|
||||
def write(path, content):
|
||||
tmp = path + '.tmp'
|
||||
with io.open(tmp, 'w', encoding='utf-8', newline='') as f:
|
||||
f.write(content)
|
||||
os.replace(tmp, path)
|
||||
|
||||
|
||||
def instance_file(pvr_dir):
|
||||
"""Our instance file: the one that already reads radio.m3u, else the
|
||||
first free number from FIRST_INSTANCE on."""
|
||||
for path in glob.glob(os.path.join(pvr_dir, 'instance-settings-*.xml')):
|
||||
if HOME + 'radio.m3u' in (read(path) or ''):
|
||||
return path
|
||||
n = FIRST_INSTANCE
|
||||
while os.path.exists(os.path.join(pvr_dir, 'instance-settings-{}.xml'.format(n))):
|
||||
n += 1
|
||||
return os.path.join(pvr_dir, 'instance-settings-{}.xml'.format(n))
|
||||
|
||||
|
||||
def restart_iptv_simple():
|
||||
for enabled in (False, True):
|
||||
rpc('Addons.SetAddonEnabled', addonid='pvr.iptvsimple', enabled=enabled)
|
||||
xbmc.sleep(3000)
|
||||
|
||||
|
||||
def main():
|
||||
monitor, player = xbmc.Monitor(), xbmc.Player()
|
||||
profile = xbmcvfs.translatePath(ADDON.getAddonInfo('profile'))
|
||||
pvr_dir = xbmcvfs.translatePath('special://profile/addon_data/pvr.iptvsimple/')
|
||||
for d in (profile, pvr_dir):
|
||||
if not os.path.isdir(d):
|
||||
os.makedirs(d)
|
||||
|
||||
path = instance_file(pvr_dir)
|
||||
if read(path) != SETTINGS:
|
||||
write(path, SETTINGS)
|
||||
log('wrote ' + path)
|
||||
|
||||
numbers_set = os.path.join(profile, 'numbers-set')
|
||||
if not os.path.exists(numbers_set):
|
||||
# Show the stations' own numbers (Vigo ones are their FM frequency).
|
||||
# With more than one IPTV Simple instance Kodi ignores them unless
|
||||
# "always" is on too; that also keeps KodiMov+'s TV numbers.
|
||||
for setting in ('pvrmanager.usebackendchannelnumbers', 'pvrmanager.usebackendchannelnumbersalways'):
|
||||
rpc('Settings.SetSettingValue', setting=setting, value=True)
|
||||
write(numbers_set, '')
|
||||
log('turned on backend channel numbers')
|
||||
|
||||
m3u = read(xbmcvfs.translatePath(HOME + 'radio.m3u')) or ''
|
||||
state = hashlib.sha1((SETTINGS + m3u).encode('utf-8')).hexdigest()
|
||||
if read(os.path.join(profile, 'state')) == state:
|
||||
return
|
||||
|
||||
while player.isPlaying(): # restarting IPTV Simple stops the radio or TV playing
|
||||
if monitor.waitForAbort(10):
|
||||
return
|
||||
if monitor.waitForAbort(5):
|
||||
return
|
||||
log('station list or settings changed, restarting IPTV Simple')
|
||||
restart_iptv_simple()
|
||||
write(os.path.join(profile, 'state'), state)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user