Support for showing playback progress in media_player (#150)

* Added support for showing playback progress in media_player.

* Small bugfix.

* Playback progress now updates without needed state transitions in HA.

* media_position_update_at property is now a datetime.

* Linting fixes + removed _internal polymer property + cleanup

* More linting.
This commit is contained in:
Bjarni Ivarsson 2016-11-28 07:25:17 +01:00 committed by Paulus Schoutsen
parent 9184aaf33f
commit 4d7e1fef75

View File

@ -100,6 +100,7 @@
}
.controls {
position: relative;
@apply(--paper-font-body1);
padding: 8px;
border-bottom-left-radius: 2px;
@ -112,6 +113,14 @@
height: 44px;
}
.controls .progress {
position: absolute;
top: 0;
left: 0;
width: 100%;
--paper-progress-active-color: red;
}
paper-icon-button {
opacity: var(--dark-primary-opacity);
}
@ -150,6 +159,13 @@
</div>
<div class='controls layout horizontal justified'>
<paper-progress
max='[[playbackDuration]]'
value='[[playbackPosition]]'
hidden$='[[!playbackVisible]]'
class='progress'
></paper-progress>
<paper-icon-button
icon='mdi:power'
on-tap='handleTogglePower'
@ -221,13 +237,86 @@ Polymer({
value: 1,
reflectToAttribute: true,
},
playbackDuration: {
type: Number,
},
playbackPosition: {
type: Number,
},
playbackVisible: {
type: Boolean,
value: false,
},
},
playerObjChanged: function (playerObj) {
var timeSincePositionValid;
if (!playerObj.isOff && !playerObj.isIdle) {
this.$.cover.style.backgroundImage = playerObj.stateObj.attributes.entity_picture ?
'url(' + playerObj.stateObj.attributes.entity_picture + ')' : '';
}
if (typeof this._positionTracking === 'undefined') {
this._positionTracking = {
position: null, // last value of media_position
time: null, // when that value was updated
interval: null, // interval timer to update playbackPosition property
};
}
// clear previous interval timer
if (this._positionTracking.interval) {
clearInterval(this._positionTracking.interval);
this._positionTracking.interval = null;
}
// update playback state from object
if (playerObj.stateObj.attributes.media_position_updated_at) {
// when was the position valid?
timeSincePositionValid = Math.abs(
new Date() - Date.parse(playerObj.stateObj.attributes.media_position_updated_at)
);
// update "current" position (in ms) to reflect that
this._positionTracking.position = (1000 * playerObj.stateObj.attributes.media_position) +
timeSincePositionValid;
// base playbackPosition calculations on calculate position now
this._positionTracking.time = Date.now();
// playbackDuration is expressed in ms (rounded to the next second)
this.playbackDuration = 1000 * playerObj.stateObj.attributes.media_duration;
} else {
// no playback position
this._positionTracking.position = null;
this._positionTracking.time = null;
this.playbackDuration = null;
}
if (playerObj.isPlaying && this._positionTracking.position != null && this.playbackDuration) {
// playback is in progress, update the playback status on an interval timer
// we choose 200ms here in order to get the playback paper-progress control movement smooth
this._positionTracking.interval = setInterval(this.updatePlaybackPosition.bind(this), 200);
} else {
// no playback in progress (or no playback info), update playback status
this.updatePlaybackPosition();
}
},
updatePlaybackPosition: function () {
if (this._positionTracking.position != null && this.playbackDuration) {
// calculate playback position in ms
this.playbackPosition = this._positionTracking.position +
(Date.now() - this._positionTracking.time);
this.playbackVisible = true;
} else {
this.playbackPosition = null;
this.playbackVisible = false;
}
},
computeBannerClasses: function (playerObj) {