前言:
之前用的GCloudVoice,一个很坑的SDK。后来用着用着突然发现不能用了,神奇!然后去登录控制台一查,发现腾讯把这个东西的相关网页从腾讯云平台上删除了。现在只能在百度上面搜到他的原始网页,不过这些也不重要了,只要知道现在就用新的语音SDK:GME(游戏多媒体引擎)就好了。
OK,在删除了腾讯云语音之后,现在开始重新学习新的SDK。
正文:
1、新的SDK接入
首先从官网上下载新的SDK文件和Demo:
通过参阅官方文档,新版的SDK接入方便了许多,至少不用写安卓文件来调用,只要把SDK丢进去就好了。就这一点上,就不知比GCloudVoice高到哪里去了。
PS:现在貌似还可以领100块钱的代金券, 不知道后面还有没有。
2、申请应用
去GME的控制台注册一个应用,当然,这个也是接入这类SDK的常规操作了。
3、导入SDK文件
将SDK中Plugins的文件分别导入进我们自己的工程去:
然后是脚本部分:
只要报上述两个文件夹分别导入进去就OK了。
另外,在Demo里还有个文件,放在Editor文件夹里面:
看了下,大概是打包出IOS需要的东西。既然这样也一并导入算了,反正也没什么关系,总之IOS比较矫情要各种处理就对了。不过要注意的是,这个东西打包进工程之后,那个BuildScript的代码要自己改一改。你打开之后就发现这个是哪个Demo的设置,要设置成你自己项目的东西就OK了。
不过我看了下这个文件,貌似本身并没有什么用,就设置设置包名打包而已。如果你的项目已经有了打包的相关管理,可以把这个类删了也无所谓。
另外,在Demo里的QAVThreadHelper.cs这个类也需要导入。
4、在自己项目中启动
完成前三步骤之后,准备工作就算基本完成了,接下来我们需要在代码里启动这个SDK。一边参阅(抄)Demo里面的代码一边写:
/// <summary>
/// 是否启动成功;
/// </summary>
public static bool IsInitSucess { get; private set; }
/// <summary>
/// 初始化
/// </summary>
void Init()
{
try
{
QAVThreadHelper.CreateThreadHelper();
int ret = ITMGContext.GetInstance().Init(appID.ToString(), openID);
if (ret != QAVError.OK)
{
IsInitSucess = false;
Debug.LogError("语音初始化错误:" + ret);
return;
}
IsInitSucess = true;
var authBuffer = QAVAuthBuffer.GenAuthBuffer(appID, null, openID, appKey);
ITMGContext.GetInstance().GetPttCtrl().ApplyPTTAuthbuffer(authBuffer);
//初始化完成;
Debug.Log("语音聊天初始化完成!");
}
catch (Exception ex)
{
Debug.LogError("初始化语音聊天失败!\n" + ex.Message);
IsInitSucess = false;
}
}
这个便是初始化的步骤;
5、事件注册
为了方便调用,可以将ITMGContent的单例写个简单的get函数,下文都直接调用这个:
public ITMGContext iTMGContent { get { return ITMGContext.GetInstance(); } }
进出房间、录音成功/失败都是有回调的,需要进行分别处理:
//所有的回调,返回 ret == 0 表示成功,其余是报错;
//需要比对错误码表进行查证排错;
//进入聊天房间的回调:
iTMGContent.OnEnterRoomCompleteEvent += (int ret, string errInfo) =>{};
//退出聊天房间;
iTMGContent.OnExitRoomCompleteEvent += () =>{};
//房间成员变化;
//eventID 对应 ITMGContext 中的几个静态变量
//EVENT_ID_ENDPOINT_ENTER:成员进入房间
//EVENT_ID_ENDPOINT_EXIT:成员离开房间
//EVENT_ID_ENDPOINT_HAS_AUDIO:成员正在说话
//EVENT_ID_ENDPOINT_NO_AUDIO:成员停止说话
iTMGContent.OnEndpointsUpdateInfoEvent += (int eventID, int count, string[] ArrOpenID) =>{};
注册完回调函数之后就可以调用代码进行进出房间等操作了。
如无说明,一般来讲返回的结果(ret/code)为0时就是操作成功了。
6、进出房间的操作
//进入聊天房间;
//CurChatRoomID 为当前的房间号;
iTMGContent.EnterRoom(CurChatRoomID, ITMGRoomType.ITMG_ROOM_TYPE_FLUENCY,
//退出聊天房间
iTMGContent.ExitRoom();
注意,这里进入房间后并不代表这你就可以聊天了,此时需要手动打开音频的上下行。毕竟有的游戏是进房间就可以快乐说话,有的游戏则是进房间需要一定条件才可以说话。此时调用以下代码:
//开启麦克风;(上行)
int ret = iTMGContent.GetAudioCtrl().EnableMic(true);
//开启听筒;(下行)
ret = iTMGContent.GetAudioCtrl().EnableSpeaker(true);
而在你退出房间的时候,听筒和麦克风都会自动设置为False,所以不必要重复设置了。
7、录音、停止录音
需要注册的回调:
//语音录制完成;
iTMGContent.GetPttCtrl().OnRecordFileComplete += (int code, string filePath) =>{};
上面这个回调似乎没什么鸟用,因为开启录音、停止录音的工作都在本地。调用停止录音的API会返回是否成功,所以似乎没什么必要等待一个异步的回调调用:
//开始录音,当ret返回为0时为成功,其他情况为失败;
//RecordPath 为保存到本地的录音文件地址(.silk)
int ret = iTMGContent.GetPttCtrl().StartRecording(RecordPath);
//结束录音,当ret返回为0时为成功,其他情况为失败;
int ret = iTMGContent.GetPttCtrl().StopRecording();
8、音频文件的上传、下载
需要注册的回调:
//上传语音完成;code == 0 表示成功;
iTMGContent.GetPttCtrl().OnUploadFileComplete += (int code, string filepath, string fileid) =>{};
//下载语音完成;code == 0 表示成功;
iTMGContent.GetPttCtrl().OnDownloadFileComplete += (int code, string filePath, string fileid) =>{};
这里要注意的是fileid这个参数,这个是你的某一条语音消息的唯一ID,这个是需要联网,由SDK返给你的。所以我们在将一条语音消息录制完成上传后,一定要监听上传成功的回调,获取fileid,并将其记录下来。这个fileid将会用在后续的下载、语音转文字等功能。
上传和下载调用以下API:
//上传语音,ret == 0 为成功,其他为失败;
//这里的CureentRecordPath是你进行录制语音时的本地文件地址(.silk);
int ret= iTMGContent.GetPttCtrl().UploadRecordedFile(CureentRecordPath);
//下载语音:这里理论上需要通过异步的回调来判断是否下载成功;
//这里的 Path 是指你下载到本地的文件位置
iTMGContent.GetPttCtrl().DownloadRecordedFile(FileID, Path);
9、音频文件的播放、停止播放
可以选择监听一个语音正常播放完成的回调:
//语音播放完成
iTMGContent.GetPttCtrl().OnPlayFileComplete += (int code, string filepath) =>{};
播放、停止播放的API:
//开始语音播放;ret == 0 为播放成功,其余为失败;
//filePath 为本地录音的文件路径(.silk文件)
int ret = iTMGContent.GetPttCtrl().PlayRecordedFile(filePath);
//停止语音播放;
iTMGContent.GetPttCtrl().StopPlayFile();
10、语音转文字
监听回调消息:
//语音转文字完成,code == 0 为转换成功;
//result 为转换后的文字
iTMGContent.GetPttCtrl().OnSpeechToTextComplete += (int code, string fileID, string result) =>{};
这里的回调函数和之前的GCloudVoice很像,Code就是错误码,0为没有错误;在语音转文字正确的情况下,result就是转换成对应语言的文本。
调用的API如下:
//语音转文字,默认为中文;
iTMGContent.GetPttCtrl().SpeechToText(FileID);
//语音转文字,填入目标语言;
iTMGContent.GetPttCtrl().SpeechToText(FileID,Laguage);
关于填入的Language,可以参考网页:游戏多媒体引擎 语言参数参考列表-客户端 API-文档中心-腾讯云 。总之是有很多语言,不知道是不是都有用。
后记
1、关于打包的问题;
有可能会有如下的报错:
Found plugins with same names and architectures, Assets/Plugins/x86/MediaEngine.dll (ARMv7) and Assets/Plugins/x86_64/MediaEngine.dll (ARMv7). Assign different architectures or delete the duplicate.
UnityEditor.AndroidPluginImporterExtension:CheckFileCollisions(String)
UnityEditorInternal.PluginsHelper:CheckFileCollisions(BuildTarget) (at C:/buildslave/unity/build/Editor/Mono/Plugins/PluginsHelper.cs:25)
UnityEditor.HostView:OnGUI()
这种情况下是因为Plugins里面的文件有冲突了(同样名字的文件出现了2份)。就图上的问题来看,是X86里的东西和X86_64的东西冲突了。这样我们将X86下涉及到的文件,在Unity中设置为如下格式:
这样就OK了。
2、关于蓝牙耳机的问题
貌似GME和蓝牙耳机之间的沟通有些问题,也有可能只是我这个耳机有问题(我用的是小米的蓝牙耳机)。
具体表现是,当我通过GME进入聊天房间之后,貌似GME会占用蓝牙播放通道。如果我之前在播放其他音频(比如说放歌的时候),那么就会突然听不到声音了。但是当我关掉一次GME的上行,然后再开启,或者停止游戏运行重新Play初始化GME一次,就会恢复正常了。
目前在PC调试上出现过这个问题,手机上还没试过。
3、录音上传错误:8193
遇到过这样的问题,电脑上没问题,但是手机上上传录音文件的时候返回错误码8193。
虽然官方的错误码写的是 “上传文件时,文件访问错误”,给出的解决方案是“确保文件存在,保证路径合法性”。看起来像是手机和电脑上的路径不一样导致的。也就是直觉认为路径写错了。
当然如果路径真的错了也可能有这个问题,但是我遇到的是路径并没有填错。
后来排除发现居然是因为系统没有给游戏录音权限导致;后来给游戏开启了录音权限之后,这个问题就没有了。
(错误码表:游戏多媒体引擎 错误码-文档中心-腾讯云)