tencent cloud

游戏多媒体引擎

产品动态
产品介绍
产品概述
优势特性
产品功能
应用场景
安全合规认证
新手指引
产品计费
免费额度
购买指南
SDK 下载指引
产品功能体验
基本功能演示
场景化 Demo 体验
控制台指南
用量查看
服务开通
快速入门
快速接入 SDK
快速接入 Sample Project
基础功能开发指南
鉴权密钥
实时语音角色设置
音质选择
进阶功能开发指南
服务端录制
万人范围语音
3D 音效
音效与伴奏
网络音频流转发路由
自定义消息通道
如何应对公司防火墙限制
语言参数参考列表
房间管理功能
客户端 API
Unity SDK
Unreal Engine SDK
Cocos2D SDK
Windows SDK
iOS SDK
Android SDK
macOS SDK
H5SDK
Electron SDK
Flutter SDK
SDK 版本升级指引
错误码
编译工具链文档
服务端 API
History
Introduction
API Category
Usage APIs
Recording APIs
Making API Requests
Voice Chat APIs
Application APIs
Data Types
Error Codes
常见问题
产品功能问题
问题解决指南
计费相关问题
Sample Project 使用问题
一般性问题
鉴权相关问题
实时语音进房失败问题
实时语音无声及音频问题
网络问题
语音转文本问题
工程导出问题
服务协议
服务等级协议
联系我们
词汇表
GME 政策
数据处理和安全协议
隐私协议
文档游戏多媒体引擎

获取音频原数据

聚焦模式
字号
最后更新时间: 2023-04-27 17:07:00
声音模块是一个高复杂度的模块,SDK 需要严格控制声音设备的采集和播放逻辑。在某些场景下,当您需要获取远程用户的音频数据或者需要获取本地麦克风采集到的音频数据时,此功能可以获取实时语音房间内的实时音频流原始格式数据。

使用前提

已开通实时语音服务:可参见 服务开通指引
已接入 GME SDK:包括核心接口和实时语音接口的接入,详情可参见 Native SDK 快速接入Unity SDK 快速接入Unreal SDK 快速接入
需要在成功进入实时语音房间后,才可以使用此功能。

使用流程





调用流程

代码引入

Android 平台需要引入 ITMGAudioDataObserver。Unity 平台需要引入头文件 ITMGEngine_Adv.cs。
import com.tencent.TMG.advance.ITMGAudioDataObserver;

打开获取音频原数据功能开关

示例代码

Unity
SetAdvanceParams("AllowDumpCapture", "1");
注意:
需要在进房接口(EnterRoom)调用前调用 SetAdvanceParams。

设置音频原数据参数

通过此接口设置音频原数据参数。

函数原型

Unity
public abstract int SetAudioDataFormat(Audio_Data_Type audioType, int sampleRate, int channelCount);

接口参数列表

参数
类型
描述
audioType
Audio_Data_Type
需要设置的音频原数据类型
sampleRate
int
音频原数据音频采样率,建议填入48000
channelCount
int
音频原数据音频通道数,建议填入2

音频数据类型(Audio_Data_Type)

Audio_Data_Type 类型枚举
描述
AUDIO_DATA_TYPE_CAPTURE
获取麦克风采集到的音频原数据(需要先调用 EnableMic 接口打开麦克风)。
AUDIO_DATA_TYPE_LOOPBACK
获取麦克风采集并通过音效处理(例如:变声)后的音频原数据。
AUDIO_DATA_TYPE_SEND
获取音频流上行(包含麦克风采集并通过音效处理的人声以及伴奏声音)的音频原数据。
AUDIO_DATA_TYPE_PLAY
获取所有从扬声器播放的音频原数据(需要先调用 EnableSpeaker 接口打开扬声器)。
AUDIO_DATA_TYPE_CAPTURE_PLAY
包含 AUDIO_DATA_TYPE_CAPTURE 以及 AUDIO_DATA_TYPE_PLAY 两种类型的音频原数据。

开始获取音频原数据

通过此接口开始获取音频原数据,获取的音频原数据通过回调返回。

函数原型

Native
Unity
RegisteAudioDataCallback

public abstract int RegisteAudioDataCallback(Audio_Data_Type dataType);
参数
类型
含义
audioType
Audio_Data_Type
原始格式音频帧类型

停止获取音频原数据

通过此接口停止获取音频原数据。

函数原型

Native
Unity
UnRegisterAudioDataCallback
public abstract int UnRegisteAudioDataCallback(Audio_Data_Type dataType);
参数
类型
含义
audioType
Audio_Data_Type
音频原数据类型

示例代码

Objective-C
Java
unity

