Merge pull request #938 from AlexandrePTJ/feature/frontend_audioevents
Propagate stream metadata
This commit is contained in:
commit
fcab27b5da
@ -279,7 +279,7 @@ class RootCommand(Command):
|
||||
mixer = self.start_mixer(config, mixer_class)
|
||||
audio = self.start_audio(config, mixer)
|
||||
backends = self.start_backends(config, backend_classes, audio)
|
||||
core = self.start_core(mixer, backends)
|
||||
core = self.start_core(mixer, backends, audio)
|
||||
self.start_frontends(config, frontend_classes, core)
|
||||
loop.run()
|
||||
except (exceptions.BackendError,
|
||||
@ -360,9 +360,9 @@ class RootCommand(Command):
|
||||
|
||||
return backends
|
||||
|
||||
def start_core(self, mixer, backends):
|
||||
def start_core(self, mixer, backends, audio):
|
||||
logger.info('Starting Mopidy core')
|
||||
return Core.start(mixer=mixer, backends=backends).proxy()
|
||||
return Core.start(mixer=mixer, backends=backends, audio=audio).proxy()
|
||||
|
||||
def start_frontends(self, config, frontend_classes, core):
|
||||
logger.info(
|
||||
|
||||
@ -7,12 +7,14 @@ import pykka
|
||||
|
||||
from mopidy import audio, backend, mixer
|
||||
from mopidy.audio import PlaybackState
|
||||
from mopidy.audio.utils import convert_tags_to_track
|
||||
from mopidy.core.history import HistoryController
|
||||
from mopidy.core.library import LibraryController
|
||||
from mopidy.core.listener import CoreListener
|
||||
from mopidy.core.playback import PlaybackController
|
||||
from mopidy.core.playlists import PlaylistsController
|
||||
from mopidy.core.tracklist import TracklistController
|
||||
from mopidy.models import TlTrack, Track
|
||||
from mopidy.utils import versioning
|
||||
|
||||
|
||||
@ -40,7 +42,7 @@ class Core(
|
||||
"""The tracklist controller. An instance of
|
||||
:class:`mopidy.core.TracklistController`."""
|
||||
|
||||
def __init__(self, mixer=None, backends=None):
|
||||
def __init__(self, mixer=None, backends=None, audio=None):
|
||||
super(Core, self).__init__()
|
||||
|
||||
self.backends = Backends(backends)
|
||||
@ -57,6 +59,8 @@ class Core(
|
||||
|
||||
self.tracklist = TracklistController(core=self)
|
||||
|
||||
self.audio = audio
|
||||
|
||||
def get_uri_schemes(self):
|
||||
futures = [b.uri_schemes for b in self.backends]
|
||||
results = pykka.get_all(futures)
|
||||
@ -102,6 +106,34 @@ class Core(
|
||||
# Forward event from mixer to frontends
|
||||
CoreListener.send('mute_changed', mute=mute)
|
||||
|
||||
def tags_changed(self, tags):
|
||||
# Validity checks
|
||||
if not self.audio:
|
||||
return
|
||||
if self.playback.current_tl_track is None:
|
||||
return
|
||||
|
||||
tags = self.audio.get_current_tags().get()
|
||||
if not tags:
|
||||
return
|
||||
|
||||
# Request available metadata and set a track
|
||||
mt_track = convert_tags_to_track(tags)
|
||||
|
||||
# Merge current_tl_track with metadata in current_metadata_track
|
||||
c_track = self.playback.current_tl_track.track
|
||||
track_kwargs = {k: v for k, v in c_track.__dict__.items() if v}
|
||||
for k, v in mt_track.__dict__.items():
|
||||
if v:
|
||||
track_kwargs[k] = v
|
||||
|
||||
self.playback.current_metadata_track = TlTrack(**{
|
||||
'tlid': self.playback.current_tl_track.tlid,
|
||||
'track': Track(**track_kwargs)})
|
||||
|
||||
# Send event to frontends
|
||||
CoreListener.send('current_metadata_changed')
|
||||
|
||||
|
||||
class Backends(list):
|
||||
def __init__(self, backends):
|
||||
|
||||
@ -163,3 +163,11 @@ class CoreListener(listener.Listener):
|
||||
:type time_position: int
|
||||
"""
|
||||
pass
|
||||
|
||||
def current_metadata_changed(self):
|
||||
"""
|
||||
Called whenever current track's metadata changed
|
||||
|
||||
*MAY* be implemented by actor.
|
||||
"""
|
||||
pass
|
||||
|
||||
@ -126,6 +126,15 @@ class PlaybackController(object):
|
||||
mute = property(get_mute, set_mute)
|
||||
"""Mute state as a :class:`True` if muted, :class:`False` otherwise"""
|
||||
|
||||
def get_current_metadata_track(self):
|
||||
return self.current_metadata_track
|
||||
|
||||
current_metadata_track = None
|
||||
"""
|
||||
The currently playing metadata :class:`mopidy.models.Track`,
|
||||
or :class:`None`.
|
||||
"""
|
||||
|
||||
# Methods
|
||||
|
||||
# TODO: remove this.
|
||||
|
||||
@ -73,3 +73,6 @@ class MpdFrontend(pykka.ThreadingActor, CoreListener):
|
||||
|
||||
def mute_changed(self, mute):
|
||||
self.send_idle('output')
|
||||
|
||||
def current_metadata_changed(self):
|
||||
self.send_idle('playlist')
|
||||
|
||||
@ -275,9 +275,26 @@ def plchanges(context, version):
|
||||
- Calls ``plchanges "-1"`` two times per second to get the entire playlist.
|
||||
"""
|
||||
# XXX Naive implementation that returns all tracks as changed
|
||||
if int(version) < context.core.tracklist.version.get():
|
||||
tracklist_version = context.core.tracklist.version.get()
|
||||
iversion = int(version)
|
||||
if iversion < tracklist_version:
|
||||
return translator.tracks_to_mpd_format(
|
||||
context.core.tracklist.tl_tracks.get())
|
||||
elif iversion == tracklist_version:
|
||||
# If version are equals, it is just a metadata update
|
||||
# So we replace the updated track in playlist
|
||||
current_md_track = context.core.playback.current_metadata_track.get()
|
||||
if current_md_track is None:
|
||||
return None
|
||||
|
||||
ntl_tracks = []
|
||||
tl_tracks = context.core.tracklist.tl_tracks.get()
|
||||
for tl_track in tl_tracks:
|
||||
if tl_track.tlid == current_md_track.tlid:
|
||||
ntl_tracks.append(current_md_track)
|
||||
else:
|
||||
ntl_tracks.append(tl_track)
|
||||
return translator.tracks_to_mpd_format(ntl_tracks)
|
||||
|
||||
|
||||
@protocol.commands.add('plchangesposid', version=protocol.INT)
|
||||
|
||||
@ -34,7 +34,9 @@ def currentsong(context):
|
||||
Displays the song info of the current song (same song that is
|
||||
identified in status).
|
||||
"""
|
||||
tl_track = context.core.playback.current_tl_track.get()
|
||||
tl_track = context.core.playback.current_metadata_track.get()
|
||||
if tl_track is None:
|
||||
tl_track = context.core.playback.current_tl_track.get()
|
||||
if tl_track is not None:
|
||||
position = context.core.tracklist.index(tl_track).get()
|
||||
return translator.track_to_mpd_format(tl_track, position=position)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user