Heim  >  Artikel  >  Backend-Entwicklung  >  C# P2P-Voice-Chat-Tool basierend auf UDP

C# P2P-Voice-Chat-Tool basierend auf UDP

黄舟
黄舟Original
2018-05-16 16:45:012635Durchsuche

Originalitätserklärung

Die Quelle dieses Blogbeitrags ist http://www.php.cn/ Wenn Sie fertig sind, geben Sie beim Nachdruck bitte die Quelle an. Dieser Artikel ist ein Original des Autors. Senden Sie eine E-Mail an zhujunxxxxx@163.com. Wenn Sie Fragen haben, wenden Sie sich bitte an den Autor

Übersicht

Ich habe schon einmal einen Artikel gepostethttp://www.php.cn / Die UDP-Funktion zum Senden von Daten in Paketen wurde implementiert. In diesem Artikel handelt es sich hauptsächlich um eine Anwendung, die UDP zum Übertragen von Informationen wie Sprache und Text verwendet. In diesem System gibt es keinen Server und keinen Client, und die gegenseitige Kommunikation steht in direktem Zusammenhang miteinander. Kann gute Ergebnisse erzielen.

Spracherfassung

Um eine Sprachnachricht zu senden, müssen Sie zuerst die Stimme abrufen. Es gibt mehrere Methoden, um DirectXSound zu verwenden Einfachheit. Ein Open-Source-Plug-in NAudio zur Implementierung von Sprachaufzeichnungen. Referenz NAudio.dll

//------------------录音相关-----------------------------
        private IWaveIn waveIn;
        private WaveFileWriter writer;


        private void LoadWasapiDevicesCombo()
        {
            var deviceEnum = new MMDeviceEnumerator();
            var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active).ToList();
            comboBox1.DataSource = devices;
            comboBox1.DisplayMember = "FriendlyName";
        }
        private void CreateWaveInDevice()
        {

            waveIn = new WaveIn();
            waveIn.WaveFormat = new WaveFormat(8000, 1);
            waveIn.DataAvailable += OnDataAvailable;
            waveIn.RecordingStopped += OnRecordingStopped;
        }
        void OnDataAvailable(object sender, WaveInEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new EventHandler<WaveInEventArgs>(OnDataAvailable), sender, e);
            }
            else
            {
                writer.Write(e.Buffer, 0, e.BytesRecorded);
                int secondsRecorded = (int)(writer.Length / writer.WaveFormat.AverageBytesPerSecond);
                if (secondsRecorded >= 10)//最大10s
                {
                    StopRecord();
                }
                else
                {
                    l_sound.Text = secondsRecorded + " s";
                }
            }
        }
        void OnRecordingStopped(object sender, StoppedEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<StoppedEventArgs>(OnRecordingStopped), sender, e);
            }
            else
            {
                FinalizeWaveFile();
            }
        }
        void StopRecord()
        {
            AllChangeBtn(btn_luyin, true);
            AllChangeBtn(btn_stop, false);
            AllChangeBtn(btn_sendsound, true);
            AllChangeBtn(btn_play, true);


            //btn_luyin.Enabled = true;
            //btn_stop.Enabled = false;
            //btn_sendsound.Enabled = true;
            //btn_play.Enabled = true;
            if (waveIn != null)
                waveIn.StopRecording();
            //Cleanup();
        }
		private void Cleanup()
        {
            if (waveIn != null)
            {
                waveIn.Dispose();
                waveIn = null;
            }
            FinalizeWaveFile();
        }
        private void FinalizeWaveFile()
        {
            if (writer != null)
            {
                writer.Dispose();
                writer = null;
            }
        }
		 //开始录音
        private void btn_luyin_Click(object sender, EventArgs e)
        {
            btn_stop.Enabled = true;
            btn_luyin.Enabled = false;
            if (waveIn == null)
            {
                CreateWaveInDevice();
            }
            if (File.Exists(soundfile))
            {
                File.Delete(soundfile);
            }

            writer = new WaveFileWriter(soundfile, waveIn.WaveFormat);
            waveIn.StartRecording();
        }
im Projekt. Der obige Code implementiert die Aufnahme und schreibt in die Datei p2psound_A. wav


Sprachübertragung

Nachdem wir die Stimme erhalten haben, müssen wir sie senden raus

