zoukankan      html  css  js  c++  java
  • C#实现MJPEG服务器

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

     public class MjpegWriter : IDisposable
        {
    
            private static byte[] CRLF = new byte[] { 13, 10 };
            private static byte[] EmptyLine = new byte[] { 13, 10, 13, 10 };
    
            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
    " +
                        "Content-Type: multipart/x-mixed-replace; boundary=" +
                        this.Boundary +
                        "
    "
                     );
    
                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("
    ");
    
                this.Stream.Flush();
    
            }
    
            private void Write(byte[] data)
            {
                this.Stream.Write(data, 0, data.Length);
            }
    
            private void Write(string text)
            {
                byte[] data = BytesOf(text);
                this.Stream.Write(data, 0, 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, 0, data.Length);
    
                if (count != 0)
                    return Encoding.ASCII.GetString(data, 0, 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 = 111;
    
            }
    
            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(8080);
            }
    
            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(10);
    
                    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 > 0)
                                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(0);
                    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)

  • 相关阅读:
    Java之JVM调优案例分析与实战(3)
    Java之JVM调优案例分析与实战(2)
    Java之JVM调优案例分析与实战(1)
    Creating a Fragment: constructor vs newInstance()
    Patterns-Observer
    Global Times 单词(日常收集)
    Unity3D入门工具介绍(一)
    指定安装应用程序移至SD卡(App2SD)
    Android源代码目录结构(转)
    技术路线的选择重要但不具有决定性(转)
  • 原文地址:https://www.cnblogs.com/xienb/p/11109711.html
Copyright © 2011-2022 走看看