音频外部采集与渲染
1 使用场景
1.1 外部采集
以下情况时,建议使用音频外部采集功能:
客户需要从现有音频流、音频文件、或者定制的采集系统中获得采集后输入,交给 SDK 传输。
客户有自己对 PCM 输入源做特殊的音效处理的需求,在音效处理后输入,交给 SDK 传输。
1.2 外部渲染
当客户有自己渲染的需求,例如对拉取到的原始 PCM 数据做特殊应用或者处理后再渲染,建议使用 SDK 的音频外部渲染功能。
请注意:
音频外部采集和外部渲染是一体的,所以如果开发者采用了外部渲染,则在有需要的情况下,应当自己实现外部采集。同理,采用了外部采集,则在有需要的情况下,应当自己实现外部渲染。
开发者采用外部采集和渲染后,SDK 内部不负责声音增强、噪音抑制、回音消除等功能,需要用户自己实现。
2 相关接口
音频外部采集和渲染是一体的,相关接口都位于 ZegoExternalAudioDevice 类中,结构如下所示:
ZegoExternalAudioDevice.java
public class ZegoExternalAudioDevice {
{
/**
* 开启音频外部采集。
*
注意:必须在InitSDK之后调用
*
* @return true:调用成功,false:调用失败
*/
public static native boolean startCapture();
/**
* 关闭音频外部采集。
*
注意:必须在InitSDK之后调用
*
* @return true:调用成功,false:调用失败
*/
public static native boolean stopCapture();
/**
* 开启音频外部渲染。
*
注意:必须在InitSDK之后调用
*
* @return true:调用成功,false:调用失败
*/
public static native boolean startRender();
/**
* 关闭音频外部渲染。
*
注意:必须在InitSDK之后调用
*
* @return true:调用成功,false:调用失败
*/
public static native boolean stopRender();
/**
* 发送外部采集数据。
*
注意:必须先调用{@link #startCapture()}开启音频外部采集,等待推流成功后再发送数据
*
* @param audioFrame 音频数据
*
* @return true:调用成功,false:调用失败
*/
public static native boolean onRecordAudioFrame(ZegoAudioFrame audioFrame);
/**
* 获取sdk采集的数据,用于外部渲染。
*
注意:必须先调用{@link #startRender()} 开启音频外部渲染,等待拉流成功后再获取数据
*
* @param audioFrame 音频数据
*
* @return true:调用成功,false:调用失败
*/
public static native boolean onPlaybackAudioFrame(ZegoAudioFrame audioFrame);
};
其中,ZegoAudioFrame 表示音频帧,具体结构为:
ZegoAudioFrame.java
public class ZegoAudioFrame {
{
/**
* refer to FrameType.
*/
public int frameType;
/**
* PCM:capture pcm samples at this input. AAC:aac encode one frame need samples.
*/
public int samples;
/**
* bytes per sample, only support 2 bytes per sample.
*/
public int bytesPerSample;
/**
* channels, 1 or 2.
*/
public int channels;
/**
* PCM: capture sample rate; AAC: encode sample rate. supported [16k/32k/44.1k/48k].
*/
public int sampleRate;
/**
* time stamp, PCM: 0; AAC: 0 or encode timeStamp, if buffer data only contain special config fill 0.
*/
public double timeStamp;
/**
* aac special config Len, PCM: 0; AAC: range [0-64]. 0 indicate this frame not contain spcial config.
*/
public int configLen;
/**
* buffer Length, PCM bufLen = 2 * samples * channels(only need correct fill samples and channels,
* not use filed bufLen). AAC encode data len = bufLen - configLen.
*/
public int bufLen;
/**
* data buffer, the caller is responsible for bufer allocate and release.
*
注意: 必须使用{@link ByteBuffer#allocateDirect(int)}创建buffer, 否则数据无法传递给sdk
*/
public ByteBuffer buffer;
/**
* 帧数据编码类型
*/
public static final class FrameType{
/**
* PCM.
*/
public static final int PCM = 0x1001;
/**
* AAC.
*/
public static final int AAC_STREAM = 0x1003;
}
};
当 FrameType 为 PCM 时,各字段的含义说明:
字段
说明
samples
此帧包含的 PCM 采样数
bytesPerSample
bytesPerSample = 2 x channels (只支持 bit depth 为 16bit / 2byte)
channels
声道数,取值为 [1, 2]
sampleRate
PCM 采集采样率,取值为 [8000, 16000, 22050, 24000, 32000, 44100, 48000]
timeStamp
固定为 0,PCM 帧忽略此参数
configLen
固定为 0,PCM 帧忽略此参数
bufLen
buffer 中含有的 PCM 数据长度,单位为字节。对于 PCM 帧:bufLen = 2 x samples x channels
buffer
此时 buffer 中的数据由 PCM 组成。结构如下图
当 FrameType 为 AAC_STREAM 时,各字段的含义说明:
字段
说明
samples
AAC 编码一帧所需要的采样数,取值为 [480, 512, 1024, 1960, 2048]
bytesPerSample
bytesPerSample = 2 x channels (只支持 bit depth 为 16bit / 2byte)
channels
声道数,取值为 [1, 2]
sampleRate
AAC 编码采样率,取值为 [8000, 16000, 22050, 24000, 32000, 44100, 48000]
timeStamp
编码时间戳
configLen
AAC 编码的 audio special config 长度
bufLen
buffer 中含有的数据长度,单位为字节
buffer
此时 buffer 中的数据由 aac spcial config 和 encode data 组成。结构如下图
关于 buffer 结构,请注意:
如果 configLen == 0,则 buffer 中全部是 aac encode data 数据。
如果 configLen == bufLen,则 buffer 中全部是 aac special config 数据。
如果 (configLen != 0) && (configLen < bufLen),则 buffer 中含有 configLen 长度的 aac special config 数据和 (bufLen - configLen) 长度的 encode data 数据。
下文将详细讲述如何使用 ZegoExternalAudioDevice 实现音频外部采集和渲染。
2.1 开启外部音频设备
使用音频外部采集和外部渲染之前,必须先启用外部音频设备,调用如下接口:
ZegoExternalAudioDevice.java
/**
* 音频外部采集、渲染总开关。
*
注意:必须在InitSDK之前调用
*
* @param enable true:开启,false:关闭。默认为false
*/
public static void enableExternalAudioDevice(boolean enable);
2.2 音频外部采集
音频外部采集的接口调用步骤如下图所示:
请注意
调用 onRecordAudioFrame(ZegoAudioFrame audioFrame) 输入采集数据给 SDK 时,audioFrame 只是输入参数
数据 buffer 内存由外部调用者负责分配和释放,各字段均由外部调用者填写。
2.3 音频外部渲染
音频外部渲染的接口调用步骤如下图所示:
请注意
调用 onPlaybackAudioFrame(ZegoAudioFrame audioFrame) 从 SDK 获取可渲染数据时,参数 audioFrame 即为输入参数,也为输出参数。
数据 buffer 内存由外部调用者负责分配和释放。
当 audioFrame 作为输入参数时,外部渲染模块参数需要按照如下方式填写:
字段
填写
frameType
TYPE_PCM
samples
此次渲染帧外部需要的 PCM 数据采样数
bytesPerSample
bytesPerSample = 2 x channels (只支持 bit depth 为 16bit / 2byte)
channels
需要的声道数,取值 [1, 2]
sampleRate
外部渲染需要的采样率,取值为 [16000, 32000, 44100, 48000]
timeStamp
固定为 0,忽略
configLen
固定为 0,忽略
bufLen
外部已经分配好的 buffer 的长度,单位为字节。buffer 长度应该不小于 2 x samples x channels
buffer
外部已经分配好的 buffer
当 audioFrame 作为输出参数时,SDK 会按照外部渲染要求填充好 buffer 中的数据,会修改 bufLen = 2 x samples x channels,其他字段不变。