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 */ 15import audio from '@ohos.multimedia.audio' 16import Logger from '../model/Logger' 17// @ts-ignore 18import fs from '@ohos.file.fs'; 19 20 21class AudioRenderer { 22 private tag: string = 'qlw AudioRenderer' 23 private static instance: AudioRenderer = new AudioRenderer() 24 private audioRenderer: audio.AudioRenderer = undefined 25 private fd: number = undefined 26 private offset: number = undefined 27 private length: number = undefined 28 29 async createAudioRenderer() { 30 let audioStreamInfo = { 31 samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100, 32 channels: audio.AudioChannel.CHANNEL_2, 33 // channels: audio.AudioChannel.CHANNEL_1, 34 sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, 35 encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW 36 } 37 let audioRendererInfo = { 38 content: audio.ContentType.CONTENT_TYPE_MUSIC, 39 usage: audio.StreamUsage.STREAM_USAGE_MEDIA, 40 rendererFlags: 0 41 } 42 let audioRendererOptions = { 43 streamInfo: audioStreamInfo, 44 rendererInfo: audioRendererInfo 45 } 46 this.audioRenderer = await audio.createAudioRenderer(audioRendererOptions); 47 } 48 49 async startRenderer() { 50 try { 51 await this.audioRenderer.start() 52 globalThis.abilityContext.resourceManager.getRawFd("test_44100_2.wav").then(async (value) => { 53 this.fd = value.fd 54 this.offset = value.offset 55 this.length = value.length 56 Logger.info(this.tag, `getRawFd fd : ${this.fd}, offset: ${value.offset}, length: ${value.length}`) 57 let bufferSize = await this.audioRenderer.getBufferSize() 58 Logger.info(this.tag, `audioRenderer bufferSize:` + JSON.stringify(bufferSize)) 59 let len = this.length % bufferSize == 0 ? Math.floor(this.length / bufferSize) : Math.floor(this.length / bufferSize + 1); 60 let buf = new ArrayBuffer(bufferSize); 61 while (true) { 62 for (let i = 0; i < len; i++) { 63 let options = { 64 offset: i * bufferSize + this.offset, 65 length: bufferSize 66 } 67 await fs.read(this.fd, buf, options) 68 try { 69 await this.audioRenderer.write(buf) 70 } catch (err) { 71 console.error(`audioRenderer.write err: ${err}`) 72 } 73 } 74 } 75 }).catch(err => { 76 console.log(`getRawFd fail err: ${err}, message: ${err.message}, code: ${err.code}`); 77 }) 78 } catch (err) { 79 Logger.info(this.tag, `startRenderer fail err: ${err}, message: ${err.message}, code: ${err.code}`) 80 } 81 } 82 83 async stopRenderer() { 84 try { 85 await this.audioRenderer.stop() 86 } catch (err) { 87 Logger.info(this.tag, `stopCapturer fail err: ${err}, message: ${err.message}, code: ${err.code}`) 88 } 89 } 90 91 async releaseRenderer() { 92 try { 93 if (this.audioRenderer) { 94 await this.audioRenderer.release() 95 await globalThis.abilityContext.resourceManager.closeRawFd('test_44100_2.wav').then(() => { 96 Logger.info(this.tag, `closeRawFileDescriptor success`) 97 }).catch(err => { 98 Logger.info(this.tag, `closeRawFileDescriptor fail err: ${err}, message: ${err.message}, code: ${err.code}`) 99 }); 100 } 101 } catch (err) { 102 Logger.info(this.tag, `stopCapturer fail err: ${err}, message: ${err.message}, code: ${err.code}`) 103 } 104 } 105} 106 107export default new AudioRenderer()