一、錄製語音
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