当前位置:   article > 正文

C# VideoCapture 多路视频播放

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

}
 

  1. using OpenCvSharp;
  2. using System;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using System.Windows.Forms;
  9. namespace MultiVideoDemo
  10. {
  11. public partial class Form4 : Form
  12. {
  13. public Form4()
  14. {
  15. InitializeComponent();
  16. }
  17. CancellationTokenSource ctsShow;
  18. CancellationTokenSource[] taskCTS = new CancellationTokenSource[6];
  19. ConcurrentQueue<Mat>[] matQueue = new ConcurrentQueue<Mat>[6];
  20. int fps = 25;
  21. string[] rtsp_url = new string[40];
  22. List<RTSPURLInfo> play_rtsp_url = new List<RTSPURLInfo>();
  23. /// <summary>
  24. /// 停止
  25. /// </summary>
  26. /// <param name="sender"></param>
  27. /// <param name="e"></param>
  28. private void button2_Click(object sender, EventArgs e)
  29. {
  30. ctsShow.Cancel();
  31. for (int i = 0; i < 6; i++)
  32. {
  33. taskCTS[i].Cancel();
  34. }
  35. }
  36. private void Form1_Load(object sender, EventArgs e)
  37. {
  38. //初始化
  39. for (int i = 0; i < 6; i++)
  40. {
  41. taskCTS[i] = new CancellationTokenSource();
  42. matQueue[i] = new ConcurrentQueue<Mat>();
  43. }
  44. for (int i = 0; i < 40; i++)
  45. {
  46. rtsp_url[i] = "1.dav";
  47. }
  48. //play_rtsp_url
  49. for (int i = 0; i < 6; i++)
  50. {
  51. play_rtsp_url.Add(new RTSPURLInfo((i + 1).ToString(), rtsp_url[i]));
  52. }
  53. }
  54. /// <summary>
  55. /// 播放
  56. /// </summary>
  57. /// <param name="sender"></param>
  58. /// <param name="e"></param>
  59. private void button1_Click(object sender, EventArgs e)
  60. {
  61. ctsShow = new CancellationTokenSource();
  62. for (int i = 0; i < 6; i++)
  63. {
  64. taskCTS[i] = new CancellationTokenSource();
  65. matQueue[i] = new ConcurrentQueue<Mat>();
  66. }
  67. play_rtsp_url.Clear();
  68. for (int i = 0; i < 6; i++)
  69. {
  70. play_rtsp_url.Add(new RTSPURLInfo((i + 1).ToString(), rtsp_url[i]));
  71. }
  72. for (int i = 0; i < play_rtsp_url.Count; i++)
  73. {
  74. Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
  75. System.Threading.Thread.Sleep(100);
  76. }
  77. //显示线程
  78. Task.Run(() =>
  79. {
  80. Mat mat = new Mat();
  81. string winName = "video";
  82. Cv2.NamedWindow(winName, WindowFlags.Normal);
  83. Cv2.ResizeWindow(winName, fullSize);
  84. int delay = (int)(1000 / fps);
  85. Stopwatch stopwatch = new Stopwatch();
  86. while (true)
  87. {
  88. stopwatch.Restart();
  89. delay = (int)(1000 / fps);
  90. if (ctsShow.IsCancellationRequested) break;
  91. Mat frame = CombiningImages();
  92. Cv2.ImShow(winName, frame);
  93. delay = (int)(delay - stopwatch.ElapsedMilliseconds);
  94. if (delay <= 0)
  95. {
  96. delay = 1;
  97. }
  98. Console.WriteLine("delay:" + delay.ToString());
  99. Cv2.WaitKey(delay);
  100. frame.Dispose();
  101. }
  102. Cv2.DestroyAllWindows();
  103. });
  104. }
  105. OpenCvSharp.Size fullSize = new OpenCvSharp.Size(1008, 570);
  106. OpenCvSharp.Size mainSize = new OpenCvSharp.Size(672, 380);
  107. OpenCvSharp.Size subSize = new OpenCvSharp.Size(336, 190);
  108. Mat CombiningImages()
  109. {
  110. Console.WriteLine(string.Format("matQueue0:{0},matQueue1:{1},matQueue2:{2},matQueue3:{3},matQueue4:{4},matQueue5:{5}"
  111. , matQueue[0].Count
  112. , matQueue[1].Count
  113. , matQueue[2].Count
  114. , matQueue[3].Count
  115. , matQueue[4].Count
  116. , matQueue[5].Count
  117. ));
  118. Mat mat = Mat.Zeros(fullSize, MatType.CV_8UC3);
  119. Mat mat0 = new Mat();
  120. matQueue[0].TryDequeue(out mat0);
  121. if (mat0 == null || mat0.Empty())
  122. {
  123. mat0 = Mat.Zeros(mainSize, MatType.CV_8UC3);
  124. }
  125. Cv2.Resize(mat0, mat0, mainSize);
  126. Mat mat1 = new Mat();
  127. matQueue[1].TryDequeue(out mat1);
  128. if (mat1 == null || mat1.Empty())
  129. {
  130. mat1 = Mat.Zeros(subSize, MatType.CV_8UC3);
  131. }
  132. Cv2.Resize(mat1, mat1, subSize);
  133. Mat mat2 = new Mat();
  134. matQueue[2].TryDequeue(out mat2);
  135. if (mat2 == null || mat2.Empty())
  136. {
  137. mat2 = Mat.Zeros(subSize, MatType.CV_8UC3);
  138. }
  139. Cv2.Resize(mat2, mat2, subSize);
  140. Mat mat3 = new Mat();
  141. matQueue[3].TryDequeue(out mat3);
  142. if (mat3 == null || mat3.Empty())
  143. {
  144. mat3 = Mat.Zeros(subSize, MatType.CV_8UC3);
  145. }
  146. Cv2.Resize(mat3, mat3, subSize);
  147. Mat mat4 = new Mat();
  148. matQueue[4].TryDequeue(out mat4);
  149. if (mat4 == null || mat4.Empty())
  150. {
  151. mat4 = Mat.Zeros(subSize, MatType.CV_8UC3);
  152. }
  153. Cv2.Resize(mat4, mat4, subSize);
  154. Mat mat5 = new Mat();
  155. matQueue[5].TryDequeue(out mat5);
  156. if (mat5 == null || mat5.Empty())
  157. {
  158. mat5 = Mat.Zeros(subSize, MatType.CV_8UC3);
  159. }
  160. Cv2.Resize(mat5, mat5, subSize);
  161. //第一张主图
  162. Rect roi0 = new Rect(0, 0, 672, 380);
  163. Mat position0 = new Mat(mat, roi0);
  164. mat0.CopyTo(position0);
  165. //第二张图
  166. Rect roi1 = new Rect(672, 0, 336, 190);
  167. Mat position1 = new Mat(mat, roi1);
  168. mat1.CopyTo(position1);
  169. //第三张图
  170. Rect roi2 = new Rect(672, 190, 336, 190);
  171. Mat position2 = new Mat(mat, roi2);
  172. mat2.CopyTo(position2);
  173. //4张图
  174. Rect roi3 = new Rect(672, 380, 336, 190);
  175. Mat position3 = new Mat(mat, roi3);
  176. mat3.CopyTo(position3);
  177. //5张图
  178. Rect roi4 = new Rect(336, 380, 336, 190);
  179. Mat position4 = new Mat(mat, roi4);
  180. mat4.CopyTo(position4);
  181. //6张图
  182. Rect roi5 = new Rect(0, 380, 336, 190);
  183. Mat position5 = new Mat(mat, roi5);
  184. mat5.CopyTo(position5);
  185. mat0.Dispose();
  186. mat1.Dispose();
  187. mat2.Dispose();
  188. mat3.Dispose();
  189. mat4.Dispose();
  190. mat5.Dispose();
  191. position0.Dispose();
  192. position1.Dispose();
  193. position2.Dispose();
  194. position3.Dispose();
  195. position4.Dispose();
  196. position5.Dispose();
  197. return mat;
  198. }
  199. void DecodeRTSP(string index, ConcurrentQueue<Mat> matQueue, string url, CancellationToken cancellationToken = default)
  200. {
  201. VideoCapture vcapture = new VideoCapture(url);
  202. if (!vcapture.IsOpened())
  203. {
  204. Console.WriteLine("打开视频文件失败");
  205. return;
  206. }
  207. // 计算等待时间(毫秒)
  208. int taskDelay = (int)(1000 / fps);
  209. Stopwatch stopwatch = new Stopwatch();
  210. while (true)
  211. {
  212. if (cancellationToken.IsCancellationRequested) break;
  213. stopwatch.Restart();
  214. Mat frame = new Mat();
  215. if (!vcapture.Read(frame))
  216. {
  217. Console.WriteLine("读取失败");
  218. break;
  219. }
  220. taskDelay = (int)(1000 / fps);
  221. //中间标注数字,模拟路数
  222. Cv2.PutText(frame, index.ToString(), new OpenCvSharp.Point(frame.Width / 2, frame.Height / 2), HersheyFonts.HersheySimplex, 20, Scalar.Red, 20);
  223. matQueue.Enqueue(frame);
  224. taskDelay = (int)(taskDelay - stopwatch.ElapsedMilliseconds);
  225. if (matQueue.Count > 100)
  226. {
  227. Console.WriteLine("index:" + index + ",后续处理能力不足……");
  228. }
  229. if (matQueue.Count < 10)
  230. {
  231. taskDelay = taskDelay - 5;
  232. }
  233. if (taskDelay <= 0)
  234. {
  235. taskDelay = 0;
  236. }
  237. Console.WriteLine("index:" + index + ",taskDelay:" + taskDelay);
  238. Task.Delay(taskDelay).Wait();
  239. }
  240. vcapture.Release();
  241. }
  242. /// <summary>
  243. /// 取消第一路
  244. /// </summary>
  245. /// <param name="sender"></param>
  246. /// <param name="e"></param>
  247. private void button4_Click(object sender, EventArgs e)
  248. {
  249. taskCTS[0].Cancel();
  250. }
  251. /// <summary>
  252. /// 记载第7
  253. /// </summary>
  254. /// <param name="sender"></param>
  255. /// <param name="e"></param>
  256. private void button3_Click(object sender, EventArgs e)
  257. {
  258. for (int i = 0; i < 6; i++)
  259. {
  260. taskCTS[i].Cancel();
  261. }
  262. for (int i = 0; i < 6; i++)
  263. {
  264. taskCTS[i] = new CancellationTokenSource();
  265. }
  266. //删除最后一个元素
  267. play_rtsp_url.RemoveAt(play_rtsp_url.Count - 1);
  268. //把第7路的地址 放到第一的位置
  269. play_rtsp_url.Insert(0, new RTSPURLInfo("7", rtsp_url[6]));
  270. for (int i = 0; i < play_rtsp_url.Count; i++)
  271. {
  272. Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
  273. System.Threading.Thread.Sleep(10);
  274. }
  275. }
  276. /// <summary>
  277. /// 加载第8
  278. /// </summary>
  279. /// <param name="sender"></param>
  280. /// <param name="e"></param>
  281. private void button5_Click(object sender, EventArgs e)
  282. {
  283. for (int i = 0; i < 6; i++)
  284. {
  285. taskCTS[i].Cancel();
  286. }
  287. for (int i = 0; i < 6; i++)
  288. {
  289. taskCTS[i] = new CancellationTokenSource();
  290. }
  291. //删除最后一个元素
  292. play_rtsp_url.RemoveAt(play_rtsp_url.Count - 1);
  293. //把第8路的地址 放到第一的位置
  294. play_rtsp_url.Insert(0, new RTSPURLInfo("8", rtsp_url[7]));
  295. for (int i = 0; i < play_rtsp_url.Count; i++)
  296. {
  297. Task.Run(() => DecodeRTSP(play_rtsp_url[i].index, matQueue[i], play_rtsp_url[i].url, taskCTS[i].Token));
  298. System.Threading.Thread.Sleep(10);
  299. }
  300. }
  301. }
  302. public class RTSPURLInfo
  303. {
  304. public string index;
  305. public string url;
  306. public RTSPURLInfo(string index, string url)
  307. {
  308. this.index = index;
  309. this.url = url;
  310. }
  311. }
  312. }

下载

源码下载

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/1005650
推荐阅读
相关标签
  

闽ICP备14008679号