• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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 audio from '@ohos.multimedia.audio';
17import Logger from '../utils/Logger';
18
19const TAG = 'mAudioCapturer';
20
21// 与使用AudioCapturer开发音频录制功能过程相似,关键区别在于audioCapturerInfo参数和音频数据流向
22export default class AudioCapturerHelper {
23  private audioCapturer: audio.AudioCapturer | null = null;
24
25  private audioStreamInfo: audio.AudioStreamInfo = {
26    samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000, // 采样率
27    channels: audio.AudioChannel.CHANNEL_2, // 通道数
28    sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式
29    encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式
30  };
31  private audioCapturerInfo: audio.AudioCapturerInfo = {
32    // 需使用通话场景相应的参数
33    source: audio.SourceType.SOURCE_TYPE_VOICE_COMMUNICATION, // 音源类型:语音通话
34    capturerFlags: 0 // 音频采集器标志:默认为0即可
35  };
36  private audioCapturerOptions: audio.AudioCapturerOptions = {
37    streamInfo: this.audioStreamInfo,
38    capturerInfo: this.audioCapturerInfo
39  };
40
41  // 初始化,创建实例
42  async init(): Promise<void> {
43    try {
44      this.audioCapturer = await audio.createAudioCapturer(this.audioCapturerOptions);
45      Logger.info(TAG,`create AudioCapturer success`);
46    } catch (err) {
47      Logger.error(TAG,`Invoke createAudioCapturer failed ${JSON.stringify(err)}`);
48    }
49
50  }
51
52  // 开始一次音频采集
53  async start(callback: (buffer: ArrayBuffer, size: number) => void): Promise<void> {
54    if (!this.audioCapturer) {
55      Logger.info(TAG,`start failed AudioCapturer is null`);
56      return;
57    }
58
59    let stateGroup = [audio.AudioState.STATE_PREPARED, audio.AudioState.STATE_PAUSED, audio.AudioState.STATE_STOPPED];
60    if (stateGroup.indexOf(this.audioCapturer.state) === -1) { // 当且仅当状态为prepared、paused和stopped之一时才能启动采集
61      Logger.info(TAG,`start failed`);
62      return;
63    }
64
65    try {
66      await this.audioCapturer.start(); // 启动采集
67      Logger.info(TAG,`start AudioCapturer success`);
68      let bufferSize: number = await this.audioCapturer.getBufferSize(); // rk打印出来2972? 先不用
69      Logger.info(TAG,`read bufferSize ${bufferSize}`);
70      while (true) {
71
72        let buffer: ArrayBuffer = await this.audioCapturer.read(bufferSize, true);
73        if (buffer === undefined) {
74          Logger.error(TAG,`read buffer failed`);
75        } else {
76          if (callback) {
77            callback(buffer, bufferSize);
78          }
79        }
80      }
81    } catch (err) {
82      Logger.error(TAG,`start Capturer failed ${JSON.stringify(err)}`);
83    }
84  }
85
86  // 停止采集
87  async stop(): Promise<void> {
88    Logger.info(TAG,`Capturer stop`);
89    try {
90      // 只有采集器状态为STATE_RUNNING或STATE_PAUSED的时候才可以停止
91      if (this.audioCapturer.state !== audio.AudioState.STATE_RUNNING && this.audioCapturer.state !== audio.AudioState.STATE_PAUSED) {
92        Logger.info(TAG,`Capturer is not running or paused`);
93        return;
94      }
95      await this.audioCapturer.stop(); // 停止采集
96    } catch (err) {
97      Logger.error(TAG,`stop Capturer failed ${JSON.stringify(err)}`);
98    }
99
100  }
101
102  // 销毁实例,释放资源
103  async release(): Promise<void> {
104    Logger.info(TAG,`Capturer release`);
105    try {
106      // 采集器状态不是STATE_RELEASED或STATE_NEW状态,才能release
107      if (this.audioCapturer.state === audio.AudioState.STATE_RELEASED || this.audioCapturer.state === audio.AudioState.STATE_NEW) {
108        Logger.info(TAG,`Capturer already released`);
109        return;
110      }
111      await this.audioCapturer.release(); // 释放资源
112    } catch (err) {
113      Logger.error(TAG,`release Capturer failed ${JSON.stringify(err)}`);
114    }
115  }
116}
117