Wenn wir das Audio aufnehmen, klicken Sie auf Senden. Der relevante Code für diesen Teil ist

 MsgTranslator tran = null;
 public Form1()
        {
            InitializeComponent();
            LoadWasapiDevicesCombo();//显示音频设备

            Config cfg = SeiClient.GetDefaultConfig();
            cfg.Port = 7777;
            UDPThread udp = new UDPThread(cfg);
            tran = new MsgTranslator(udp, cfg);
            tran.MessageReceived += tran_MessageReceived;
            tran.Debuged += new EventHandler<DebugEventArgs>(tran_Debuged);
        }
		private void btn_sendsound_Click(object sender, EventArgs e)
        {
            if (t_ip.Text == "")
            {
                MessageBox.Show("请输入ip");
                return;
            }
            if (t_port.Text == "")
            {
                MessageBox.Show("请输入端口号");
                return;
            }
            string ip = t_ip.Text;
            int port = int.Parse(t_port.Text);
            string nick = t_nick.Text;
            string msg = "语音消息";

            IPEndPoint remote = new IPEndPoint(IPAddress.Parse(ip), port);
            Msg m = new Msg(remote, "zz", nick, Commands.SendMsg, msg, "Come From A");
            m.IsRequireReceive = true;
            m.ExtendMessageBytes = FileContent(soundfile);
            m.PackageNo = Msg.GetRandomNumber();
            m.Type = Consts.MESSAGE_BINARY;
            tran.Send(m);
        }
		private byte[] FileContent(string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            try
            {
                byte[] buffur = new byte[fs.Length];
                fs.Read(buffur, 0, (int)fs.Length);

                return buffur;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                if (fs != null)
                {

                    //关闭资源
                    fs.Close();
                }
            }
        }

Auf diese Weise haben wir die generierte Sprachdatei gesendet

Empfang und Wiedergabe der Stimme

Eigentlich der Empfang und Sprachwiedergabe Es gibt keinen Unterschied beim Empfang von Textnachrichten, außer dass die Stimme binär gesendet wird. Nach dem Empfang der Stimme sollten wir sie also in eine Datei schreiben. Nachdem der Empfang abgeschlossen ist, spielen Sie einfach die Stimme ab.

Der folgende Code dient hauptsächlich dazu, die empfangenen Daten in einer Datei zu speichern. Dieses Funktionsereignis wird ausgelöst, wenn eine Nachricht in meinem NetFrame empfangen wird


void tran_MessageReceived(object sender, MessageEventArgs e)
        {
            Msg msg = e.msg;

            if (msg.Type == Consts.MESSAGE_BINARY)
            {
                string m = msg.Type + "->" + msg.UserName + "发来二进制消息!";
                AddServerMessage(m);
                if (File.Exists(recive_soundfile))
                {
                    File.Delete(recive_soundfile);
                }
                FileStream fs = new FileStream(recive_soundfile, FileMode.Create, FileAccess.Write);
                fs.Write(msg.ExtendMessageBytes, 0, msg.ExtendMessageBytes.Length);
                fs.Close();
                //play_sound(recive_soundfile);
                ChangeBtn(true);

            }
            else
            {
                string m = msg.Type + "->" + msg.UserName + "说:" + msg.NormalMsg;
                AddServerMessage(m);
            }
        }

Nachdem wir die Sprachnachricht erhalten haben, müssen wir sie abspielen und beim Abspielen immer noch dasselbe Plug-In verwenden Spielen

//--------播放部分----------
        private IWavePlayer wavePlayer;
        private WaveStream reader;


        public void play_sound(string filename)
        {
            if (wavePlayer != null)
            {
                wavePlayer.Dispose();
                wavePlayer = null;
            }
            if (reader != null)
            {
                reader.Dispose();
            }
            reader = new MediaFoundationReader(filename, new MediaFoundationReader.MediaFoundationReaderSettings() { SingleReaderObject = true });

            if (wavePlayer == null)
            {

                wavePlayer = new WaveOut();
                wavePlayer.PlaybackStopped += WavePlayerOnPlaybackStopped;
                wavePlayer.Init(reader);
            }
            wavePlayer.Play();
        }
        private void WavePlayerOnPlaybackStopped(object sender, StoppedEventArgs stoppedEventArgs)
        {
            if (stoppedEventArgs.Exception != null)
            {
                MessageBox.Show(stoppedEventArgs.Exception.Message);
            }
            if (wavePlayer != null)
            {
                wavePlayer.Stop();
            }
            btn_luyin.Enabled = true;
        }private void btn_play_Click(object sender, EventArgs e)
        {
            btn_luyin.Enabled = false;
            play_sound(soundfile);
        }



Die Schnittstelle zum Empfangen und Senden einer Sprachnachricht ist oben dargestellt

Technische Zusammenfassung

Die wichtigsten verwendeten Technologien sind UDP und NAudio Recording und Wiedergabefunktionen

Das Obige ist der Inhalt des in c# basierenden P2P-Voice-Chat-Tools, das auf udp basiert. Weitere verwandte Inhalte finden Sie hier zur chinesischen PHP-Website (www.php.cn)!



Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn