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:
parent
e251c0e0e0
commit
c205487620
|
@ -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({
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue