Player controlls working

This commit is contained in:
Thomas Lovén 2019-06-27 11:10:10 +02:00
parent b7eb237632
commit 3e704e97d1
4 changed files with 84 additions and 19 deletions

View File

@ -1 +1 @@
!function(e){var o={};function n(t){if(o[t])return o[t].exports;var r=o[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=o,n.d=function(e,o,t){n.o(e,o)||Object.defineProperty(e,o,{enumerable:!0,get:t})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,o){if(1&o&&(e=n(e)),8&o)return e;if(4&o&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&o&&"string"!=typeof e)for(var r in e)n.d(t,r,function(o){return e[o]}.bind(null,r));return t},n.n=function(e){var o=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(o,"a",o),o},n.o=function(e,o){return Object.prototype.hasOwnProperty.call(e,o)},n.p="",n(n.s=0)}([function(e,o,n){"use strict";n.r(o);let t=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}();window.browser_mod=new class{constructor(){window.hassConnection.then(e=>this.connect(e.conn))}connect(e){console.log("Connection opened. Connecting to browser_mod"),this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:t}),console.log("Connected"),console.log(this.connection)}callback(e){console.log("Got ws message"),console.log(e),"update"===e.command&&this.update()}update(){this.conn&&this.conn.sendMessage({type:"browser_mod/update",deviceID:t,data:{browser:{},player:{state:"idle"}}})}}}]);
!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);let o=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}();window.browser_mod=new class{constructor(){window.hassConnection.then(e=>this.connect(e.conn)),this.player=new Audio,this.player.addEventListener("ended",this.update.bind(this)),this.player.addEventListener("play",this.update.bind(this)),this.player.addEventListener("pause",this.update.bind(this)),this.player.addEventListener("volumechange",this.update.bind(this))}connect(e){console.log("Connection opened. Connecting to browser_mod"),this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:o}),console.log("Connected"),console.log(this.connection)}callback(e){switch(console.log("Got ws message"),console.log(e),e.command){case"update":this.update(e);break;case"play":this.play(e);break;case"pause":this.pause(e);break;case"stop":this.stop(e);break;case"set_volume":this.set_volume(e);break;case"mute":this.mute(e)}}get player_state(){return this.player.src?this.player.ended?"stopped":this.player.paused?"paused":"playing":"stopped"}play(e){const t=e.media_content_id;t&&(this.player.src=t),this.player.play()}pause(e){this.player.pause()}stop(e){this.player.pause(),this.player.src=null}set_volume(e){void 0!==e.volume_level&&(this.player.volume=e.volume_level)}mute(e){this.player.muted=Boolean(e.mute)}update(){this.conn&&this.conn.sendMessage({type:"browser_mod/update",deviceID:o,data:{browser:{},player:{volume:this.player.volume,muted:this.player.muted,src:this.player.src,state:this.player_state}}})}}}]);

View File

@ -52,11 +52,10 @@ class BrowserModEntity(Entity):
self._ws_connection = None
self.entity_id = async_generate_entity_id("media_player.{}", alias or deviceID, hass=hass)
def ws_send(self, command, data=None):
data = data or {}
def ws_send(self, command, **kwargs):
self._ws_connection.send_message(event_message(self._ws_cid, {
"command": command,
**data,
**kwargs,
}))
def ws_connect(self, connection, cid):

View File

@ -10,6 +10,7 @@ from homeassistant.const import (
STATE_PAUSED,
STATE_PLAYING,
STATE_IDLE,
STATE_UNKNOWN,
)
from .const import DOMAIN, DATA_DEVICES, DATA_ADDERS, DATA_ALIASES
@ -46,12 +47,20 @@ class BrowserModPlayer(MediaPlayerDevice, BrowserModEntity):
"browser": self._ws_data.get("browser"),
}
@property
def _player_data(self):
return self._ws_data.get("player", {});
@property
def state(self):
if not self._ws_connection:
return STATE_UNAVAILABLE
return STATE_IDLE
return None
state = self._player_data.get("state", "unknown")
return {
"playing": STATE_PLAYING,
"paused": STATE_PAUSED,
"stopped": STATE_IDLE,
}.get(state, STATE_UNKNOWN)
@property
def supported_features(self):
return (
@ -61,26 +70,26 @@ class BrowserModPlayer(MediaPlayerDevice, BrowserModEntity):
)
@property
def volume_level(self):
return 0
return self._player_data.get("volume", 0)
@property
def is_volume_mutes(self):
return False
def is_volume_muted(self):
return self._player_data.get("muted", False)
@property
def media_content_id(self):
return ""
return self._player_data.get("src", "")
def set_volume_level(self, volume):
pass
self.ws_send("set_volume", volume_level=volume)
def mute_volume(self, mute):
pass
self.ws_send("mute", mute=mute)
def play_media(self, media_type, media_id, **kwargs):
pass
self.ws_send("play", media_content_id=media_id)
def media_play(self):
pass
self.ws_send("play")
def media_pause(self):
pass
self.ws_send("pause")
def media_stop(self):
pass
self.ws_send("stop")

View File

@ -3,6 +3,12 @@ class BrowserMod {
constructor() {
window.hassConnection.then((conn) => this.connect(conn.conn));
this.player = new Audio();
this.player.addEventListener("ended", this.update.bind(this));
this.player.addEventListener("play", this.update.bind(this));
this.player.addEventListener("pause", this.update.bind(this));
this.player.addEventListener("volumechange", this.update.bind(this));
}
connect(conn) {
@ -19,10 +25,58 @@ class BrowserMod {
callback(msg) {
console.log("Got ws message");
console.log(msg);
if(msg.command === "update")
this.update();
switch (msg.command) {
case "update":
this.update(msg);
break;
case "play":
this.play(msg);
break;
case "pause":
this.pause(msg);
break;
case "stop":
this.stop(msg);
break;
case "set_volume":
this.set_volume(msg);
break;
case "mute":
this.mute(msg);
break;
}
}
get player_state() {
if (!this.player.src) return "stopped";
if (this.player.ended) return "stopped";
if (this.player.paused) return "paused";
return "playing";
}
play(msg) {
const src = msg.media_content_id;
if(src)
this.player.src = src;
this.player.play();
}
pause(msg) {
this.player.pause();
}
stop(msg) {
this.player.pause();
this.player.src = null;
}
set_volume(msg) {
if (msg.volume_level === undefined) return;
this.player.volume = msg.volume_level;
}
mute(msg) {
this.player.muted = Boolean(msg.mute)
}
update() {
if(!this.conn) return;
@ -34,7 +88,10 @@ class BrowserMod {
},
player: {
state: "idle",
volume: this.player.volume,
muted: this.player.muted,
src: this.player.src,
state: this.player_state,
},
},
});