试图通过TCP流2路音频? [英] Trying to stream 2 way audio over TCP?

查看:274
本文介绍了试图通过TCP流2路音频?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使一个视频会议应用程序(C#编写的),将使用TCP允许2用户的视频会议。此外,用户可以单独文字聊天。现在,我有一个工作视频流,但没有音频没有工作。我不确定如何访问麦克风,使用TCP流,然后发挥它在其他用户的发言,因为我是比较新的C#和全新的使用媒体。

如果任何人都可以点我朝着样品code,帮助我知道如何访问麦克风,或其他任何你认为会帮我,那简直太好了。

我附上我的code作为参考。

WEBCAM.cs

 使用系统;
使用System.IO;
使用System.Linq的;
使用System.Text;
使用WebCam_Capture;
使用System.Windows.Controls的;
使用System.Collections.Generic;
使用System.Windows.Media.Imaging;
使用System.Net;
使用的System.Net.Sockets;
使用System.Windows;命名空间DuckTalk
{类摄像头
{
    const int的TEXT_VIDEO_NUM = 45674;
    私人System.Windows.Controls.TextBox _hostIpAddressBox;
    私人WebCamCapture网络摄像头;
    私人INT帧编号= 30;    公共无效InitializeWebCam(参考System.Windows.Controls.TextBox hostIpAddressBox)
    {        摄像头=新WebCamCapture();
        webcam.FrameNumber =((ULONG)(0ul));
        webcam.TimeToCapture_milliseconds =帧编号;
        webcam.ImageCaptured + =新WebCamCapture.WebCamEventHandler(webcam_ImageCaptured);
        _hostIpAddressBox = hostIpAddressBox;
    }    无效webcam_ImageCaptured(对象源,WebcamEventArgs E)
    {
        TcpClient的连接= NULL;
        的NetworkStream流= NULL;
        字节[] imgBytes;        尝试
        {
            //设置ip地址
            ip地址ip地址= IPAddress.Parse(_hostIpAddressBox.Text);
            IPEndPoint ipLocalEndPoint =新IPEndPoint(ip地址,TEXT_VIDEO_NUM);            //连接到TCP
            连接=新的TcpClient();
            connection.Connect(ipLocalEndPoint);            //获取客户流进行读取和写入。
            流= connection.GetStream();            //发送图像作为字节
            imgBytes = ImageByteConverter.ImageToBytes((System.Drawing.Bitmap)e.WebCamImage);
            stream.Write(imgBytes,0,imgBytes.Length);
        }
        赶上(例外错误)
        {
            的MessageBox.show(错误:+返回Error.message);
        }
        最后
        {
            //关闭一切。
            如果(连接!= NULL)
                connection.close()时;            如果(流!= NULL)
                stream.Close();
        }
    }
    公共无效启动()
    {
        webcam.TimeToCapture_milliseconds =帧编号;
        webcam.Start(0);
    }
    公共无效停止()
    {
        webcam.Stop();
    }}
}

ImageByteConverter.cs

 使用系统;
使用System.IO;
使用System.Linq的;
使用System.Text;
使用System.Drawing中;
使用System.Collections.Generic;
使用System.Windows.Media.Imaging;
命名空间DuckTalk
{
类ImageByteConverter
{
    公共静态的byte [] ImageToBytes(System.Drawing.Bitmap位图)
    {
        字节[]的字节数组;        使用(MemoryStream的流=新的MemoryStream())
        {
            bitmap.Save(流System.Drawing.Imaging.ImageFormat.Png);
            stream.Close();            的字节数组= stream.ToArray();
        }        返回的字节数组;
    }    公共静态的BitmapImage BytesToImage(字节[] imgBytes)
    {
        VAR图像=新的BitmapImage();        image.BeginInit();
        image.StreamSource =新System.IO.MemoryStream(imgBytes);
        image.EndInit();        返回形象;
    }
}
}

Window1.xaml.cs

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.Windows;
使用System.Windows.Controls的;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
使用System.ComponentModel;
使用System.Net;
使用的System.Net.Sockets;命名空间DuckTalk
{
///<总结>
///为Window1.xaml交互逻辑
///< /总结>
公共部分类主窗口:窗口
{
    const int的TEXT_PORT_NUM = 45673;
    const int的TEXT_VIDEO_NUM = 45674;
    摄像头摄像头;    公共主窗口()
    {
        的InitializeComponent();
    }    私人无效mainWindow_Loaded(对象发件人,System.Windows.RoutedEventArgs E)
    {
        摄像头=新的摄像头();
        webcam.InitializeWebCam(REF xaml_hostTextBox);        VAR _backgroundIMWorker =新的BackgroundWorker();
        VAR _backgroundVidWorker =新的BackgroundWorker();        _backgroundIMWorker.WorkerReportsProgress = TRUE;
        _backgroundVidWorker.WorkerReportsProgress = TRUE;        //设置背景工人事件
        _backgroundIMWorker.DoWork + =新DoWorkEventHandler(keepListeningForInstantMessages);
        _backgroundVidWorker.DoWork + =新DoWorkEventHandler(keepListeningForVideoMessages);        //运行背景工人
        _backgroundIMWorker.RunWorkerAsync();
        _backgroundVidWorker.RunWorkerAsync();
    }    ////////////////////////////////////////////////// /////////////////////////////////////////////
    //
    //
    //接下来的2个功能照顾程序的即时通讯部分
    //
    //
    //
    ////////////////////////////////////////////////// /////////////////////////////////////////////
    私人无效keepListeningForInstantMessages(对象发件人,DoWorkEventArgs E)
    {
        动作<串GT; displayIncomingMessage =(incomingMsg)= GT;
        {
            xaml_incomingTextBox.Text + =\\ n \\ nINCOMING消息:+ incomingMsg;
            xaml_incomingTextScroll.ScrollToBottom();
        };        Socket连接;
        字节]的数据;
        弦乐味精;        //创建套接字
        插座listenSocket =新的Socket(AddressFamily.InterNetwork,
                                         SocketType.Stream,
                                         ProtocolType.Tcp);        //监听套接字绑定端口
        IPEndPoint EP =新IPEndPoint(IPAddress.Any,TEXT_PORT_NUM);
        listenSocket.Bind(EP);        而(真)
        {
            味精=;
            数据=新的字节[3000];            //开始监听
            listenSocket.Listen(1);            //已接收的连接
            连接= listenSocket.Accept();            //获取数据
            connection.Receive(数据);            //获取字符串格式的消息
            味精= System.Text.Encoding.Default.GetString(数据);
            味精= msg.Substring(0,msg.IndexOf((char)的0));            //发送消息到UI
            xaml_incomingTextBox.Dispatcher.BeginInvoke(displayIncomingMessage,味精);            connection.close()时;
        }
    } // keepListeningForInstantMessages结束    无效SendInstantMsg(对象发件人,RoutedEventArgs E)
    {
        TcpClient的连接= NULL;
        的NetworkStream流= NULL;
        字节[]数据;        xaml_incomingTextBox.Text + =\\ n \\ nOUTGOING消息:+ xaml_outgoingTextBox.Text;        尝试
        {
            //设置ip地址
            ip地址ip地址= IPAddress.Parse(xaml_hostTextBox.Text);
            IPEndPoint ipLocalEndPoint =新IPEndPoint(ip地址,TEXT_PORT_NUM);            //连接到TCP
            连接=新的TcpClient();
            connection.Connect(ipLocalEndPoint);            //将文本转换为字节
            数据= System.Text.Encoding.ASCII.GetBytes(xaml_outgoingTextBox.Text);            //获取客户流进行读取和写入。
            流= connection.GetStream();            //将消息发送给连接的TCPSERVER。
            stream.Write(数据,0,data.Count());            xaml_outgoingTextBox.Text =;
        }
        赶上(例外错误)
        {
            的MessageBox.show(错误:+返回Error.message);
        }
        最后
        {
            //关闭一切。
            如果(连接!= NULL)
                connection.close()时;            如果(流!= NULL)
                stream.Close();
        }
    } // SendInstantMsg结束    ////////////////////////////////////////////////// /////////////////////////////////////////////
    //
    //
    //接下来的2个功能照顾节目的视频部分
    //
    //
    //
    ////////////////////////////////////////////////// /////////////////////////////////////////////
    私人无效keepListeningForVideoMessages(对象发件人,DoWorkEventArgs E)
    {
        动作<字节[]> displayIncomingVideo =(incomingImgBytes)= GT;
        {
            xaml_incomingVideo.Source = ImageByteConverter.BytesToImage(incomingImgBytes);
        };        Socket连接;
        字节] incomingBytes;
        字节]的数据;
        INT抵消;
        INT numOfBytesRecieved;        //创建套接字
        插座listenSocket =新的Socket(AddressFamily.InterNetwork,
                                         SocketType.Stream,
                                         ProtocolType.Tcp);        //监听套接字绑定端口
        IPEndPoint EP =新IPEndPoint(IPAddress.Any,TEXT_VIDEO_NUM);
        listenSocket.Bind(EP);        而(真)
        {
            偏移量= 0;
            numOfBytesRecieved = -1;
            incomingBytes =新的字节[300000]。            //开始监听
            listenSocket.Listen(1);            //已接收的连接
            连接= listenSocket.Accept();            //从连接流中的所有数据
            而(numOfBytesRecieved!= 0)
            {
                numOfBytesRecieved = connection.Receive(incomingBytes,胶印,10000,SocketFlags.None);                胶印+ = numOfBytesRecieved;
            }            数据=新的字节[偏移]
            Array.Copy(incomingBytes,数据,偏移量);            //发送图像到UI
            xaml_incomingTextBox.Dispatcher.BeginInvoke(displayIncomingVideo,数据);            connection.close()时;
        }
    } // keepListeningForVideoMessages结束
    私人无效SendVideoMsg(对象发件人,RoutedEventArgs E)
    {
        xaml_incomingVideo.Visibility = Visibility.Visible;
        xaml_StopVideoButton.Visibility = Visibility.Visible;
        xaml_SendTextButton.Visibility = Visibility.Hidden;
        webcam.Start();
    }
    私人无效StopVideoMsg(对象发件人,RoutedEventArgs E)
    {
        xaml_incomingVideo.Visibility = Visibility.Hidden;
        xaml_StopVideoButton.Visibility = Visibility.Hidden;
        xaml_SendTextButton.Visibility = Visibility.Visible;
        webcam.Stop();
    }} //类的结束
} //命名空间的结束


