AudioPlayer fixes:

- Prevent needing to double-click the play button if something makes the stream stop
- Use the web BroadcastChannel API to prevent audio from playing in multiple tabs or players at once
This commit is contained in:
Buster Neece 2023-09-01 12:41:47 -05:00
parent e251c0e0e0
commit c205487620
No known key found for this signature in database
3 changed files with 36 additions and 15 deletions

View File

@ -10,7 +10,7 @@
import getLogarithmicVolume from '~/functions/getLogarithmicVolume';
import Hls from 'hls.js';
import {usePlayerStore} from "~/store";
import {nextTick, onMounted, ref, toRef, watch} from "vue";
import {nextTick, onMounted, onScopeDispose, ref, toRef, watch} from "vue";
const props = defineProps({
title: {
@ -36,6 +36,8 @@ const store = usePlayerStore();
const isPlaying = toRef(store, 'isPlaying');
const current = toRef(store, 'current');
const bc = ref<BroadcastChannel | null>(null);
watch(toRef(props, 'volume'), (newVol) => {
if ($audio.value !== null) {
$audio.value.volume = getLogarithmicVolume(newVol);
@ -125,6 +127,10 @@ const play = () => {
$audio.value.load();
$audio.value.play();
if (bc.value) {
bc.value.postMessage('played');
}
});
};
@ -166,6 +172,19 @@ onMounted(() => {
stop();
});
}
if ('BroadcastChannel' in window) {
bc.value = new BroadcastChannel('audio_player');
bc.value.addEventListener('message', () => {
stop();
}, {passive: true});
}
});
onScopeDispose(() => {
if (bc.value) {
bc.value.close()
}
});
defineExpose({

View File

@ -47,11 +47,11 @@ const isPlaying = toRef($store, 'isPlaying');
const current = toRef($store, 'current');
const isThisPlaying = computed(() => {
if (!get(isPlaying)) {
if (!isPlaying.value) {
return false;
}
const playingUrl = getUrlWithoutQuery(get(current).url);
const playingUrl = getUrlWithoutQuery(current.value.url);
const thisUrl = getUrlWithoutQuery(props.url);
return playingUrl === thisUrl;
});

View File

@ -3,24 +3,25 @@ import {defineStore} from "pinia";
export const usePlayerStore = defineStore(
'player',
{
state: () => {
return {
isPlaying: false,
current: {
state: () => ({
isPlaying: false,
current: {
url: null,
isStream: true
}
}),
actions: {
resetCurrent(): void {
this.current = {
url: null,
isStream: true
}
};
},
actions: {
};
},
toggle(payload): void {
const url = payload.url;
if (this.current.url === url) {
this.current = {
url: null,
isStream: true
};
this.resetCurrent();
} else {
this.current = payload;
}
@ -30,6 +31,7 @@ export const usePlayerStore = defineStore(
},
stopPlaying(): void {
this.isPlaying = false;
this.resetCurrent();
}
}
}