c#视频流这么慢
c# video stream so slowly
我是 c# 的新手,我为流视频编写代码,我不知道这是否正确
倾听者
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Socket sk;
private NetworkStream ns;
private TcpListener tlp;
private Thread th;
void res()
{
try
{
tlp = new TcpListener(2100);
tlp.Start();
sk = tlp.AcceptSocket();
ns = new NetworkStream(sk);
pictureBox1.Image = Image.FromStream(ns);
tlp.Stop();
if (sk.Connected == true)
{
while (true)
{
res();
}
}
}catch(Exception ex){}
}
private void Form1_Load(object sender, EventArgs e)
{
th = new Thread(new ThreadStart(res));
th.Start();
}
}
}
和客户
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private FilterInfoCollection capture;
private VideoCaptureDevice frame;
private NetworkStream ns;
private TcpClient tlp;
private MemoryStream ms;
private BinaryWriter br;
private void Form1_Load(object sender, EventArgs e)
{
capture = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach(FilterInfo de in capture){
com.Items.Add(de.Name);
}
//com.SelectedIndex = 0;
}
private void st_Click(object sender, EventArgs e)
{
frame = new VideoCaptureDevice(capture[com.SelectedIndex].MonikerString);
frame.NewFrame += frame_NewFrame;
frame.Start();
}
void frame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
ms = new MemoryStream();
pictureBox1.Image.Save(ms, ImageFormat.Bmp);
byte[] buffer = ms.GetBuffer();
ms.Close();
tlp = new TcpClient("192.168.0.104", 2100);
ns = tlp.GetStream();
br = new BinaryWriter(ns);
br.Write(buffer);
tlp.Close();
ms.Close();
ns.Close();
br.Close();
}
catch (Exception ex) { MessageBox.Show(ex.Message); };
}
}
}
我在同一网络上的两台计算机上进行测试
它显示来自另一台计算机的图像,但速度太慢了
我的代码有什么问题
您在客户端的表单线程中执行所有操作,而应该在后台异步缓冲数据并仅在主线程中播放。还有多种其他方法可以做您想做的事情,其中之一是在您的表单中嵌入 Windows Media Player 控件以播放 WMP 支持的任何可流格式。
如果您只想流式传输数据,那么在您的客户端的 NewFrame 处理程序中,您唯一应该做的就是在缓冲区中缓冲数据,可能是 Queue<Bitmap>
或您的数据所采用的任何格式。您应该跟踪在主线程上缓冲了多少帧,并在缓冲区中至少有 2-3 帧(如果是视频,则为 5-10 秒)后启动显示。您的显示例程将从您的缓冲区中 .Dequeue() 数据直到为空。然后您再次等待缓冲更多数据。请注意,您将需要使用锁定对象来防止读写线程之间发生冲突,或者只需使用 .NET 4.0 中引入的新并发集合之一,如 ConcurrentQueue<T>
(在 System.Collections.Concurrent 中)。 (https://msdn.microsoft.com/en-us/library/dd267265%28v=vs.100%29.aspx)
我是 c# 的新手,我为流视频编写代码,我不知道这是否正确
倾听者
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Socket sk;
private NetworkStream ns;
private TcpListener tlp;
private Thread th;
void res()
{
try
{
tlp = new TcpListener(2100);
tlp.Start();
sk = tlp.AcceptSocket();
ns = new NetworkStream(sk);
pictureBox1.Image = Image.FromStream(ns);
tlp.Stop();
if (sk.Connected == true)
{
while (true)
{
res();
}
}
}catch(Exception ex){}
}
private void Form1_Load(object sender, EventArgs e)
{
th = new Thread(new ThreadStart(res));
th.Start();
}
}
}
和客户
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private FilterInfoCollection capture;
private VideoCaptureDevice frame;
private NetworkStream ns;
private TcpClient tlp;
private MemoryStream ms;
private BinaryWriter br;
private void Form1_Load(object sender, EventArgs e)
{
capture = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach(FilterInfo de in capture){
com.Items.Add(de.Name);
}
//com.SelectedIndex = 0;
}
private void st_Click(object sender, EventArgs e)
{
frame = new VideoCaptureDevice(capture[com.SelectedIndex].MonikerString);
frame.NewFrame += frame_NewFrame;
frame.Start();
}
void frame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
ms = new MemoryStream();
pictureBox1.Image.Save(ms, ImageFormat.Bmp);
byte[] buffer = ms.GetBuffer();
ms.Close();
tlp = new TcpClient("192.168.0.104", 2100);
ns = tlp.GetStream();
br = new BinaryWriter(ns);
br.Write(buffer);
tlp.Close();
ms.Close();
ns.Close();
br.Close();
}
catch (Exception ex) { MessageBox.Show(ex.Message); };
}
}
}
我在同一网络上的两台计算机上进行测试 它显示来自另一台计算机的图像,但速度太慢了 我的代码有什么问题
您在客户端的表单线程中执行所有操作,而应该在后台异步缓冲数据并仅在主线程中播放。还有多种其他方法可以做您想做的事情,其中之一是在您的表单中嵌入 Windows Media Player 控件以播放 WMP 支持的任何可流格式。
如果您只想流式传输数据,那么在您的客户端的 NewFrame 处理程序中,您唯一应该做的就是在缓冲区中缓冲数据,可能是 Queue<Bitmap>
或您的数据所采用的任何格式。您应该跟踪在主线程上缓冲了多少帧,并在缓冲区中至少有 2-3 帧(如果是视频,则为 5-10 秒)后启动显示。您的显示例程将从您的缓冲区中 .Dequeue() 数据直到为空。然后您再次等待缓冲更多数据。请注意,您将需要使用锁定对象来防止读写线程之间发生冲突,或者只需使用 .NET 4.0 中引入的新并发集合之一,如 ConcurrentQueue<T>
(在 System.Collections.Concurrent 中)。 (https://msdn.microsoft.com/en-us/library/dd267265%28v=vs.100%29.aspx)