C# OpenCvSharp读取rtsp流录制mp4

news2024/12/23 18:12:54

效果

 项目

代码

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace OpenCvSharp读取rtsp流录制mp4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        CancellationTokenSource cts;
        VideoCapture capture;
        Mat frame;
        private volatile bool SaveFlag = false;
        private VideoWriter VideoWriter;

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBoxIP.Text == "" || textBoxPort.Text == "" ||
               textBoxUserName.Text == "" || textBoxPassword.Text == "")
            {
                MessageBox.Show("Please input IP, Port, User name and Password!");
                return;
            }

            String rtspUrl = string.Format("rtsp://{0}:{1}@{2}:{3}"
                , textBoxUserName.Text
                , textBoxPassword.Text
                , textBoxIP.Text
                , textBoxPort.Text
                );

            button1.Enabled = false;
            button2.Enabled = true;

            cts = new CancellationTokenSource();
            Task task = new Task(() =>
            {
                capture.Open(rtspUrl, VideoCaptureAPIs.ANY);
                if (capture.IsOpened())
                {
                    int time = Convert.ToInt32(Math.Round(1000 / capture.Fps));
                    frame = new Mat();
                    //var dsize = new System.Windows.Size(capture.FrameWidth, capture.FrameHeight);
                    while (true)
                    {
                        Thread.Sleep(time);
                        //判断是否被取消;
                        if (cts.Token.IsCancellationRequested)
                        {
                            pictureBox1.Image = null;
                            frame = null;
                            return;
                        }
                        //Read image 会阻塞线程
                        capture.Read(frame);
                        if (frame.Empty())
                            continue;

                        if (SaveFlag && VideoWriter != null)
                        {
                            VideoWriter.Write(frame);
                        }

                        if (pictureBox1.Image != null)
                        {
                            pictureBox1.Image.Dispose();
                        }
                        pictureBox1.Image = BitmapConverter.ToBitmap(frame);
                    }
                }

            }, cts.Token);
            task.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            button2.Enabled = false;
            button1.Enabled = true;
            cts.Cancel();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (capture != null)
            {
                capture.Release();
                capture.Dispose();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            capture = new VideoCapture();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (frame != null)
            {   //图片保存路径和文件名 the path and file name to save
                String sJpegPicFileName = "JPEG_test.jpg";
                String str = "Successful to capture the JPEG file and the saved file is " + sJpegPicFileName;
                Mat dst = frame.Clone();
                Cv2.ImWrite(sJpegPicFileName, dst);
                dst.Dispose();
                MessageBox.Show(str);
            }
        }

        //录像保存路径和文件名 the path and file name to save
        string sVideoFileName = "Record_test.mp4";

        private void button4_Click(object sender, EventArgs e)
        {
            if (capture == null || capture.IsDisposed)
            {
                return;
            }

            if (!capture.IsOpened()) return;

            button4.Enabled = false;
            button5.Enabled = true;

            VideoWriter = new VideoWriter(sVideoFileName, FourCC.MPG4, capture.Fps, new OpenCvSharp.Size(capture.FrameWidth, capture.FrameHeight));
            SaveFlag = true;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            button5.Enabled = false;
            button4.Enabled = true;

            SaveFlag = false;
            if (VideoWriter != null && !VideoWriter.IsDisposed)
            {
                VideoWriter.Dispose();
                VideoWriter = null;
                string str = "Successful to stop recording and the saved file is " + sVideoFileName;
                MessageBox.Show(str);
            }
        }
    }
}

Demo下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/861731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【雕爷学编程】Arduino动手做(12)---霍尔磁场传感器模块2

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

Linux: network: tools: tcpdump,抓取vlan包需要注意的事情;不然会出现LLC协议

https://bugzilla.redhat.com/show_bug.cgi?id498981#c4 https://serverfault.com/questions/544651/vlan-tags-not-shown-in-packet-capture-linux-via-tcpdump 如果不加-e参数,抓取不到 vlan信息,会导致wireshark解析出现问题。因为,抓到…

调整项目符号/项目编号与文本的距离

百度知道多年前的答案是调整标尺,我的PPT里没有标尺 调节悬挂缩进即可

STM32HAL库:简化STM32微控制器开发

简介:在微控制器开发领域,效率、易用性和兼容性至关重要。STMicroelectronics通过其STM32HAL库为这些问题提供了解决方案,该库是专门为STM32微控制器系列设计的软件开发库。本文旨在探索STM32HAL库的特性、优势和应用程序,并提供使…

【看表情包学Linux】初识文件描述符 | 虚拟文件系统 (VFS) 初探 | 系统传递标记位 | O_TRUNC | O_APPEND

