subject-two/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts

222 lines
6.3 KiB
TypeScript

import media from '@ohos.multimedia.media';
import Prompt from '@system.prompt';
import url from '@ohos.url';
import fileuri from "@ohos.file.fileuri";
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
const TAG = 'VoiceAnnounce'
export default class VoiceAnnounce{
//队列时候立马终止
private isStopped:Boolean
private queue:{
url:string,
callback?:Function
}[]
private newQueue:{
url:string,
callback?:Function
}[]
private pendingQueue:String[]
private callback:Function;
constructor() {
this.isStopped = false;
this.queue = []
}
async playAudio(urls:string[],shit?:boolean,callback?:Function){
const {isStopped,queue} = this;
const tempUrls = urls.map((url,index)=>{
return {
url,
callback:(index === urls.length - 1)?callback:undefined
}
});
if(shit){
//队列清空,重新初始化
this.isStopped = true;
this.newQueue = tempUrls
}
if(queue.length){
//队列续上
this.queue = this.queue.concat(tempUrls)
// console.info(TAG,'语音队列开始'+shit + JSON.stringify( this.queue))
}else{
this.queue = tempUrls
// console.info(TAG,'语音队列开始' + shit+JSON.stringify( this.queue))
await this.executeQueue()
}
}
async executeQueue(){
const go = async () => {
const {queue,isStopped,newQueue} = this;
const avPlayer = new AVPlayer();
if(isStopped){
//清空原来队列
this.queue = newQueue
this.isStopped = false;
await go()
return
}
console.info(TAG,'当前播放队列' + JSON.stringify( queue))
await avPlayer.play(queue[0].url,queue[0].callback);
this.queue.shift();
console.info(TAG,'当前播放队列播放完成退出');
avPlayer.avPlayerStop();
if(this.queue.length){
await go()
}
}
await go()
}
}
class AVPlayer {
public avPlayer:any = null;
private voiceUrl: string[];
private voiceStatus: 'completed' | 'playing'
private endCallback:Function
constructor() {}
// 以下为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例
async play(name,callback) {
try {
//检查SD中的语音
// console.info('surenjun name',name)
// console.info('surenjun name',name.split('/')[1])
let playSrc = await this.queryFile(name.split('/')[1]);
let fdPath = await playSrc.open('r')
let audioPlayer = media.createAudioPlayer()
// console.info('surenjun fdPath=>',fdPath)
console.info(TAG,'audioPlayer => 准备加载资源播放')
audioPlayer.on('dataLoad', () => {
this.voiceStatus = 'playing'
console.info(TAG,'audioPlayer => 播放资源开始')
audioPlayer.play()
})
return new Promise(async (resolve)=>{
audioPlayer.on('finish', () => {
console.info(TAG,'audioPlayer => 播放资源播放')
//@ts-ignore
this.voiceStatus = 'completed'
if(callback){
callback()
}
audioPlayer.stop();
audioPlayer.reset()
audioPlayer.release()
resolve(true)
})
audioPlayer.reset()
audioPlayer.src = `fd://${fdPath}`
})
}catch (e){
//检查SD中的语音
this.endCallback = callback
this.avPlayer = await media.createAVPlayer();
return new Promise(async (resolve,reject) => {
await this.setAVPlayerCallback(()=>{
//@ts-ignore
resolve()
});
try {
this.avPlayer.fdSrc = await globalThis.context.resourceManager.getRawFd(name);
} catch (e) {
Prompt.showToast({
message: `${name}语音文件不存在`,
duration: 4000
});
resolve(1)
}
})
}
}
async queryFile(displayName): Promise<mediaLibrary.FileAsset> {
return new Promise(async (resolve,reject)=>{
const mediaLib = mediaLibrary.getMediaLibrary(globalThis.context);
let ret
let fetchOp = {
selections: `media_type=? AND display_name = ?`,
selectionArgs: [`${mediaLibrary.MediaType.AUDIO}`,displayName],
};
let fileResult = await mediaLib.getFileAssets(fetchOp);
let retCount = fileResult.getCount();
if (retCount > 0) {
ret = fileResult.getFirstObject();
return resolve(ret);
}else{
return reject(false);
}
})
}
//音频播放队列
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调用成功后上报该状态机
console.info(TAG,'播放资源播放')
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接口成功调用后触发该状态机上报
this.avPlayer.reset(); // 调用reset接口初始化avplayer状态
console.info(TAG,'播放资源释放')
if(endCallback){
endCallback()
}
callBack()
break;
case 'released':
break;
default:
break;
}
})
}
}