添加声音连续播放
This commit is contained in:
@@ -88,6 +88,11 @@ class AudioManager {
|
||||
this.isLoading = false;
|
||||
this.loadingPromise = null;
|
||||
|
||||
// 连续播放队列相关属性
|
||||
this.sequenceQueue = [];
|
||||
this.sequenceIndex = 0;
|
||||
this.isSequenceRunning = false;
|
||||
|
||||
// 网络状态相关
|
||||
this.networkOnline = true;
|
||||
this.pendingPlayKey = null;
|
||||
@@ -206,6 +211,8 @@ class AudioManager {
|
||||
this.currentPlayingKey = null;
|
||||
}
|
||||
this.allowPlayMap.set(key, false);
|
||||
// 触发连续播放队列的衔接
|
||||
this.onAudioEnded(key);
|
||||
});
|
||||
|
||||
// 监听播放停止事件
|
||||
@@ -263,16 +270,51 @@ class AudioManager {
|
||||
this.createAudio(key);
|
||||
}
|
||||
|
||||
// 播放指定音频
|
||||
play(key) {
|
||||
// 离线:缓存播放意图,待网络恢复后自动播放
|
||||
// 播放指定音频或音频数组(数组则按顺序连续播放)
|
||||
play(input) {
|
||||
// 离线:缓存播放意图(可为字符串或数组),待网络恢复后自动播放
|
||||
if (!this.networkOnline) {
|
||||
this.pendingPlayKey = input;
|
||||
debugLog(`网络不可用,记录播放意图: ${Array.isArray(input) ? input.join(',') : input}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 再次调用 play:打断前面所有声音与队列
|
||||
this.stopAll();
|
||||
this.isSequenceRunning = false;
|
||||
this.sequenceQueue = [];
|
||||
this.sequenceIndex = 0;
|
||||
|
||||
if (Array.isArray(input)) {
|
||||
// 过滤可播放的 key
|
||||
const queue = input.filter((k) => !!audioFils[k]);
|
||||
if (queue.length === 0) {
|
||||
debugLog("连续播放队列为空或无效");
|
||||
return;
|
||||
}
|
||||
this.sequenceQueue = queue;
|
||||
this.sequenceIndex = 0;
|
||||
this.isSequenceRunning = true;
|
||||
// 开始播放队列的第一个
|
||||
this._playSingle(queue[0], false);
|
||||
} else if (typeof input === "string") {
|
||||
this._playSingle(input, false);
|
||||
} else {
|
||||
debugLog("play 参数类型无效,仅支持字符串或字符串数组");
|
||||
}
|
||||
}
|
||||
|
||||
// 内部方法:播放单个 key
|
||||
_playSingle(key, forceStopAll = false) {
|
||||
if (!this.networkOnline) {
|
||||
this.pendingPlayKey = key;
|
||||
debugLog(`网络不可用,记录播放意图: ${key}`);
|
||||
return;
|
||||
}
|
||||
// 覆盖播放:若当前播放且不是同一音频,先停止当前播放
|
||||
if (this.currentPlayingKey && this.currentPlayingKey !== key) {
|
||||
|
||||
if (forceStopAll) {
|
||||
this.stopAll();
|
||||
} else if (this.currentPlayingKey && this.currentPlayingKey !== key) {
|
||||
this.stop(this.currentPlayingKey);
|
||||
}
|
||||
|
||||
@@ -303,6 +345,25 @@ class AudioManager {
|
||||
}
|
||||
}
|
||||
|
||||
// 连续播放:在某个音频结束后,若处于队列播放状态则继续下一个
|
||||
onAudioEnded(key) {
|
||||
if (!this.isSequenceRunning) return;
|
||||
const currentKey = this.sequenceQueue[this.sequenceIndex];
|
||||
if (currentKey !== key) return;
|
||||
|
||||
const nextIndex = this.sequenceIndex + 1;
|
||||
if (nextIndex < this.sequenceQueue.length) {
|
||||
this.sequenceIndex = nextIndex;
|
||||
const nextKey = this.sequenceQueue[nextIndex];
|
||||
this._playSingle(nextKey, false);
|
||||
} else {
|
||||
// 队列播放完成
|
||||
this.isSequenceRunning = false;
|
||||
this.sequenceQueue = [];
|
||||
this.sequenceIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 停止指定音频
|
||||
stop(key) {
|
||||
const audio = this.audioMap.get(key);
|
||||
|
||||
@@ -22,26 +22,23 @@ const totalShot = ref(0);
|
||||
watch(
|
||||
() => tips.value,
|
||||
(newVal) => {
|
||||
let key = "";
|
||||
if (newVal.includes("重回")) return;
|
||||
if (newVal.includes("红队")) key = "请红方射箭";
|
||||
if (newVal.includes("蓝队")) key = "请蓝方射箭";
|
||||
if (!sound.value) return;
|
||||
let key = [];
|
||||
if (newVal.includes("重回")) return;
|
||||
if (currentRoundEnded.value) {
|
||||
currentRound.value += 1;
|
||||
// 播放当前轮次语音
|
||||
audioManager.play(
|
||||
`第${["一", "二", "三", "四", "五"][currentRound.value - 1]}轮`
|
||||
);
|
||||
key.push(`第${["一", "二", "三", "四", "五"][currentRound.value - 1]}轮`);
|
||||
}
|
||||
// 延迟播放队伍提示音
|
||||
setTimeout(
|
||||
() => {
|
||||
if (key) audioManager.play(newVal.includes("你") ? "轮到你了" : key);
|
||||
currentRoundEnded.value = false;
|
||||
},
|
||||
currentRoundEnded.value ? 1000 : 0
|
||||
key.push(
|
||||
newVal.includes("你")
|
||||
? "轮到你了"
|
||||
: newVal.includes("红队")
|
||||
? "请红方射箭"
|
||||
: "请蓝方射箭"
|
||||
);
|
||||
audioManager.play(key);
|
||||
currentRoundEnded.value = false;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -26,6 +26,18 @@ onBeforeUnmount(() => {
|
||||
<template>
|
||||
<Container title="音频测试">
|
||||
<view class="container">
|
||||
<view>
|
||||
<text>连续播放1</text>
|
||||
<button hover-class="none" @click="playAudio(['第一轮', '请蓝方射箭'])">
|
||||
播放
|
||||
</button>
|
||||
</view>
|
||||
<view>
|
||||
<text>连续播放2</text>
|
||||
<button hover-class="none" @click="playAudio(['第二轮', '请红方射箭'])">
|
||||
播放
|
||||
</button>
|
||||
</view>
|
||||
<view v-for="key in Object.keys(audioFils)" :key="key">
|
||||
<text>{{ key }}</text>
|
||||
<text v-if="!loaded[key]">未加载</text>
|
||||
|
||||
Reference in New Issue
Block a user