2024-07-10 14:09:42 +08:00
|
|
|
import media from '@ohos.multimedia.media';
|
|
|
|
|
import Prompt from '@system.prompt';
|
2024-07-11 16:16:43 +08:00
|
|
|
import url from '@ohos.url';
|
2024-07-10 14:09:42 +08:00
|
|
|
|
|
|
|
|
const TAG = 'VoiceAnnounce'
|
|
|
|
|
|
|
|
|
|
export default class VoiceAnnounce{
|
|
|
|
|
|
|
|
|
|
//队列时候立马终止
|
|
|
|
|
private isStopped:Boolean
|
2024-07-11 16:16:43 +08:00
|
|
|
private queue:{
|
|
|
|
|
url:string,
|
|
|
|
|
callback?:Function
|
|
|
|
|
}[]
|
|
|
|
|
private newQueue:{
|
|
|
|
|
url:string,
|
|
|
|
|
callback?:Function
|
|
|
|
|
}[]
|
2024-07-10 14:09:42 +08:00
|
|
|
private pendingQueue:String[]
|
|
|
|
|
private callback:Function;
|
|
|
|
|
constructor() {
|
|
|
|
|
this.isStopped = false;
|
|
|
|
|
this.queue = []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async playAudio(urls:string[],shit?:boolean,callback?:Function){
|
|
|
|
|
const {isStopped,queue} = this;
|
2024-07-11 16:16:43 +08:00
|
|
|
const tempUrls = urls.map((url,index)=>{
|
|
|
|
|
return {
|
|
|
|
|
url,
|
|
|
|
|
callback:(index === urls.length - 1)?callback:undefined
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2024-07-10 14:09:42 +08:00
|
|
|
if(shit){
|
|
|
|
|
//队列清空,重新初始化
|
|
|
|
|
this.isStopped = true;
|
2024-07-11 16:16:43 +08:00
|
|
|
this.newQueue = tempUrls
|
2024-07-10 14:09:42 +08:00
|
|
|
}
|
|
|
|
|
if(queue.length){
|
|
|
|
|
//队列续上
|
2024-07-11 16:16:43 +08:00
|
|
|
this.queue = this.queue.concat(tempUrls)
|
2024-07-10 14:09:42 +08:00
|
|
|
|
|
|
|
|
}else{
|
2024-07-11 16:16:43 +08:00
|
|
|
this.queue = tempUrls
|
2024-07-10 14:09:42 +08:00
|
|
|
await this.executeQueue()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async executeQueue(){
|
|
|
|
|
const avPlayer = new AVPlayer();
|
|
|
|
|
const go = async () => {
|
2024-07-11 16:16:43 +08:00
|
|
|
const {queue,isStopped,newQueue} = this;
|
2024-07-10 14:09:42 +08:00
|
|
|
if(isStopped){
|
|
|
|
|
//清空原来队列
|
|
|
|
|
this.queue = newQueue
|
|
|
|
|
this.isStopped = false;
|
|
|
|
|
await go()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-11 16:16:43 +08:00
|
|
|
await avPlayer.play(queue[0].url,queue[0].callback);
|
2024-07-10 14:09:42 +08:00
|
|
|
this.queue.shift();
|
|
|
|
|
console.info(TAG,JSON.stringify(this.queue),'堆栈弹出');
|
|
|
|
|
if(this.queue.length){
|
|
|
|
|
await go()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await go()
|
|
|
|
|
avPlayer.avPlayerStop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AVPlayer {
|
|
|
|
|
|
|
|
|
|
public avPlayer:any = null;
|
|
|
|
|
|
|
|
|
|
private voiceUrl: string[];
|
|
|
|
|
private voiceStatus: 'completed' | 'playing'
|
|
|
|
|
private endCallback:Function
|
|
|
|
|
constructor() {}
|
|
|
|
|
|
|
|
|
|
// 以下为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例
|
|
|
|
|
async play(name,callback) {
|
|
|
|
|
this.endCallback = callback
|
|
|
|
|
const avPlayer = await media.createAVPlayer();
|
|
|
|
|
this.avPlayer = avPlayer;
|
2024-07-11 16:16:43 +08:00
|
|
|
console.info('surenjun',callback)
|
2024-07-10 14:09:42 +08:00
|
|
|
return new Promise(async (resolve,reject) => {
|
|
|
|
|
let url = ''
|
|
|
|
|
await this.setAVPlayerCallback(()=>{
|
|
|
|
|
//@ts-ignore
|
|
|
|
|
resolve()
|
|
|
|
|
});
|
|
|
|
|
try {
|
|
|
|
|
url = await globalThis.context.resourceManager.getRawFd(name);
|
|
|
|
|
this.avPlayer.fdSrc = url;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
Prompt.showToast({
|
|
|
|
|
message: `${name}语音文件不存在`,
|
|
|
|
|
duration: 4000
|
|
|
|
|
});
|
|
|
|
|
resolve(1)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
//音频播放队列
|
|
|
|
|
public releasePlayer() {
|
|
|
|
|
this.avPlayer.release();
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-11 16:16:43 +08:00
|
|
|
avPlayerStop = ()=> {
|
2024-07-10 14:09:42 +08:00
|
|
|
this.avPlayer && this.avPlayer.stop()
|
|
|
|
|
this.avPlayer && this.avPlayer.reset()
|
|
|
|
|
this.avPlayer && this.avPlayer.release()
|
|
|
|
|
}
|
|
|
|
|
// 注册avplayer回调函数
|
|
|
|
|
setAVPlayerCallback(callBack) {
|
|
|
|
|
|
|
|
|
|
this.avPlayer.on('error', (err) => {
|
|
|
|
|
this.avPlayer && this.avPlayer.stop()
|
|
|
|
|
this.avPlayer && this.avPlayer.reset()
|
|
|
|
|
this.avPlayer && this.avPlayer.release()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
let num = 0;
|
|
|
|
|
// 状态机变化回调函数
|
|
|
|
|
this.avPlayer.on('stateChange', async (state, reason) => {
|
|
|
|
|
const {endCallback} = this;
|
|
|
|
|
switch (state) {
|
|
|
|
|
case 'idle': // 成功调用reset接口后触发该状态机上报
|
|
|
|
|
break;
|
|
|
|
|
case 'initialized': // avplayer 设置播放源后触发该状态上报
|
|
|
|
|
this.avPlayer.prepare()
|
|
|
|
|
break;
|
|
|
|
|
case 'prepared': // prepare调用成功后上报该状态机
|
|
|
|
|
this.avPlayer.play();
|
|
|
|
|
this.voiceStatus = 'playing'
|
|
|
|
|
break;
|
|
|
|
|
case 'playing': // play成功调用后触发该状态机上报
|
|
|
|
|
break;
|
|
|
|
|
case 'paused': // pause成功调用后触发该状态机上报
|
|
|
|
|
break;
|
|
|
|
|
case 'completed': // 播放结束后触发该状态机上报
|
|
|
|
|
this.voiceStatus = 'completed'
|
|
|
|
|
this.avPlayer.stop(); //调用播放结束接口
|
|
|
|
|
if(endCallback){
|
|
|
|
|
endCallback()
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'stopped': // stop接口成功调用后触发该状态机上报
|
|
|
|
|
this.avPlayer.reset(); // 调用reset接口初始化avplayer状态
|
|
|
|
|
callBack()
|
|
|
|
|
break;
|
|
|
|
|
case 'released':
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|