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 private videoLoadedCallback: (isLoaded: boolean) => void = () => {}; 27 28 constructor() { 29 Log.info(`AVPlayer seek succeede in `); 30 this.playState = AppStorage.SetAndLink('playState', -1); 31 } 32 33 public async init() { 34 this.avPlayer = await media.createAVPlayer(); 35 this.setAVPlayerCallback(); 36 return this.avPlayer; 37 } 38 39 setVideoLoadedCallback(callback: (isLoaded: boolean) => void) { 40 this.videoLoadedCallback = callback; 41 } 42 43 setAVPlayerCallback() { 44 if (!this.avPlayer) { 45 Log.info('no acPlayer'); 46 return; 47 } 48 this.avPlayer.on('seekDone', (seekDOneTime) => { 49 Log.info(`AVPlayer seek succeeded, seek time is ${seekDOneTime}`); 50 }) 51 this.avPlayer.on('error', (err) => { 52 Log.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`); 53 this.avPlayer?.reset(); 54 }) 55 this.avPlayer.on('stateChange', async (state) => { 56 this.state = state; 57 switch (state) { 58 case 'idle': 59 Log.info('AVPlayer state idle called.'); 60 this.callbackMap = new Map(); 61 break; 62 case 'initialized': 63 Log.info('AVPlayer state initialized called.'); 64 if (this.avPlayer && this.surfaceId) { 65 this.avPlayer.surfaceId = this.surfaceId; 66 } 67 try { 68 this.avPlayer?.prepare().then(() => { 69 this.videoLoadedCallback(true); 70 Log.info('AVPlayer prepare succeeded.'); 71 }); 72 } catch(err) { 73 Log.info(`Invoke prepare failed, err : ${JSON.stringify(err)}`) 74 } 75 break; 76 case 'prepared': 77 Log.info('AVPlayer state prepare called.'); 78 if (this.callbackMap.get('prepared')) { 79 this.callbackMap.get('prepared'); 80 Log.info('AVPlayer state prepare start.'); 81 this.callbackMap.set('prepared', ()=>{}); 82 } 83 break; 84 case 'playing': 85 Log.info('AVPlayer state playing called.'); 86 break; 87 case 'paused': 88 Log.info('AVPlayer state paused called.'); 89 break; 90 case 'completed': 91 Log.info('AVPlayer state completed called.'); 92 this.playState.set(-1); 93 break; 94 case 'stopped': 95 Log.info('AVPlayer state stopped called.'); 96 break; 97 case 'released': 98 Log.info('AVPlayer state released called.'); 99 break; 100 default: 101 Log.info('AVPlayer state unknown called.'); 102 break; 103 } 104 }) 105 } 106 107 public on(event: string, callback: Function) { 108 this.callbackMap.set(event, callback) 109 } 110 111 public async loadFromSrcFd(fileDescriptor: media.AVFileDescriptor) { 112 this.videoLoadedCallback(false); 113 Log.info('loadFromSrcFd: ' + JSON.stringify(fileDescriptor)); 114 if (!this.avPlayer) { 115 Log.info('no acPlayer'); 116 return; 117 } 118 if (this.state !== 'idle') { 119 await this.avPlayer.reset(); 120 } 121 this.avPlayer.fdSrc = fileDescriptor; 122 return this.avPlayer; 123 } 124 125 public async loadFromRawFile(fileName: string) { 126 this.videoLoadedCallback(false); 127 Log.info('loadFromRawFile: ' + fileName); 128 if (!this.avPlayer) { 129 Log.info('no avplayer'); 130 return; 131 } 132 if (this.state !== 'idle') { 133 await this.avPlayer.reset(); 134 } 135 const context = getContext(this) as common.UIAbilityContext; 136 const fileDescriptor = await context.resourceManager.getRawFd(fileName); 137 Log.info('fileDescriptor: ' + fileDescriptor); 138 this.avPlayer.fdSrc = fileDescriptor; 139 return this.avPlayer; 140 } 141 142 public async loadFromNetwork(url: string) { 143 this.videoLoadedCallback(false); 144 Log.info('loadFromNetwork: ' + url); 145 if (!this.avPlayer) { 146 Log.info('no avplayer'); 147 return; 148 } 149 if (this.state !== 'idle') { 150 await this.avPlayer.reset(); 151 } 152 this.avPlayer.url = url; 153 return this.avPlayer; 154 } 155}