uniapp微信小程序端的websocket返回的base64音頻數據自動緩存播放,你可以修改緩衝隊列數,可以播放和暫停
class AudioPlay {
constructor() {
// createInnerAudioContext
this.audioContext = uni.createInnerAudioContext();
// 自動播放
this.audioContext.autoplay = true;
// 緩衝數組
this.queue = [];
// 至少n個片段才開始播放
this.MIN_BUFFER = 4
// 是否正在播放
this.isPlaying = false;
// 是否已傳入最後一段音頻
this.isFinish = false;
}
/**
* 添加播放隊列和播放音頻
* @param base64 音頻數據
* @param isFinish 是否已傳入最後一段音頻
*/
async addQueuePlay(base64, isFinish) {
this.isFinish = isFinish;
this.queue.push(base64)
// 未播放,且隊列數大於指定長度
if (!this.isPlaying && this.queue.length >= this.MIN_BUFFER) {
this.playNext();
} else if (!this.isPlaying && this.isFinish) {
// 沒有播放但音頻數據已完全傳入,兼容時長不足n秒的短音頻
this.playNext();
}
}
/**
* 播放下一個音頻
*/
async playNext() {
// 隊列長度為0, 暫停播放
if (this.queue.length === 0) {
return (this.isPlaying = false);
}
// 獲取隊列第一個音頻
let base64 = this.queue.shift();
// mp3的base64格式數據頭
let mp3Head = 'data:audio/mp3;base64,';
// 微信小程序環境播放mp3必須要完整的base64格式
// 拼接完整base64,移除Base64字符串中可能存在的換行符
this.audioContext.src = mp3Head + base64.replace(/[\r\n]/g, '');
// 播放
this.audioContext.onPlay(() => {
this.isPlaying = true;
});
// 自然播放結束
this.audioContext.onEnded(() => {
// 已傳入最後一個音頻數據,且隊列為0
if (this.isFinish && this.queue.length == 0) {
this.stopConnection();
} else {
this.playNext();
}
});
}
/**
* 停止播放
*/
async stopConnection() {
try {
if (this.audioContext) {
// 停止播放
this.audioContext.stop();
// 取消播放監聽和結束監聽
this.audioContext.offPlay();
this.audioContext.offEnded();
}
// 重置隊列、播放狀態、isFinish狀態
this.queue.length = 0;
this.isPlaying = false;
this.isFinish = false;
} catch (err) {
console.log(`手動斷開失敗: ${err}`);
}
};
}
export default AudioPlay;
頁面使用
<script setup>
import AudioPlay from "@/utils/AudioPlay.js"
const audioPlay = new AudioPlay();
// websocket響應
const onMessage = (e) => {
// 其它邏輯...
audioPlay.addQueuePlay(data.base64, data.isFinish)
};
// 斷開連接
const stopConnection = async () => {
try {
audioPlay.stopConnection();
// 其它邏輯...
} catch (err) {
console.log(`手動斷開失敗: ${err}`);
}
};
</script>
參考資料:
createInnerAudioContext