logo
当前页

自定义音频处理

2026-02-10

功能简介

自定义音频处理一般用于去除语音中的干扰,由于 SDK 已经对采集的音频原始数据进行了回声消除、噪声抑制等处理,通常情况下,开发者无需再重复处理。

如果开发者想在采集音频数据后或拉取远端音频数据渲染前,通过自定义处理实现特殊功能时(例如变声、美声等),可以参考本文档。

说明

自定义音频处理的数据,是原始音频进行 3A(AEC 回声消除、AGC 自动增益控制、ANS 降噪)处理之后的音频数据:

  • 如果开发者需要对原始数据进行处理,请先调用 enableAECenableAGCenableANS 接口关闭音频 3A 处理。如果开启了变声、混响、立体声等音效处理(默认是关闭的),也需要先关闭后,才能获取到原始音频数据。
  • 如果开发者需要同时获取原始数据和 3A 处理之后的音频数据进行处理,请参考 自定义音频采集

前提条件

在实现自定义音频处理之前,请确保:

使用步骤

说明
  • SDK 在 ets 层提供开启自定义音频处理的接口 enableCustomAudioCaptureProcessing 等。
  • SDK 在 native 层提供多个音频数据的回调接口和数据结构,详情查阅 har 包 include 目录下的 zego-experss-custom-audio-io.h 文件。

1 初始化 SDK

请参考 快速开始 - 实现流程 的 "创建引擎"。

2 开启自定义音频处理

注意

自定义音频处理相关接口需要在开始推拉流之前调用才有效。

SDK 提供了多个音频处理回调点,开发者可以根据需求选择性地启用。以下按音频链路顺序介绍各个处理点。

3 处理采集的音频数据

处理麦克风采集的原始音频数据,适用于添加音效、降噪、变声等场景。

1

配置音频处理参数

// 配置音频处理参数
let audioCapConfig: ZegoCustomAudioProcessConfig = new ZegoCustomAudioProcessConfig();
// 设置采样率(支持 16K、32K、44.1K、48K 等)
audioCapConfig.sampleRate = ZegoAudioSampleRate.SampleRate44K;
// 设置声道数(1 表示单声道,2 表示双声道)
audioCapConfig.channel = ZegoAudioChannel.Mono;
// 设置每帧采样点数(0 表示使用 SDK 默认值)
audioCapConfig.samples = 0;

// 开启自定义音频采集处理
this.engine.enableCustomAudioCaptureProcessing(true, audioCapConfig);
2

在 native 层引入 ZegoExpressEngine.so 库

通过修改 native 层的 CMakeLists.txt 文件引入包含在 ZegoExpressEngine.har 包里的 ZegoExpressEngine.so 库,便于 native 层代码调用相关接口。


# 定义平台宏,native 接口会通过这个宏判断平台
add_definitions(-D_OS_OHOS_)

# 设置依赖的libZegoExpressEngine.so路径
set(DEPENDENCY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules)
add_library(ZegoExpressEngine SHARED IMPORTED)
set_target_properties(ZegoExpressEngine
    PROPERTIES
    IMPORTED_LOCATION ${DEPENDENCY_PATH}/@zego/zego-express-engine/libs/${OHOS_ARCH}/libZegoExpressEngine.so)

# 包含头文件 ${DEPENDENCY_PATH}/ZegoExpressEngine/include
include_directories(${NATIVERENDER_ROOT_PATH}
                    ${NATIVERENDER_ROOT_PATH}/include
                    ${CMAKE_CURRENT_SOURCE_DIR}/CustomVideoCapture
                    ${DEPENDENCY_PATH}/ZegoExpressEngine/include)

set(SRC_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/napi_init.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/CustomIOPlugin.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/CustomVideoCapture/CustomVideoCapture.cpp)

add_library(entry SHARED ${SRC_FILES})

# 指定链接的库 ZegoExpressEngine
target_link_libraries(entry PUBLIC libace_napi.z.so hilog_ndk.z.so ZegoExpressEngine)
3

实现原生音频处理类

#include "zego-express-defines.h"
#include "zego-express-custom-audio-io.h"
#include <hilog/log.h>

class CustomAudioProcess
{
public:
    CustomAudioProcess();

    // 初始化,注册回调
    void init();

public:
    // 处理采集的音频数据回调
    void onProcessCapturedAudioData(
        unsigned char *data,
        unsigned int dataLength,
        struct zego_audio_frame_param *param,
        double timestamp
    );
};
4

注册音频处理回调

void zego_on_process_captured_audio_data_func(
    unsigned char *data,
    unsigned int dataLength,
    struct zego_audio_frame_param *param,
    double timestamp,
    void *user_context)
{
    CustomAudioProcess *self = (CustomAudioProcess*)user_context;
    self->onProcessCapturedAudioData(data, dataLength, param, timestamp);
}

void CustomAudioProcess::init()
{
    // 注册数据回调接口
    zego_register_process_captured_audio_data_callback(
        zego_on_process_captured_audio_data_func, this);
}
5

