0


C# VideoCapture 多路视频播放

效果

C#VideoCapture多路视频播放

项目

代码

using OpenCvSharp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MultiVideoDemo
{
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
}

    CancellationTokenSource ctsShow;
     CancellationTokenSource[] taskCTS = new CancellationTokenSource[6];
     ConcurrentQueue<Mat>[] matQueue = new ConcurrentQueue<Mat>[6];
     int fps = 25;
     string[] rtsp_url = new string[40];
     List<RTSPURLInfo> play_rtsp_url = new List<RTSPURLInfo>();

    /// <summary>
     /// 停止
     /// </summary>
     /// <param name="sender"></param>
     /// <param name="e"></param>
     private void button2_Click(object sender, EventArgs e)
     {
         ctsShow.Cancel();

        for (int i = 0; i < 6; i++)
         {
             taskCTS[i].Cancel();
         }
     }

    private void Form1_Load(object sender, EventArgs e)
     {
         //初始化
         for (int i = 0; i < 6; i++)
         {
             taskCTS[i] = new CancellationTokenSource();
             matQueue[i] = new ConcurrentQueue<Mat>();
         }

        for (int i = 0; i < 40; i++)
         {
             rtsp_url[i] = "1.dav";
         }

        //play_rtsp_url
         for (int i = 0; i < 6; i++)
         {
             play_rtsp_url.Add(new RTSPURLInfo((i + 1).ToString(), rtsp_url[i]));
         }
     }

    /// <summary>
     /// 播放
     /// </summary>
     /// <param name="sender"></param>
     /// <param name="e"></param>
     private void button1_Click(object sender, EventArgs e)
     {
         ctsShow = new CancellationTokenSource();

        for (int i = 0; i < 6; i++)
         {
             taskCTS[i] = new CancellationTokenSource();
             matQueue[i] = new ConcurrentQueue<Mat>();
         }

        play_rtsp_url.Clear();
         for (int i = 0; i < 6; i++)
         {
             play_rtsp_url.Add(new RTSPURLInfo((i + 1).ToString(), rtsp_url[i]));
         }

        for (int i = 0; i < play_rtsp_url.Count; i++)
         {
             Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
             System.Threading.Thread.Sleep(100);
         }

        //显示线程
         Task.Run(() =>
         {
             Mat mat = new Mat();
             string winName = "video";

            Cv2.NamedWindow(winName, WindowFlags.Normal);
             Cv2.ResizeWindow(winName, fullSize);

            int delay = (int)(1000 / fps);
             Stopwatch stopwatch = new Stopwatch();

            while (true)
             {
                 stopwatch.Restart();
                 delay = (int)(1000 / fps);
                 if (ctsShow.IsCancellationRequested) break;

                Mat frame = CombiningImages();

                Cv2.ImShow(winName, frame);

                delay = (int)(delay - stopwatch.ElapsedMilliseconds);
                 if (delay <= 0)
                 {
                     delay = 1;
                 }
                 Console.WriteLine("delay:" + delay.ToString());
                 Cv2.WaitKey(delay);

                frame.Dispose();
             }
             Cv2.DestroyAllWindows();
         });
     }

    OpenCvSharp.Size fullSize = new OpenCvSharp.Size(1008, 570);
     OpenCvSharp.Size mainSize = new OpenCvSharp.Size(672, 380);
     OpenCvSharp.Size subSize = new OpenCvSharp.Size(336, 190);

    Mat CombiningImages()
     {
         Console.WriteLine(string.Format("matQueue0:{0},matQueue1:{1},matQueue2:{2},matQueue3:{3},matQueue4:{4},matQueue5:{5}"
             , matQueue[0].Count
             , matQueue[1].Count
             , matQueue[2].Count
             , matQueue[3].Count
             , matQueue[4].Count
             , matQueue[5].Count
             ));

        Mat mat = Mat.Zeros(fullSize, MatType.CV_8UC3);

        Mat mat0 = new Mat();
         matQueue[0].TryDequeue(out mat0);
         if (mat0 == null || mat0.Empty())
         {
             mat0 = Mat.Zeros(mainSize, MatType.CV_8UC3);
         }
         Cv2.Resize(mat0, mat0, mainSize);

        Mat mat1 = new Mat();
         matQueue[1].TryDequeue(out mat1);
         if (mat1 == null || mat1.Empty())
         {
             mat1 = Mat.Zeros(subSize, MatType.CV_8UC3);
         }
         Cv2.Resize(mat1, mat1, subSize);

        Mat mat2 = new Mat();
         matQueue[2].TryDequeue(out mat2);
         if (mat2 == null || mat2.Empty())
         {
             mat2 = Mat.Zeros(subSize, MatType.CV_8UC3);
         }
         Cv2.Resize(mat2, mat2, subSize);

        Mat mat3 = new Mat();
         matQueue[3].TryDequeue(out mat3);
         if (mat3 == null || mat3.Empty())
         {
             mat3 = Mat.Zeros(subSize, MatType.CV_8UC3);
         }
         Cv2.Resize(mat3, mat3, subSize);

        Mat mat4 = new Mat();
         matQueue[4].TryDequeue(out mat4);
         if (mat4 == null || mat4.Empty())
         {
             mat4 = Mat.Zeros(subSize, MatType.CV_8UC3);
         }
         Cv2.Resize(mat4, mat4, subSize);

        Mat mat5 = new Mat();
         matQueue[5].TryDequeue(out mat5);
         if (mat5 == null || mat5.Empty())
         {
             mat5 = Mat.Zeros(subSize, MatType.CV_8UC3);
         }
         Cv2.Resize(mat5, mat5, subSize);

        //第一张主图
         Rect roi0 = new Rect(0, 0, 672, 380);
         Mat position0 = new Mat(mat, roi0);
         mat0.CopyTo(position0);

        //第二张图
         Rect roi1 = new Rect(672, 0, 336, 190);
         Mat position1 = new Mat(mat, roi1);
         mat1.CopyTo(position1);

        //第三张图
         Rect roi2 = new Rect(672, 190, 336, 190);
         Mat position2 = new Mat(mat, roi2);
         mat2.CopyTo(position2);

        //第4张图
         Rect roi3 = new Rect(672, 380, 336, 190);
         Mat position3 = new Mat(mat, roi3);
         mat3.CopyTo(position3);

        //第5张图
         Rect roi4 = new Rect(336, 380, 336, 190);
         Mat position4 = new Mat(mat, roi4);
         mat4.CopyTo(position4);

        //第6张图
         Rect roi5 = new Rect(0, 380, 336, 190);
         Mat position5 = new Mat(mat, roi5);
         mat5.CopyTo(position5);

        mat0.Dispose();
         mat1.Dispose();
         mat2.Dispose();
         mat3.Dispose();
         mat4.Dispose();
         mat5.Dispose();

        position0.Dispose();
         position1.Dispose();
         position2.Dispose();
         position3.Dispose();
         position4.Dispose();
         position5.Dispose();

        return mat;

    }

    void DecodeRTSP(string index, ConcurrentQueue<Mat> matQueue, string url, CancellationToken cancellationToken = default)
     {
         VideoCapture vcapture = new VideoCapture(url);
         if (!vcapture.IsOpened())
         {
             Console.WriteLine("打开视频文件失败");
             return;
         }

        // 计算等待时间(毫秒)
         int taskDelay = (int)(1000 / fps);
         Stopwatch stopwatch = new Stopwatch();

         while (true)
         {
             if (cancellationToken.IsCancellationRequested) break;

            stopwatch.Restart();
             Mat frame = new Mat();
             if (!vcapture.Read(frame))
             {
                 Console.WriteLine("读取失败");
                 break;
             }

            taskDelay = (int)(1000 / fps);

            //中间标注数字,模拟路数
             Cv2.PutText(frame, index.ToString(), new OpenCvSharp.Point(frame.Width / 2, frame.Height / 2), HersheyFonts.HersheySimplex, 20, Scalar.Red, 20);

            matQueue.Enqueue(frame);

            taskDelay = (int)(taskDelay - stopwatch.ElapsedMilliseconds);
             if (matQueue.Count > 100)
             {
                 Console.WriteLine("index:" + index + ",后续处理能力不足……");
             }

            if (matQueue.Count < 10)
             {
                 taskDelay = taskDelay - 5;
             }

            if (taskDelay <= 0)
             {
                 taskDelay = 0;
             }
             Console.WriteLine("index:" + index + ",taskDelay:" + taskDelay);
             Task.Delay(taskDelay).Wait();

        }

        vcapture.Release();

    }

    /// <summary>
     /// 取消第一路
     /// </summary>
     /// <param name="sender"></param>
     /// <param name="e"></param>
     private void button4_Click(object sender, EventArgs e)
     {
         taskCTS[0].Cancel();
     }

    /// <summary>
     /// 记载第7路
     /// </summary>
     /// <param name="sender"></param>
     /// <param name="e"></param>
     private void button3_Click(object sender, EventArgs e)
     {
         for (int i = 0; i < 6; i++)
         {
             taskCTS[i].Cancel();
         }

        for (int i = 0; i < 6; i++)
         {
             taskCTS[i] = new CancellationTokenSource();
         }

        //删除最后一个元素
         play_rtsp_url.RemoveAt(play_rtsp_url.Count - 1);

        //把第7路的地址 放到第一的位置
         play_rtsp_url.Insert(0, new RTSPURLInfo("7", rtsp_url[6]));

        for (int i = 0; i < play_rtsp_url.Count; i++)
         {
             Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
             System.Threading.Thread.Sleep(10);
         }
     }

    /// <summary>
     /// 加载第8路
     /// </summary>
     /// <param name="sender"></param>
     /// <param name="e"></param>
     private void button5_Click(object sender, EventArgs e)
     {
         for (int i = 0; i < 6; i++)
         {
             taskCTS[i].Cancel();
         }

        for (int i = 0; i < 6; i++)
         {
             taskCTS[i] = new CancellationTokenSource();
         }

        //删除最后一个元素
         play_rtsp_url.RemoveAt(play_rtsp_url.Count - 1);

        //把第8路的地址 放到第一的位置
         play_rtsp_url.Insert(0, new RTSPURLInfo("8", rtsp_url[7]));

        for (int i = 0; i < play_rtsp_url.Count; i++)
         {
             Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
             System.Threading.Thread.Sleep(10);
         }

     }
 }

