获取原始音频数据

本文将介绍如何获取采集的原始音频数据,对这些数据进行处理。

示例代码

Android端获取原始音频数据Android/ARTCExample/AdvancedUsage/src/main/java/com/aliyun/artc/api/advancedusage/ProcessAudioRawData/ProcessAudioRawDataActivity.java

iOS端获取原始音频数据iOS/ARTCExample/AdvancedUsage/ProcessAudioRawData/ProcessAudioRawDataVC.swift

前提条件

在设置视频配置之前,请确保达成以下条件:

功能实现

image

1.初始化 RTC 引擎

获取音频原始数据前,需要创建和初始化一个音视频引擎类。

2.实现音频数据回调方法

为了获取音频数据,需要实现相关回调方法,回调方法如下:

回调方法

相关含义

注意事项

onCapturedAudioFrame

本地采集的音频数据回调。

无。

onProcessCapturedAudioFrame

经过3A环节后的音频数据回调。

无。

onPublishAudioFrame

推流的音频数据回调。

只能设置为只读模式。

onPlaybackAudioFrame

本地播放的音频数据回调(可能包含多个远端用户混音)。

无。

onRemoteUserAudioFrame

指定远端用户的音频数据回调。

不能设置采样率和声道数,会跟随远端用户的设置,但是可以设置为读写模式。

Android

需要集成并实现AliRtcAudioFrameObserver类的相关方法,具体实现哪些回调请根据您的业务场景来决定。

private final AliRtcEngine.AliRtcAudioFrameObserver rtcAudioFrameObserver = new AliRtcEngine.AliRtcAudioFrameObserver() {
    @Override
    public boolean onCapturedAudioFrame(AliRtcEngine.AliRtcAudioFrame frame) {
        // 本地采集音频数据回调,根据业务场景进行处理
        Log.i(TAG, "onCaptureAudioFrame");
        return true;
    }

    @Override
    public boolean onProcessCapturedAudioFrame(AliRtcEngine.AliRtcAudioFrame frame) {
        // 3A后数据回调,根据业务场景进行处理
        Log.i(TAG, "onProcessCaptureAudioFrame");
        return true;
    }

    @Override
    public boolean onPublishAudioFrame(AliRtcEngine.AliRtcAudioFrame frame) {
        // 推流音频数据回调,根据业务场景进行处理
        Log.i(TAG, "onPublishAudioFrame");
        return true;
    }

    @Override
    public boolean onPlaybackAudioFrame(AliRtcEngine.AliRtcAudioFrame frame) {
        // 播放数据(混音后),根据业务场景进行处理
        Log.i(TAG, "onPlaybackAudioFrame");
        return true;
    }

    @Override
    @Deprecated
    public boolean onMixedAllAudioFrame(AliRtcEngine.AliRtcAudioFrame frame) {
        // 该方法已弃用
        return true;
    }

    @Override
    public boolean onRemoteUserAudioFrame(String uid, AliRtcEngine.AliRtcAudioFrame frame) {
        // 远端用户拉流音频数据,根据业务场景进行处理
        Log.i(TAG, "onRemoteUserAudioFrame");
        return true;
    }
};

iOS

为了获取原始音频数据,需要实现AliRtcAudioFrameDelegate中的回调方法,具体实现哪些回调请根据您的业务场景来决定。

// MARK: 音频数据回调
extension ProcessAudioRawDataMainVC: AliRtcAudioFrameDelegate {
    func onCapturedAudioFrame(_ frame: AliRtcAudioFrame) -> Bool {
        let message = "onCaptureVideoSample: numofSamples: \(frame.numOfSamples), numofChannels: \(frame.numOfChannels), SampleRate: \(frame.samplesPerSec)"
        message.printLog()
        updateInfoLabel(captureInfoLabel, text: message)
        return true
    }
    
    func onProcessCapturedAudioFrame(_ frame: AliRtcAudioFrame) -> Bool {
        let message = "onProcessCapturedAudioFrame: numofSamples: \(frame.numOfSamples), numofChannels: \(frame.numOfChannels), SampleRate: \(frame.samplesPerSec)"
        message.printLog()
        updateInfoLabel(processInfoLabel, text: message)
        return true
    }
    
