# 自定义音频采集和渲染

# 简介

实时音频传输过程中,JC SDK 会启动默认的音频模块进行采集和渲染。当遇到不支持系统标准 API 的音频设备的时候,或者希望使用自己已经拥有的音频模块进行音频采集和渲染的时候,您可以选择在音频被采集前自定义音频采集,也可以选择在音频播放前自定义音频渲染

# 前提条件

在自定义音频采集和渲染前,确保已经初始化了 JCMediaDevice 模块。

# 自定义音频采集

参照下述步骤,在音频输入前,修改音频输入源和采样率等参数:

  1. 发起通话前,将 JCMediaDeviceAudioParam 中 的 autoStartAudioInputDevice (opens new window) 设置为 false。这种情况下才可以获取音频输入数据。
  2. 调用 inputCustomAudioData (opens new window) 自定义音频采集。 建议在一对一通话状态为连接中时或者加入频道成功后,在子线程不断的调用此方法传入音频数据。
  3. 在结束通话的时候,关闭子线程停止音频采集。
// 关闭自动音频采集
JCMediaDeviceAudioParam param;
param.autoStartAudioInputDevice = false;
mediaDevice->setAudioParam(&param);

// 启动线程执行
CString path = path + "C:\\customAudio.pcm";
FILE *stream;
errno_t err = fopen_s(&stream, path.GetBuffer() , "rb");
if (err != 0) {
    return;
}
fseek(stream, NULL, SEEK_END);
int len = ftell(stream);
rewind(stream);
unsigned char* buff = new unsigned char[len];
fread(buff, 1, len, stream);
// 根据实际文件调整
int packetLen = 32 * 1024;
int packetNum = len / packetLen;
int num = 0;
while (mThreadRun)
{
    JCManager::shared()->mediaDevice->inputCustomAudioData(16000, 1, buff + num * packetLen, packetLen, 0, 0, 0);
    num = (++num) % packetNum;
    Sleep(1000);
}
delete[] buff;

# 自定义音频渲染

参照下述步骤,在音频播放前,修改音频输入源和采样率等参数:

  1. 发起通话前,将 JCMediaDeviceAudioParam 中 的 autoStartAudioInputDevice (opens new window) 设置为 false。这种情况下才可以获取音频输出数据。
  2. 调用 getAudioOutputData (opens new window) 自定义音频渲染。建议在一对一通话状态为连接中时或者加入频道成功后,在子线程不断的调用此方法渲染音频数据。
  3. 在结束通话的时候,关闭子线程停止音频渲染。
// 关闭自动音频播放
JCMediaDeviceAudioParam param;
param.autoStartAudioOutputDevice = false;
mediaDevice->setAudioParam(&param);

//启动线程执行音频播放
HWAVEOUT        hwo;
WAVEHDR         wh;
WAVEFORMATEX    wfx;
HANDLE          wait;
wfx.wFormatTag = WAVE_FORMAT_PCM; 
wfx.nChannels = 1;
wfx.nSamplesPerSec = 16000; 
wfx.nAvgBytesPerSec = 16000;  
wfx.nBlockAlign = 2;
wfx.wBitsPerSample = 16;
wfx.cbSize = 0; 
wait = CreateEvent(NULL, 0, 0, NULL);
waveOutOpen(&hwo, WAVE_MAPPER, &wfx, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);
char buf[1024];
ZeroMemory(buf, 1024);
while (mThreadRun) {
    JCManager::shared()->mediaDevice->getAudioOutputData(16000, 1, (unsigned char*)buf, 1024);
    wh.lpData = buf;
    wh.dwBufferLength = 1024;
    wh.dwFlags = 0L;
    wh.dwLoops = 1L;
    waveOutPrepareHeader(hwo, &wh, sizeof(WAVEHDR));
    waveOutWrite(hwo, &wh, sizeof(WAVEHDR));  
    WaitForSingleObject(wait, INFINITE);
}
waveOutReset(hwo);
waveOutUnprepareHeader(hwo, &wh, sizeof(WAVEHDR));
waveOutClose(hwo);
最后更新时间: 2021/3/30 14:57:27