当前位置: 首页 > news >正文

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_urlfor (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;}}}

下载

源码下载

相关文章:

  • uniapp粘贴板地址识别 address-parse插件的使用
  • 20240810在荣品RK3588S-AHD开发板的预置Android13下挂载exFAT的256GB的TF卡
  • 十二、OpenCVSharp 中的图像匹配与模板匹配
  • buildroot是啥,用来干什么?怎么用
  • ImportError: DLL load failed: 找不到指定的程序的解决方案
  • GLM4 API 调用方法
  • CH07_数据绑定
  • 电子电气架构 --- 座舱域控制器:一芯多屏快速渗透
  • 【定稿】英飞凌Aurix2G TC3XX CAN模块详解
  • extern在头文件中添加是否必要?(C/C++)
  • 怎么衡量数据仓库模型的优与劣
  • 电池常用,但电芯热电耦合难?科学仿真技术轻松解决
  • 接口优化笔记
  • ThinkPHP5漏洞分析之代码执行
  • LeeCode Practice Journal | Day44_DP11 子序列问题
  • JavaScript 如何正确处理 Unicode 编码问题!
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • Apache Zeppelin在Apache Trafodion上的可视化
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • docker-consul
  • GitUp, 你不可错过的秀外慧中的git工具
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • leetcode98. Validate Binary Search Tree
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • 从setTimeout-setInterval看JS线程
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 用 Swift 编写面向协议的视图
  • ​secrets --- 生成管理密码的安全随机数​
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • (1)svelte 教程:hello world
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (安卓)跳转应用市场APP详情页的方式
  • (待修改)PyG安装步骤
  • (第27天)Oracle 数据泵转换分区表
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)视频码率,帧率和分辨率的联系与区别
  • (转载)利用webkit抓取动态网页和链接
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET Core引入性能分析引导优化
  • .Net Winform开发笔记(一)
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • .net开发引用程序集提示没有强名称的解决办法
  • .NET学习全景图
  • /dev/sda2 is mounted; will not make a filesystem here!
  • @antv/x6 利用interacting方法来设置禁止结点移动的方法实现。
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [2]十道算法题【Java实现】
  • [20150629]简单的加密连接.txt