自定义音频采集
2024-02-27
功能简介
以下场景中,建议使用自定义音频采集功能:
- 开发者需要从现有音频流、音频文件、或者定制的采集系统中获得采集后输入,交给 SDK 传输。
- 开发者有自己对 PCM 输入源做特殊的音效处理的需求,在音效处理后输入,交给 SDK 传输。
前提条件
在实现自定义音频采集之前,请确保:
- 已在 ZEGO 控制台 创建项目,并申请有效的 AppID 和 AppSign,详情请参考 控制台 - 项目信息。
- 已在项目中集成 ZEGO Express SDK,并实现了基本的音视频推拉流功能,详情请参考 快速开始 - 集成 和 快速开始 - 实现流程。
- 已在 CMakeLists.txt 中正确配置 ZegoExpressEngine 的头文件路径和链接库。
使用步骤
说明
- SDK 在 ets 层提供开启自定义音频采集的接口 enableCustomAudioIO。
- SDK 在 native 层提供发送音频数据的接口
zego_express_send_custom_audio_capture_pcm_data和数据结构,详情查阅 har 包 include 目录下的 zego-experss-custom-audio-io.h 文件。
1 初始化 SDK
请参考 快速开始 - 实现流程 的 "创建引擎"。
2 开启自定义音频采集
可调用 ZegoCustomAudioConfig 设置 sourceType = ZegoAudioSourceType.CUSTOM,再调用 enableCustomAudioIO 接口开启自定义音频 IO 功能。
// 设置音频源为自定义采集
let config: ZegoCustomAudioConfig = new ZegoCustomAudioConfig();
config.sourceType = ZegoAudioSourceType.Custom;
ZegoExpressEngine.enableCustomAudioIO(true, config);3 登录房间后推/拉流
请参考 快速开始 - 实现流程 的 "登录房间"、"推流" 和 "拉流"。
4 在 native 层实现自定义采集音频数据发送功能
1
在 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)2
创建自定义音频处理类
创建一个继承自 SDK 回调接口的类:
#include "zego-express-defines.h"
#include "zego-express-custom-audio-io.h"
#include <hilog/log.h>
class CustomAudioCapture
{
public:
CustomAudioCapture();
public:
void Start();
void Stop();
void SendCustomAudioPcmData();
};3
实现音频采集发送逻辑
开发者可以在各个回调中对音频数据进行处理:
void CustomAudioCapture::Start( )
{
// 调用开始推流后,就通知这里开始发送音频数据
}
void CustomAudioCapture::Stop()
{
// 调用停止推流后,就通知这里停止发送音频数据
}
void CustomAudioCapture::SendCustomAudioPcmData(
const unsigned char *data,
unsigned int dataLength,
struct zego_audio_frame_param param,
enum zego_publish_channel channel)
{
// 调用接口发送数据
zego_express_send_custom_audio_capture_pcm_data(data, data_length, param, channel);
}5 注册原生音频处理插件
通过 NAPI 接口将 C++ 实现暴露给 ArkTS 层调用。
1
实现 NAPI 接口
#include "napi/native_api.h"
#include "CustomIOPlugin.h"
static napi_value InitCustomAudioCapture(napi_env env, napi_callback_info info)
{
ZegoCustomIOPlugin::getInstance().initCustomAudioCapture();
napi_value result;
napi_create_int32(env, 0, &result);
return result;
}
static napi_value StartCustomAudioCapture(napi_env env, napi_callback_info info)
{
ZegoCustomIOPlugin::getInstance().StartCustomAudioCapture();
napi_value result;
napi_create_int32(env, 0, &result);
return result;
}
static napi_value StopCustomAudioCapture(napi_env env, napi_callback_info info)
{
ZegoCustomIOPlugin::getInstance().StopCustomAudioCapture();
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[] = {
{"InitCustomAudioCapture", 0, InitCustomAudioCapture, 0, 0, 0, napi_default, 0},
{"StartCustomAudioCapture", 0, StartCustomAudioCapture, 0, 0, 0, napi_default, 0},
{"StopCustomAudioCapture", 0, StopCustomAudioCapture, 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';
// 在登录房间后初始化自定义音频处理
initCustomIO(): void {
// 配置音频处理参数
let audioCapConfig: ZegoCustomAudioConfig = new ZegoCustomAudioConfig();
audioCapConfig.sourceType = ZegoAudioSourceType.Custom;
// 开启自定义音频采集处理
ZegoExpressEngine.enableCustomAudioIO(true, audioCapConfig);
// 初始化原生音频处理插件
InitCustomAudioCapture();
// 调用开始推流后
StartCustomAudioCapture();
// 调用停止推流后
StopCustomAudioCapture();
}音频参数说明
zego_audio_frame_param 结构体包含了音频帧的关键参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| sample_rate | uint32_t | 采样率,支持 16000、32000、44100、48000 等 |
| channel_count | uint32_t | 声道数,1 表示单声道,2 表示双声道 |
| frame_length | uint32_t | 音频帧的采样点数量(每声道) |
说明
- 音频帧大小计算公式:
frameSize = sampleRate / 1000 * frameDurationMs * channelCount * sizeof(int16_t) - 例如:44100Hz、单声道、20ms 帧长的音频大小为 44100 / 1000 * 20 * 1 * 2 = 1764 字节
常见问题
-
调用自定义音频采集相关接口的时机?
- enableCustomAudioIO:应该在引擎启动后、开始预览和推拉流之前调用。
- InitCustomAudioCapture(NAPI 接口):建议在登录房间后、开始推流前调用。
