2013-12-08 4 views
2

Я пытаюсь сделать приложение для видеоконференций (написанное на C#), которое позволит 2 пользователям видеоконференции с использованием TCP. Кроме того, пользователи могут отправлять текстовый чат отдельно. Прямо сейчас у меня есть рабочий видеопоток, но пока нет звука. Я не знаю, как получить доступ к микрофону, передать его с помощью TCP, а затем воспроизвести его на динамиках других пользователей, поскольку я относительно новичок в C# и новичок в использовании носителей.Попытка потока 2-way аудио через TCP?

Если кто-нибудь может указать мне на образец кода, помочь мне узнать, как получить доступ к микрофону или что-то еще, что, по вашему мнению, мне поможет, это было бы здорово.

Я прикрепляю свой код как для справки.

WEBCAM.cs

using System; 
using System.IO; 
using System.Linq; 
using System.Text; 
using WebCam_Capture; 
using System.Windows.Controls; 
using System.Collections.Generic; 
using System.Windows.Media.Imaging; 
using System.Net; 
using System.Net.Sockets; 
using System.Windows; 

namespace DuckTalk 
{ 

class WebCam 
{  
    const int TEXT_VIDEO_NUM = 45674; 
    private System.Windows.Controls.TextBox _hostIpAddressBox; 


    private WebCamCapture webcam; 
    private int FrameNumber = 30; 





    public void InitializeWebCam(ref System.Windows.Controls.TextBox hostIpAddressBox) 
    { 

     webcam = new WebCamCapture(); 
     webcam.FrameNumber = ((ulong)(0ul)); 
     webcam.TimeToCapture_milliseconds = FrameNumber; 
     webcam.ImageCaptured += new WebCamCapture.WebCamEventHandler(webcam_ImageCaptured); 


     _hostIpAddressBox = hostIpAddressBox;    
    } 



    void webcam_ImageCaptured(object source, WebcamEventArgs e) 
    { 
     TcpClient connection = null; 
     NetworkStream stream = null; 
     byte[] imgBytes; 

     try 
     { 
      //Set up IPAddress 
      IPAddress ipAddress = IPAddress.Parse(_hostIpAddressBox.Text); 
      IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, TEXT_VIDEO_NUM); 

      //Connect to TCP 
      connection = new TcpClient(); 
      connection.Connect(ipLocalEndPoint); 

      // Get a client stream for reading and writing. 
      stream = connection.GetStream(); 

      //Send image as bytes 
      imgBytes = ImageByteConverter.ImageToBytes((System.Drawing.Bitmap)e.WebCamImage); 
      stream.Write(imgBytes, 0, imgBytes.Length); 
     } 
     catch (Exception error) 
     { 
      MessageBox.Show("ERROR: " + error.Message); 
     } 
     finally 
     { 
      // Close everything. 
      if (connection != null) 
       connection.Close(); 

      if (stream != null) 
       stream.Close(); 
     }    
    } 


    public void Start() 
    { 
     webcam.TimeToCapture_milliseconds = FrameNumber; 
     webcam.Start(0); 
    } 


    public void Stop() 
    { 
     webcam.Stop(); 
    } 

} 
} 

ImageByteConverter.cs

using System; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.Collections.Generic; 
using System.Windows.Media.Imaging; 


namespace DuckTalk 
{ 
class ImageByteConverter 
{    
    public static byte[] ImageToBytes(System.Drawing.Bitmap bitmap) 
    { 
     byte[] byteArray; 

     using (MemoryStream stream = new MemoryStream()) 
     { 
      bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
      stream.Close(); 

      byteArray = stream.ToArray(); 
     } 

     return byteArray; 
    } 

    public static BitmapImage BytesToImage(byte[] imgBytes) 
    { 
     var image = new BitmapImage(); 

     image.BeginInit(); 
     image.StreamSource = new System.IO.MemoryStream(imgBytes); 
     image.EndInit(); 

     return image; 
    } 
} 
} 

