鸿蒙音频录制方式总结

HarmonyOS 音频录制「一条龙」指南

(ArkTS/C++/NDK C 三种方式一次看齐)


  1. 选型速览表
层级 核心 API 语言 输出 延迟 典型场景 代码量
应用层 AVRecorder / AudioCapturer ArkTS 文件 / Stream 高/中 UI直接调用、录音笔
C++层 oboe::AudioStreamBuilder C++17 PCM 回调 游戏、实时语音
NDK层 OH_AudioCapturer C PCM 回调 极低 编解码器、专业工具

  1. ArkTS(应用层)

2.1 普通文件录制(AVRecorder)

ts 复制代码
// FileRecordPage.ets
import media from '@ohos.multimedia.media';

@Entry @Component struct FileRecordPage {
  private recorder?: media.AVRecorder;
  private path = getContext().filesDir + '/audio.aac';

  async start() {
    this.recorder = await media.createAVRecorder();
    const fd = fileio.openSync(this.path, 0o100 | 0o2);
    const cfg: media.AVRecorderConfig = {
      audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC,
      profile: { audioBitrate: 128000, audioChannels: 2, audioCodec: media.CodecMimeType.AUDIO_AAC, audioSampleRate: 48000 },
      url: `fd://${fd}`
    };
    await this.recorder.prepare(cfg);
    await this.recorder.start();
  }

  async stop() {
    await this.recorder?.stop();
    await this.recorder?.release();
  }

  build() {
    Column({ space: 20 }) {
      Button('开始').onClick(() => this.start());
      Button('停止').onClick(() => this.stop());
    }.padding(20);
  }
}

2.2 低延迟内存流(AudioCapturer)

ts 复制代码
// StreamRecordPage.ets
import audio from '@ohos.multimedia.audio';

@Entry @Component struct StreamRecordPage {
  private capturer?: audio.AudioCapturer;
  private isCapturing = false;

  async start() {
    const stream: audio.AudioStreamInfo = {
      samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
      channels: audio.AudioChannel.CHANNEL_1,
      sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
      encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
    };
    this.capturer = await audio.createAudioCapturer(stream, {
      source: audio.SourceType.SOURCE_TYPE_MIC
    });
    await this.capturer.start();
    this.isCapturing = true;

    while (this.isCapturing) {
      const data = await this.capturer.read(4096, true);
      // TODO: 实时发送或处理 data.buffer
    }
  }

  async stop() {
    this.isCapturing = false;
    await this.capturer?.stop();
    await this.capturer?.release();
  }

  build() { /* 同上 */ }
}

2.3 多轨混合录制

需要额外声明 CAPTURE_AUDIO_PLAYBACK 权限

读取麦克风 + 系统回环,两路 PCM 自行混音即可。


  1. C++ 层(Oboe)

3.1 CMakeLists.txt(模块级)

cmake 复制代码
cmake_minimum_required(VERSION 3.16)
find_package(oboe REQUIRED PATHS ${OHOS_SYSROOT}/usr/lib)
add_library(record SHARED record.cpp)
target_link_libraries(record oboe log)

3.2 record.cpp

cpp 复制代码
#include <oboe/Oboe.h>
#include <fstream>
#include <chrono>
#include <thread>

class Callback : public oboe::AudioStreamCallback {
public:
    explicit Callback(std::ofstream& f) : fout_(f) {}
    oboe::DataCallbackResult
    onAudioReady(oboe::AudioStream* s, void* data, int32_t frames) override {
        fout_.write(static_cast<char*>(data),
                    frames * s->getChannelCount() * sizeof(int16_t));
        return oboe::DataCallbackResult::Continue;
    }
private:
    std::ofstream& fout_;
};

