自定义音频采集与渲染
NERTC SDK 支持自定义音频采集与渲染功能,可以向 NERTC SDK 提供自定义的音频输入源数据,使用自定义的渲染器,并由 NERTC SDK 进行编码推流。
一般情况下,App 采用默认设备采集音频数据,通常是本设备的内置麦克风。但在部分场景下可能需要使用自定义的音频源,例如:
- 需要使用自定义的音效或美声库、前处理库等场景。
- 需要使用外部音频源、或使用外接设备进行音频数据采集,例如在音视频通话或互动直播中播放音频文件等场景。
- App 无法获取音频采集设备的控制权限,例如音频采集设备已被其他业务占用、硬件设备的默认音频采集模块损坏等场景。
基于以上场景,NERTC SDK 支持使用自定义的音频源或渲染器,以实现业务场景中的相关需求。本文档将介绍如何实现自定义音频采集功能。
Android
您可以通过 NERTC SDK 的 setExternalAudioSource 接口开启自定义音频采集功能。然后使用 pushExternalAudioFrame 接口将外部音频数据帧推送给 NERTC SDK,音频数据格式通过 pushExternalAudioFrame 函数参数 NERtcAudioExternalFrame 来指定。
注意事项
setExternalAudioSource 接口必须在加入房间前设置,并且在通话结束后设置依然有效。如果需要关闭该功能,需要在下次通话前调用接口关闭外部音频数据输入功能。
通过 pushExternalAudioFrame 向 SDK 投送的数据必须是 PCM 格式的未经压缩的音频裸数据,不支持其他压缩格式。
您需要自行管理音频数据采集和渲染的处理逻辑。
实现方法
自定义音频采集
- 在 joinChannel 之前,调用 setExternalAudioSource 开启自定义音频采集功能,并设置外部音频采集参数。
- 本地用户成功加入房间之后,使用自采集模块采集音频数据。您需要自行管理音频数据采集和处理逻辑。
- 完成音频数据处理后,调用 pushExternalAudioFrame 将外部音频数据帧推送给 NERTC SDK。
自定义音频渲染
- 加入房间前,通过调用 setExternalAudioRender 开启并设置外部音频渲染。
成功加入房间后,调用 pullExternalAudioFrame 拉取远端发送的音频。
注意:pullExternalAudioFrame 中的参数 buffer 数组必须使用 ByteBuffer.allocateDirect 创建。建议拉取的音频数据时长至少为 10 毫秒。
计算公式为: len = sampleRate/1000 × 2 × channels × 音频数据时长(毫秒)
您需要自行渲染并播放拉取到的音频数据。
示例代码
//自定义音频采集
NERtcAudioExternalFrame audioFrame = new
NERtcAudioExternalFrame();
audioFrame.audioData = sampleData;
audioFrame.numberOfChannels = 1;
audioFrame.sampleRate = 48000;
audioFrame.samplesPerChannel = 48000 * 20 / 1000;
NERtcEx.getInstance().pushExternalAudioFrame(audioFrame);
//自定义音频渲染
NERtcEx.getInstance().setExternalAudioRender(true,sampleRate,channels);
int len = sampleRate/1000 × 2 × channels × 10;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(len);
NERtcEx.getInstance().pullExternalAudioFrame(byteBuffer,len);
byteBuffer.rewind();
iOS
您可以通过 NERTC SDK 的 setExternalAudioSource 接口开启自定义音频采集功能,并设置外部音频采集参数。然后使用 pushExternalAudioFrame 接口将外部音频数据帧推送给 NERTC SDK。
注意事项
setExternalAudioSource 接口必须在加入房间前设置,并且在通话结束后设置依然有效。如果需要关闭该功能,需要在下次通话前调用接口关闭外部音频数据输入功能。
通过 pushExternalAudioFrame 向 SDK 投送的数据必须是 PCM 格式的未经压缩的音频裸数据,不支持其他压缩格式。
您需要自行管理音频数据采集和渲染的处理逻辑。
建议同时使用自定义音频采集和音频渲染功能,此时您需要自行维护 AVAudioSession 的设置,即通过 setAudioSessionOperationRestriction 设置 SDK 对 AVAudioSession 的操作权限为 kNERtcAudioSessionOperationRestrictionAll。
实现方法
自定义音频采集
在 joinChannel 之前,调用 setExternalAudioSource 开启自定义音频采集功能,并设置外部音频采集参数。
本地用户成功加入房间之后,通过 enableLocalAudio 开启音频功能,并使用自采集模块采集音频数据。
您需要自行管理音频数据采集和处理逻辑。
完成音频数据处理后,调用 pushExternalAudioFrame 将外部音频数据帧推送给 NERTC SDK。
自定义音频渲染
- 加入房间前,通过调用 setExternalAudioRender 开启并设置外部音频渲染。
- 成功加入房间后,调用 pullExternalAudioFrame 拉取远端发送的音频
- 您需要自行渲染并播放拉取到的音频数据。
示例代码
[NERtcEngine sharedEngine] setExternalAudioSource:YES sampleRate:48000 channels:1];
NERtcAudioFrame *frame = [[NERtcAudioFrame alloc] init];
NERtcAudioFormat *format = [[NERtcAudioFormat alloc] init];
frame.data = data;
frame.format = format;
format.bytesPerSample = 2;
format.channels = 1;
format.sampleRate = 48000;
format.samplesPerChannel = format.sampleRate / (1000 / 10); //假设采样周期是10ms
[[NERtcEngine sharedEngine] pushExternalAudioFrame:frame];
//自定义音频渲染
//开关自定义音频渲染,设置想要的数据采样率和声道,需加入频道前设置
//返回值succ为true则操作成功,否则操作失败
BOOL succ = [[NERtcEngine sharedEngine] setExternalAudioRender:enable sampleRate:48000 channels:1];
if(succ) {
//操作成功
}else {
//操作失败,需要用户处理
}
//拉取音频数据
int audioDataSize = 1024;//申请的实际内存长度,用户根据采样数和声道,自行设置,建议稍大一点防止溢出
void *audioData = malloc(audioDataSize);
int succ = [[NERtcEngine sharedEngine] pullExternalAudioFrame:audioData length:audioDataSize];
if(succ != 0) {
//拉取音频数据失败,建议填充静音数据
memset(audioData, 0, audioDataSize);
}
Windows&macOS
您可以通过 NERTC SDK 的 setExternalAudioSource 接口开启自定义音频采集功能,并设置外部音频采集参数。然后使用 pushExternalAudioFrame 接口将外部音频数据帧推送给 NERTC SDK。
注意事项
- setExternalAudioSource 接口必须在加入房间前设置,并且在通话结束后设置依然有效。如果需要关闭该功能,需要在下次通话前调用接口关闭外部音频数据输入功能。
- 通过 pushExternalAudioFrame 向 SDK 投送的数据必须是 PCM 格式的未经压缩的音频裸数据,不支持其他压缩格式。
- 您需要自行管理音频数据采集和渲染的处理逻辑。
实现方法
自定义音频采集
加入房间前,调用 setExternalAudioSource 开启自定义音频采集功能,并设置外部音频采集参数。
本地用户成功加入房间之后,使用自采集模块采集音频数据。
您需要自行管理音频数据采集和处理逻辑。
完成音频数据处理后,调用 pushExternalAudioFrame 将外部音频数据帧推送给 NERTC SDK。
自定义音频渲染(Windows)
注意:macOS 暂时不支持自定义音频渲染。
- 加入房间前,通过调用 setExternalAudioRender 开启并设置外部音频渲染。
- 成功加入房间后,调用 pullExternalAudioFrame 拉取远端发送的音频
- 您需要自行渲染并播放拉取到的音频数据。
示例代码
//使用自定义音频
rtc_engine_->setExternalAudioSource(true, 48000, 1);
//push 数据
nertc::NERtcAudioFrame frame;
frame.data = (void*)(external_audioin_pcm_data);
frame.format.type = nertc::kNERtcAudioTypePCM16;
frame.format.bytes_per_sample = 2;
frame.format.samples_per_channel = 48000 * 10 / 1000;
frame.format.sample_rate = 48000;
frame.format.channels = 1;
rtc_engine_->pushExternalAudioFrame(frame);
//自定义音频渲染
int samplerate = 48000;
int channels = 2;
nrtc_engine_->setExternalAudioRender(true, samplerate, channels);
//push 数据
int32_t duration= 10;//毫秒
int32_t sample_len = samplerate * channels* duration * 2 / 1000;
uint8_t* data = new uint8_t[sample_len];
nrtc_engine_->pullExternalAudioFrame((void*)data, sample_len);
//to play audio data
WebWeb
通过 createStream 创建音频流时,可以通过 audioSource 指定自定义的音频输入源,以此实现自定义音频采集。
示例代码
const mediaStream = await navigator.mediaDevices.getUserMedia({audio: true});
const audioSource = await mediaStream.getAudioTracks()[0];
// 处理一番audioSource
const localStream = WebRTC2.createStream({
audio: true,
audioSource: audioSource
});
await localStream.init();
await client.publish(localStream);


此文档对你是否有帮助

