HarmonyOS 音频录制「一条龙」指南
(ArkTS/C++/NDK C 三种方式一次看齐)
- 选型速览表
层级 | 核心 API | 语言 | 输出 | 延迟 | 典型场景 | 代码量 |
---|---|---|---|---|---|---|
应用层 | AVRecorder / AudioCapturer | ArkTS | 文件 / Stream | 高/中 | UI直接调用、录音笔 | 少 |
C++层 | oboe::AudioStreamBuilder | C++17 | PCM 回调 | 低 | 游戏、实时语音 | 中 |
NDK层 | OH_AudioCapturer | C | PCM 回调 | 极低 | 编解码器、专业工具 | 中 |
- 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 自行混音即可。
- 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();
}
}
- 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)
-
权限与编译
-
module.json5
(通用)
json5
"reqPermissions": [
"ohos.permission.MICROPHONE",
"ohos.permission.CAPTURE_AUDIO_PLAYBACK" // 仅多轨/系统回环需要
]
- 编译
- ArkTS:DevEco Studio 一键运行
- C++ / NDK:
bash
cd entry/src/main/cpp
cmake -B build -DOHOS_STL=c++_static
cmake --build build
生成的 .so
会自动打包进 hap。
- 一句话总结
- 业务 App 直接 ArkTS → 文件 or Stream;
- 游戏/实时 → C++ Oboe;
- 极限延迟 → NDK OHAudio。
全部代码复制即可跑,至此「录制」全家桶完毕。