自定义音频采集与渲染
更新时间: 2024/09/18 16:26:13
在合唱或直播场景中,用户往往需要共享非麦克风采集的外部音频源,比如希望在合唱过程中使用自定义的音乐文件。为了支持用户使用自定义音频源, NERTC SDK 为用户提供传输通道,并进行编码推流。
功能介绍
NERTC SDK 支持自定义音频采集与渲染功能,可以向 NERTC SDK 提供自定义的音频输入源数据,使用自定义的渲染器,并由 NERTC SDK 进行编码推流。
一般情况下,App 通过本设备的内置麦克风采集音频数据。但在部分场景下可能需要使用自定义的音频源,例如:
- 需要使用自定义的音效、美声库或前处理库。
- 需要使用外部音频源或外接设备进行音频数据采集,例如在音视频通话或互动直播中播放自定义的音频文件。
- App 无法获取音频采集设备的控制权限,例如音频采集设备已被其他业务占用,或硬件设备的默认音频采集模块损坏等场景下。
基于以上场景,NERTC SDK 支持使用自定义的音频源或渲染器,以实现业务场景中的相关需求。
注意事项
- 自定义音频采集场景中,您需要自行管理音频数据的采集和处理;自定义音频渲染场景中,您需要自行管理音频数据的处理和播放。在两种场景下,音频处理 3A 算法(AEC、ANS 和 AGC)均为关闭状态,不可手动开启。
- 若您需要开启外部音频采集,建议在创建外部音频输入源之前调用
enableLocalAudio
或enableLocalSubStreamAudio
方法关闭本地音频设备采集(若未打开则无需关心),再在创建外部音频输入源之后再次调用enableLocalAudio
或enableLocalSubStreamAudio
方法开启媒体传输通道。 - 通过
pushExternalAudioFrame
或pushExternalSubStreamAudioFrame
接口向 SDK 投送的数据必须是 PCM 格式的未经压缩的音频裸数据,不支持其他压缩格式。 - 若您需要开启外部音频渲染,请在加入房间前调用
setExternalAudioRender
方法,此接口设置在通话结束后后仍然有效,直至销毁 SDK。
示例项目源码
网易云信提供ExternalAudioCapture 示例项目源码,您可以参考该源码实现自定义音频采集与渲染。
自定义音频采集
技术原理
API 调用时序
sequenceDiagram
participant 应用层
participant NERtcSDK
应用层->>NERtcSDK: setExternalAudioSource/setExternalSubStreamAudioSource
应用层->>NERtcSDK: enableLocalAudio/enableLocalSubStreamAudio
Note over 应用层, NERtcSDK: 自行处理音频数据
应用层->>NERtcSDK: pushExternalAudioFrame/pushExternalSubStreamAudioFrame
实现方法
- 在加入房间前,调用
setExternalAudioSource
方法开启外部音频主流输入或调用setExternalSubStreamAudioSource
方法开启外部音频辅流输入,并设置外部音频采集参数,相关参数说明如下:- enabled:是否开启外部音频输入,默认关闭。
- sample_rate:外部音频源的数据采样率,单位为赫兹(Hz)。
- channels:外部音频源的数据声道数,可设置为单声道(1)或双声道(2)。
- 自定义外部音频采集接口支持在通话过程中动态调用,接口设置在通话结束后仍然有效;若您需要关闭该功能,请在下次通话前再次调用此方法关闭自定义音频采集。
- 您可以同时开启外部音频主、辅流输入。在这种情况下,您可以通过
syncTimeStamp
参数同步音频主辅流的时间戳。
- 调用
enableLocalAudio
或enableLocalSubStreamAudio
方法开启媒体传输通道。若您开启的是外部音频主流输入,请开启对应的媒体主流传输通道,辅流同理。
- 成功加入房间之后,使用自采集模块采集音频数据。您需要自行管理音频数据采集和处理逻辑。
- 完成音频数据处理后,调用
pushExternalAudioFrame
方法将外部音频主流数据帧推送给 NERTC SDK,或调用pushExternalSubStreamAudioFrame
推送外部音频辅流数据帧,并设置外部音频格式。- 建议推送的音频数据帧时长至少为 10 ms。
samplesPerChannel
指单通道的采样点个数,计算公式为 sampleRate * (time)/ 1000,其中 time 是推送给 SDK 的音频数据的时间间隔,比如一次是 20ms 的数据,则 time = 20。
示例代码
//开启自定义音频主流采集
NERtcEx.getInstance().setExternalAudioSource(true,sample_rate,channels);
// 开启音频主流,SDK 默认开启
NERtcEx.getInstance().enableLocalAudio(true);
NERtcAudioExternalFrame frame = new
NERtcAudioExternalFrame();
audioFrame.audioData = sampleData; //音频数据
audioFrame.numberOfChannels = 1; //音频声道数
audioFrame.sampleRate = 48000; //音频采样率
audioFrame.samplesPerChannel = 48000 * 20 / 1000; //单声道的采样点个数
audio.syncTimeStamp = -1; //同步音频主辅流时间戳
NERtcEx.getInstance().pushExternalAudioFrame(frame);
//开启自定义音频辅流采集
NERtcEx.getInstance().setExternalSubStreamAudioSource(true,sample_rate,channels);
// 开启音频辅流,SDK 默认关闭
NERtcEx.getInstance().enableLocalSubStreamAudio(true);
NERtcAudioExternalFrame frame = new
NERtcAudioExternalFrame();
audioFrame.audioData = sampleData; //音频数据
audioFrame.numberOfChannels = 1; //音频声道数
audioFrame.sampleRate = 48000; //音频采样率
audioFrame.samplesPerChannel = 48000 * 20 / 1000; //单声道的采样点个数
audio.syncTimeStamp = -1; //同步音频主辅流时间戳
NERtcEx.getInstance().pushExternalSubStreamAudioFrame(frame);
API 参考
方法 | 功能描述 |
---|---|
enableLocalSubStreamAudio |
开启音频辅流 |
setExternalAudioSource |
开启自定义音频主流采集 |
setExternalSubStreamAudioSource |
开启自定义音频辅流采集 |
pushExternalAudioFrame |
将外部音频主流数据帧推送给 NERTC SDK |
pushExternalSubStreamAudioFrame |
将外部音频辅流数据帧推送给 NERTC SDK |
自定义音频渲染
API 调用时序
sequenceDiagram
participant 应用层
participant NERtcSDK
应用层->>NERtcSDK: setExternalAudioRender
应用层->>NERtcSDK: pullExternalAudioFrame
Note over 应用层, NERtcSDK: 自行处理音频数据
实现方法
- 在加入房间前,调用
setExternalAudioRender
方法开启外部音频渲染,并设置外部音频渲染参数,相关参数的说明如下:- enabled:是否开启外部音频输入,默认关闭。
- sample_rate:外部音频源的数据采样率,单位为赫兹(Hz)。
- channels:外部音频源的数据声道数,可设置为单声道(1)或双声道(2)。
此接口设置在通话结束后仍然有效;若您需要关闭该功能,请在下次通话前再次调用此方法关闭自定义音频渲染。
- 成功加入房间后,调用
pullExternalAudioFrame
方法拉取远端发送的外部音频数据帧,相关参数的说明如下:- buffer:待填充的 buffer 数组。需要您来创建,且必须使用 ByteBuffer.allocateDirect 创建。
- len:待拉取音频数据的字节数。该参数的单位为 byte,数据长度不能超过 7680 字节。
计算公式为: len = sampleRate/1000 × 2 × channels × 音频数据时长(ms)。
- 建议推送的音频数据帧时长至少为 10 ms。
- 音频渲染设备关闭后,调用此方法时会返回空数据。例如在通话结束或通话前扬声器设备测试关闭等情况下,该设置不再生效。
- 您需要自行渲染并播放拉取到的音频数据。
示例代码
//自定义音频渲染
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();
API 参考
方法 | 功能描述 |
---|---|
setExternalAudioRender |
开启外部音频渲染 |
pullExternalAudioFrame |
拉取远端发送的外部音频数据帧 |
此文档是否对你有帮助?