def connect(self, first=True): ''' Try to get dbus connection with player ''' def gotPlayer(name): self.connected = True self.launched = True log.msg("got dbus connection with player") log.msg("player = %s" % name.encode('utf-8'), loglevel=logging.DEBUG) self._errors = 0 self.getStatus() def noPlayer(err): self.connected = False if self._errors > 5: self.launch_player(True) log.msg("maximum number of errors reached, \ killing player process") return self._errors += 1 log.msg("get dbus client failed: %s" % err.getErrorMessage()) if self.connected: return defer.succeed(None) if self.mediaplayer is None: self.mediaplayer = MediaPlayer(self.player) d = self.mediaplayer.connect() d.addCallbacks(gotPlayer, noPlayer) return d
def connect(self, first=True): """ Try to get dbus connection with player """ def gotPlayer(name): self.connected = True self.launched = True log.msg("got dbus connection with player") log.msg("player = %s" % name.encode("utf-8"), loglevel=logging.DEBUG) self._errors = 0 self.getStatus() def noPlayer(err): self.connected = False if self._errors > 5: self.launch_player(True) log.msg( "maximum number of errors reached, \ killing player process" ) return self._errors += 1 log.msg("get dbus client failed: %s" % err.getErrorMessage()) if self.connected: return defer.succeed(None) if self.mediaplayer is None: self.mediaplayer = MediaPlayer(self.player) d = self.mediaplayer.connect() d.addCallbacks(gotPlayer, noPlayer) return d
class Mprisclient(Service): """ Manage player through dbus mpris interface """ name = "MprisPlayer" launching = True launched = False connected = False repeat = False shuffle = False has_tracklist = False playlist = [] _playlist = [] oh_playlist = [] songid = 0 maxsongid = 0 numid = {} # badlist =[] idArray = "" tracksmax = 10000 max_volume = 100 _state = "Pending" upnp_state = "TRANSITIONING" oh_state = "Buffering" _duration = 0 reltime = "0:00:00" seconds = 0 _track_URI = "" _managed = False _errors = 0 stopping = False _volume = 100 notify = False rate = "1" _rate = "" _mtlist = "" mtlist = "" _muted = False timer = False metadata = {} _metadata = {} metadata_str = "NOT_IMPLEMENTED" playfunc = None mediaplayer = None def __init__(self, program="", args=None, **kwargs): """ Constructor """ self.playercmd_args = args self.player_path = program self.player_args = [program] self.player = program.split("/")[-1] def startService(self): """ Check and launch player program """ # print(self.playercmd_args, self.player_path) self.launch_player() def launch_player(self, test=False): if self.playercmd_args is not None: self.player_args = [self.player_path] + self.playercmd_args.split() for proc in psutil.process_iter(): if proc.name() == self.player: log.msg("Player process found", loglevel=logging.DEBUG) self._managed = False self.extpid = proc.pid self.juststarted = False reactor.callWhenRunning(self.connect) # @UndefinedVariable if test: if self._errors > 5: try: self.protocol.shutdown() except: proc.kill() return False else: self._errors += 1 return True return None if test: return False self._managed = True try: reactor.spawnProcess( # @UndefinedVariable PlayerProcess(self), self.player_path, self.player_args, env=os.environ ) except: log.err("Program unknown : %s" % self.player_args) def connect(self, first=True): """ Try to get dbus connection with player """ def gotPlayer(name): self.connected = True self.launched = True log.msg("got dbus connection with player") log.msg("player = %s" % name.encode("utf-8"), loglevel=logging.DEBUG) self._errors = 0 self.getStatus() def noPlayer(err): self.connected = False if self._errors > 5: self.launch_player(True) log.msg( "maximum number of errors reached, \ killing player process" ) return self._errors += 1 log.msg("get dbus client failed: %s" % err.getErrorMessage()) if self.connected: return defer.succeed(None) if self.mediaplayer is None: self.mediaplayer = MediaPlayer(self.player) d = self.mediaplayer.connect() d.addCallbacks(gotPlayer, noPlayer) return d def reconnect(self): if not self.connected: if not self.launched: test = self.launch_player(True) if test is False: reactor.callLater(10, self.reconnect) # @UndefinedVariable def checkPid(self): print(".") try: if self.extpid.poll() is None: reactor.callLater(3, self.checkPid) # @UndefinedVariable else: # log.msg("ext process stopped") self.extpid = None self.launched = False self.set_state("Stopped") self.connectionLost("Player process died") except: try: p = psutil.Process(self.extpid) del (p) reactor.callLater(3, self.checkPid) # @UndefinedVariable except: self.extpid = None self.launched = False self.set_state("Stopped") self.connectionLost("Player process died") # log.msg("ext process stopped: %s" % e) def endprocess(self): try: self._self.protocol.shutdown() except AttributeError: try: os.kill(self.extpid, signal.SIGINT) except Exception, e: log.err("endprocess failure : %s" % e.message) self.stopping = False
class Mprisclient(Service): ''' Manage player through dbus mpris interface ''' name = "MprisPlayer" launching = True launched = False connected = False repeat = False shuffle = False has_tracklist = False playlist = [] _playlist = [] oh_playlist = [] songid = 0 maxsongid = 0 numid = {} # badlist =[] idArray = '' tracksmax = 10000 max_volume = 100 _state = "Pending" upnp_state = "TRANSITIONING" oh_state = 'Buffering' _duration = 0 reltime = '0:00:00' seconds = 0 _track_URI = '' _managed = False _errors = 0 stopping = False _volume = 100 notify = False rate = '1' _rate = "" _mtlist = '' mtlist = '' _muted = False timer = False metadata = {} _metadata = {} metadata_str = 'NOT_IMPLEMENTED' playfunc = None mediaplayer = None def __init__(self, program='', args=None, **kwargs): ''' Constructor ''' self.playercmd_args = args self.player_path = program self.player_args = [program] self.player = program.split("/")[-1] def startService(self): ''' Check and launch player program ''' # print(self.playercmd_args, self.player_path) self.launch_player() def launch_player(self, test=False): if self.playercmd_args is not None: self.player_args = [self.player_path]\ + self.playercmd_args.split() for proc in psutil.process_iter(): if proc.name() == self.player: log.msg('Player process found', loglevel=logging.DEBUG) self._managed = False self.extpid = proc.pid self.juststarted = False reactor.callWhenRunning(self.connect) # @UndefinedVariable if test: if self._errors > 5: try: self.protocol.shutdown() except: proc.kill() return False else: self._errors += 1 return True return None if test: return False self._managed = True try: reactor.spawnProcess( # @UndefinedVariable PlayerProcess(self), self.player_path, self.player_args, env=os.environ) except: log.err("Program unknown : %s" % self.player_args) def connect(self, first=True): ''' Try to get dbus connection with player ''' def gotPlayer(name): self.connected = True self.launched = True log.msg("got dbus connection with player") log.msg("player = %s" % name.encode('utf-8'), loglevel=logging.DEBUG) self._errors = 0 self.getStatus() def noPlayer(err): self.connected = False if self._errors > 5: self.launch_player(True) log.msg("maximum number of errors reached, \ killing player process") return self._errors += 1 log.msg("get dbus client failed: %s" % err.getErrorMessage()) if self.connected: return defer.succeed(None) if self.mediaplayer is None: self.mediaplayer = MediaPlayer(self.player) d = self.mediaplayer.connect() d.addCallbacks(gotPlayer, noPlayer) return d def reconnect(self): if not self.connected: if not self.launched: test = self.launch_player(True) if test is False: reactor.callLater( 10, # @UndefinedVariable self.reconnect) def checkPid(self): print('.') try: if self.extpid.poll() is None: reactor.callLater(3, self.checkPid) # @UndefinedVariable else: # log.msg("ext process stopped") self.extpid = None self.launched = False self.set_state('Stopped') self.connectionLost('Player process died') except: try: p = psutil.Process(self.extpid) del (p) reactor.callLater(3, self.checkPid) # @UndefinedVariable except: self.extpid = None self.launched = False self.set_state('Stopped') self.connectionLost('Player process died') # log.msg("ext process stopped: %s" % e) def endprocess(self): try: self._self.protocol.shutdown() except AttributeError: try: os.kill(self.extpid, signal.SIGINT) except Exception, e: log.err("endprocess failure : %s" % e.message) self.stopping = False
class OmxPlayer(Service): ''' Manage omxplayer through dbus mpris interface ''' name = "OmxPlayer" launched = False cancelplay = False _state = "TRANSITIONING" _track_URI = '' _event = False _managed = False _errors = 0 indirect = False client = False robj = False is_player = False _volume = 100 notify = False _rate = "1" _mtlist = '' _muted = False reltime = '0:00:00' counter = 0 metadata = {} _metadata = {} metadata_str = 'NOT_IMPLEMENTED' # metadata = 'NOT_IMPLEMENTED' playfunc = None mediaplayer = None def __init__(self, player_path, args=None): ''' Constructor ''' self.playercmd_args = args self.player_path = player_path self.player_args = [player_path] self.player = player_path.split("/")[-1] def startService(self): ''' Check and launch player program ''' self.launch_player() def launch_player(self, test=False): if self.playercmd_args is not None: self.player_args = [self.player_path]\ + self.playercmd_args.split() for proc in psutil.process_iter(): if proc.name() == self.player: log.msg('Player process found', loglevel=logging.DEBUG) self._managed = False self.extpid = proc.pid self.juststarted = False self.running = 1 reactor.callWhenRunning(self.connect) # @UndefinedVariable if test: if self._errors > 5: try: self.protocol.shutdown() except: proc.kill() return False else: self._errors += 1 return True return if test: return False self._managed = True # try: # reactor.spawnProcess( # @UndefinedVariable # PlayerProcess(self), # self.player_path, # self.player_args, # env=os.environ) # except: # log.err("Program unknown : %s" % self.player_args) def connect(self, first=True): ''' Try to get dbus connection with player ''' def gotPlayer(name): self.connected = True self.launched = True log.msg("got dbus connection with player") log.msg("player = %s" % name.encode('utf8'), loglevel=logging.DEBUG) self._errors = 0 self.getStatus(True) def noPlayer(err): self.connected = False if self._errors > 5: self.launch_player(True) log.msg("maximum number of errors reached, \ killing player process") return self._errors += 1 log.msg("get dbus client failed: %s" % err.getErrorMessage()) # log.msg('Trying again...') if self.mediaplayer is None: self.mediaplayer = MediaPlayer(self.player) d = self.mediaplayer.connect() d.addCallbacks(gotPlayer, noPlayer) return d def disconnect(self, obj=None, reason=''): log.msg('dbus disconnected, reason=%s' % reason, loglevel=logging.DEBUG) self.set_state('STOPPED') def connectionLost(self, reason): self.disconnect(reason=reason) def getStatus(self, first=True): ''' Setup initial status and Install notifications ''' if first: self.notify = False try: self.mediaplayer.register_signal('PropertiesChanged', self.changed_state) except: log.msg("dbus register signal not supported, polling...", loglevel=logging.DEBUG) task.deferLater(reactor, 1, self.getStatus, False) # self.getStatus(False) else: self.notify = True self.mediaplayer.register_signal('NameLost', self.disconnect, interf='org.freedesktop.DBus') log.msg("notify = OK", loglevel=logging.DEBUG) task.deferLater(reactor, 1, self.getStatus, False) # self.getStatus(False) else: if self.launched: d = self.mediaplayer.get( "PlaybackStatus", interf='org.mpris.MediaPlayer2.Player') d.addCallbacks(self.set_state, dbus_func_failed, errbackArgs=('PlaybackStatus',)) reactor.callLater(3, self.checkPid) # @UndefinedVariable dd = self.mediaplayer.get("SupportedMimeTypes") dd.addCallbacks(self.set_mimetypes, dbus_func_failed, errbackArgs=('SupportedMimeTypes',)) ddd = self.mediaplayer.get( "Volume", interf='org.mpris.MediaPlayer2.Player') ddd.addCallbacks( lambda v: self.changed_state( 'org.mpris.MediaPlayer2.Player', {'Volume': v}, 0), dbus_func_failed, errbackArgs=('Get Volume',)) if not self.notify: reactor.callLater( # @UndefinedVariable 3, self.getStatus, False) else: if self.launch_player(True): return self.getStatus(True) def getMetadata(self): if self.launched: d = self.mediaplayer.get("Metadata", interf='org.mpris.MediaPlayer2.Player') d.addCallbacks(self.update_metadata, dbus_func_failed, errbackArgs=("Metadata",)) return self.metadata else: if self.launch_player(True): return self.getMetadata() def checkPid(self): try: if self.extpid.poll() is None: reactor.callLater(3, self.checkPid) # @UndefinedVariable else: # log.msg("ext process stopped") self.extpid = None self.launched = False self.set_state('STOPPED') self.connectionLost('Player process died') except: try: p = psutil.Process(self.extpid) del(p) reactor.callLater(3, self.checkPid) # @UndefinedVariable except: self.extpid = None self.launched = False # log.msg("ext process stopped: %s" % e) def changed_state(self, dbus_interface, msg, lst, pending=False): if pending: log.msg('pending', loglevel=logging.DEBUG) if not self._event: log.msg('cancelled', loglevel=logging.DEBUG) return defer.succeed(None) self._event = False log.msg('remote client %s changed state = %s' % (dbus_interface, msg), loglevel=logging.DEBUG) if 'PlaybackStatus' in msg.keys(): if len(msg['PlaybackStatus']) > 1: self.set_state(msg['PlaybackStatus']) if 'Rate' in msg.keys(): rate = msg['Rate'] self._rate = str( Fraction(float(rate)). limit_denominator(1). numerator)\ + "/"\ + str(Fraction(float(rate)). limit_denominator(1).denominator) if "Volume" in msg.keys(): log.msg('volume changed', loglevel=logging.DEBUG) vol = int(float(msg["Volume"])*100) if vol != self._volume: if vol != 0: self._volume = int(float(msg["Volume"])*100) self._muted = False else: self._muted = True log.msg('send volume', loglevel=logging.DEBUG) self.upnp_eventRCS( {'evtype': 'last_change', 'data': [{'vname': 'Volume', 'value': {'channel': 'Master', 'val': self._volume}}, {'vname': 'Mute', 'value': {'channel': 'Master', 'val': int(self._muted)}}]}) if 'Metadata' in msg.keys(): self.update_metadata(msg['Metadata']) def update_metadata(self, metadata): if metadata != self._metadata: self._metadata.update(metadata) self.metadata.update(mpris_decode(metadata)) if 'mpris:length' in metadata.keys(): ln = int(metadata['mpris:length']) if ln < 1: self._track_duration = "0:00:00" else: self._track_duration = mpristime_to_upnptime(ln) log.msg('track length: %s' % self._track_duration, loglevel=logging.DEBUG) if 'xesam:url' in metadata.keys(): self._track_URI = metadata['xesam:url'] self.metadata_str = didl_encode(self.metadata) def set_metadata(self, metadata): if (metadata != self.metadata) and (len(metadata) > 0): self.metadata.update(metadata) if 'duration' in metadata.keys(): self._track_duration = metadata['duration'] if 'url' in metadata.keys(): self._track_URI = metadata['url'] def set_state(self, state): log.msg("SET NEW STATE : %s " % state, loglevel=logging.DEBUG) if state in ['Stop', 'Play', 'Pause']: return defer.succeed(None) if state == "Paused": state = "PAUSED_PLAYBACK" else: self.cancelplay = False if state.upper() != self._state: self._state = str(state.upper()) log.msg('send new state: %s' % self._state, loglevel=logging.DEBUG) self.prepare_event('upnp_eventAV') self.upnp_eventAV( {'evtype': 'last_change', 'data': [{'vname': 'TransportState', 'value': {'val': self._state}}]}) else: return defer.succeed(None) def set_mimetypes(self, mtlist): # log.msg("mtlist: % s" % mtlist) if self._mtlist != mtlist and len(mtlist) > 0: self._mtlist = mtlist self.upnp_eventCM({ 'evtype': 'sink_protocol_info', 'data': [{'vname': 'SinkProtocolInfo', 'value': {'text': 'http-get:*:'+'' .join([':*,http-get:*:' .join(mtlist)])+':*'}}]}) def upnp_eventAV(self, evt): raise NotImplementedError() def upnp_eventCM(self, evt): raise NotImplementedError() def upnp_eventRCS(self, evt): raise NotImplementedError() def get_state(self): return self._state def get_rate(self): return self._rate def get_track_duration(self): try: duration = self._track_duration except: duration = '00:00:00' return duration def get_track_URI(self): try: uri = self._track_URI except: uri = '' return uri def get_track_md(self): return self.metadata_str def get_track(self): if self._state == 'STOPPED': track = 0 else: track = 1 return track def get_relcount(self): return 2147483647 def get_abscount(self): return 2147483647 def get_abstime(self): return '00:00:00' def endprocess(self): try: self._self.protocol.shutdown() except AttributeError: try: os.kill(self.extpid, signal.SIGINT) except Exception, e: log.err("endprocess failure : %s" % e.message) self.stopping = False