解决方案

您应该尝试下载n音讯,它是一个开源的音频库。它配备了如何使用UDP从一台PC到另一个流音频演示;它是在被称为网络聊天的NAudioDemo应用程序。

HTTP://naudio.$c$cplex.com/

是不是真的建议音频您正在使用TCP。使用UDP代替

http://www.onsip.com/有关的VoIP / SIP / UDP抗TCP换VOIP

另外,如果你不想重新发明轮子(我不知道什么是你的最终目标与您的项目),你可以尝试下载我们iConf.NET视频会议SDK,做最专家组的工作对你(但不是免费的)

http://avspeed.com/

I'm trying to make a video conferencing application (written in c#) that would allow 2 users to video conference using TCP. In addition, users can text chat separately. Right now, I have a working video stream, yet don't have the audio working yet. I'm unsure of how to access the microphone, stream it using TCP, and then play it on the other user's speakers as I'm relatively new to c# and brand new to using media.

If anyone could point me towards sample code, help me know how to access the mic, or anything else you think would help me, that'd be great.

I'm attaching my code as is for reference.

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

解决方案

You should try downloading NAudio, it is an open source audio library. It comes with a demo on how to stream audio using UDP from one pc to another; it is in the NAudioDemo app called "Network Chat".

http://naudio.codeplex.com/

TCP which you are currently using is not really recommended for audio. Use UDP instead

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

Alternatively, if you do not want to reinvent the wheel ( I am not sure what is your ultimate goal with your project ), you can try downloading our iConf.NET video conferencing SDK that does most of the leg work for you ( but is not free )

http://avspeed.com/

这篇关于试图通过TCP流2路音频?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