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.
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: