예제 #1
0
 def update_listitem(self, listitem, type, id, market='SE'):
     if type == 'Podcast':
         info = self.get_endpoint(SPOTIFY_ENDPOINT_EPISODES, id, market)
         album = get(
             info,
             ['show', 'name'],
             'unknown show',
         )
         artist = get(info, ['show', 'publisher'], 'unknown publisher')
         thumb = get(info, ['images', 0, 'url'], ADDON_ICON)
         title = get(info, ['name'], 'unknown episode')
     elif type == 'Track':
         info = self.get_endpoint(SPOTIFY_ENDPOINT_TRACKS, id, market)
         album = get(info, ['album', 'name'], 'unknown album')
         artist = get(info, ['artists', 0, 'name'], 'unknown artist')
         thumb = get(info, ['album', 'images', 0, 'url'], ADDON_ICON)
         title = get(info, ['name'], 'unknown title')
     else:
         album = ''
         artist = 'Unknown Media Type'
         thumb = ADDON_ICON
         title = ''
     listitem.setArt(dict(fanart=thumb, thumb=thumb))
     listitem.setInfo('music', dict(album=album, artist=artist,
                                    title=title))
     log('{}#{}#{}#{}'.format(title, artist, album, thumb))
예제 #2
0
 def load_modules(self):
     args = [module[2] for module in self.list_modules()]
     for module in [self.null_sink, self.rtp_send]:
         if module['args'] not in args:
             run('pactl load-module {} {}'.format(module['module'],
                                                  module['args']))
             log('loaded {} {}'.format(module['module'], module['args']))
     self.suspend_sink(1)
예제 #3
0
 def onPlayBackStopped(self):
     if self.is_playing_librespot:
         log('librespot playback stopped')
         self.is_playing_librespot = False
         self.stop_librespot(True)
     else:
         log('Kodi playback stopped')
         self.start_librespot()
예제 #4
0
 def get_headers(self):
     if time.time() > self.expiration:
         log('token expired')
         token = requests.post(**SPOTIFY_REQUEST_TOKEN).json()
         log(token)
         self.expiration = time.time() + float(token['expires_in']) - 5
         self.headers['Authorization'] = 'Bearer {}'.format(
             token['access_token'])
예제 #5
0
 def get_endpoint(self, endpoint, id, market):
     try:
         self.get_headers()
         return requests.get(url=endpoint + id,
                             headers=self.headers,
                             params=dict(market=market)).json()
     except Exception as e:
         log('failed to get {} from Spotify {}'.format(endpoint, e))
         return {}
예제 #6
0
 def __init__(self):
     super().__init__()
     settings = get_settings()
     quoted = {k: shlex.quote(v) for (k, v) in settings.items()}
     command = LIBRESPOT
     if settings['autoplay'] == 'true':
         command += LIBRESPOT_AUTOPLAY
     if (settings['discovery'] == 'false' and
             settings['password'] != '' and
             settings['username'] != ''):
         command += LIBRESPOT_AUTHENTICATE
     self.command = shlex.split(command.format(**quoted))
     log(shlex.split(command.format(**dict(quoted, password='******'))))
     self.is_aborted = False
     self.is_dead = False
     self.pulseaudio = Pulseaudio(settings)
     self.listitem = xbmcgui.ListItem()
     self.listitem.addStreamInfo('audio', {'codec': CODEC})
     self.listitem.setPath(path=self.pulseaudio.url)
예제 #7
0
 def run(self):
     log('monitor started')
     is_aborted = False
     is_dead = False
     while not (is_aborted or is_dead):
         self.is_changed = False
         librespot = Librespot()
         with librespot:
             while True:
                 is_aborted = self.waitForAbort(1)
                 if is_aborted:
                     log('monitor aborted')
                     librespot.is_aborted = True
                     break
                 is_dead = librespot.is_dead
                 if is_dead:
                     log('librespot died')
                     notification('Too many errors')
                     break
                 if self.is_changed:
                     log('settings changed')
                     break
     log('monitor stopped')
예제 #8
0
 def on_event_playing(self, type, id):
     log('event playing')
     SPOTIFY.update_listitem(self.listitem, type, id, self.country)
     if not self.isPlaying():
         log('starting librespot playback')
         self.pulseaudio.suspend_sink(0)
         self.play(self.pulseaudio.url, self.listitem)
     elif self.is_playing_librespot:
         log('updating librespot playback')
         self.updateInfoTag(self.listitem)
예제 #9
0
 def unload_modules(self):
     for module in self.list_modules():
         if module[2] in [self.null_sink['args'], self.rtp_send['args']]:
             run('pactl unload-module {}'.format(module[0]))
             log('unloaded {} {}'.format(module[1], module[2]))
예제 #10
0
 def suspend_sink(self, bit):
     run(self.suspend.format(bit))
     log('suspended sink {}'.format(bit))
예제 #11
0
 def onPlayBackStarted(self):
     log('Kodi playback started')
     self.is_playing_librespot = self.getPlayingFile() == self.pulseaudio.url
     if not self.is_playing_librespot:
         self.stop_librespot()
예제 #12
0
 def on_event_stopped(self):
     self.pulseaudio.suspend_sink(1)
     log('event stopped')
     self.panics = 0
     self.stop()
예제 #13
0
 def on_event_panic(self):
     self.pulseaudio.suspend_sink(1)
     self.panics += 1
     log('event panic {}/{}'.format(self.panics, MAX_PANICS))
     self.is_dead = self.panics >= MAX_PANICS
     self.stop_librespot(True)
예제 #14
0
 def stop(self):
     if self.is_playing_librespot and not self.is_aborted:
         log('stopping librespot playback')
         self.is_playing_librespot = False
         super().stop()
예제 #15
0
 def run_librespot(self):
     log('librespot thread started')
     self.restart = True
     while self.restart and not self.is_dead:
         self.librespot = subprocess.Popen(
             self.command,
             cwd=ADDON_HOME,
             env=ADDON_ENVT,
             stderr=subprocess.STDOUT,
             stdout=subprocess.PIPE,
             text=True)
         log('librespot started')
         with self.librespot.stdout:
             for line in self.librespot.stdout:
                 words = line.split()
                 if words[0] == '@Playing':
                     self.on_event_playing(words[1], words[2])
                 elif words[0] == '@Stopped':
                     self.on_event_stopped()
                 elif words[0] == 'stack':
                     self.on_event_panic()
                 else:
                     log(line.rstrip())
                     if 'Country:' in line:
                         self.country = words[-1].strip('"')
                         log('country={}'.format(self.country))
         self.pulseaudio.suspend_sink(1)
         self.stop()
         self.librespot.wait()
         log('librespot stopped')
     self.librespot = None
     log('librespot thread stopped')