腾讯语音插件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 为说话状态,其他为沉默状态

         提供一下源码连接:封装包