最近使用gvoice的小隊語音 一些坑和感悟《一》
阿新 • • 發佈:2019-01-08
騰訊語音外掛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 為說話狀態,其他為沉默狀態