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 fileIO from '@ohos.fileio' 18 19import { Action } from '../../redux/actions/Action' 20import { Log } from '../../utils/Log' 21import { EventBus } from '../../worker/eventbus/EventBus' 22import { EventBusManager } from '../../worker/eventbus/EventBusManager' 23import { SettingManager } from '../../setting/SettingManager' 24import { Voice } from '../../setting/settingitem/Voice' 25 26export class PlaySound { 27 private TAG: string = '[PlaySound]:' 28 private appEventBus: EventBus = EventBusManager.getInstance().getEventBus() 29 private settingManager = SettingManager.getInstance() 30 private fdNumber: number = 0 31 private fdPath 32 // @ts-ignore 33 private mAVPlayer: media.AVPlayer 34 private static sInstancePlaySound: PlaySound; 35 36 constructor() { 37 Log.info(`${this.TAG} constructor start, enroll playCapture to ACTION_CAPTURE`) 38 this.appEventBus.on(Action.ACTION_CAPTURE, this.playCapture.bind(this)) 39 // @ts-ignore 40 media.createAVPlayer().then((avPlayer) => { 41 Log.info(`${this.TAG} createAVPlayer then ${avPlayer}`) 42 this.mAVPlayer = avPlayer; 43 this.setAVPlayerCallback(); 44 }) 45 } 46 47 setAVPlayerCallback(): void { 48 Log.info(`${this.TAG} setAudioCallback`) 49 this.mAVPlayer.on('stateChange', async (state, reason) => { 50 switch (state) { 51 case 'idle': 52 Log.info(`${this.TAG} stateChange idle state`) 53 break; 54 case 'initialized': 55 Log.info(`${this.TAG} stateChange initialized state`) 56 this.mAVPlayer.prepare().then(() => {}, (err) => { 57 Log.error(`${this.TAG} case prepare error`) 58 }) 59 break; 60 case 'prepared': 61 Log.info(`${this.TAG} stateChange prepared state`) 62 if (this.settingManager.getCaptureMute() == Voice.SOUND) { 63 this.mAVPlayer.play() 64 } 65 break; 66 case 'playing': 67 Log.info(`${this.TAG} stateChange playing state`) 68 break; 69 case 'completed': 70 Log.info(`${this.TAG} stateChange completed state`) 71 if (this.fdNumber !== 0) { 72 fileIO.closeSync(this.fdNumber) 73 Log.info(`${this.TAG} fileIO closeSync success`) 74 } 75 this.mAVPlayer.stop() 76 break; 77 case 'stopped': 78 Log.info(`${this.TAG} stateChange stopped state`) 79 this.mAVPlayer.reset() 80 break; 81 case 'error': 82 Log.info(`${this.TAG} case error called, err is: ${reason}`) 83 break; 84 default: 85 Log.info(`${this.TAG} unknow state: ${state}`) 86 break; 87 } 88 }) 89 } 90 91 public static getInstance(): PlaySound { 92 if (!PlaySound.sInstancePlaySound) { 93 PlaySound.sInstancePlaySound = new PlaySound(); 94 } 95 return PlaySound.sInstancePlaySound; 96 } 97 private playCapture(data): void { 98 Log.info(`${this.TAG} playCapture invoke E`); 99 if (this.settingManager.getCaptureMute() == Voice.SOUND) { 100 this.playSound(Voice.CAPTURE_URI) 101 } 102 Log.info(`${this.TAG} playCapture invoke X`); 103 } 104 105 private async playSound(soundUri) { 106 Log.info(`${this.TAG} playSound invoke E`) 107 this.fdPath = 'fd://' 108 fileIO.open(Voice.CAPTURE_URI).then((fdData) => { 109 this.fdPath = this.fdPath + '' + fdData 110 this.mAVPlayer.url = this.fdPath 111 this.fdNumber = fdData 112 Log.info(`${this.TAG} fileIO open then ${this.fdPath}`); 113 }).catch((err) => { 114 Log.info(`${this.TAG} open soundUri failed, err: ${err}`) 115 }) 116 Log.info(`${this.TAG} playSound invoke X`) 117 } 118}