150 lines
3.9 KiB
TypeScript
150 lines
3.9 KiB
TypeScript
|
|
import media from '@ohos.multimedia.media';
|
||
|
|
import Prompt from '@system.prompt';
|
||
|
|
|
||
|
|
const TAG = 'VoiceAnnounce'
|
||
|
|
|
||
|
|
export default class VoiceAnnounce{
|
||
|
|
|
||
|
|
//队列时候立马终止
|
||
|
|
private isStopped:Boolean
|
||
|
|
private queue:String[]
|
||
|
|
private newQueue:String[]
|
||
|
|
private pendingQueue:String[]
|
||
|
|
private callback:Function;
|
||
|
|
constructor() {
|
||
|
|
this.isStopped = false;
|
||
|
|
this.queue = []
|
||
|
|
}
|
||
|
|
|
||
|
|
async playAudio(urls:string[],shit?:boolean,callback?:Function){
|
||
|
|
const {isStopped,queue} = this;
|
||
|
|
this.callback = callback
|
||
|
|
if(shit){
|
||
|
|
//队列清空,重新初始化
|
||
|
|
this.isStopped = true;
|
||
|
|
this.newQueue = urls
|
||
|
|
}
|
||
|
|
if(queue.length){
|
||
|
|
//队列续上
|
||
|
|
this.queue = this.queue.concat(urls);
|
||
|
|
|
||
|
|
}else{
|
||
|
|
this.queue = urls
|
||
|
|
await this.executeQueue()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async executeQueue(){
|
||
|
|
const avPlayer = new AVPlayer();
|
||
|
|
const go = async () => {
|
||
|
|
const {queue,callback,isStopped,newQueue} = this;
|
||
|
|
if(isStopped){
|
||
|
|
//清空原来队列
|
||
|
|
this.queue = newQueue
|
||
|
|
this.isStopped = false;
|
||
|
|
await go()
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
await avPlayer.play(queue[0],callback);
|
||
|
|
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;
|
||
|
|
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();
|
||
|
|
}
|
||
|
|
|
||
|
|
avPlayerStop() {
|
||
|
|
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;
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|