Add AudioListener for events from the audio actor
This is analogous to how the core actor sends events to the frontends. This removes the audio actor's direct dependency on the core actor, which conceptually is on a higher layer.
This commit is contained in:
parent
8c78d469e2
commit
4b13f46e2e
@ -10,10 +10,17 @@ the URI of the resource they want to play, for these cases the default playback
|
||||
provider should be used.
|
||||
|
||||
For more advanced cases such as when the raw audio data is delivered outside of
|
||||
GStreamer or the backend needs to add metadata to the currently playing resource,
|
||||
developers should sub-class the base playback provider and implement the extra
|
||||
behaviour that is needed through the following API:
|
||||
GStreamer or the backend needs to add metadata to the currently playing
|
||||
resource, developers should sub-class the base playback provider and implement
|
||||
the extra behaviour that is needed through the following API:
|
||||
|
||||
|
||||
.. autoclass:: mopidy.audio.Audio
|
||||
:members:
|
||||
|
||||
|
||||
Audio listener
|
||||
==============
|
||||
|
||||
.. autoclass:: mopidy.audio.AudioListener
|
||||
:members:
|
||||
|
||||
@ -6,13 +6,13 @@ import gobject
|
||||
import logging
|
||||
|
||||
from pykka.actor import ThreadingActor
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import core, settings, utils
|
||||
from mopidy import settings, utils
|
||||
from mopidy.utils import process
|
||||
|
||||
# Trigger install of gst mixer plugins
|
||||
from mopidy.audio import mixers
|
||||
from . import mixers
|
||||
from .listener import AudioListener
|
||||
|
||||
logger = logging.getLogger('mopidy.audio')
|
||||
|
||||
@ -149,7 +149,7 @@ class Audio(ThreadingActor):
|
||||
|
||||
def _on_message(self, bus, message):
|
||||
if message.type == gst.MESSAGE_EOS:
|
||||
self._notify_core_of_eos()
|
||||
self._trigger_reached_end_of_stream_event()
|
||||
elif message.type == gst.MESSAGE_ERROR:
|
||||
error, debug = message.parse_error()
|
||||
logger.error(u'%s %s', error, debug)
|
||||
@ -158,14 +158,9 @@ class Audio(ThreadingActor):
|
||||
error, debug = message.parse_warning()
|
||||
logger.warning(u'%s %s', error, debug)
|
||||
|
||||
def _notify_core_of_eos(self):
|
||||
core_refs = ActorRegistry.get_by_class(core.Core)
|
||||
assert len(core_refs) <= 1, 'Expected at most one running core instance'
|
||||
if core_refs:
|
||||
logger.debug(u'Notifying core of end-of-stream')
|
||||
core_refs[0].proxy().playback.on_end_of_track()
|
||||
else:
|
||||
logger.debug(u'No core instance to notify of end-of-stream found')
|
||||
def _trigger_reached_end_of_stream_event(self):
|
||||
logger.debug(u'Triggering reached end of stream event')
|
||||
AudioListener.send('reached_end_of_stream')
|
||||
|
||||
def set_uri(self, uri):
|
||||
"""
|
||||
|
||||
28
mopidy/audio/listener.py
Normal file
28
mopidy/audio/listener.py
Normal file
@ -0,0 +1,28 @@
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
|
||||
class AudioListener(object):
|
||||
"""
|
||||
Marker interface for recipients of events sent by the audio actor.
|
||||
|
||||
Any Pykka actor that mixes in this class will receive calls to the methods
|
||||
defined here when the corresponding events happen in the core actor. This
|
||||
interface is used both for looking up what actors to notify of the events,
|
||||
and for providing default implementations for those listeners that are not
|
||||
interested in all events.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def send(event, **kwargs):
|
||||
"""Helper to allow calling of audio listener events"""
|
||||
listeners = ActorRegistry.get_by_class(AudioListener)
|
||||
for listener in listeners:
|
||||
getattr(listener.proxy(), event)(**kwargs)
|
||||
|
||||
def reached_end_of_stream(self):
|
||||
"""
|
||||
Called whenever the end of the audio stream is reached.
|
||||
|
||||
*MAY* be implemented by actor.
|
||||
"""
|
||||
pass
|
||||
@ -1,12 +1,14 @@
|
||||
from pykka.actor import ThreadingActor
|
||||
|
||||
from mopidy import audio
|
||||
|
||||
from .current_playlist import CurrentPlaylistController
|
||||
from .library import LibraryController
|
||||
from .playback import PlaybackController
|
||||
from .stored_playlists import StoredPlaylistsController
|
||||
|
||||
|
||||
class Core(ThreadingActor):
|
||||
class Core(ThreadingActor, audio.AudioListener):
|
||||
#: The current playlist controller. An instance of
|
||||
#: :class:`mopidy.core.CurrentPlaylistController`.
|
||||
current_playlist = None
|
||||
@ -40,3 +42,6 @@ class Core(ThreadingActor):
|
||||
def uri_schemes(self):
|
||||
"""List of URI schemes we can handle"""
|
||||
return self._backend.uri_schemes.get()
|
||||
|
||||
def reached_end_of_stream(self):
|
||||
self.playback.on_end_of_track()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user