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

View file

@ -1,4 +1,5 @@
.music-container { .music-container {
position: relative;
width: inherit; width: inherit;
height: inherit; height: inherit;
display: table-cell; display: table-cell;
@ -51,3 +52,17 @@
font-size: 25px; 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'), var $widget = $('.widget.music'),
$trackContainer = $widget.find('.track-container'), $trackContainer = $widget.find('.track-container'),
$timeContainer = $widget.find('.time-container'), $timeContainer = $widget.find('.time-container'),
$playbackStatusContainer = $widget.find('.playback-status-container'),
$noTrackElement = $trackContainer.find('.no-track-info'), $noTrackElement = $trackContainer.find('.no-track-info'),
$trackElement = $trackContainer.find('.track-info'), $trackElement = $trackContainer.find('.track-info'),
$artistElement = $trackElement.find('[data-bind=artist]'), $artistElement = $trackElement.find('[data-bind=artist]'),
@ -9,6 +10,11 @@ $(document).ready(function() {
$timeElapsedElement = $timeContainer.find('.time-elapsed'), $timeElapsedElement = $timeContainer.find('.time-elapsed'),
$timeTotalElement = $timeContainer.find('.time-total'), $timeTotalElement = $timeContainer.find('.time-total'),
$elapsedTimeBar = $widget.find('.time-bar > .elapsed'), $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, timeElapsed,
timeTotal, timeTotal,
refreshElapsedInterval; refreshElapsedInterval;
@ -30,6 +36,14 @@ $(document).ready(function() {
case 'platypush.message.event.music.MusicStopEvent': case 'platypush.message.event.music.MusicStopEvent':
refreshStatus(event.args.status); refreshStatus(event.args.status);
break; 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); $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() { var initWidget = function() {
$.when( $.when(
execute({ type: 'request', action: 'music.mpd.currentsong' }), execute({ type: 'request', action: 'music.mpd.currentsong' }),
@ -110,6 +150,7 @@ $(document).ready(function() {
).done(function(t, s) { ).done(function(t, s) {
refreshTrack(t[0].response.output); refreshTrack(t[0].response.output);
refreshStatus(s[0].response.output); refreshStatus(s[0].response.output);
refreshPlaybackStatus(s[0].response.output);
}); });
}; };

View file

@ -27,5 +27,37 @@
</div> </div>
</div> </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> </div>

View file

@ -4,7 +4,9 @@ import time
from platypush.backend import Backend from platypush.backend import Backend
from platypush.context import get_plugin from platypush.context import get_plugin
from platypush.message.event.music import MusicPlayEvent, MusicPauseEvent, \ from platypush.message.event.music import MusicPlayEvent, MusicPauseEvent, \
MusicStopEvent, NewPlayingTrackEvent, PlaylistChangeEvent MusicStopEvent, NewPlayingTrackEvent, PlaylistChangeEvent, VolumeChangeEvent, \
PlaybackConsumeModeChangeEvent, PlaybackSingleModeChangeEvent, \
PlaybackRepeatModeChangeEvent, PlaybackRandomModeChangeEvent
class MusicMpdBackend(Backend): class MusicMpdBackend(Backend):
@ -40,6 +42,7 @@ class MusicMpdBackend(Backend):
def run(self): def run(self):
super().run() super().run()
last_status = {}
last_state = None last_state = None
last_track = None last_track = None
last_playlist = None last_playlist = None
@ -79,6 +82,27 @@ class MusicMpdBackend(Backend):
if state == 'play' and track != last_track: if state == 'play' and track != last_track:
self.bus.post(NewPlayingTrackEvent(status=status, track=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_state = state
last_track = track last_track = track
time.sleep(self.poll_seconds) time.sleep(self.poll_seconds)

View file

@ -43,6 +43,51 @@ class MusicPauseEvent(MusicEvent):
super().__init__(*args, **kwargs) 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): class PlaylistChangeEvent(MusicEvent):
""" """
Event fired upon playlist change Event fired upon playlist change