加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读