140 lines
3.6 KiB
TypeScript
140 lines
3.6 KiB
TypeScript
|
|
import media from '@ohos.multimedia.media';
|
|||
|
|
|
|||
|
|
const TAG = 'VoiceAnnounce'
|
|||
|
|
|
|||
|
|
export default class VoiceAnnounce{
|
|||
|
|
|
|||
|
|
//队列时候立马终止
|
|||
|
|
private isStopped:Boolean
|
|||
|
|
private queue:String[]
|
|||
|
|
private newQueue:String[]
|
|||
|
|
private pendingQueue:String[]
|
|||
|
|
|
|||
|
|
constructor() {
|
|||
|
|
this.isStopped = false;
|
|||
|
|
this.queue = []
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async playAudio(urls:string[],shit){
|
|||
|
|
const {isStopped,queue} = this;
|
|||
|
|
|
|||
|
|
if(shit){
|
|||
|
|
//队列清空,重新初始化
|
|||
|
|
this.isStopped = true;
|
|||
|
|
this.newQueue = urls
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(queue.length){
|
|||
|
|
//队列续上
|
|||
|
|
this.queue = this.queue.concat(urls);
|
|||
|
|
}else{
|
|||
|
|
console.info(TAG,this.isStopped);
|
|||
|
|
this.queue = urls
|
|||
|
|
await this.executeQueue()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async executeQueue(){
|
|||
|
|
const avPlayer = new AVPlayer();
|
|||
|
|
const go = async () => {
|
|||
|
|
const {queue} = this;
|
|||
|
|
console.info(TAG,JSON.stringify(queue))
|
|||
|
|
for (const url of queue) {
|
|||
|
|
const {isStopped,queue,newQueue} = this
|
|||
|
|
|
|||
|
|
if(isStopped){
|
|||
|
|
//清空原来队列
|
|||
|
|
this.queue = newQueue
|
|||
|
|
this.isStopped = false;
|
|||
|
|
await go()
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const result = await avPlayer.play(url);
|
|||
|
|
this.queue.shift()
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if(this.queue.length){
|
|||
|
|
await go()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
await go()
|
|||
|
|
avPlayer.avPlayerStop();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
class AVPlayer {
|
|||
|
|
|
|||
|
|
public avPlayer:any = null;
|
|||
|
|
|
|||
|
|
private voiceUrl: string[];
|
|||
|
|
private voiceStatus: 'completed' | 'playing'
|
|||
|
|
|
|||
|
|
constructor() {}
|
|||
|
|
|
|||
|
|
// 以下为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例
|
|||
|
|
async play(name) {
|
|||
|
|
const avPlayer = await media.createAVPlayer();
|
|||
|
|
this.avPlayer = avPlayer;
|
|||
|
|
return new Promise(async (resolve)=>{
|
|||
|
|
await this.setAVPlayerCallback(()=>{
|
|||
|
|
//@ts-ignore
|
|||
|
|
resolve()
|
|||
|
|
});
|
|||
|
|
const url = await globalThis.context.resourceManager.getRawFd(name,)
|
|||
|
|
this.avPlayer.fdSrc = url;
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
//音频播放队列
|
|||
|
|
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.reset(); // 调用reset重置资源,触发idle状态
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
let num = 0;
|
|||
|
|
// 状态机变化回调函数
|
|||
|
|
this.avPlayer.on('stateChange', async (state, reason) => {
|
|||
|
|
const {voiceUrl}= 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(); //调用播放结束接口
|
|||
|
|
break;
|
|||
|
|
case 'stopped': // stop接口成功调用后触发该状态机上报
|
|||
|
|
console.info(TAG,'播放释放')
|
|||
|
|
this.avPlayer.reset(); // 调用reset接口初始化avplayer状态
|
|||
|
|
callBack()
|
|||
|
|
break;
|
|||
|
|
case 'released':
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|