实现流写入,将图像作为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. VUE【三、指令】

    模板指令 1.数据渲染(对应data数据) {{a}} 当使用v-once指令时,数据会一次绑定,后续修改值不会变化 v-text="a" 等同于{{a}} v-html=&quo ...

  2. 移动端设备管理平台 atx server2实践

    目录 1.需求背景 2.初步调研 2.1.云测试平台 2.2.开源工具 2.3.VNC 2.4.企业内部自研云测试平台 3.ATX Server安装 依赖环境 安装rethinkdb 安装atx se ...

  3. 网络编程基础之TCP学习(二)编程案例

    TCP网络编程流程如下: 实现功能:服务器端与客户端成功通讯后返回get! 服务器端程序 #include <netdb.h> #include <sys/socket.h> ...

  4. (转)android(SignalA)接收.net(SignalR)推送过来的消息

    从网络上搜索到的Demo,自己进行了稍微的改动 Signala类库从https://github.com/erizet/SignalA获得,不过相关引用有错误,需要手动修正. 下载相关源码 packa ...

  5. vue2.0+webpack+vuerouter+vuex+axios构建项目基础

    前言 本文讲解的是vue2.0+webpack+vuerouter+vuex+axios构建项目基础 步骤 1.全局安装webpack,命令 npm install webpack -g 注意,web ...

  6. IDEA 2019.1版本 永久激活(假装是永久激活,其实还是有时间的,不过这个时间比较长)

    先下载 一个 jar 包 链接: https://pan.baidu.com/s/12eC8OZzMrUve2xC7aRUKLQ 提取码: bavi 将下载下来的jar包,放置你安装idea的目录的b ...

  7. bind支持mysql

    最近打算将bind的记录信息存入到数据库中去,网上找了下,原来早有老外写好了mysql-bind的补丁,重新编译bind即可实现bind支持mysql存储.(http://mysql-bind.sou ...

  8. 《Redis 设计与实现》读书笔记(二)

    单机数据库实现 九.数据库 1.服务器中的数据库 一个redis服务器保存多个数据库. struct redisServer { //一个数组,多个数据库 redisDb *db; } 当执行sele ...

  9. 题解 [BZOJ1295][SCOI2009] 最长距离

    题面 解析 \(n\)只有\(30\)可以直接枚举每个矩形, 判断他们的左上角到右下角或右上角到左上角的最短路是否小于\(T\). 最短路可以用\(dijkstra\). 一开始想用\(DP\)写最短 ...

  10. TabSheet源码

    TabSheet.h #if !defined(AFX_TABSHEET_H__42EE262D_D15F_46D5_8F26_28FD049E99F4__INCLUDED_) #define AFX ...