Allow changing volume media player entity (#11781)

Co-authored-by: Zack Barett <zackbarett@hey.com>
This commit is contained in:
Paulus Schoutsen 2022-02-22 14:51:25 -08:00 committed by GitHub
parent f5b5414461
commit 5335772a7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 3 deletions

View File

@ -360,3 +360,17 @@ export const cleanupMediaTitle = (title?: string): string | undefined => {
const index = title.indexOf("?authSig=");
return index > 0 ? title.slice(0, index) : title;
};
/**
* Set volume of a media player entity.
* @param hass Home Assistant object
* @param entity_id entity ID of media player
* @param volume_level number between 0..1
* @returns
*/
export const setMediaPlayerVolume = (
hass: HomeAssistant,
entity_id: string,
volume_level: number
) =>
hass.callService("media_player", "volume_set", { entity_id, volume_level });

View File

@ -4,6 +4,7 @@ import {
MediaPlayerItem,
SUPPORT_PAUSE,
SUPPORT_PLAY,
SUPPORT_VOLUME_SET,
} from "../../data/media-player";
import { ResolvedMediaSource } from "../../data/media_source";
import { HomeAssistant } from "../../types";
@ -20,9 +21,11 @@ export class BrowserMediaPlayer {
public hass: HomeAssistant,
public item: MediaPlayerItem,
public resolved: ResolvedMediaSource,
volume: number,
private onChange: () => void
) {
const player = new Audio(this.resolved.url);
player.volume = volume;
player.addEventListener("play", this._handleChange);
player.addEventListener("playing", () => {
this.buffering = false;
@ -57,6 +60,11 @@ export class BrowserMediaPlayer {
this.player.play();
}
public setVolume(volume: number) {
this.player.volume = volume;
this.onChange();
}
public remove() {
this._removed = true;
// @ts-ignore
@ -89,8 +97,9 @@ export class BrowserMediaPlayer {
base.attributes = {
media_title: this.item.title,
entity_picture: this.item.thumbnail,
volume_level: this.player.volume,
// eslint-disable-next-line no-bitwise
supported_features: SUPPORT_PLAY | SUPPORT_PAUSE,
supported_features: SUPPORT_PLAY | SUPPORT_PAUSE | SUPPORT_VOLUME_SET,
};
if (this.player.duration) {

View File

@ -9,6 +9,7 @@ import {
mdiPlay,
mdiPlayPause,
mdiStop,
mdiVolumeHigh,
} from "@mdi/js";
import {
css,
@ -40,10 +41,12 @@ import {
getCurrentProgress,
MediaPlayerEntity,
MediaPlayerItem,
setMediaPlayerVolume,
SUPPORT_BROWSE_MEDIA,
SUPPORT_PAUSE,
SUPPORT_PLAY,
SUPPORT_STOP,
SUPPORT_VOLUME_SET,
} from "../../data/media-player";
import { ResolvedMediaSource } from "../../data/media_source";
import type { HomeAssistant } from "../../types";
@ -77,6 +80,8 @@ export class BarMediaPlayer extends LitElement {
private _progressInterval?: number;
private _browserPlayerVolume = 0.8;
public connectedCallback(): void {
super.connectedCallback();
@ -124,6 +129,7 @@ export class BarMediaPlayer extends LitElement {
this.hass,
item,
resolved,
this._browserPlayerVolume,
() => this.requestUpdate("_browserPlayer")
);
this._newMediaExpected = false;
@ -230,7 +236,7 @@ export class BarMediaPlayer extends LitElement {
)}
.path=${control.icon}
action=${control.action}
@click=${this._handleClick}
@click=${this._handleControlClick}
>
</ha-icon-button>
`
@ -257,6 +263,27 @@ export class BarMediaPlayer extends LitElement {
const isBrowser = this.entityId === BROWSER_PLAYER;
return html`
<div class="choose-player ${isBrowser ? "browser" : ""}">
${
stateObj && supportsFeature(stateObj, SUPPORT_VOLUME_SET)
? html`
<ha-button-menu corner="BOTTOM_START">
<ha-icon-button
slot="trigger"
.path=${mdiVolumeHigh}
></ha-icon-button>
<ha-slider
min="0"
max="100"
step="1"
.value=${stateObj.attributes.volume_level! * 100}
@change=${this._handleVolumeChange}
>
</ha-slider>
</ha-button-menu>
`
: ""
}
<ha-button-menu corner="BOTTOM_START">
${
this.narrow
@ -441,7 +468,7 @@ export class BarMediaPlayer extends LitElement {
}
}
private _handleClick(e: MouseEvent): void {
private _handleControlClick(e: MouseEvent): void {
const action = (e.currentTarget! as HTMLElement).getAttribute("action")!;
if (!this._browserPlayer) {
@ -474,6 +501,17 @@ export class BarMediaPlayer extends LitElement {
fireEvent(this, "player-picked", { entityId });
}
private async _handleVolumeChange(ev) {
ev.stopPropagation();
const value = Number(ev.target.value) / 100;
if (this._browserPlayer) {
this._browserPlayerVolume = value;
this._browserPlayer.setVolume(value);
} else {
await setMediaPlayerVolume(this.hass, this.entityId, value);
}
}
static get styles(): CSSResultGroup {
return css`
:host {