c# – 如何通过Unity3D中的麦克风传输实时音频?
发布时间:2020-12-15 22:16:31 所属栏目:百科 来源:网络整理
导读:到目前为止,这是主要代码的一部分(网络是单独完成的): void Update(){ if (Network.connections.Length 0) { audioFloat = new float[audioInfo.clip.samples * audioInfo.clip.channels]; audioInfo.clip.GetData (audioFloat,0); networkView.RPC("PlayMi
到目前为止,这是主要代码的一部分(网络是单独完成的):
void Update() { if (Network.connections.Length > 0) { audioFloat = new float[audioInfo.clip.samples * audioInfo.clip.channels]; audioInfo.clip.GetData (audioFloat,0); networkView.RPC("PlayMicrophone",RPCMode.Others,ToByteArray(audioFloat),audioInfo.clip.channels); } } [RPC] void PlayMicrophone(byte[] ba,int c) { float[] flar = ToFloatArray (ba); audio.clip = AudioClip.Create ("test",flar.Length,c,44100,true,false); audio.clip.SetData (flar,0); audio.loop = true; while (!(Microphone.GetPosition("") > 0)) {} audio.Play(); } void OnConnectedToServer() { audioInfo.clip = Microphone.Start(null,100,44100); } // When you are the server and the client connected to void OnPlayerConnected(NetworkPlayer player) { audioInfo.clip = Microphone.Start(null,44100); } public byte[] ToByteArray(float[] floatArray) { int len = floatArray.Length * 4; byte[] byteArray = new byte[len]; int pos = 0; foreach (float f in floatArray) { byte[] data = System.BitConverter.GetBytes(f); System.Array.Copy(data,byteArray,pos,4); pos += 4; } return byteArray; } public float[] ToFloatArray(byte[] byteArray) { int len = byteArray.Length / 4; float[] floatArray = new float[len]; for (int i = 0; i < byteArray.Length; i+=4) { floatArray[i/4] = System.BitConverter.ToSingle(byteArray,i); } return floatArray; } 我知道它可能不会播放完美,但我希望即使是一秒钟也能听到最轻微的声音,但它从未发生过.数据似乎正在通过RPC发送,但音频将无法播放. 在Update()函数中,它将不断调用RPC以开始从麦克风播放.在将连接作为客户端或服务器进行连接后会发生这种情况. 由于你不能发送除字节数组之外的任何数组,我将音频数据作为浮点数组,然后转换为字节数组,以发送给连接的其他人.代码运行时没有错误,但声音仍然没有播放. 我们的想法是从各自的播放器麦克风收集完全直播的双向音频.我觉得即使缓冲区只有100秒;到目前为止它仍然应该发出声音. 当时机成熟时,我可能最终会使用循环缓冲区.声音还没有播放. 我尝试使用Here和Here中的示例,但仍然无法生成结果. 非常感谢任何帮助,感谢阅读! 解决方法
我决定回到
here发布的代码并尝试不同的东西.我做的唯一区别是使用FixedUpdate而不是Update,并在建立连接时启动FixedUpdate中的麦克风.使用Update时有很多口吃,所以我选择以0.5秒的间隔使用FixedUpdate并且它可以正常工作.
int lastSample = 0; void FixedUpdate() { // If there is a connection if (Network.connections.Length > 0) { if (notRecording) { notRecording = false; sendingClip = Microphone.Start(null,FREQUENCY); sending = true; } else if(sending) { int pos = Microphone.GetPosition(null); int diff = pos-lastSample; if (diff > 0) { float[] samples = new float[diff * sendingClip.channels]; sendingClip.GetData (samples,lastSample); byte[] ba = ToByteArray (samples); networkView.RPC ("Send",ba,sendingClip.channels); Debug.Log(Microphone.GetPosition(null).ToString()); } lastSample = pos; } } } [RPC] public void Send(byte[] ba,int chan) { float[] f = ToFloatArray(ba); audio.clip = AudioClip.Create("",f.Length,chan,FREQUENCY,false); audio.clip.SetData(f,0); if (!audio.isPlaying) audio.Play(); } // Used to convert the audio clip float array to bytes public byte[] ToByteArray(float[] floatArray) { int len = floatArray.Length * 4; byte[] byteArray = new byte[len]; int pos = 0; foreach (float f in floatArray) { byte[] data = System.BitConverter.GetBytes(f); System.Array.Copy(data,4); pos += 4; } return byteArray; } // Used to convert the byte array to float array for the audio clip public float[] ToFloatArray(byte[] byteArray) { int len = byteArray.Length / 4; float[] floatArray = new float[len]; for (int i = 0; i < byteArray.Length; i+=4) { floatArray[i/4] = System.BitConverter.ToSingle(byteArray,i); } return floatArray; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |