1

我想制作一个应用程序来实时传输笔记本电脑或 PC 中麦克风的音频,就像 YouTube 流一样,但没有视频。我将描述我的过程:

  1. 我通过将普通文件转换为字节然后再返回原点来传输普通文件。
  2. 我将文件类型更改为 MP3 或 wav,然后使用 NAudio。工作正常我也可以在传输或接收时播放文件
  3. 我将输入文件更改为麦克风并接收音频。

问题是:NAudio 无法将来自麦克风的直播流然后自动发送。总是,缓冲区在调试时给了我一个空指针异常,然后它给了我另一个错误,即 NAudio 的解码器没有收到任何数据,“顺便说一句不可接受”。

它应该侦听或继续接收数据,直到端口或连接关闭。

我试图搜索任何关于 VoIP 的库,但除了 Ozeki 之外什么都没有找到,但没有教程可以处理。我发现的只是不起作用的旧视频。我搜索了一个多星期,但没有结果。我不想要一个完全开发的项目,因为我已经找到了一个,但它太复杂了——大约 2K 行代码。我所需要的只是知道该做什么或获得解决问题的代码。

这是客户端代码:

   public void client()
    {
        try
        {
            //byte[] send_data = Audio_to_byte(); // ORIGINAL WORK CODE
            byte[] send_data = new byte [BufferSize]; // 100M buffer size 
            TcpClient client = new TcpClient(serverip, port);
            NetworkStream stream = client.GetStream();
            // sourceStream and wavein is global vars
            sourceStream = new NAudio.Wave.WaveIn();
            sourceStream.DeviceNumber = 1;
            sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(1).Channels);
            wavein = new NAudio.Wave.WaveInProvider(sourceStream);
            //wavein.Read(send_data, 0, send_data.Length); // this buffer not work some times give me full buffer
            BufferedWaveProvider pro = new BufferedWaveProvider(wavein.WaveFormat);
            pro.AddSamples(send_data, 0, send_data.Length); // Empty buffer or error full buffer
            stream.Write(send_data, 0, send_data.Length);
            stream.Close();
            client.Close();

        }
        catch (Exception e)
        {
            MessageBox.Show("Server is offline" + e, "Error");
// Here the message is buffer is full or send it empty then the decoder did not receive anything give exception error or of them happen first
        }
    }

和这个带有 MP3 阅读器代码的服务器端代码

 IPAddress ip = Dns.GetHostEntry(serverip).AddressList[0];
        TcpListener server_obj = new TcpListener(ip,port);
        TcpClient client = default(TcpClient);
        try
        {
            server_obj.Start();
            while (true)
            {
                // accept all client
                client = server_obj.AcceptTcpClient();
                // make byte storage from network
                byte[] received_buffer = new byte[BufferSize];
                //get data from cst
                NetworkStream stream = client.GetStream();
                //save data from network to memory till finish then save with playing
                MemoryStream ms = new MemoryStream();

                int numBytesRead = 0;
               
                while ((numBytesRead = stream.Read(received_buffer, 0, received_buffer.Length)) > 0)
                {
                    // THIS STEP TO RECEIVE ALL DATA FROM CLIENT
                    ms.Write(received_buffer, 0, numBytesRead);
                    //receive sound then play it direct
                    WaveOut(ms.ToArray());
                }

                Byte_to_audio(ms.ToArray()); // YOU can make or allow override
            }
        }
        catch(Exception e)
        {
           MessageBox.Show("Error Message : " + e, "Error");
        }
    }

这是从网络读取流接收数据的方法

       private void WaveOut(byte[] mp3Bytes)
    {
        // MP3 Format
        mp3Stream = new MemoryStream(mp3Bytes);
        mp3FileReader = new Mp3FileReader(mp3Stream);
        wave32 = new WaveChannel32(mp3FileReader, 0.3f, 3f);
        ds = new DirectSoundOut(); // but declration up global
        ds.Init(wave32);
        ds.Play(); // work code*/ 
    }
4

1 回答 1

0

如果必须实时,我建议使用 UDP。

当我将 Nadio 与 vb.net 一起使用时,我以这篇文章为基础。

客户端示例:

waveIn = new WaveIn();
waveIn.BufferMilliseconds = 50; //Milissecondes Buffer
waveIn.DeviceNumber = inputDeviceNumber;
waveIn.WaveFormat = HEREWaveFormatHERE;
waveIn.DataAvailable += waveIn_DataAvailable; //Event to receive Buffer
waveIn.StartRecording();

void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
   //e -> BUFFER

stream.Write(send_data, 0, send_data.Length);
            stream.Close();
            client.Close();

}
  • 收到:

1 - 创建 WaveOut 和 BufferProvider 全局

WOut = New WaveOut(WaveCallbackInfo.FunctionCallback());

BufferedWaveProvider pro = new BufferedWaveProvider(HEREWaveFormatHERE);
pro.BufferLength = 20 * 1024;      //Max Size BufferedWaveProvider
pro.DiscardOnBufferOverflow = True;
WOut.Init(pro);
WOut.Play();

只要没有音频,BufferedWaveProvider 就会为 WaveOut 或其他输出提供静音,它还会将所有到达的内容排队,以进行连续播放。

2 - 播放和排队

while ((numBytesRead = stream.Read(received_buffer, 0, received_buffer.Length)) > 0)
                {
                   pro.AddSamples(received_buffer, 0, numBytesRead);
                }

我对naudio的了解仅限于此

来自谷歌翻译的英语

于 2020-06-24T23:19:22.430 回答