def setup_apiserver(self):
     if self.apiserver is not None:
         self.apiserver.disconnect_websocket()
     
     apiserver = __tidalstream_settings__.getSetting("apiservercontroller")
     if not apiserver or apiserver == '0':
         return False
     
     self.apiserver = TidalStream(
         apiserver,
         __tidalstream_settings__.getSetting("apiurl-%s" % apiserver),
         __tidalstream_settings__.getSetting("username-%s" % apiserver),
         __tidalstream_settings__.getSetting("password-%s" % apiserver),
         identifier=IDENTIFIER,
         player_name=xbmc.getInfoLabel('System.FriendlyName')
     )
     
     self.apiserver.connect_websocket()
     
     return True
class TidalPlayer(xbmc.Player):
    last_file = None
    last_update_time = 0
    apiserver = None
    
    def __init__(self):
        xbmc.Player.__init__(self)
        
        self.setup_apiserver()
    
    def setup_apiserver(self):
        if self.apiserver is not None:
            self.apiserver.disconnect_websocket()
        
        apiserver = __tidalstream_settings__.getSetting("apiservercontroller")
        if not apiserver or apiserver == '0':
            return False
        
        self.apiserver = TidalStream(
            apiserver,
            __tidalstream_settings__.getSetting("apiurl-%s" % apiserver),
            __tidalstream_settings__.getSetting("username-%s" % apiserver),
            __tidalstream_settings__.getSetting("password-%s" % apiserver),
            identifier=IDENTIFIER,
            player_name=xbmc.getInfoLabel('System.FriendlyName')
        )
        
        self.apiserver.connect_websocket()
        
        return True
    
    def are_settings_equal(self):
        apiserver = __tidalstream_settings__.getSetting("apiservercontroller")
        if self.apiserver is None:
            if (not apiserver or apiserver == '0'):
                return True
            else:
                return False
        
        if apiserver != self.apiserver.name or \
           __tidalstream_settings__.getSetting("apiurl-%s" % apiserver) != self.apiserver.url or \
           __tidalstream_settings__.getSetting("username-%s" % apiserver) != self.apiserver.username or \
           __tidalstream_settings__.getSetting("password-%s" % apiserver) != self.apiserver.password or \
           IDENTIFIER != self.apiserver.identifier:
            return False
        
        return True
    
    def shutdown(self):
        if self.apiserver is not None:
            self.apiserver.disconnect_websocket()
    
    def report_ended(self):
        self.last_file = None
        
        if self.apiserver and self.apiserver.connected:
            self.apiserver.player_report('player_ended')
    
    def report_update(self, *args): # args here because some functions have arguments we don't care about
        if not self.isPlaying() or get_player() is None:
            return
        
        current_file = self.getPlayingFile()
        
        chapters = executeJSONRPC('XBMC.GetInfoLabels', labels=['Player.ChapterCount'])['Player.ChapterCount']
        current_chapter = executeJSONRPC('XBMC.GetInfoLabels', labels=['Player.Chapter'])['Player.Chapter']
        chapters = chapters and int(chapters) or 0
        current_chapter = current_chapter and int(current_chapter) or 0
        
        title = executeJSONRPC('Player.GetItem', properties=['title'], playerid=get_player())
        if title is None:
            return
        title = title['item']['title']
        
        if not title and self.isPlayingVideo():
           title = executeJSONRPC('XBMC.GetInfoLabels', labels=['VideoPlayer.Title'])['VideoPlayer.Title']
        
        current_status = executeJSONRPC('Player.GetProperties', properties=['audiostreams', 'subtitles', 'currentaudiostream', 'currentsubtitle', 'time', 'totaltime', 'type', 'speed'], playerid=get_player())
        
        speed = current_status['speed']
        totaltime = timestamp2seconds(current_status['totaltime'])
        current_time = timestamp2seconds(current_status['time'])
        
        audiostreams = [(audiostream['index'], audiostream['name'] or audiostream['language']) for audiostream in current_status['audiostreams']]
        current_audiostream = None
        if current_status['currentaudiostream']:
            current_audiostream = current_status['currentaudiostream']['index']
        
        subtitles = [(subtitle['index'], subtitle['name'] or subtitle['language']) for subtitle in current_status['subtitles']]
        current_subtitle = None
        if current_status['currentsubtitle']:
            current_subtitle = current_status['currentsubtitle']['index']
        
        report = {'current_time': current_time}
        
        if self.last_file != current_file or self.apiserver and self.apiserver.do_full_update:
            self.last_file = current_file
            
            report['title'] = title
            report['chapters'] = chapters
            report['length'] = totaltime
            report['audiostreams'] = audiostreams
            report['subtitles'] = subtitles
            self.speed = report['speed'] = 1
            
            self.current_chapter = None
            self.speed = None
            self.current_audiostream = None
            self.current_subtitle = None
            
            if self.apiserver:
                self.apiserver.do_full_update = False
        
        if self.current_chapter != current_chapter:
            self.current_chapter = report['current_chapter'] = current_chapter
        
        if self.speed != speed:
            self.speed = report['speed'] = speed
        
        if self.current_audiostream != current_audiostream:
            self.current_audiostream = report['current_audiostream'] = current_audiostream
        
        if self.current_subtitle != current_subtitle:
            self.current_subtitle = report['current_subtitle'] = current_subtitle
        
        if self.apiserver and self.apiserver.connected:
            self.apiserver.player_report('player_update', **report)
    
    def periodic_check(self):
        if self.apiserver and self.apiserver.ts_queue and not self.apiserver.ts_queue.empty():
            while not self.apiserver.ts_queue.empty():
                action, kwargs = self.apiserver.ts_queue.get()
                self.handle_action(action, **(kwargs or {}))
        
        if self.last_update_time + UPDATE_INTERVAL <= time.time():
            self.last_update_time = time.time()
            self.report_update()
        
        if self.apiserver:
            self.apiserver.check_periodic_stuff()
    
    onPlayBackPaused = report_update
    onPlayBackResumed = report_update
    onPlayBackStarted = report_update
    onPlayBackSeek = report_update
    onPlayBackSeekChapter = report_update
    onPlayBackSpeedChanged = report_update
    
    onPlayBackEnded = report_ended
    onPlayBackStopped = report_ended
    
    def handle_action(self, action, **kwargs):
        print 'got action %s / %s' % (action, kwargs)
        if action == 'open':
            self.play(kwargs['url'])
            return
        
        if get_player() is None:
            return
        
        if action == 'stop':
            executeJSONRPC('Player.Stop', playerid=get_player())
        elif action == 'next' or action == 'previous':
            executeJSONRPC('Player.GoTo', to=action, playerid=get_player())
        elif action == 'seek':
            executeJSONRPC('Player.Seek', playerid=get_player(), value=seconds2timestamp(kwargs['time']))
        elif action == 'set_speed':
            executeJSONRPC('Player.SetSpeed', playerid=get_player(), speed=kwargs['speed'])
        elif action == 'set_subtitle':
            executeJSONRPC('Player.SetSubtitle', playerid=get_player(), subtitle=kwargs['track_id'])
        elif action == 'set_audio_stream':
            executeJSONRPC('Player.SetAudioStream', playerid=get_player(), stream=kwargs['track_id'])