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

发布了31 篇原创文章 · 获赞 2 · 访问量 2766

猜你喜欢

转载自blog.csdn.net/BDDNH/article/details/104498099