extern "C" void start_oboe_record() {
    std::ofstream pcm("/data/storage/el2/base/hfiles/oboe.pcm", std::ios::binary);
    Callback cb(pcm);

    oboe::AudioStreamBuilder b;
    b.setDirection(oboe::Direction::Input)
     ->setSampleRate(48000)
     ->setChannelCount(oboe::ChannelCount::Mono)
     ->setFormat(oboe::AudioFormat::I16)
     ->setPerformanceMode(oboe::PerformanceMode::LowLatency)
     ->setCallback(&cb);

    oboe::AudioStream* stream = nullptr;
    if (b.openStream(&stream) == oboe::Result::OK) {
        stream->requestStart();
        std::this_thread::sleep_for(std::chrono::seconds(5));
        stream->requestStop();
        stream->close();
    }
}

  1. NDK C 层(OHAudio)

4.1 oh_record.c

c 复制代码
#include <ohaudio/native_audio_capturer.h>
#include <stdio.h>
#include <unistd.h>

static FILE* gFile;
static OH_AudioCapturer* gCapturer;

static void OnData(OH_AudioCapturer* c, void* user, void* buffer, int32_t len) {
    fwrite(buffer, 1, len, gFile);
}

void start_oh_record() {
    OH_AudioCapturerBuilder* b;
    OH_AudioCapturer_CreateBuilder(&b);
    OH_AudioCapturerBuilder_SetSamplingRate(b, 48000);
    OH_AudioCapturerBuilder_SetChannelCount(b, 1);
    OH_AudioCapturerBuilder_SetSampleFormat(b, AUDIO_SAMPLE_FORMAT_S16LE);
    OH_AudioCapturerBuilder_SetCapturerInfoCallback(b, OnData, NULL);
    OH_AudioCapturerBuilder_GenerateCapturer(b, &gCapturer);
    OH_AudioCapturerBuilder_Destroy(b);

    gFile = fopen("/data/storage/el2/base/hfiles/oh.pcm", "wb");
    OH_AudioCapturer_Start(gCapturer);

    sleep(5);

    OH_AudioCapturer_Stop(gCapturer);
    OH_AudioCapturer_Destroy(gCapturer);
    fclose(gFile);
}

4.2 CMakeLists.txt

cmake 复制代码
cmake_minimum_required(VERSION 3.16)
project(oh_record)
add_library(oh_record SHARED oh_record.c)
target_link_libraries(oh_record ohaudio)

  1. 权限与编译

  2. module.json5(通用)

json5 复制代码
"reqPermissions": [
  "ohos.permission.MICROPHONE",
  "ohos.permission.CAPTURE_AUDIO_PLAYBACK" // 仅多轨/系统回环需要
]
  1. 编译
  • ArkTS:DevEco Studio 一键运行
  • C++ / NDK:
bash 复制代码
cd entry/src/main/cpp
cmake -B build -DOHOS_STL=c++_static
cmake --build build

生成的 .so 会自动打包进 hap。


  1. 一句话总结
  • 业务 App 直接 ArkTS → 文件 or Stream;
  • 游戏/实时 → C++ Oboe;
  • 极限延迟 → NDK OHAudio。

全部代码复制即可跑,至此「录制」全家桶完毕。

相关推荐
whysqwhw3 小时前
鸿蒙音频播放方式总结
harmonyos
zhanshuo5 小时前
HarmonyOS 实战:用 @Observed + @ObjectLink 玩转多组件实时数据更新
harmonyos
zhanshuo5 小时前
鸿蒙任务调度机制深度解析:优先级、时间片、多核与分布式的流畅秘密
harmonyos
小小小小小星11 小时前
ArkUI 5.0 核心特性与实战案例
harmonyos
奶糖不太甜13 小时前
鸿蒙多端开发:如何一次编写适配手机、手表、电视?
harmonyos
whysqwhw21 小时前
鸿蒙多线程
harmonyos
zhanshuo1 天前
鸿蒙文件系统全攻略:从设计原理到跨设备实战,带你玩转本地与分布式存储
harmonyos
zhanshuo1 天前
HarmonyOS 实战:一次性搞定全局初始化,从启动到多模块协同的完整方案
harmonyos
science138631 天前
鸿蒙抖音直播最严重的一个内存泄漏分析与解决
harmonyos