一、录制语音
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