Window1.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.ComponentModel; 
using System.Net; 
using System.Net.Sockets; 

namespace DuckTalk 
{ 
/// <summary> 
/// Interaction logic for Window1.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    const int TEXT_PORT_NUM = 45673; 
    const int TEXT_VIDEO_NUM = 45674; 
    WebCam webcam; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void mainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e) 
    { 
     webcam = new WebCam(); 
     webcam.InitializeWebCam(ref xaml_hostTextBox); 

     var _backgroundIMWorker = new BackgroundWorker(); 
     var _backgroundVidWorker = new BackgroundWorker(); 

     _backgroundIMWorker.WorkerReportsProgress = true; 
     _backgroundVidWorker.WorkerReportsProgress = true; 

     // Set up the Background Worker Events 
     _backgroundIMWorker.DoWork += new DoWorkEventHandler(keepListeningForInstantMessages); 
     _backgroundVidWorker.DoWork += new DoWorkEventHandler(keepListeningForVideoMessages); 

     // Run the Background Workers 
     _backgroundIMWorker.RunWorkerAsync(); 
     _backgroundVidWorker.RunWorkerAsync(); 
    } 

    /////////////////////////////////////////////////////////////////////////////////////////////// 
    // 
    // 
    // The next 2 functions take care of the instant messaging part of the program 
    // 
    // 
    // 
    /////////////////////////////////////////////////////////////////////////////////////////////// 
    private void keepListeningForInstantMessages(object sender, DoWorkEventArgs e) 
    { 
     Action<string> displayIncomingMessage = (incomingMsg) => 
     { 
      xaml_incomingTextBox.Text += "\n\nINCOMING MESSAGE: " + incomingMsg; 
      xaml_incomingTextScroll.ScrollToBottom(); 
     }; 

     Socket connection; 
     Byte[] data; 
     String msg; 

     // create the socket 
     Socket listenSocket = new Socket(AddressFamily.InterNetwork, 
             SocketType.Stream, 
             ProtocolType.Tcp); 

     // bind the listening socket to the port 
     IPEndPoint ep = new IPEndPoint(IPAddress.Any, TEXT_PORT_NUM); 
     listenSocket.Bind(ep); 

     while (true) 
     { 
      msg = ""; 
      data = new Byte[3000]; 

      // start listening 
      listenSocket.Listen(1); 

      //Received a connection 
      connection = listenSocket.Accept(); 

      //Get Data 
      connection.Receive(data); 

      //Get the message in string format 
      msg = System.Text.Encoding.Default.GetString(data); 
      msg = msg.Substring(0,msg.IndexOf((char)0)); 

      //Send message to the UI 
      xaml_incomingTextBox.Dispatcher.BeginInvoke(displayIncomingMessage, msg); 

      connection.Close(); 
     } 
    }//end of keepListeningForInstantMessages 

    void SendInstantMsg(object sender, RoutedEventArgs e) 
    { 
     TcpClient connection = null; 
     NetworkStream stream = null; 
     byte[] data; 

     xaml_incomingTextBox.Text += "\n\nOUTGOING MESSAGE: " + xaml_outgoingTextBox.Text; 

     try 
     { 
      //Set up IPAddress 
      IPAddress ipAddress = IPAddress.Parse(xaml_hostTextBox.Text); 
      IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, TEXT_PORT_NUM); 

      //Connect to TCP 
      connection = new TcpClient(); 
      connection.Connect(ipLocalEndPoint); 

      //Convert text to bytes 
      data = System.Text.Encoding.ASCII.GetBytes(xaml_outgoingTextBox.Text);        

      // Get a client stream for reading and writing. 
      stream = connection.GetStream(); 

      // Send the message to the connected TcpServer. 
      stream.Write(data, 0, data.Count()); 

      xaml_outgoingTextBox.Text = ""; 
     } 
     catch (Exception error) 
     { 
      MessageBox.Show("ERROR: " + error.Message); 
     } 
     finally 
     { 
      // Close everything. 
      if (connection != null) 
       connection.Close(); 

      if (stream != null) 
       stream.Close(); 
     } 
    }//end of SendInstantMsg 

    /////////////////////////////////////////////////////////////////////////////////////////////// 
    // 
    // 
    // The next 2 functions take care of the video part of the program 
    // 
    // 
    // 
    /////////////////////////////////////////////////////////////////////////////////////////////// 
    private void keepListeningForVideoMessages(object sender, DoWorkEventArgs e) 
    { 
     Action<Byte[]> displayIncomingVideo = (incomingImgBytes) => 
     { 
      xaml_incomingVideo.Source = ImageByteConverter.BytesToImage(incomingImgBytes); 
     }; 

     Socket connection; 
     Byte[] incomingBytes; 
     Byte[] data; 
     int offset; 
     int numOfBytesRecieved; 

     // create the socket 
     Socket listenSocket = new Socket(AddressFamily.InterNetwork, 
             SocketType.Stream, 
             ProtocolType.Tcp); 

     // bind the listening socket to the port 
     IPEndPoint ep = new IPEndPoint(IPAddress.Any, TEXT_VIDEO_NUM); 
     listenSocket.Bind(ep); 

     while (true) 
     { 
      offset = 0; 
      numOfBytesRecieved = -1; 
      incomingBytes = new Byte[300000]; 

      // start listening 
      listenSocket.Listen(1); 

      //Received a connection 
      connection = listenSocket.Accept(); 

      //Get all the data from the connection stream 
      while (numOfBytesRecieved != 0) 
      { 
       numOfBytesRecieved = connection.Receive(incomingBytes, offset, 10000, SocketFlags.None); 

       offset += numOfBytesRecieved; 
      } 

      data = new Byte[offset]; 
      Array.Copy(incomingBytes, data, offset); 

      //Send image to the UI 
      xaml_incomingTextBox.Dispatcher.BeginInvoke(displayIncomingVideo, data); 

      connection.Close(); 
     } 
    }//end of keepListeningForVideoMessages 


    private void SendVideoMsg(object sender, RoutedEventArgs e) 
    { 
     xaml_incomingVideo.Visibility = Visibility.Visible; 
     xaml_StopVideoButton.Visibility = Visibility.Visible; 
     xaml_SendTextButton.Visibility = Visibility.Hidden; 
     webcam.Start(); 
    } 


    private void StopVideoMsg(object sender, RoutedEventArgs e) 
    { 
     xaml_incomingVideo.Visibility = Visibility.Hidden; 
     xaml_StopVideoButton.Visibility = Visibility.Hidden; 
     xaml_SendTextButton.Visibility = Visibility.Visible; 
     webcam.Stop(); 
    } 

}//end of Class 
}//end of NameSpace 
+2

'Я относительно новым для C# и совершенно новый для использования media' Затем я рекомендовал бы искать какие-то библиотеки. Было бы трудно написать это с нуля. –

ответ

0

Вы должны попытаться загрузить NAudio, он является открытым исходным кодом аудио библиотека. Он поставляется с демонстрацией о том, как передавать аудио, используя UDP от одного компьютера к другому; он находится в приложении NAudioDemo под названием «Сетевой чат».

http://naudio.codeplex.com/

TCP, который вы используете на самом деле не рекомендуется для аудио. Использование UDP вместо

http://www.onsip.com/about-voip/sip/udp-versus-tcp-for-voip

В качестве альтернативы, если вы не хотите изобретать велосипед (я не уверен, что ваша конечная цель вашего проекта), вы можете попытаться загрузить наш iConf.NET видеоконференций SDK, что делает большую часть работы ноги для вас (но не бесплатно)

http://avspeed.com/

Смежные вопросы