    func onPublishAudioFrame(_ frame: AliRtcAudioFrame) -> Bool {
        let message = "onPublishAudioFrame: numofSamples: \(frame.numOfSamples), numofChannels: \(frame.numOfChannels), SampleRate: \(frame.samplesPerSec)"
        message.printLog()
        updateInfoLabel(publishInfoLabel, text: message)
        return true
    }
    
    func onPlaybackAudioFrame(_ frame: AliRtcAudioFrame) -> Bool {
        let message = "onPlaybackAudioFrame: numofSamples: \(frame.numOfSamples), numofChannels: \(frame.numOfChannels), SampleRate: \(frame.samplesPerSec)"
        message.printLog()
        updateInfoLabel(prePlaybackInfoLabel, text: message)
        return true
    }
    
    func onRemoteUserAudioFrame(_ uid: String?, frame: AliRtcAudioFrame) -> Bool {
        let message = "onRemoteUserAudioFrame: uid: \(uid ?? "invalid"), numofSamples: \(frame.numOfSamples), numofChannels: \(frame.numOfChannels), SampleRate: \(frame.samplesPerSec)"
        message.printLog()
        updateInfoLabel(remoteUserInfoLabel, text: message)
        return true
    }
}

3.开启获取原始音频数据功能

  1. 调用registerAudioFrameObserver接口注册音频数据监听器。

  2. 调用enableAudioFrameObserver接口开启指定Audio Source回调,并配置期望的数据格式。如果需要开启多个回调,请多次调用。

    • enable:true表示开启,false表示关闭。

    • audioSource:回调数据类型,与上面的回调一一对应。

    • config:回调数据类型设置,如果为null,默认为48000+单声道+ReadOnly模式。

    说明
    • enableAudioFrameObserver的调用与音频数据回调一一对应,可以根据业务场景多次调用。

    • enableAudioFrameObserver在加入频道前后均可调用。

  3. 在对应的回调接口中接收音频数据,并根据业务场景对音频数据进行处理。

Android

// 注册音频帧原始数据回调监听器
mAliRtcEngine.registerAudioFrameObserver(rtcAudioFrameObserver);

// 启用对应回调,根据业务场景选择性调用
mAliRtcEngine.enableAudioFrameObserver(isChecked, AliRtcEngine.AliRtcAudioSource.AliRtcAudioSourceCaptured, config);
mAliRtcEngine.enableAudioFrameObserver(isChecked, AliRtcEngine.AliRtcAudioSource.AliRtcAudioSourceProcessCaptured, config);
mAliRtcEngine.enableAudioFrameObserver(isChecked, AliRtcEngine.AliRtcAudioSource.AliRtcAudioSourcePub, config);
mAliRtcEngine.enableAudioFrameObserver(isChecked, AliRtcEngine.AliRtcAudioSource.AliRtcAudioSourcePlayback, config);
mAliRtcEngine.enableAudioFrameObserver(isChecked, AliRtcEngine.AliRtcAudioSource.AliRtcAudioSourceRemoteUser, config);

iOS

// 注册音频数据回调
self.rtcEngine?.registerAudioFrameObserver(self)

// 启用对应回调,根据业务场景选择性调用,在此根据配置调用
for (source, config) in configs {
    if config.enable, let observerConfig = config.observerConfig {
        // 启用音频数据监听器
        self.rtcEngine?.enableAudioFrameObserver(config.enable, audioSource: source, config: observerConfig)
        isEnableAudioRawFrame = true
    }
}

4.停止音频数据回调

如果希望停止音频数据回调,可以调用registerAudioFrameObserver(null)取消音频帧注册监听器,或者通过enableAudioFrameObserver传入false来关闭对应Audio Source的数据回调。

Android

// 停止指定Audio Source的音频数据回调
mAliRtcEngine.enableAudioFrameObserver(false, AliRtcEngine.AliRtcAudioSource.AliRtcAudioSourceCaptured, config);

// 取消注册
mAliRtcEngine.registerAudioFrameObserver(null);

iOS

// 停止指定Audio Source的音频数据回调
self.rtcEngine?.enableAudioFrameObserver(false, audioSource: source, config: observerConfig)

// 取消注册
self.rtcEngine?.registerAudioFrameObserver(nil)

注意事项

必须调用enableAudioFrameObserver接口开启对应Audio Source的音频数据回调,否则不会触发对应回调。