Click here to Skip to main content
15,896,912 members
Articles / Web Development / ASP.NET

Your First Step to the Silverlight Voice/Video Chatting Client/Server

Rate me:
Please Sign up or sign in to vote.
4.85/5 (44 votes)
15 Dec 2013CPOL5 min read 343.7K   22.6K   188  
What you should to do to create your own Silverlight Voice/Video chatting system
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net.Sockets;
using VoiceEncoder;
using System.IO;
using System.Threading;

namespace SocketCoder_VoiceChat
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

       #region Global Declarations
        private CaptureSource _source = new CaptureSource();
        private PcmToWave _pcm = new PcmToWave();
        private MemoryAudioSink _sink;
        private bool _isRecording;
        private bool _isConnected = false;
        private Socket _client_socket;
        private delegate void mydelegate(byte[] buffer);
        private delegate void ShowMessagedelegate(string MSG);
        private delegate void Enabledelegate(bool value);

        private int BufferSize = 15840;
        #endregion Global Declarations

       #region Socket Methods
        void Conncet(string IP_Address)
        {
            _client_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs()
            {
                RemoteEndPoint = new IPEndPoint(IPAddress.Parse(IP_Address), 4530)
            };
            socketEventArg.Completed += OnConncetCompleted;
            _client_socket.ConnectAsync(socketEventArg);
        }

        void Send_Bytes(byte[] buffer)
        {
            _client_socket.NoDelay = true;
                
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.Completed += OnSendCompleted;
            socketEventArg.SetBuffer(buffer, 0, buffer.Length);
            _client_socket.SendAsync(socketEventArg);
            
        }

        void StartReceiving()
        {
            byte[] response = new byte[BufferSize];
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.Completed += OnReceiveCompleted;
            socketEventArg.SetBuffer(response, 0, response.Length);
            _client_socket.ReceiveAsync(socketEventArg);
        }
        void OnConncetCompleted(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                this.Dispatcher.BeginInvoke(new ShowMessagedelegate(ShowMessageBox), "Connceted Successfully!");
                this.Dispatcher.BeginInvoke(new Enabledelegate(EnableControl), true);
                
            }
            else
            {
                this.Dispatcher.BeginInvoke(new ShowMessagedelegate(ShowMessageBox), e.SocketError.ToString());
                this.Dispatcher.BeginInvoke(new Enabledelegate(EnableControl), false);
            }

        }
        void OnSendCompleted(object sender, SocketAsyncEventArgs e)
        {

        }
        void OnReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
            this.Dispatcher.BeginInvoke(new mydelegate(PlayReceivedBuffer), e.Buffer);
            
        }
        #endregion Socket Methods

       #region Encoding/Decoding Methods

        void StartRecording()
        {
            try
            {
                if (!_isRecording)
                {
                    _source = new CaptureSource();
                    if ((CaptureDeviceConfiguration.AllowedDeviceAccess | CaptureDeviceConfiguration.RequestDeviceAccess()) & (_source.State == CaptureState.Stopped))
                    {

                        _sink = new MemoryAudioSink();

                        if (_source.AudioCaptureDevice.SupportedFormats.Count >= 10)
                        {
                            AudioFormat audioFormat = _source.AudioCaptureDevice.SupportedFormats[10];
                            VoiceCompLB.Content = "Format " + (audioFormat.BitsPerSample.ToString() + " Bits, " + audioFormat.Channels.ToString() + " Channel, " + audioFormat.SamplesPerSecond.ToString() + " Samples On G.711");
                            _source.AudioCaptureDevice.DesiredFormat = audioFormat;
                        }
                        else ShowMessageBox("Your sound device may do not support (16 bits,8000 samples,1 channel) please try to find this Audio Compression in SupportedFormats collection!");

                        _sink.OnBufferFulfill += new EventHandler(SendVoiceBuffer);

                        _sink.CaptureSource = _source;
                        _source.Start();
                        _isRecording = true;
                    }

                }
            }
            catch (Exception ex) { 
            ShowMessageBox("Your sound device may in use! " + ex.Message);
            }
        }
        void SendVoiceBuffer(object VoiceBuffer, EventArgs e)
        {

            byte[] PCM_Buffer = (byte[])VoiceBuffer;
            byte[] Encoded = VoiceEncoder.G711Audio.ALawEncoder.ALawEncode(PCM_Buffer);

            Send_Bytes(Encoded);
            this.Dispatcher.BeginInvoke(new ShowMessagedelegate(ShowBufferSize), Encoded.Length.ToString());

        }
        void StopRecording()
        {
            if (_source.State == CaptureState.Started)
            {
                _source.Stop();
                _isRecording = false;
                _sink.StartSending = false;
                StartSendingBTN.IsEnabled = true;
                StopSendingBT.IsEnabled = false;
            }
        }
        void OpenWavFile()
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog().Value)
            {
                Stream s = ofd.File.OpenRead();
                WaveMediaStreamSource wavMss = new WaveMediaStreamSource(s);
                mediaElement1.SetSource(wavMss);
                mediaElement1.Play();
            }
        }

        void SaveTheVoiceSession() 
        {
            // To DO In the Next Version: to record the voice session
            // Just Need to create a new stream object to 
            // collect the incoming/outgoing voice streams

            //    SaveFileDialog SaveDialog = new SaveFileDialog();

            //    SaveDialog.Filter = "Audio Files (*.wav)|*.wav";

            //    SaveDialog.ShowDialog();

            //    try
            //    {
            //        using (Stream filestream = SaveDialog.OpenFile())
            //        {

            //            _pcm.SavePcmToWav(_sink._stream, filestream,_sink._format);
            //        }
            //   
            //    catch (Exception){}
            //}
        }

        private void PlayReceivedBuffer(byte[] Encodedbuffer)
        {
            if (MuteCheckBox.IsChecked == false)
                try
                {
                    //Decode to Wave Format Then Play
                    byte[] DecodedBuffer = new byte[Encodedbuffer.Length * 2];
                    VoiceEncoder.G711Audio.ALawDecoder.ALawDecode(Encodedbuffer, out DecodedBuffer); ;
                    PlayWave(DecodedBuffer);
                    
                }
                catch (Exception) { }

                StartReceiving();
        }

        void PlayWave(byte[] PCMBytes)
        {
            MemoryStream ms_PCM = new MemoryStream(PCMBytes);
            MemoryStream ms_Wave = new MemoryStream();

            _pcm.SavePcmToWav(ms_PCM, ms_Wave,16,8000,1);

            WaveMediaStreamSource WaveStream = new WaveMediaStreamSource(ms_Wave);
            mediaElement1.SetSource(WaveStream);
            mediaElement1.Play();
        }
        private void ShowBufferSize(string Buffer_Size)
        {
            BufferSizeLB.Content = Buffer_Size;
        }
        #endregion Encoding/Decoding Methods

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            button1.IsEnabled = false;
            button3.IsEnabled = true;

            StartRecording();
        }
        private void ConnectBTN_Click(object sender, RoutedEventArgs e)
        {
            if (IPAddress_TXT.Text != "")
            {
                Conncet(IPAddress_TXT.Text);
                
            }
            else ShowMessageBox("The Server IP is required!");
        }
        private void ShowMessageBox(string MSG)
        {
            MessageBox.Show(MSG);
        }
        private void EnableControl(bool value)
        {
            button1.IsEnabled = value;
            ListeningBTN.IsEnabled = value;
            _isConnected = value;
            MuteCheckBox.IsEnabled = value;
        }

        private void StopSendingBT_Click(object sender, RoutedEventArgs e)
        {
            _sink.StartSending = false;
            StartSendingBTN.IsEnabled = true;
            StopSendingBT.IsEnabled = false;
        }

        private void StartSendingBTN_Click(object sender, RoutedEventArgs e)
        {
            if (_isRecording)
            {
                BufferSizeLB.Content = (BufferSize).ToString();
                _sink.StartSending = true;
                StartSendingBTN.IsEnabled = false;
                StopSendingBT.IsEnabled = true;
            }
            else ShowMessageBox("Please Press On Start The Microphone Firstly!");
        }
        private void button3_Click(object sender, RoutedEventArgs e)
        {
            button1.IsEnabled = true;
            StopRecording();
        }

        private void ListeningBTN_Click(object sender, RoutedEventArgs e)
        {
            if (_isConnected)
            {
                StartReceiving();
                ListeningBTN.IsEnabled = false;
                BufferSizeLB.Content = BufferSize.ToString();
                StartSendingBTN.IsEnabled = true;
            }
            else ShowMessageBox("Sorry but you are not Connected!");

        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Systems Engineer SocketCoder.Com
Jordan Jordan
Fadi Abdelqader
WebSite: http://www.SocketCoder.com
Facebook Group: http://www.facebook.com/groups/socketcoder/
Facebook Page: http://www.facebook.com/socketcoders/

Last Published Book:
-Professional Network, Distributed Systems & TCP/IP Programming In .NET Framework 1.1 & 2.0 (2006 Release)

Last Published eBook:
- The SocketCoder e-Reference For Network, Distributed Systems And TCP/IP Programming In .NET, Arabic (SocketCoder.Com 2010)

Last Projects:
- Silverlight Based Projects For Web Video Conferencing (WCS,WMS,WCS Plus..)
-(SocketCoder) RTP Multicasting VOIP Library
-(SocketCoder) Remote Controlling Systems

Last SocketCoder RSS: http://www.socketcoder.com/feed/

http://www.socketcoder.com

Comments and Discussions