c#基於udp實現的p2p語音交談工具

來源:互聯網
上載者:User

原創性申明

此博文的出處 為 http://www.php.cn/如果進行轉載請註明出處。本文作者原創,郵箱zhujunxxxxx@163.com,如有問題請聯絡作者

概述

之前發過一篇文章http://www.php.cn/ 已經實現過了UDP的分包發送資料的功能,而這篇文章主要是一個應用,使用udp傳送語音和文本等資訊。在這個系統中沒有服務端和用戶端,相互連訊都是直接相互聯絡的。能夠很好的實現效果。

語音擷取

要想發送語音資訊,首先得擷取語音,這裡有幾種方法,一種是使用DirectX的DirectXsound來錄音,我為了簡便使用一個開源的外掛程式NAudio來實現語音錄取。 在項目中引用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();        }

上面的代碼實現了錄音,並且寫入檔案p2psound_A.wav

語音發送

擷取到語音後我們要把語音發送出去

當我們錄好音後點擊發送,這部分相關代碼是

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


如此一來我們就把產生的語音檔案發送出去了

語音的接收與播放

其實語音的接收和簡訊的接收沒有什麼不同,只不過語音發送的時候是以二進位發送的,因此我們在收到語音後 就應該寫入到一個檔案裡面去,接收完成後,播放這段語音就行了。

下面這段代碼主要是把收到的資料儲存到檔案中去,這個函數式我的NetFrame裡收到訊息時所觸發的事件,在文章前面提過的那篇文章裡


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


收到語音訊息後,我們要進行播放,播放時仍然用剛才那個外掛程式播放

//--------播放部分----------        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);        }



在上面示範了接收和發送一段語音訊息的介面

技術總結

主要用到的技術就是UDP和NAudio的錄音和播放功能

以上就是c#基於udp實現的p2p語音交談工具的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.