JPEG串流问题-我如何将图像串流到我选择的服务器

本文关键字:选择 服务器 图像 问题 JPEG | 更新日期: 2023-09-27 18:08:19

为了简短地介绍,我将提到我一直在构建一个应用程序,该应用程序涉及从我构建的私人网站执行远程命令,并让我的个人家用计算机响应这些命令。

我发现桌面直播将是一个完美的功能,我计划使用一个iframe来适应我的网站。然而,我似乎找不到一个好的c#库,可以让我实时流式传输我的桌面。

除了这个:http://www.codeproject.com/Articles/371955/Motion-JPEG-Streaming-Server

问题是,这只允许我将我的桌面流式传输到localhost, 127.0.0.1和其他本地主机链接。

我需要一种方法来修改它,以便能够让它流到我选择的服务器,然后我可以访问它。例如www.mystream.com/stream.php

它由两个类组成:ImageStreamingServer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
using System.IO;
// -------------------------------------------------
// Developed By : Ragheed Al-Tayeb
// e-Mail       : ragheedemail@gmail.com
// Date         : April 2012
// -------------------------------------------------
namespace rtaNetworking.Streaming
{
    /// <summary>
    /// Provides a streaming server that can be used to stream any images source
    /// to any client.
    /// </summary>
    public class ImageStreamingServer:IDisposable
    {
        private List<Socket> _Clients;
        private Thread _Thread;
        public ImageStreamingServer():this(Screen.Snapshots(600,450,true))
        {
        }
        public ImageStreamingServer(IEnumerable<Image> imagesSource)
        {
            _Clients = new List<Socket>();
            _Thread = null;
            this.ImagesSource = imagesSource;
            this.Interval = 50;
        }

        /// <summary>
        /// Gets or sets the source of images that will be streamed to the 
        /// any connected client.
        /// </summary>
        public IEnumerable<Image> ImagesSource { get; set; }
        /// <summary>
        /// Gets or sets the interval in milliseconds (or the delay time) between 
        /// the each image and the other of the stream (the default is . 
        /// </summary>
        public int Interval { get; set; }
        /// <summary>
        /// Gets a collection of client sockets.
        /// </summary>
        public IEnumerable<Socket> Clients { get { return _Clients; } }
        /// <summary>
        /// Returns the status of the server. True means the server is currently 
        /// running and ready to serve any client requests.
        /// </summary>
        public bool IsRunning { get { return (_Thread != null && _Thread.IsAlive); } }
        /// <summary>
        /// Starts the server to accepts any new connections on the specified port.
        /// </summary>
        /// <param name="port"></param>
        public void Start(int port)
        {
            lock (this)
            {
                _Thread = new Thread(new ParameterizedThreadStart(ServerThread));
                _Thread.IsBackground = true;
                _Thread.Start(port);
            }
        }
        /// <summary>
        /// Starts the server to accepts any new connections on the default port (8080).
        /// </summary>
        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;
                }
            }
        }
        /// <summary>
        /// This the main thread of the server that serves all the new 
        /// connections from clients.
        /// </summary>
        /// <param name="state"></param>
        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();
        }
        /// <summary>
        /// Each client connection will be served by this thread.
        /// </summary>
        /// <param name="client"></param>
        private void ClientThread(object client)
        {
            Socket socket = (Socket)client;
            System.Diagnostics.Debug.WriteLine(string.Format("New client from {0}",socket.RemoteEndPoint.ToString()));
            lock (_Clients)
                _Clients.Add(socket);
            try
            {
                using (MjpegWriter wr = new MjpegWriter(new NetworkStream(socket, true)))
                {
                    // Writes the response header to the client.
                    wr.WriteHeader();
                    // Streams the images from the source to the client.
                    foreach (var imgStream in Screen.Streams(this.ImagesSource))
                    {
                        if (this.Interval > 0)
                            Thread.Sleep(this.Interval);
                        wr.Write(imgStream);
                    }
                }
            }
            catch { }
            finally
            {
                lock (_Clients)
                    _Clients.Remove(socket);
            }
        }

        #region IDisposable Members
        public void Dispose()
        {
            this.Stop();
        }
        #endregion
    }
    static class SocketExtensions
    {
        public static IEnumerable<Socket> IncommingConnectoins(this Socket server)
        {
            while(true)
                yield return server.Accept();
        }
    }

    static class Screen
    {

        public static IEnumerable<Image> Snapshots()
        {
            return Screen.Snapshots(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height,true);
        }
        /// <summary>
        /// Returns a 
        /// </summary>
        /// <param name="delayTime"></param>
        /// <returns></returns>
        public static IEnumerable<Image> Snapshots(int width,int height,bool showCursor)
        {
            Size size = new Size(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height);
            Bitmap srcImage = new Bitmap(size.Width, size.Height);
            Graphics srcGraphics = Graphics.FromImage(srcImage);
            bool scaled = (width != size.Width || height != size.Height);
            Bitmap dstImage = srcImage;
            Graphics dstGraphics = srcGraphics;
            if(scaled)
            {
                dstImage = new Bitmap(width, height);
                dstGraphics = Graphics.FromImage(dstImage);
            }
            Rectangle src = new Rectangle(0, 0, size.Width, size.Height);
            Rectangle dst = new Rectangle(0, 0, width, height);
            Size curSize = new Size(32, 32);
            while (true)
            {
                srcGraphics.CopyFromScreen(0, 0, 0, 0, size);
                if (showCursor)
                    Cursors.Default.Draw(srcGraphics,new Rectangle(Cursor.Position,curSize));
                if (scaled)
                    dstGraphics.DrawImage(srcImage, dst, src, GraphicsUnit.Pixel);
                yield return dstImage;
            }
            srcGraphics.Dispose();
            dstGraphics.Dispose();
            srcImage.Dispose();
            dstImage.Dispose();
            yield break;
        }
        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;
        }
    }
}

MjpegWriter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
// -------------------------------------------------
// Developed By : Ragheed Al-Tayeb
// e-Mail       : ragheedemail@gmail.com
// Date         : April 2012
// -------------------------------------------------
namespace rtaNetworking.Streaming
{
    /// <summary>
    /// Provides a stream writer that can be used to write images as MJPEG 
    /// or (Motion JPEG) to any stream.
    /// </summary>
    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'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, 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
    }
}

JPEG串流问题-我如何将图像串流到我选择的服务器

这个应用程序应该也可以在互联网上工作。确保您通过它远程访问的端口是打开的。

如果你不想为应用程序打开一个端口。然后考虑将上述源更改为反向连接,其中您的桌面计算机充当客户端而不是服务器。

祝你好运