实现流写入,将图像作为mjpeg写入

 public class MjpegWriter : IDisposable
{ private static byte[] CRLF = new byte[] { , };
private static byte[] EmptyLine = new byte[] { , , , }; private string _Boundary; public MjpegWriter(Stream stream)
: this(stream, "--boundary")
{ } public MjpegWriter(Stream stream, string boundary)
{ this.Stream = stream;
this.Boundary = boundary;
} public string Boundary { get; private set; }
public Stream Stream { get; private set; } public void WriteHeader()
{ Write(
"HTTP/1.1 200 OK\r\n" +
"Content-Type: multipart/x-mixed-replace; boundary=" +
this.Boundary +
"\r\n"
); this.Stream.Flush();
} public void Write(Image image)
{
MemoryStream ms = BytesOf(image);
this.Write(ms);
} public void Write(MemoryStream imageStream)
{ StringBuilder sb = new StringBuilder(); sb.AppendLine();
sb.AppendLine(this.Boundary);
sb.AppendLine("Content-Type: image/jpeg");
sb.AppendLine("Content-Length: " + imageStream.Length.ToString());
sb.AppendLine(); Write(sb.ToString());
imageStream.WriteTo(this.Stream);
Write("\r\n"); this.Stream.Flush(); } private void Write(byte[] data)
{
this.Stream.Write(data, , data.Length);
} private void Write(string text)
{
byte[] data = BytesOf(text);
this.Stream.Write(data, , data.Length);
} private static byte[] BytesOf(string text)
{
return Encoding.ASCII.GetBytes(text);
} private static MemoryStream BytesOf(Image image)
{
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms;
} public string ReadRequest(int length)
{ byte[] data = new byte[length];
int count = this.Stream.Read(data, , data.Length); if (count != )
return Encoding.ASCII.GetString(data, , count); return null;
} #region IDisposable Members public void Dispose()
{ try
{ if (this.Stream != null)
this.Stream.Dispose(); }
finally
{
this.Stream = null;
}
} #endregion
}

服务器实现:

 public class ImageStreamingServer : IDisposable
{ private List<Socket> _Clients;
private Thread _Thread; public ImageStreamingServer() : this(IRImg.Snapshots())
{ } public ImageStreamingServer(IEnumerable<Image> imagesSource)
{ _Clients = new List<Socket>();
_Thread = null; this.ImagesSource = imagesSource;
this.Interval = ; } public IEnumerable<Image> ImagesSource { get; set; } public int Interval { get; set; } public IEnumerable<Socket> Clients { get { return _Clients; } } public bool IsRunning { get { return (_Thread != null && _Thread.IsAlive); } } public void Start(int port)
{ lock (this)
{
_Thread = new Thread(new ParameterizedThreadStart(ServerThread));
_Thread.IsBackground = true;
_Thread.Start(port);
} } public void Start()
{
this.Start();
} public void Stop()
{ if (this.IsRunning)
{
try
{
_Thread.Join();
_Thread.Abort();
}
finally
{ lock (_Clients)
{ foreach (var s in _Clients)
{
try
{
s.Close();
}
catch { }
}
_Clients.Clear(); } _Thread = null;
}
}
} private void ServerThread(object state)
{ try
{
Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Server.Bind(new IPEndPoint(IPAddress.Any, (int)state));
Server.Listen(); System.Diagnostics.Debug.WriteLine(string.Format("Server started on port {0}.", state)); foreach (Socket client in Server.IncommingConnectoins())
ThreadPool.QueueUserWorkItem(new WaitCallback(ClientThread), client); }
catch { } this.Stop();
} private void ClientThread(object client)
{ Socket socket = (Socket)client;
lock (_Clients)
_Clients.Add(socket); try
{
using (MjpegWriter wr = new MjpegWriter(new NetworkStream(socket, true)))
{
wr.WriteHeader();
foreach (var imgStream in IRImg.Streams(this.ImagesSource))
{
if (this.Interval > )
Thread.Sleep(this.Interval); wr.Write(imgStream);
} }
}
catch { }
finally
{
lock (_Clients)
_Clients.Remove(socket);
}
} public void Dispose()
{
this.Stop();
}
} static class SocketExtensions
{ public static IEnumerable<Socket> IncommingConnectoins(this Socket server)
{
while (true)
yield return server.Accept();
} } static class IRImg
{
public static IEnumerable<Image> Snapshots()
{
while (true)
{
yield return IRCommon.Instance.GetBitmap();
}
} internal static IEnumerable<MemoryStream> Streams(this IEnumerable<Image> source)
{
MemoryStream ms = new MemoryStream(); foreach (var img in source)
{
ms.SetLength();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
yield return ms;
} ms.Close();
ms = null; yield break;
} }

