1/* 2* Copyright (C) 2023 Huawei Device Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15 16import media from '@ohos.multimedia.media'; 17import common from '@ohos.app.ability.common'; 18import Log from './Log'; 19 20export default class AudioUtils { 21 public avPlayer: media.AVPlayer | null = null; 22 public state: string = ''; 23 public surfaceId: string = ''; 24 private callbackMap: Map<string, Function> = new Map(); 25 private playState: SubscribedAbstractProperty<number>; 26 27 constructor() { 28 Log.info(`AVPlayer seek succeede in `); 29 this.playState = AppStorage.SetAndLink('playState', -1); 30 } 31 32 public async init() { 33 this.avPlayer = await media.createAVPlayer(); 34 this.setAVPlayerCallback(); 35 return this.avPlayer; 36 } 37 38 setAVPlayerCallback() { 39 if (!this.avPlayer) { 40 Log.info('no acPlayer'); 41 return; 42 } 43 this.avPlayer.on('seekDone', (seekDOneTime) => { 44 Log.info(`AVPlayer seek succeeded, seek time is ${seekDOneTime}`); 45 }) 46 this.avPlayer.on('error', (err) => { 47 Log.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`); 48 this.avPlayer?.reset(); 49 }) 50 this.avPlayer.on('stateChange', async (state) => { 51 this.state = state; 52 switch (state) { 53 case 'idle': 54 Log.info('AVPlayer state idle called.'); 55 this.callbackMap = new Map(); 56 break; 57 case 'initialized': 58 Log.info('AVPlayer state initialized called.'); 59 if (this.avPlayer && this.surfaceId) { 60 this.avPlayer.surfaceId = this.surfaceId; 61 } 62 try { 63 this.avPlayer?.prepare().then(() => { 64 Log.info('AVPlayer prepare succeeded.'); 65 }); 66 } catch(err) { 67 Log.info(`Invoke prepare failed, err : ${JSON.stringify(err)}`) 68 } 69 break; 70 case 'prepared': 71 Log.info('AVPlayer state prepare called.'); 72 if (this.callbackMap.get('prepared')) { 73 this.callbackMap.get('prepared'); 74 Log.info('AVPlayer state prepare start.'); 75 this.callbackMap.set('prepared', ()=>{}); 76 } 77 break; 78 case 'playing': 79 Log.info('AVPlayer state playing called.'); 80 break; 81 case 'paused': 82 Log.info('AVPlayer state paused called.'); 83 break; 84 case 'completed': 85 Log.info('AVPlayer state completed called.'); 86 this.playState.set(-1); 87 break; 88 case 'stopped': 89 Log.info('AVPlayer state stopped called.'); 90 break; 91 case 'released': 92 Log.info('AVPlayer state released called.'); 93 break; 94 default: 95 Log.info('AVPlayer state unknown called.'); 96 break; 97 } 98 }) 99 } 100 101 public on(event: string, callback: Function) { 102 this.callbackMap.set(event, callback) 103 } 104 105 public async loadFromSrcFd(fileDescriptor: media.AVFileDescriptor) { 106 Log.info('loadFromSrcFd: ' + JSON.stringify(fileDescriptor)); 107 if (!this.avPlayer) { 108 Log.info('no acPlayer'); 109 return; 110 } 111 if (this.state !== 'idle') { 112 await this.avPlayer.reset(); 113 } 114 this.avPlayer.fdSrc = fileDescriptor; 115 return this.avPlayer; 116 } 117 118 public async loadFromRawFile(fileName: string) { 119 Log.info('loadFromRawFile: ' + fileName); 120 if (!this.avPlayer) { 121 Log.info('no avplayer'); 122 return; 123 } 124 if (this.state !== 'idle') { 125 await this.avPlayer.reset(); 126 } 127 const context = getContext(this) as common.UIAbilityContext; 128 const fileDescriptor = await context.resourceManager.getRawFd(fileName); 129 Log.info('fileDescriptor: ' + fileDescriptor); 130 this.avPlayer.fdSrc = fileDescriptor; 131 return this.avPlayer; 132 } 133 134 public async loadFromNetwork(url: string) { 135 Log.info('loadFromNetwork: ' + url); 136 if (!this.avPlayer) { 137 Log.info('no avplayer'); 138 return; 139 } 140 if (this.state !== 'idle') { 141 await this.avPlayer.reset(); 142 } 143 this.avPlayer.url = url; 144 return this.avPlayer; 145 } 146}