Rip out rest of code that supported simulatnous outputs

This commit is contained in:
Thomas Adamcik 2011-07-17 04:14:21 +02:00
parent f912164d39
commit b2ccdec960
7 changed files with 19 additions and 145 deletions

View File

@ -17,10 +17,17 @@ v0.6.0 (in development)
- Replace :attr:`mopidy.backends.base.Backend.uri_handlers` with
:attr:`mopidy.backends.base.Backend.uri_schemes`, which just takes the part
up to the colon of an URI, and not any prefix.
- Add Listener API, :mod:`mopidy.listeners`, to be implemented by actors
wanting to receive events from the backend. This is a formalization of the
ad hoc events the Last.fm scrobbler has already been using for some time.
- Fix metadata update in Shoutcast streaming (Fixes: :issue:`122`)
- Fix metadata update in Shoutcast streaming (Fixes: :issue:`122`)
- Multiple simultaneously playing outputs was considered more trouble than what
it is worth maintnance wise. Thus, this feature has been axed for now.
Switching outputs is still posible, but only one can be active at a time, and
it is still the case that switching during playback does not funtion.
v0.5.0 (2011-06-15)

View File

@ -73,8 +73,8 @@ Using a custom audio sink
=========================
If you for some reason want to use some other GStreamer audio sink than
``autoaudiosink``, you can add ``mopidy.outputs.custom.CustomOutput`` to the
:attr:`mopidy.settings.OUTPUTS` setting, and set the
``autoaudiosink``, you can set :attr:`mopidy.settings.OUTPUTS` to
``mopidy.outputs.custom.CustomOutput``, and set the
:attr:`mopidy.settings.CUSTOM_OUTPUT` setting to a partial GStreamer pipeline
description describing the GStreamer sink you want to use.

View File

@ -131,7 +131,7 @@ server simultaneously. To use the SHOUTcast output, do the following:
#. Install, configure and start the Icecast server. It can be found in the
``icecast2`` package in Debian/Ubuntu.
#. Add ``mopidy.outputs.shoutcast.ShoutcastOutput`` output to the
#. Set ``mopidy.outputs.shoutcast.ShoutcastOutput`` as the first output in the
:attr:`mopidy.settings.OUTPUTS` setting.
#. Check the default values for the following settings, and alter them to match

View File