将上面代码中的这行 IRCommon.Instance.GetBitmap();改为自己的bitmap来源即可实现mjpeg图像传输

浏览器可直接输入 127.0.0.1:8080访问,chrome没问题,但是ie下,会一直下载图片

C#客户端可以用afroge实现浏览,具体可参考:在WPF中使用AForge控件

本项目来源:Motion JPEG Streaming Server   (codeproject)

C#实现MJPEG服务器的更多相关文章

  1. 适用于Windows和Linux的Yolo-v3和Yolo-v2(上)

    适用于Windows和Linux的Yolo-v3和Yolo-v2(上) https://github.com/eric-erki/darknetAB (用于对象检测的神经网络)-Tensor Core ...

  2. C#开源实现MJPEG流传输

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 许久以前写了篇文章<基于.NET打造IP智能网络视频监控系统>,记录和介绍了自己几年来积 ...

  3. Web服务器部署浅析

    企业内网站 中小型企业一般将企业宣传网站外包给第三方进行统一设计.部署和运维.大型企业因为访问量和数据量有所增加,部分网站可能具备在线咨询或订单的功能,此类Web服务器采用最通用的IU机架式服务器以降 ...

  4. 基于mjpg_streamer视频服务器移植【转】

    本文转载自:http://blog.csdn.net/wavemcu/article/details/7539560 MJPG简介: MJPG是MJPEG的缩写,但是MJPEG还可以表示文件格式扩展名 ...

  5. M-JPEG和MPEG-4的区别 M-JPEG VS MPEG

    http://blog.sina.com.cn/s/blog_4b357b300100gre9.html M-JPEG VS MPEG http://blog.csdn.net/bluesky_sun ...

  6. 网络摄像头Androi端显示(mjpeg)源码分析

    main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and ...

  7. M-JPEG、MPEG4、H.264都有何区别

    压缩方式是网络视频服务器和网络摄像机的核心技术,压缩方式很大程度上决定着图像的质量.压缩比.传输效率.传输速度等性能,它是评价网络视频服务器和网络摄像机性能优劣的重要一环.随着多媒体技术的发展,相继推 ...

  8. arm开发板6410/2440上mjpg-streamer网络视频服务器移植

    摄像头移植 一.环境 主机环境 :ubuntu 10.10         目标板 :FS-S5PC100 主机工具链 :gcc-4.4.5         交叉工具链 :arm-unknown-li ...

  9. 基于mjpg-streamer网络视频服务器移植

    MJPG简介: MJPG是MJPEG的缩写,但是MJPEG还可以表示文件格式扩展名. MJPEG 全名为 "Motion Joint Photographic Experts Group&q ...

随机推荐

  1. 5.SpringMVC 配置式开发-处理器适配器

    处理器适配器HandlerAdapter 1.SimpleControllerHandlerAdapter(默认) 所有实现了 Controller 接口的处理器 Bean,均是通过SimpleCon ...

  2. Form组件 cookie和session

    django form组件 1.渲染标签 2.校验数据 3.展示信息 第一步需要一个form类 from django import forms class MyForm(forms.Form): n ...

  3. 一图一知-NPM&YARN常用命令

  4. 「SNOI2019」通信 分治建图

    根据题意 每个点可以直接与S,T相连 也可以和前面的哨站相连 暴力建边的话 有n2条边 要用分治优化建边: 类似于归并排序 先对每一层分为左半边与右半边 对每一半都拿出来先排序去重后 直接排成一条链建 ...

  5. 【Java 基础项目 - - Bank项目4】 对象构造/跨package调用

    UML设计: 文件组织: (注: 在bank4中,直接调用bank3的内容, 不再重复编写代码即可!) 代码编写Bank.java: package Banking_4; import Banking ...

  6. CSS基础学习 17.CSS动画

  7. 本地安装mysql脚本

    [root@tianyun ~]# vim mysql_install.sh #!/usr/bin/env bash #mysql install 2 #by tianyun #yum 配置yum源 ...

  8. GDI根据位图和透明度创建蒙版

    #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l ...

  9. [ES2015] Number.isNaN instead of isNaN

    const result = Number('55px'); // isNaN "NaN" console.log(isNaN(result)); // true console. ...

  10. Java学习 1.5——静态Static的作用与用法

    在网上查阅资料,静态大约分为这几部分:修饰成员变量:修饰成员方法:静态代码块:静态导包,下面会用代码一一展示: 修饰成员变量: 一个类中,使用static修饰成员变量后,该变量变为全局变量,当再次ne ...