mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-10 02:46:38 +00:00
Allow changing volume media player entity (#11781)
Co-authored-by: Zack Barett <zackbarett@hey.com>
This commit is contained in:
parent
f5b5414461
commit
5335772a7a
@ -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 });
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user