@ -29,7 +29,7 @@ class GStreamer(ThreadingActor):
**Settings:**
- :attr:`mopidy.settings.OUTPUTS`
- :attr:`mopidy.settings.OUTPUT`
"""
@ -66,9 +66,9 @@ class GStreamer(ThreadingActor):
self._pipeline.get_by_name('convert').get_pad('sink'))
def _setup_outputs(self):
for output in settings.OUTPUTS:
self._outputs.append(get_class(output)(self))
self._outputs[0].connect()
for klass in settings.OUTPUTS:
self._outputs.append(get_class(klass)())
self.connect_output(self._outputs[0].bin)
def _setup_message_processor(self):
bus = self._pipeline.get_bus()
@ -87,10 +87,6 @@ class GStreamer(ThreadingActor):
pad.link(target_pad)
def _on_message(self, bus, message):
if message.src in self._handlers:
if self._handlers[message.src](message):
return # Message was handeled by output
if message.type == gst.MESSAGE_EOS:
logger.debug(u'GStreamer signalled end-of-stream. '
'Telling backend ...')
@ -305,86 +301,4 @@ class GStreamer(ThreadingActor):
gst.element_link_many(self._volume, output)
logger.debug('Output set to %s', output.get_name())
def list_outputs(self):
"""
Get list with the name of all active outputs.
:rtype: list of strings
"""
return [output.get_name() for output in self._outputs]
def remove_output(self, output):
"""
Remove output from our pipeline.
:param output: output to remove from the pipeline
:type output: :class:`gst.Bin`
"""
peersrc = output.get_pad('sink').get_peer()
handler = peersrc.add_event_probe(self._handle_event_probe)
struct = gst.Structure('mopidy-unlink')
struct.set_value('handler', handler)
event = gst.event_new_custom(gst.EVENT_CUSTOM_DOWNSTREAM, struct)
self._volume.send_event(event)
def _handle_event_probe(self, srcpad, event):
if event.type == gst.EVENT_CUSTOM_DOWNSTREAM and event.has_name('mopidy-unlink'):
data = self._get_structure_data(event.get_structure())
output = srcpad.get_peer().get_parent()
srcpad.unlink(srcpad.get_peer())
srcpad.remove_event_probe(data['handler'])
output.set_state(gst.STATE_NULL)
self._pipeline.remove(output)
logger.warning('Removed %s', output.get_name())
return False
return True
def _get_structure_data(self, struct):
# Ugly hack to get around missing get_value in pygst bindings :/
data = {}
def get_data(key, value):
data[key] = value
struct.foreach(get_data)
return data
def connect_message_handler(self, element, handler):
"""
Attach custom message handler for given element.
Hook to allow outputs (or other code) to register custom message
handlers for all messages coming from the element in question.
In the case of outputs, :meth:`mopidy.outputs.BaseOutput.on_connect`
should be used to attach such handlers and care should be taken to
remove them in :meth:`mopidy.outputs.BaseOutput.on_remove` using
:meth:`remove_message_handler`.
The handler callback will only be given the message in question, and
is free to ignore the message. However, if the handler wants to prevent
the default handling of the message it should return :class:`True`
indicating that the message has been handled.
Note that there can only be one handler per element.
:param element: element to watch messages from
:type element: :class:`gst.Element`
:param handler: callable that takes :class:`gst.Message` and returns
:class:`True` if the message has been handeled
:type handler: callable
"""
self._handlers[element] = handler
def remove_message_handler(self, element):
"""
Remove custom message handler.
:param element: element to remove message handling from.
:type element: :class:`gst.Element`
"""
self._handlers.pop(element, None)
# FIXME re-add disconnect / swap output code?

View File

@ -13,8 +13,7 @@ class BaseOutput(object):
MESSAGE_ERROR = gst.MESSAGE_ERROR
MESSAGE_WARNING = gst.MESSAGE_WARNING
def __init__(self, gstreamer):
self.gstreamer = gstreamer
def __init__(self):
self.bin = self._build_bin()
self.bin.set_name(self.get_name())
@ -25,32 +24,6 @@ class BaseOutput(object):
logger.debug('Creating new output: %s', description)
return gst.parse_bin_from_description(description, True)
def connect(self):
"""Attach output to GStreamer pipeline."""
self.gstreamer.connect_output(self.bin)
self.on_connect()
def on_connect(self):
"""
Called after output has been connected to GStreamer pipeline.
*MAY be implemented by subclass.*
"""
pass
def remove(self):
"""Remove output from GStreamer pipeline."""
self.gstreamer.remove_output(self.bin)
self.on_remove()
def on_remove(self):
"""
Called after output has been removed from GStreamer pipeline.
*MAY be implemented by subclass.*
"""
pass
def get_name(self):
"""
Get name of the output. Defaults to the output's class name.

View File

@ -40,19 +40,3 @@ class ShoutcastOutput(BaseOutput):
u'username': settings.SHOUTCAST_OUTPUT_USERNAME,
u'password': settings.SHOUTCAST_OUTPUT_PASSWORD,
})
def on_connect(self):
self.gstreamer.connect_message_handler(
self.bin.get_by_name('shoutcast'), self.message_handler)
def on_remove(self):
self.gstreamer.remove_message_handler(
self.bin.get_by_name('shoutcast'))
def message_handler(self, message):
if message.type != self.MESSAGE_ERROR:
return False
error, debug = message.parse_error()
logger.warning('%s (%s)', error, debug)
self.remove()
return True

View File

@ -173,12 +173,8 @@ MPD_SERVER_PASSWORD = None
#:
#: Default::
#:
#: OUTPUTS = (
#: u'mopidy.outputs.local.LocalOutput',
#: )
OUTPUTS = (
u'mopidy.outputs.local.LocalOutput',
)
#: OUTPUTS = (u'mopidy.outputs.local.LocalOutput',)
OUTPUTS = (u'mopidy.outputs.local.LocalOutput',)
#: Hostname of the SHOUTcast server which Mopidy should stream audio to.
#: