Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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