实现音频处理逻辑

void CustomAudioProcess::onProcessCapturedAudioData(
    unsigned char *data,
    unsigned int dataLength,
    struct zego_audio_frame_param *param,
    double timestamp)
{
    // 在这里对采集的音频数据进行处理
    // 例如:音量调节、降噪、变声等

    // 示例:简单的音量调节
    int16_t *audioData = (int16_t*)data;
    int samples = dataLength / sizeof(int16_t);
    float volume = 1.5f; // 提升 50% 音量

    for (int i = 0; i < samples; i++)
    {
        int32_t sample = (int32_t)(audioData[i] * volume);
        // 限幅,防止溢出
        if (sample > 32767) sample = 32767;
        if (sample < -32768) sample = -32768;
        audioData[i] = (int16_t)sample;
    }
}

4 其他类型的音频数据

1

处理耳机监控后的采集音频数据

处理通过耳机监控后的音频数据,适用于添加耳返音效等场景。

// 开启耳机监控后的音频处理
this.engine.enableCustomAudioCaptureProcessingAfterHeadphoneMonitor(
    true, audioCapConfig);

// 注册数据回调接口
void zego_on_process_captured_audio_data_after_used_headphone_monitor_func(
        unsigned char *data, unsigned int dataLength, struct zego_audio_frame_param *param,
        double timestamp, void *user_context)
{
    CustomAudioProcess *self = (CustomAudioProcess*)user_context;
    self->onProcessCapturedAudioDataAfterUsedHeadphoneMonitor(data, dataLength, param, timestamp);
}

zego_register_process_captured_audio_data_after_used_headphone_monitor_callback(
    zego_on_process_captured_audio_data_after_used_headphone_monitor_func, this);

void CustomAudioProcess::onProcessCapturedAudioDataAfterUsedHeadphoneMonitor(
    unsigned char *data,
    unsigned int dataLength,
    struct zego_audio_frame_param *param,
    double timestamp)
{
    // 处理耳机监控后的音频数据
    // 可以在此处添加耳返音效处理,如混响、均衡器等
}
2

处理指定流的音频数据

处理拉取的远程音频流数据,适用于分析远程音频质量、添加播放特效等场景。

// 配置远程音频处理参数
let audioProcessConfig: ZegoCustomAudioProcessConfig = new ZegoCustomAudioProcessConfig();
audioProcessConfig.sampleRate = ZegoAudioSampleRate.SampleRate48K;
audioProcessConfig.channel = ZegoAudioChannel.Mono;
audioProcessConfig.samples = 0;

// 开启自定义远程音频处理
this.engine.enableCustomAudioRemoteProcessing(true, audioProcessConfig);

// 注册数据回调接口
void zego_on_process_remote_audio_data_func(unsigned char *data, unsigned int dataLength,
                                          struct zego_audio_frame_param *param,
                                          const char *streamID, double timestamp, void *user_context)
{
    CustomAudioProcess *self = (CustomAudioProcess*)user_context;
    self->onProcessRemoteAudioData(data, dataLength, param, streamID, timestamp);
}

zego_register_process_remote_audio_data_callback(zego_on_process_remote_audio_data_func, this);


void CustomAudioProcess::onProcessRemoteAudioData(
    unsigned char *data,
    unsigned int dataLength,
    struct zego_audio_frame_param *param,
    const char *streamID,
    double timestamp)
{

    // 处理远程音频数据
    // 可以在此处对拉取的音频流进行处理
    // 例如:音频质量分析、语音识别、音效增强等
}
3

处理播放音频数据

处理最终播放前的音频数据,适用于添加播放音效(如均衡器、3D 音效等)的场景。

// 开启自定义播放音频处理
this.engine.enableCustomAudioPlaybackProcessing(true, audioProcessConfig);
// 注册数据回调接口
void zego_on_process_playback_audio_data_func(unsigned char *data, unsigned int dataLength,
                                            struct zego_audio_frame_param *param, double timestamp, void *user_context)
{
    CustomAudioProcess *self = (CustomAudioProcess*)user_context;
    self->onProcessPlaybackAudioData(data, dataLength, param, timestamp);
}
zego_register_process_playback_audio_data_callback(zego_on_process_playback_audio_data_func, this);

void CustomAudioProcess::onProcessPlaybackAudioData(
    unsigned char *data,
    unsigned int dataLength,
    struct zego_audio_frame_param *param,
    double timestamp)
{

    // 处理播放音频数据
    // 可以在此处添加播放音效,如均衡器、3D 音效、混响等
}
4

处理音频预处理前的数据

获取音频预处理前的原始数据,适用于音频监测、分析等场景。

// 配置音频帧参数
let audioFrameParam: ZegoAudioFrameParam = new ZegoAudioFrameParam();
audioFrameParam.sampleRate = ZegoAudioSampleRate.SampleRate44K;
audioFrameParam.channel = ZegoAudioChannel.Mono;

