菊风已发布实时音视频2.0升级版(2.0版本说明),当前您正在访问1.0旧版本,点击此处可进入2.0升级版

# 自定义音频采集和渲染

# 简介

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

# 前提条件

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

# 自定义音频采集

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

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

private customAudioInputTask: TaskExecutor | null = null;

// 自定义音频采集,在状态为连接中时或者加入频道成功后调用此方法
customizeAudioInput(): void {
    // 创建子线程任务执行器
    this.customAudioInputTask = new TaskExecutor('CustomAudioInput', () => {
        const sampleRateHz: number = 8000;
        const channels: number = 1;

        // 自定义音频数据
        const value: ArrayBuffer = stringToArrayBuffer("Any String you want");
        const buffer: ArrayBuffer = value;

        // 将音频输入数据输入到媒体层
        while ((this.call != null && this.call.getActiveCallItem() != null) ||
               (this.mediaChannel != null && this.mediaChannel.getState() == JCMediaChannel.STATE_JOINED)) {
            this.mediaDevice.inputCustomAudioData(sampleRateHz, channels, buffer, 0, 0, 0);
            sleep(1000); // 模拟延迟
        }
    });

    // 启动任务
    this.customAudioInputTask.start();
}

// 工具函数:将字符串转换为ArrayBuffer
function stringToArrayBuffer(str: string): ArrayBuffer {
    const encoder = new TextEncoder();
    return encoder.encode(str).buffer;
}

// 工具函数:模拟延迟
function sleep(ms: number): void {
    const start = new Date().getTime();
    while (new Date().getTime() < start + ms);
}

# 自定义音频渲染

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

  1. 发起通话前,将 JCMediaDevice (opens new window)audioParam (opens new window)autoStartAudioOutputDevice (opens new window) 设置为 false。这种情况下才可以获取音频输出数据。
  2. 调用 getAudioOutputData (opens new window) 自定义音频渲染。建议在一对一通话状态为连接中时或者加入频道成功后,在子线程不断的调用此方法渲染音频数据。
  3. 在结束通话的时候,关闭子线程停止音频渲染。
// 在开启前将 autoStartAudioOutputDevice 属性设为 false
turnOffAutoStartAudioOutputDevice(): void {
    this.mediaDevice.audioParam.autoStartAudioOutputDevice = false;
}

private audioOutputTask: TaskExecutor | null = null;

// 自定义音频渲染,在状态为连接中时或者加入频道成功后调用此方法
customizeAudioOutput(): void {
    // 创建子线程任务执行器
    this.audioOutputTask = new TaskExecutor('AudioOutputData', () => {
        const sampleRateHz: number = 8000;
        const channels: number = 1;
        const bufferSize: number = Math.floor(sampleRateHz / 100) * 2 * channels;
        const buffer: ArrayBuffer = new ArrayBuffer(bufferSize);

        // 获取音频输出数据
        while ((this.call != null && this.call.getActiveCallItem() != null) ||
               (this.mediaChannel != null && this.mediaChannel.getState() == JCMediaChannel.STATE_JOINED)) {
            this.mediaDevice.getAudioOutputData(sampleRateHz, channels, buffer);
            sleep(1000); // 模拟延迟
        }
    });

    // 启动任务
    this.audioOutputTask.start();
}

// 工具函数:模拟延迟
function sleep(ms: number): void {
    const start = new Date().getTime();
    while (new Date().getTime() < start + ms);
}
最后更新时间: 2025-5-13 6:06:58 ├F10: PM┤