- (void)pCaptureChanged:(UISwitch *)sender {
if (sender.on) {
NSString *pathName = [NSString stringWithFormat:@"capture_%ld.pcm",(long)[[NSDate date] timeIntervalSince1970] * 1000];
NSString *path = [self pcmPath:pathName];
capFile = fopen(path.UTF8String, "wb");
[[ITMGAudioDataObserver GetInstance] RegisteAudioDataCallback:^(int audioDatType, unsigned long long timestamp, unsigned int sampleRate, unsigned int channelCount, int bitsType, unsigned int length, char * pcmData) {
if (capFile) {
fwrite(pcmData, sizeof(char), length, capFile);
}
}];
} else {
[[ITMGAudioDataObserver GetInstance] UnRegisterAudioDataCallback];
if (capFile) {
fclose(capFile);
capFile = NULL;
}
}
}
private void startDumpAllAudioData() {
int nRet = ITMGAudioDataObserver.GetInstance().RegisteAudioDataCallback(this);
showToast("RegisteAudioDataCallback AUDIO_DATA_TYPE_CAPTURE_PLAY ret:" + nRet);
if (nRet == 0) {
mDumpAllAudioing = true;
mBtnDumpAll.setText("StopDumpAudioPCM");
String dumpFilePath = String.format(Locale.getDefault(), "%s/Dump_Mic_Speaker_%d.pcm", getActivity().getExternalFilesDir(null).toString(),System.currentTimeMillis());
try {
File dumpFile = new File(dumpFilePath);
mDumpAllOutputStream = new FileOutputStream(dumpFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

private void stopDumpAllAudioData() {
if (!mDumpAllAudioing) {
return;
}
mDumpAllAudioing = false;
mBtnDumpAll.setText("DumpAudioPCM");
ITMGAudioDataObserver.GetInstance().UnRegisteAudioDataCallback();
try {
mDumpAllOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
mDumpAllOutputStream = null;
}
}
Toggle dumpMicToggle = transform.Find("DumpMicToggle").gameObject.GetComponent<Toggle>();
if (dumpMicToggle)
{
dumpMicToggle.onValueChanged.AddListener(delegate (bool value) {
OnDumpMicToggle(value);
});
}


public void OnDumpMicToggle(bool isOn)
{
if (isOn)
{
int nRet = ITMGAudioDataObserver.GetInstance().RegisteAudioDataCallback(Audio_Data_Type.AUDIO_DATA_TYPE_CAPTURE);
Debug.Log("RegisteAudioDataCallback AUDIO_DATA_TYPE_CAPTURE ret---:" + nRet);
if (nRet == 0 && mDumpMicOutputStream == null)
{
mDumpMicOutputStream = new FileStream(Application.persistentDataPath + "/Dump_Mic.pcm", FileMode.Create);
}
}
else
{
ITMGAudioDataObserver.GetInstance().UnRegisteAudioDataCallback(Audio_Data_Type.AUDIO_DATA_TYPE_CAPTURE);
if(mDumpMicOutputStream != null)
{
mDumpMicOutputStream.Close();
mDumpMicOutputStream = null;
}
}
}




回调处理

开始获取音频原数据后,数据会通过回调返回。

参数

回调中的参数及含义如下:
参数
类型
含义
audioDatType
int
音频原数据类型。
timestamp
long
音频原数据时间戳,用于音频帧处理。
sampleRate
int
音频原数据采样率。
channelCount
int
音频原数据声道数。
bitsType
int
音频原数据比特,一般为16000。
pcmData
byte[]
音频原数据,PCM格式。

示例代码

Objective-C
Java
unity

- (void)pCaptureChanged:(UISwitch *)sender {
if (sender.on) {
NSString *pathName = [NSString stringWithFormat:@"capture_%ld.pcm",(long)[[NSDate date] timeIntervalSince1970] * 1000];
NSString *path = [self pcmPath:pathName];
capFile = fopen(path.UTF8String, "wb");
[[ITMGAudioDataObserver GetInstance] RegisteAudioDataCallback:^(int audioDatType, unsigned long long timestamp, unsigned int sampleRate, unsigned int channelCount, int bitsType, unsigned int length, char * pcmData) {
if (capFile) {
fwrite(pcmData, sizeof(char), length, capFile);
}
}];
} else {
[[ITMGAudioDataObserver GetInstance] UnRegisterAudioDataCallback];
if (capFile) {
fclose(capFile);
capFile = NULL;
}
}
}
private FileOutputStream mDumpAllOutputStream;

public void OnAudioDataCallback(int audioDatType, long timestamp, int sampleRate, int channelCount, int bitsType, byte[] pcmData) {
if(audioDatType == AUDIO_DATA_TYPE_CAPTURE_PLAY && mDumpAllOutputStream != null) {
try {
mDumpAllOutputStream.write(pcmData);
} catch (IOException e) {
e.printStackTrace();
}
}
}
ITMGAudioDataObserver.GetInstance().OnAudioDataCallback += new QAVAudioDataCallback(OnAudioDataCallback);


private void OnAudioDataCallback(Audio_Data_Type audioDatType, UInt64 timestamp, uint sampleRate, uint channelCount, uint bitsType, byte[] pcmData)
{
Debug.Log(string.Format(
"OnAudioDataCallback, audioDatType:{0} timestamp:{1} sampleRate:{2} channelCount:{3} bitsType:{4}",
audioDatType, timestamp, sampleRate, channelCount, bitsType));
switch (audioDatType)
{
case Audio_Data_Type.AUDIO_DATA_TYPE_CAPTURE:
if (mDumpMicOutputStream != null)
{
mDumpMicOutputStream.Write(pcmData, 0, pcmData.Length);
mDumpMicOutputStream.Flush();
}
break;
case Audio_Data_Type.AUDIO_DATA_TYPE_CAPTURE_PLAY:
if (mDumpAllOutputStream != null)
{
mDumpAllOutputStream.Write(pcmData, 0, pcmData.Length);
mDumpAllOutputStream.Flush();
}
break;
case Audio_Data_Type.AUDIO_DATA_TYPE_LOOPBACK:
if (mDumpLoopBackOutputStream != null)
{
mDumpLoopBackOutputStream.Write(pcmData, 0, pcmData.Length);
mDumpLoopBackOutputStream.Flush();
}
break;
default:
break;
}
}
}


帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