Sync changes on playback volume or state with events and web UI

This commit is contained in:
Fabio Manganiello 2018-08-18 01:11:14 +02:00
parent fc1e15504d
commit d2bd49b364
5 changed files with 158 additions and 1 deletions
platypush
backend
http
static
css/widgets
js/widgets
templates/widgets
music/mpd
message/event/music

View file

@ -1,4 +1,5 @@
.music-container {
position: relative;
width: inherit;
height: inherit;
display: table-cell;
@ -51,3 +52,17 @@
font-size: 25px;
}
.playback-status-container {
position: absolute;
bottom: 0;
width: 100%;
border-top: 1px solid #ddd;
padding: 1rem 0;
font-size: 1.22rem;
color: #757f70;
}
.playback-status-container > .playback-status-values {
font-weight: bold;
}

View file

@ -2,6 +2,7 @@ $(document).ready(function() {
var $widget = $('.widget.music'),
$trackContainer = $widget.find('.track-container'),
$timeContainer = $widget.find('.time-container'),
$playbackStatusContainer = $widget.find('.playback-status-container'),
$noTrackElement = $trackContainer.find('.no-track-info'),
$trackElement = $trackContainer.find('.track-info'),
$artistElement = $trackElement.find('[data-bind=artist]'),
@ -9,6 +10,11 @@ $(document).ready(function() {
$timeElapsedElement = $timeContainer.find('.time-elapsed'),
$timeTotalElement = $timeContainer.find('.time-total'),
$elapsedTimeBar = $widget.find('.time-bar > .elapsed'),
$volumeElement = $playbackStatusContainer.find('[data-bind=playback-volume]'),
$randomElement = $playbackStatusContainer.find('[data-bind=playback-random]'),
$repeatElement = $playbackStatusContainer.find('[data-bind=playback-repeat]'),
$singleElement = $playbackStatusContainer.find('[data-bind=playback-single]'),
$consumeElement = $playbackStatusContainer.find('[data-bind=playback-consume]'),
timeElapsed,
timeTotal,
refreshElapsedInterval;
@ -30,6 +36,14 @@ $(document).ready(function() {
case 'platypush.message.event.music.MusicStopEvent':
refreshStatus(event.args.status);
break;
case 'platypush.message.event.music.VolumeChangeEvent':
case 'platypush.message.event.music.PlaybackRepeatModeChangeEvent':
case 'platypush.message.event.music.PlaybackRandomModeChangeEvent':
case 'platypush.message.event.music.PlaybackConsumeModeChangeEvent':
case 'platypush.message.event.music.PlaybackSingleModeChangeEvent':
refreshPlaybackStatus(event.args.status);
break;
}
};
@ -103,6 +117,32 @@ $(document).ready(function() {
$titleElement.text(track.title);
};
var refreshPlaybackStatus = function(status) {
if ('volume' in status) {
$volumeElement.text(status.volume + '%');
}
if ('random' in status) {
var state = !!parseInt(status.random);
$randomElement.text(state ? 'ON' : 'OFF');
}
if ('repeat' in status) {
var state = !!parseInt(status.repeat);
$repeatElement.text(state ? 'ON' : 'OFF');
}
if ('single' in status) {
var state = !!parseInt(status.single);
$singleElement.text(state ? 'ON' : 'OFF');
}
if ('consume' in status) {
var state = !!parseInt(status.consume);
$consumeElement.text(state ? 'ON' : 'OFF');
}
};
var initWidget = function() {
$.when(
execute({ type: 'request', action: 'music.mpd.currentsong' }),
@ -110,6 +150,7 @@ $(document).ready(function() {
).done(function(t, s) {
refreshTrack(t[0].response.output);
refreshStatus(s[0].response.output);
refreshPlaybackStatus(s[0].response.output);
});
};

View file

@ -27,5 +27,37 @@
</div>
</div>
</div>
<div class="playback-status-container">
<div class="row playback-status-titles">
<div class="two columns offset-by-one">Volume</div>
<div class="two columns">Random</div>
<div class="two columns">Repeat</div>
<div class="two columns">Single</div>
<div class="two columns">Consume</div>
</div>
<div class="row playback-status-values">
<div class="two columns offset-by-one">
<div data-bind="playback-volume"></div>
</div>
<div class="two columns">
<div data-bind="playback-random"></div>
</div>
<div class="two columns">
<div data-bind="playback-repeat"></div>
</div>
<div class="two columns">
<div data-bind="playback-single"></div>
</div>
<div class="two columns">
<div data-bind="playback-consume"></div>
</div>
</div>
</div>
</div>

View file

@ -4,7 +4,9 @@ import time
from platypush.backend import Backend
from platypush.context import get_plugin
from platypush.message.event.music import MusicPlayEvent, MusicPauseEvent, \
MusicStopEvent, NewPlayingTrackEvent, PlaylistChangeEvent
MusicStopEvent, NewPlayingTrackEvent, PlaylistChangeEvent, VolumeChangeEvent, \
PlaybackConsumeModeChangeEvent, PlaybackSingleModeChangeEvent, \
PlaybackRepeatModeChangeEvent, PlaybackRandomModeChangeEvent
class MusicMpdBackend(Backend):
@ -40,6 +42,7 @@ class MusicMpdBackend(Backend):
def run(self):
super().run()
last_status = {}
last_state = None
last_track = None
last_playlist = None
@ -79,6 +82,27 @@ class MusicMpdBackend(Backend):
if state == 'play' and track != last_track:
self.bus.post(NewPlayingTrackEvent(status=status, track=track))
if last_status.get('volume', None) != status['volume']:
self.bus.post(VolumeChangeEvent(
volume=int(status['volume']), status=status, track=track))
if last_status.get('random', None) != status['random']:
self.bus.post(PlaybackRandomModeChangeEvent(
state=bool(int(status['random'])), status=status, track=track))
if last_status.get('repeat', None) != status['repeat']:
self.bus.post(PlaybackRepeatModeChangeEvent(
state=bool(int(status['repeat'])), status=status, track=track))
if last_status.get('consume', None) != status['consume']:
self.bus.post(PlaybackConsumeModeChangeEvent(
state=bool(int(status['consume'])), status=status, track=track))
if last_status.get('single', None) != status['single']:
self.bus.post(PlaybackSingleModeChangeEvent(
state=bool(int(status['single'])), status=status, track=track))
last_status = status
last_state = state
last_track = track
time.sleep(self.poll_seconds)

View file

@ -43,6 +43,51 @@ class MusicPauseEvent(MusicEvent):
super().__init__(*args, **kwargs)
class VolumeChangeEvent(MusicEvent):
"""
Event fired upon volume change
"""
def __init__(self, volume, status=None, track=None, *args, **kwargs):
super().__init__(volume=volume, status=status, track=track, *args, **kwargs)
class PlaybackRepeatModeChangeEvent(MusicEvent):
"""
Event fired upon repeat mode change
"""
def __init__(self, state, status=None, track=None, *args, **kwargs):
super().__init__(state=state, status=status, track=track, *args, **kwargs)
class PlaybackRandomModeChangeEvent(MusicEvent):
"""
Event fired upon random mode change
"""
def __init__(self, state, status=None, track=None, *args, **kwargs):
super().__init__(state=state, status=status, track=track, *args, **kwargs)
class PlaybackConsumeModeChangeEvent(MusicEvent):
"""
Event fired upon consume mode change
"""
def __init__(self, state, status=None, track=None, *args, **kwargs):
super().__init__(state=state, status=status, track=track, *args, **kwargs)
class PlaybackSingleModeChangeEvent(MusicEvent):
"""
Event fired upon single mode change
"""
def __init__(self, state, status=None, track=None, *args, **kwargs):
super().__init__(state=state, status=status, track=track, *args, **kwargs)
class PlaylistChangeEvent(MusicEvent):
"""
Event fired upon playlist change