本文将介绍如何获取采集的原始音频数据,对这些数据进行处理。
示例代码
Android端获取原始音频数据:Android/ARTCExample/AdvancedUsage/src/main/java/com/aliyun/artc/api/advancedusage/ProcessAudioRawData/ProcessAudioRawDataActivity.java
。
iOS端获取原始音频数据:iOS/ARTCExample/AdvancedUsage/ProcessAudioRawData/ProcessAudioRawDataVC.swift
。
前提条件
在设置视频配置之前,请确保达成以下条件:
功能实现
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.开启获取原始音频数据功能
调用
registerAudioFrameObserver
接口注册音频数据监听器。调用
enableAudioFrameObserver
接口开启指定Audio Source回调,并配置期望的数据格式。如果需要开启多个回调,请多次调用。enable:true表示开启,false表示关闭。
audioSource:回调数据类型,与上面的回调一一对应。
config:回调数据类型设置,如果为null,默认为48000+单声道+ReadOnly模式。
说明enableAudioFrameObserver
的调用与音频数据回调一一对应,可以根据业务场景多次调用。enableAudioFrameObserver
在加入频道前后均可调用。
在对应的回调接口中接收音频数据,并根据业务场景对音频数据进行处理。
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的音频数据回调,否则不会触发对应回调。