爆笑教程《看表情包学Linux》👈 猛戳订阅!​​​​​ 💭 写在前面:通过上一章节的讲解,想必大家已对文件系统基本的接口有一个简单的了解,本章我们将继续深入讲解,继续学习系统传递标志位&…

跨境商城服务平台搭建与开发(金融服务+税务管理)

随着全球电子商务的快速发展,跨境贸易已经成为一种新的商业趋势。在这个背景下,搭建一个跨境商城服务平台,提供金融服务、税务管理等一系列服务,可以极大地促进跨境贸易的发展。本文将详细阐述跨境商城服务平台搭建与开发的步骤。…

在单元测试中使用Jest模拟VS Code extension API

对VS Code extension进行单元测试时通常会遇到一个问题,代码中所使用的VS Code编辑器的功能都依赖于vscode库,但是我们在单元测试中并没有添加对vscode库的依赖,所以导致运行单元测试时出错。由于vscode库是作为第三方依赖被引入到我们的VS C…

SpringBoot集成Redis及Redis使用方法

目录 应用背景 Redis简介 更新问题 一:环境配置 1.1: 在pom.xml文件中添加依赖 1.2:配置SpringBoot核心配置文件application.properties 二:在Config文件夹中创建RedisConfig配置文件类 2.1:RedisTemplate中的几个角色&am…

2023最新版本Activiti7系列-多实例详解

工作流多实例 1.多实例介绍 多实例活动是为业务流程中的某个步骤定义重复的一种方式。在编程概念中,多实例与 for each 结构相匹配:它允许对给定集合中的每个项目按顺序或并行地执行某个步骤或甚至一个完整的子流程。 多实例是一个有额外属性&#xff0…

【Java并发】如何进行死锁诊断?

文章目录 1.什么是死锁2.死锁怎么产生的3.如何进行死锁诊断?3.1 通过命令查看3.2 jconsole可视化工具3.2 VisualVM:故障处理工具 1.什么是死锁 死锁(Deadlock)是指两个或多个进程(线程)在执行过程中&#…

spss什么是描述性分析,以及如何去处理。

描述性分析是数据分析的第一步,是了解和认识数据基本特征和结构的方法,只有在完成了描述性统计分析,充分的了解和认识数据特征后,才能更好地开展后续更复杂的数据分析。因此,描述性分析是开展数据分析过程中最基础且必…

怎么在python里面安装库,如何在python中安装库

大家好,给大家分享一下python外部库安装后放在哪里,很多人还不知道这一点。下面详细解释一下。现在让我们来看看! Python成为最流行的语言之一,除了它的简单易学和语法简单外,还有一个重要的原因是Python有非常强大的第…

PMP认证考试有何变化?该如何备考

截至2023年1月31日,全球有超130万PMP有效持证人士,其中中国有效持证人数已超过了43万人。持有PMP也已成为企业衡量项目经理人专业度的重要指标之一。 PMP考证人数的快速发展,与其考试大纲和知识体系的科学性和实战性密不可分。PMP考纲和教材…

【雕爷学编程】Arduino动手做(201)---行空板硬件控制之LED与按键

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

数组slice、splice字符串substr、split

一、定义 这篇文章主要对数组操作的两种方法进行介绍和使用,包括:slice、splice。对字符串操作的两种方法进行介绍和使用,包括:substr、split (一)、数组 slice:可以操作的数据类型有:数组字符串 splice:数组 操作数组…

Spring依赖注入、对象装配

文章目录 依赖注入与对象装配依赖注入的常见方式属性注入(Property Injection)属性注入的优缺点 Setter 注入(Setter Injection)Setter注入优缺点 构造函数注入(Constructor Injection)构造函数注入优缺点 …

Unity游戏源码分享-多角色fps射击游戏

Unity游戏源码分享-多角色fps射击游戏 项目地址:https://download.csdn.net/download/Highning0007/88204023

Flutter BottomSheet 三段式拖拽

BottomSheetBehavior 追踪 BottomSheet系统默认实现效果准备要实现的功能点:定义三段式状态:BottomSheetBehavoir阀值定义1. 未达到滚动阀值,恢复状态2. 达到滚动阀值,更新状态 前面倒是有讲过Android原生的BottomSheetBehavior&a…

Camunda 7.x 系列【2】开源工作流引擎框架

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 开源工作流引擎框架2.1 jBPM2.2 Activ…

综合技巧练习 - Packet Tracer 简介

1.7.1:综合技巧练习 - Packet Tracer 简介 拓扑图: 以基本完成的逻辑拓扑为起点。 设备 接口 IP 地址 子网掩码 默认网关 R1-ISP Fa0/0 192.168.254.253 255.255.255.0 不适用 S0/0/0 10.10.10.6 255.255.255.252 R2-Central Fa0/0 17…