腾讯语音插件gvoice,基于unity
至于导入插件什么的就不多说,多的是教程,但是详细的使用教程少的可怜,也是踩了好多坑,才算调试通.
新建一个语音模块管理器 GVoiceManager,做成单例方便调用
public static GVoiceManager _Instance;
private IGCloudVoice m_voiceengine; //语音引擎,建议全局唯一
private bool bHaveJoin; //是否已经加入
public bool micEnable;//mic是否可用
private bool micIsOpen;//mic是否打开
private bool listenerOpen;//扬声器
private string CurrentRoomID;//房间号
private bool ReConnected;//是否重新连接房间
private Action TimeEndEvent;//等待结束执行的事件
private float WaitTime;//需要等待时间
初始化,需要的信息有APPkey,AppID,openID(openID建议用户唯一,这里使用模拟的),注册一些事件回调以便监听
m_voiceengine = GCloudVoice.GetEngine();
m_voiceengine.SetAppInfo(GVoiceAppID,GVoiceAppKey, "10000000");
m_voiceengine.Init();
m_voiceengine.OnJoinRoomComplete += OnJoinRoomComplete;
m_voiceengine.OnQuitRoomComplete += OnQuitRoomComplete;
然后关键的是加入房间退出房间等操作
//创建加入语音房间
private void JoinRoom(string roomName)
{
if (!bHaveJoin)//尚未加入房间
{
m_voiceengine.SetMode(GCloudVoiceMode.RealTime);
Debug.Log("加入的房间号:" + roomName);
int ret = m_voiceengine.JoinTeamRoom(roomName, 15000);
if (ret == 8194 || ret == 8193)
{
//bHaveJoin = true;
JoinRoom(roomName);//递归一次,尝试重连
}
}
else
{
if (roomName == CurrentRoomID|| string.IsNullOrEmpty(CurrentRoomID))//重复加入
return;
else
{
if (QuitRoom(CurrentRoomID)!= 0)//加入新房间,先退出
{
Debug.Log("退出失败");
return;
}
CurrentRoomID = roomName;
ReConnected = true;
}
}
}
//退出语音房间
private int QuitRoom(string roomname)
{
if (micIsOpen)
{
m_voiceengine.CloseMic();
}
if (listenerOpen)
{
m_voiceengine.CloseSpeaker();
}
if (bHaveJoin)
{
int ret = m_voiceengine.QuitRoom(roomname, 15000);
Debug.Log("退出房间--" + CurrentRoomID);
CloseListener();
CloseMic();
return ret;
}
return -1;
}
//加入房间结果的回调
private void OnJoinRoomComplete(IGCloudVoice.GCloudVoiceCompleteCode code, string roomName, int memberID)
{
Debugger.Log(GetType(), "加入房间结果-->" + code);
if (code == IGCloudVoice.GCloudVoiceCompleteCode.GV_ON_JOINROOM_SUCC)
{
CurrentRoomID = roomName;
bHaveJoin = true;
OpenListener();
OpenMic();
}else
{
CurrentRoomID = "";
bHaveJoin = false;
}
}
//退出房间结果的回调
private void OnQuitRoomComplete(IGCloudVoice.GCloudVoiceCompleteCode code, string roomName, int memberID)
{
if (code == IGCloudVoice.GCloudVoiceCompleteCode.GV_ON_QUITROOM_SUCC)
{
bHaveJoin = false;//退出后请保证 值为false
//重连
if (ReConnected && !string.IsNullOrEmpty(CurrentRoomID))
{
Debug.Log("尝试重连" + CurrentRoomID);
WaitTime = 1f;
TimeEndEvent = () =>
{
JoinRoom(CurrentRoomID);
ReConnected = false;
};
}
else
{
CurrentRoomID = "";
}
}
else
{
Debug.Log("退出语音房间失败" + code);
}
}
/// <summary>
/// 打开Mic 0是成功,-1是失败, -2是重复打开, -3是不可用
/// </summary>
/// <returns></returns>
public void OpenMic()
{
if (micIsOpen)
{
Debugger.Log(GetType(), "Mic重复打开");
return;
}
int ret = m_voiceengine.OpenMic();//如果成功返回0
if (ret != 0)//失败
{
Debugger.Log(GetType(), "Mic打开失败");
}
else
{
micIsOpen = true;
}
}
/// <summary>
/// 关闭Mic
/// </summary>
/// <returns></returns>
public void CloseMic()
{
if (!micIsOpen)
{
Debugger.Log(GetType(), "无需关闭Mic");
return;
}
int ret = m_voiceengine.CloseMic();
if (ret == 0)
{
micIsOpen = false;
Debugger.Log(GetType(), "Mic关闭成功---" + ret);
}
else
{
Debugger.Log(GetType(), "mic关闭失败");
}
}
/// <summary>
/// 打开扬声器
/// </summary>
/// <returns></returns>
public void OpenListener()
{
if (listenerOpen)
{
Debugger.Log(GetType(), "重复打开扬声器");
return;
}
int ret = m_voiceengine.OpenSpeaker();
if (ret == 0)
{
Debugger.Log(GetType(), "扬声器打开成功");
listenerOpen = true;
}
else
{
Debugger.Log(GetType(), "扬声器打开失败");
}
}
注意要在update中调用pull函数,相当于update
private void Update()
{
if (m_voiceengine != null)
{
m_voiceengine.Poll();
if (WaitTime > 0)
{
WaitTime -= Time.deltaTime;
}
else
{
WaitTime = 0;
if(TimeEndEvent !=null)
{
TimeEndEvent.Invoke();
TimeEndEvent = null;
}
}
}
}
void OnDestroy()
{
QuitRoom(CurrentRoomID);
}
void OnApplicationPause(bool pauseStatus)
{
if (m_voiceengine == null)
{
return;
}
// 应用暂停时GVoice引擎也暂停,应用重新开始时引擎继续
if (pauseStatus)
{
m_voiceengine.Pause();
}
else
{
m_voiceengine.Resume();
}
}
到这里小队语音基本完成。一开始以为退房间直接调用quitroom就行了,后来发现一只无法再进其他房间,最后查证,是需要在退出后等一小段时间大概0.几秒,然后去重新设置语音模式,再加入就ok了,不想设置等待时间就递归,直到加入成功,或者失败的房间回调,在重试
另外关于音量调节的调用的是 SetSpeakerLevel
int state = m_voiceengine.SetSpeakerVolume(volum); 返回值为0成功反之失败
需要注意的是,Windows平台的音量和移动端是不一样的,移动端采用十进制0-800Windows采用16进制0-65535
成员说话的监听
//注册成员状态
private void RegState()
{
Debug.Log("注册监听");
OnMemberVoiceFunc = func;
m_voiceengine.OnMemberVoice += ShowMemberState;
}
private void ShowMemberState(int[] arg1, int count)
{
for (int i = 0; i < 2* count; i+=2)
{
//Debug.Log(arg1[i] + "语音状态改--" + arg1 [i+1]);
//成员说话状态 (除了自己的)
if (roomData.MemberInfos.ContainsKey(arg1[i])&&arg1[i].ToString() !=memberID)
{
GameObject ob = gridTr.Find(arg1[i].ToString()).gameObject;
if (ob != null)
{
ob.transform.Find("Mic").gameObject.SetActive(arg1[i + 1] >1);
}
}
}
}
在退出房间是移除注册,进入房间注册即可。 需要注意的是,参数count是指变化的人数,数组奇数项是成员id,偶数项为对应状态,一般取 》1 为说话状态,其他为沉默状态
提供一下源码连接:封装包