public class RTSPURLInfo
 {
     public string index;
     public string url;

    public RTSPURLInfo(string index, string url)
     {
         this.index = index;
         this.url = url;
     }
 }

}

using OpenCvSharp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MultiVideoDemo
{
    public partial class Form4 : Form
    {
        public Form4()
        {
            InitializeComponent();
        }

        CancellationTokenSource ctsShow;
        CancellationTokenSource[] taskCTS = new CancellationTokenSource[6];
        ConcurrentQueue<Mat>[] matQueue = new ConcurrentQueue<Mat>[6];
        int fps = 25;
        string[] rtsp_url = new string[40];
        List<RTSPURLInfo> play_rtsp_url = new List<RTSPURLInfo>();

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            ctsShow.Cancel();

            for (int i = 0; i < 6; i++)
            {
                taskCTS[i].Cancel();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //初始化
            for (int i = 0; i < 6; i++)
            {
                taskCTS[i] = new CancellationTokenSource();
                matQueue[i] = new ConcurrentQueue<Mat>();
            }

            for (int i = 0; i < 40; i++)
            {
                rtsp_url[i] = "1.dav";
            }

            //play_rtsp_url
            for (int i = 0; i < 6; i++)
            {
                play_rtsp_url.Add(new RTSPURLInfo((i + 1).ToString(), rtsp_url[i]));
            }
        }

        /// <summary>
        /// 播放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ctsShow = new CancellationTokenSource();

            for (int i = 0; i < 6; i++)
            {
                taskCTS[i] = new CancellationTokenSource();
                matQueue[i] = new ConcurrentQueue<Mat>();
            }

            play_rtsp_url.Clear();
            for (int i = 0; i < 6; i++)
            {
                play_rtsp_url.Add(new RTSPURLInfo((i + 1).ToString(), rtsp_url[i]));
            }

            for (int i = 0; i < play_rtsp_url.Count; i++)
            {
                Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
                System.Threading.Thread.Sleep(100);
            }

            //显示线程
            Task.Run(() =>
            {
                Mat mat = new Mat();
                string winName = "video";

                Cv2.NamedWindow(winName, WindowFlags.Normal);
                Cv2.ResizeWindow(winName, fullSize);

                int delay = (int)(1000 / fps);
                Stopwatch stopwatch = new Stopwatch();

                while (true)
                {
                    stopwatch.Restart();
                    delay = (int)(1000 / fps);
                    if (ctsShow.IsCancellationRequested) break;

                    Mat frame = CombiningImages();

                    Cv2.ImShow(winName, frame);

                    delay = (int)(delay - stopwatch.ElapsedMilliseconds);
                    if (delay <= 0)
                    {
                        delay = 1;
                    }
                    Console.WriteLine("delay:" + delay.ToString());
                    Cv2.WaitKey(delay);

                    frame.Dispose();
                }
                Cv2.DestroyAllWindows();
            });
        }

        OpenCvSharp.Size fullSize = new OpenCvSharp.Size(1008, 570);
        OpenCvSharp.Size mainSize = new OpenCvSharp.Size(672, 380);
        OpenCvSharp.Size subSize = new OpenCvSharp.Size(336, 190);

        Mat CombiningImages()
        {
            Console.WriteLine(string.Format("matQueue0:{0},matQueue1:{1},matQueue2:{2},matQueue3:{3},matQueue4:{4},matQueue5:{5}"
                , matQueue[0].Count
                , matQueue[1].Count
                , matQueue[2].Count
                , matQueue[3].Count
                , matQueue[4].Count
                , matQueue[5].Count
                ));

            Mat mat = Mat.Zeros(fullSize, MatType.CV_8UC3);

            Mat mat0 = new Mat();
            matQueue[0].TryDequeue(out mat0);
            if (mat0 == null || mat0.Empty())
            {
                mat0 = Mat.Zeros(mainSize, MatType.CV_8UC3);
            }
            Cv2.Resize(mat0, mat0, mainSize);

            Mat mat1 = new Mat();
            matQueue[1].TryDequeue(out mat1);
            if (mat1 == null || mat1.Empty())
            {
                mat1 = Mat.Zeros(subSize, MatType.CV_8UC3);
            }
            Cv2.Resize(mat1, mat1, subSize);

            Mat mat2 = new Mat();
            matQueue[2].TryDequeue(out mat2);
            if (mat2 == null || mat2.Empty())
            {
                mat2 = Mat.Zeros(subSize, MatType.CV_8UC3);
            }
            Cv2.Resize(mat2, mat2, subSize);

            Mat mat3 = new Mat();
            matQueue[3].TryDequeue(out mat3);
            if (mat3 == null || mat3.Empty())
            {
                mat3 = Mat.Zeros(subSize, MatType.CV_8UC3);
            }
            Cv2.Resize(mat3, mat3, subSize);

            Mat mat4 = new Mat();
            matQueue[4].TryDequeue(out mat4);
            if (mat4 == null || mat4.Empty())
            {
                mat4 = Mat.Zeros(subSize, MatType.CV_8UC3);
            }
            Cv2.Resize(mat4, mat4, subSize);

            Mat mat5 = new Mat();
            matQueue[5].TryDequeue(out mat5);
            if (mat5 == null || mat5.Empty())
            {
                mat5 = Mat.Zeros(subSize, MatType.CV_8UC3);
            }
            Cv2.Resize(mat5, mat5, subSize);

            //第一张主图
            Rect roi0 = new Rect(0, 0, 672, 380);
            Mat position0 = new Mat(mat, roi0);
            mat0.CopyTo(position0);

            //第二张图
            Rect roi1 = new Rect(672, 0, 336, 190);
            Mat position1 = new Mat(mat, roi1);
            mat1.CopyTo(position1);

            //第三张图
            Rect roi2 = new Rect(672, 190, 336, 190);
            Mat position2 = new Mat(mat, roi2);
            mat2.CopyTo(position2);

            //第4张图
            Rect roi3 = new Rect(672, 380, 336, 190);
            Mat position3 = new Mat(mat, roi3);
            mat3.CopyTo(position3);

            //第5张图
            Rect roi4 = new Rect(336, 380, 336, 190);
            Mat position4 = new Mat(mat, roi4);
            mat4.CopyTo(position4);

            //第6张图
            Rect roi5 = new Rect(0, 380, 336, 190);
            Mat position5 = new Mat(mat, roi5);
            mat5.CopyTo(position5);

            mat0.Dispose();
            mat1.Dispose();
            mat2.Dispose();
            mat3.Dispose();
            mat4.Dispose();
            mat5.Dispose();

            position0.Dispose();
            position1.Dispose();
            position2.Dispose();
            position3.Dispose();
            position4.Dispose();
            position5.Dispose();

            return mat;

        }

        void DecodeRTSP(string index, ConcurrentQueue<Mat> matQueue, string url, CancellationToken cancellationToken = default)
        {
            VideoCapture vcapture = new VideoCapture(url);
            if (!vcapture.IsOpened())
            {
                Console.WriteLine("打开视频文件失败");
                return;
            }

            // 计算等待时间(毫秒)
            int taskDelay = (int)(1000 / fps);
            Stopwatch stopwatch = new Stopwatch();

            while (true)
            {
                if (cancellationToken.IsCancellationRequested) break;

                stopwatch.Restart();
                Mat frame = new Mat();
                if (!vcapture.Read(frame))
                {
                    Console.WriteLine("读取失败");
                    break;
                }

                taskDelay = (int)(1000 / fps);

                //中间标注数字,模拟路数
                Cv2.PutText(frame, index.ToString(), new OpenCvSharp.Point(frame.Width / 2, frame.Height / 2), HersheyFonts.HersheySimplex, 20, Scalar.Red, 20);

                matQueue.Enqueue(frame);

                taskDelay = (int)(taskDelay - stopwatch.ElapsedMilliseconds);
                if (matQueue.Count > 100)
                {
                    Console.WriteLine("index:" + index + ",后续处理能力不足……");
                }

                if (matQueue.Count < 10)
                {
                    taskDelay = taskDelay - 5;
                }

                if (taskDelay <= 0)
                {
                    taskDelay = 0;
                }
                Console.WriteLine("index:" + index + ",taskDelay:" + taskDelay);
                Task.Delay(taskDelay).Wait();

            }

            vcapture.Release();

        }

        /// <summary>
        /// 取消第一路
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            taskCTS[0].Cancel();
        }

        /// <summary>
        /// 记载第7路
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 6; i++)
            {
                taskCTS[i].Cancel();
            }

            for (int i = 0; i < 6; i++)
            {
                taskCTS[i] = new CancellationTokenSource();
            }

            //删除最后一个元素
            play_rtsp_url.RemoveAt(play_rtsp_url.Count - 1);

            //把第7路的地址 放到第一的位置
            play_rtsp_url.Insert(0, new RTSPURLInfo("7", rtsp_url[6]));

            for (int i = 0; i < play_rtsp_url.Count; i++)
            {
                Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
                System.Threading.Thread.Sleep(10);
            }
        }

        /// <summary>
        /// 加载第8路
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 6; i++)
            {
                taskCTS[i].Cancel();
            }

            for (int i = 0; i < 6; i++)
            {
                taskCTS[i] = new CancellationTokenSource();
            }

            //删除最后一个元素
            play_rtsp_url.RemoveAt(play_rtsp_url.Count - 1);

            //把第8路的地址 放到第一的位置
            play_rtsp_url.Insert(0, new RTSPURLInfo("8", rtsp_url[7]));

            for (int i = 0; i < play_rtsp_url.Count; i++)
            {
                Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
                System.Threading.Thread.Sleep(10);
            }

        }
    }

    public class RTSPURLInfo
    {
        public string index;
        public string url;

        public RTSPURLInfo(string index, string url)
        {
            this.index = index;
            this.url = url;
        }
    }

}

下载

源码下载


本文转载自: https://blog.csdn.net/lw112190/article/details/141200926
版权归原作者 天天代码码天天 所有, 如有侵权,请联系我们删除。

“C# VideoCapture 多路视频播放”的评论:

还没有评论