// 开启音频预处理前回调
this.engine.enableBeforeAudioPrepAudioData(true, audioFrameParam);
// 注册数据回调接口
void zego_on_before_audio_prep_audio_data_func(const unsigned char *data,
                                            unsigned int dataLength,
                                            struct zego_audio_frame_param param, void *user_context)
{
    CustomAudioProcess *self = (CustomAudioProcess*)user_context;
    self->onBeforeAudioPrepAudioData(data, dataLength, param);
}
zego_register_before_audio_prep_audio_data_callback(zego_on_before_audio_prep_audio_data_func, this);

void CustomAudioProcess::onBeforeAudioPrepAudioData(
    const unsigned char *data,
    unsigned int dataLength,
    struct zego_audio_frame_param param)
{

    // 音频预处理前的回调
    // 可用于获取音频数据进行监测
    // 注意:此回调中的数据为 const,不能修改
}

5 注册原生音频处理插件

通过 NAPI 接口将 C++ 实现暴露给 ArkTS 层调用。

1

实现 NAPI 接口

#include "napi/native_api.h"
#include "CustomIOPlugin.h"

static napi_value InitCustomAudioProcess(napi_env env, napi_callback_info info)
{
    ZegoCustomIOPlugin::getInstance().initCustomAudioProcess();
    napi_value result;
    napi_create_int32(env, 0, &result);
    return result;
}

static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        {"InitCustomAudioProcess", 0, InitCustomAudioProcess, 0, 0, 0, napi_default, 0}
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
2

在 ArkTS 中导入并初始化

import {InitCustomAudioProcess} from 'libentry.so';

// 在登录房间后初始化自定义音频处理
function initCustomIO(): void {
    // 配置音频处理参数
    let audioCapConfig: ZegoCustomAudioProcessConfig = new ZegoCustomAudioProcessConfig();
    audioCapConfig.sampleRate = ZegoAudioSampleRate.SampleRate44K;
    audioCapConfig.channel = ZegoAudioChannel.Mono;
    audioCapConfig.samples = 0;

    // 开启自定义音频采集处理
    this.engine.enableCustomAudioCaptureProcessing(true, audioCapConfig);

    // 初始化原生音频处理插件
    InitCustomAudioProcess();
}

6 登录房间后推/拉流

请参考 快速开始 - 实现流程 的 "登录房间"、"推流" 和 "拉流"。

// 登录房间
function loginRoom(): void {
    if (this.engine != null) {
        let userInfo: ZegoUser = new ZegoUser();
        userInfo.userID = this.userID;
        userInfo.userName = this.userID;
        this.engine.loginRoom(this.roomID, userInfo);

        // 初始化自定义音频处理
        this.initCustomIO();
    }
}

音频处理链路说明

SDK 的音频处理链路如下所示:

采集 → 采集处理 → 耳机监控 → 耳机监控后处理 → 音频预处理 → 远程处理 → 播放处理 → 播放
         ↑                                                              ↑
   onProcessCapturedAudioData                                  onProcessPlaybackAudioData
                                                                 (最终混音后的数据)

                                                      (远程流)
                                                      拉取到本地处理 → 播放处理
                                                         ↑
                                            onProcessRemoteAudioData
处理点回调函数用途数据是否可修改
采集处理onProcessCapturedAudioData处理麦克风采集的原始音频
耳机监控后处理onProcessCapturedAudioDataAfterUsedHeadphoneMonitor处理耳返音频
音频预处理前onBeforeAudioPrepAudioData获取预处理前的数据否(只读)
远程处理onProcessRemoteAudioData处理拉取的远程音频流
播放处理onProcessPlaybackAudioData处理最终播放前的混音数据
提示
  • 各个处理点是独立的,可以同时启用多个处理点。
  • 不同的处理点可能会收到不同采样率或格式的音频数据。
  • 播放处理回调中的数据是所有音频流(采集 + 远程)混音后的结果。
  • 音频预处理前回调是只读的,不能修改数据,仅用于监测。

音频参数说明

zego_audio_frame_param 结构体包含了音频帧的关键参数:

参数类型说明
sample_rateuint32_t采样率,支持 16000、32000、44100、48000 等
channel_countuint32_t声道数,1 表示单声道,2 表示双声道
frame_lengthuint32_t音频帧的采样点数量(每声道)
说明
  • 音频数据格式为 PCM,具体参数由配置的 ZegoCustomAudioProcessConfig 决定。
  • 采样率和声道数需要与配置保持一致,否则可能导致音频失真或播放异常。
  • 音频帧大小计算公式:frameSize = sampleRate / 1000 * frameDurationMs * channelCount * sizeof(int16_t)
  • 例如:44100Hz、单声道、20ms 帧长的音频大小为 44100 / 1000 * 20 * 1 * 2 = 1764 字节
2026-02-10

上一篇

自定义音频采集

下一篇

混流

当前页

返回到顶部