Exemple #1
0
    def __init__(self, bus, db, options=None, queue_options=None,
                 smart_queue_options=None, audiosink_config=None):
        log.Loggable.__init__(self)

        try:
            bus_name = dbus.service.BusName(BUS_NAME, bus)
        except:
            bus_name = None
            self.tube = bus
        else:
            self.tube = None
        dbus.gobject_service.ExportedGObject.__init__(self, bus,
                                                      bus_name=bus_name,
                                                      object_path=PLAYER_PATH)

        DBusPlayerAPI.__init__(self)
        self.options = options or {}
        self._bus = bus
        self._db = db
        self._current_media = {}

        self.queue = Playlist(bus, db, queue_options, smart_queue_options)
        self.queue.connect('track-added', self._track_added)
        self.queue.connect('track-removed', self._track_removed)
        self.queue.connect('current-item-changed',
                           self._current_playlist_item_changed)

        self._speed = 1.
        self._tempo = 1.
Exemple #2
0
class Player(dbus.gobject_service.ExportedGObject, log.Loggable,
             DBusPlayerAPI):
    SUPPORTS_MULTIPLE_CONNECTIONS = True

    __gsignals__ = {
        'track-ended' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                         (gobject.TYPE_FLOAT, gobject.TYPE_PYOBJECT,)),
        'now-playing' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
                         (gobject.TYPE_PYOBJECT,)),
        'state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
                          (gobject.TYPE_PYOBJECT,)),
        }

    playing = gobject.property(type=bool, default=False)
    track_start_time = gobject.property(type=float,
                                        default=time.time())

    def __init__(self, bus, db, options=None, queue_options=None,
                 smart_queue_options=None, audiosink_config=None):
        log.Loggable.__init__(self)

        try:
            bus_name = dbus.service.BusName(BUS_NAME, bus)
        except:
            bus_name = None
            self.tube = bus
        else:
            self.tube = None
        dbus.gobject_service.ExportedGObject.__init__(self, bus,
                                                      bus_name=bus_name,
                                                      object_path=PLAYER_PATH)

        DBusPlayerAPI.__init__(self)
        self.options = options or {}
        self._bus = bus
        self._db = db
        self._current_media = {}

        self.queue = Playlist(bus, db, queue_options, smart_queue_options)
        self.queue.connect('track-added', self._track_added)
        self.queue.connect('track-removed', self._track_removed)
        self.queue.connect('current-item-changed',
                           self._current_playlist_item_changed)

        self._speed = 1.
        self._tempo = 1.

    def create_pipeline(self):
        self._pipeline = gst.element_factory_make('playbin')
        pbus = self._pipeline.get_bus()
        pbus.connect('message::eos', self._bus_message_eos_cb)
        pbus.add_signal_watch()
        self.audio_sink = self.options.audiosink.name

        try:
            props = self.options.audiosink.property
            if not isinstance(props, list):
                props = [props,]
        except KeyError:
            props = []

        self.audio_sink_options = props

    def _bus_message_eos_cb(self, bus, message):
        self.info("End of stream reached")

        media = self._get_current_media()
        self.emit('track-ended', self.track_start_time, media)

        self.next_track()

    def _get_current_media(self):
        if 'length' in self._current_media and \
               not self._current_media['length']:
            self._current_media['length'] = self.duration * 1000

        return self._current_media

    def _current_playlist_item_changed(self, obj, infos):
        media_id, uri, short_name = infos
        if media_id:
            db = self.queue.db
            media = db.get_full_track_infos(media_id)
            if media:
                media = db.track_dict(media)
                media['length'] = 0

                del media['path']
                media['URI'] = uri
                self.emit('now-playing', media)
            else:
                media = {}
        else:
            media = {}
        self._current_media = media

    def _track_added(self, obj, media, play_now):
        if play_now:
            location = "file://%s" % media.path
            self.queue.set_current_item(media.id, location, media.title)
            self.play_uri(location)

    def _track_removed(self, obj, index):
        if self.queue.tracks() and self.queue.get_current_item() == self.queue.tracks()[index]:
            self.next_track()

    def start(self):
        self.next_track()

    def stop(self):
        self._pipeline.set_state(gst.STATE_READY)
        self.playing = False
        self.emit('state-changed', self.state)

    @gobject.property
    def state(self):
        return self._pipeline.get_state()[1]

    def get_audio_sink(self):
        return self._audiosink

    def set_audio_sink(self, name):
        # TODO: add support for sink options
        if not name:
            name = "autoaudiosink"

        sink = gst.element_factory_make(name)

        try:
            self._pitch_elt = gst.element_factory_make("pitch", "pitch")
        except gst.ElementNotFoundError, error:
            self.warning("gst pitch element not found.")
            self._pitch_elt = None
            self._pipeline.set_property('audio-sink', sink)
        else: