Unity 語音通話功能

一、錄製語音

Unity自帶Api

    public RecognizeVoice()
    {
        string[] microPhoneName = Microphone.devices;
        if(microPhoneName.Length > 0)
        {
            _microphone = microPhoneName[0];
        }
        gotsamples = 0;
    }

    public void StartRecognize()
    {
        _audioclip = Microphone.Start(_microphone, true, time, frequency);
    }

首先獲取設備,然後設置錄製時長,是否循環(超過時長,自動覆蓋之前數據,因爲數據實時傳遞的,設置爲true節省空間,時間可以設置長一點,放置有卡頓,數據丟失),frequency採樣率(越大精確,但是數據量大,可能丟包之類的,unity推薦錄製採樣率是44100)。


    public byte[] GetAudioData()
    {
        int audioPos = Microphone.GetPosition(_microphone);
        
        if (gotsamples == time * frequency)  //獲取到數據的最後一位了
            gotsamples = 0;
        
        float[] samples = null;

        if (gotsamples < audioPos)    //正常循環情況
        {
            samples = new float[(audioPos - gotsamples) * _audioclip.channels];
            _audioclip.GetData(samples, gotsamples);
            gotsamples = audioPos;
        }
        else if(audioPos < gotsamples)   //循環過圈的情況
        {
            samples = new float[(time * frequency - gotsamples) * _audioclip.channels];
            _audioclip.GetData(samples, gotsamples);
            gotsamples = time * frequency;
        }
       
        if (samples != null)
        {
            byte[] _bytedata = Float2Byte(samples);
            return CompressByteToByte(_bytedata);
        }
        return null;
    }

記錄讀取數據的位置這是關鍵

二、音頻轉byte[]

AudioClip中的數據保存是使用float[]的形式,因此需要轉換,具體轉換方式,看我之前的一篇文章AudioClip 和 byte[]的轉換解析

三、通信壓縮

直接傳遞byte[] 數據太大,肯定會有卡頓,而且我的項目用的UDP,所以數據不能太大。因爲傳遞前需要將數據壓縮,收到數據後再解壓 使用了ICSharpCode.SharpZipLib。壓縮後小一半,不知道有其他好用的壓縮插件沒有。

GITHUB地址  這是插件的VS工程,複雜的一些壓縮操作可能查看原工程。

 public byte[] CompressByteToByte(byte[] inputBytes)
    {
        MemoryStream ms = new MemoryStream();
        Stream stream = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(ms);
        try
        {
            stream.Write(inputBytes, 0, inputBytes.Length);
        }
        finally
        {
            stream.Close();
            ms.Close();
        }
        return ms.ToArray();
    }

public byte[] DecompressByteToByte(byte[] inputBytes)
    {
        MemoryStream ms = new MemoryStream(inputBytes);
        Stream sm = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(ms);
        byte[] data = new byte[sm.Length];
        int count = 0;
        MemoryStream re = new MemoryStream();
        while ((count = sm.Read(data, 0, data.Length)) != 0)
        {
            re.Write(data, 0, count);
        }
        sm.Close();
        ms.Close();
        return re.ToArray();
    }

這是我的壓縮和解壓。因爲還沒有實際完成項目,所以具體效果不太清楚,等我後期再更新吧。

四、網絡傳輸

我的項目採用的UDP,這一部分可以看我之前的文章Unity UDP局域網廣播 組播 Android

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章