C#利用ffmpeg借助NVIDIA GPU实现实时RTSP硬解码+硬编码录制MP4

 

目录

说明

效果

项目 

代码

下载


说明

利用周杰的开源项目 Sdcb.FFmpeg

项目地址:https://github.com/sdcb/Sdcb.FFmpeg/

代码实现参考:https://github.com/sdcb/ffmpeg-muxing-video-demo

效果

C#利用ffmpeg借助NVIDIA GPU实现实时RTSP硬解码+硬编码录制MP4

项目 

代码

using Sdcb.FFmpeg.Codecs;
using Sdcb.FFmpeg.Formats;
using Sdcb.FFmpeg.Raw;
using Sdcb.FFmpeg.Toolboxs.Extensions;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Sdcb.FFmpegDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        CancellationTokenSource cts;

        /// <summary>
        /// 播放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = true;
            cts = new CancellationTokenSource();
            string rtsp_url = txtURL.Text;
            //输出视频文件的名称。
            string outputFile = "output.mp4";
            Task.Run(() => Recording(rtsp_url, outputFile, cts.Token));
        }

        void Recording(string url, string outputFile, CancellationToken cancellationToken)
        {
            //输出视频的帧率,帧率设置为每秒25帧
            AVRational frameRate = new AVRational(25, 1);
            
            //输出视频的比特率。
            long bitRate = 16 * 1024 * 1024; // 16M

            //从文件夹读取
            //该字符串指定了源图像的文件夹和命名模式。%03d部分表示图像以三位数字命名(例如,001.jpg,002.jpg等)。
            //string sourceFolder = @".\src\%03d.jpg";
            //FormatContext srcFc = FormatContext.OpenInputUrl(sourceFolder, options: new MediaDictionary
            //{
            //    ["framerate"] = frameRate.ToString()
            //});

            FormatContext srcFc = FormatContext.OpenInputUrl(url);
            srcFc.LoadStreamInfo();
            MediaStream srcVideo = srcFc.GetVideoStream();
            CodecParameters srcCodecParameters = srcVideo.Codecpar;

            CodecContext videoDecoder = new CodecContext(Codec.FindDecoderByName("h264_cuvid"));
            {
            };
            videoDecoder.FillParameters(srcCodecParameters);
            videoDecoder.Open();

            //var d=  Codec.FindDecoders(AVCodecID.H264).Select(x => x.Name);
            //var e = Codec.FindEncoders(AVCodecID.H264).Select(x => x.Name);

            FormatContext dstFc = FormatContext.AllocOutput(OutputFormat.Guess("mp4"));

            dstFc.VideoCodec = Codec.FindEncoderByName("h264_nvenc");
            MediaStream vstream = dstFc.NewStream(dstFc.VideoCodec);

            CodecContext vcodec = new CodecContext(dstFc.VideoCodec)
            {
                Width = srcCodecParameters.Width,
                Height = srcCodecParameters.Height,
                TimeBase = frameRate.Inverse(),
                PixelFormat = AVPixelFormat.Yuv420p,
                Flags = AV_CODEC_FLAG.GlobalHeader,
                BitRate = bitRate,
            };
            vcodec.Open(dstFc.VideoCodec);
            vstream.Codecpar.CopyFrom(vcodec);
            vstream.TimeBase = vcodec.TimeBase;

            IOContext io = IOContext.OpenWrite(outputFile);
            dstFc.Pb = io;
            dstFc.WriteHeader();

            // src        -- srcFc.ReadPackets()          -->
            // src Packet -- DecodePackets(videoDecoder)  -->
            // src Frame  -- ConvertFrames(vcodec)        -->
            // dst Frame  -- EncodeFrames(vcodec)         -->
            // dst Packet -- dstFc.InterleavedWritePacket -->
            // dst

            foreach (Packet packet in srcFc
                .ReadPackets().Where(x => x.StreamIndex == srcVideo.Index)
                .DecodePackets(videoDecoder)
                .ConvertFrames(vcodec)
                .EncodeFrames(vcodec)
                )
            {
                try
                {
                    packet.RescaleTimestamp(vcodec.TimeBase, vstream.TimeBase);
                    packet.StreamIndex = vstream.Index;
                    dstFc.InterleavedWritePacket(packet);

                    if (cancellationToken.IsCancellationRequested) break;
                }
                finally
                {
                    packet.Unref();
                }
            }
            dstFc.WriteTrailer();

            io.Dispose();
            vcodec.Dispose();
            dstFc.Dispose();
            videoDecoder.Dispose();
            srcFc.Dispose();

        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            button2.Enabled = false;
            button1.Enabled = true;
            cts.Cancel();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            button2.Enabled = false;
            button1.Enabled = true;
            Sdcb.FFmpeg.Utils.FFmpegLogger.LogWriter = (level, msg) => Console.WriteLine(msg);
        }
    }

}
 

using Sdcb.FFmpeg.Codecs;
using Sdcb.FFmpeg.Formats;
using Sdcb.FFmpeg.Raw;
using Sdcb.FFmpeg.Toolboxs.Extensions;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Sdcb.FFmpegDemo
{public partial class Form1 : Form{public Form1(){InitializeComponent();}CancellationTokenSource cts;/// <summary>/// 播放/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){button1.Enabled = false;button2.Enabled = true;cts = new CancellationTokenSource();string rtsp_url = txtURL.Text;//输出视频文件的名称。string outputFile = "output.mp4";Task.Run(() => Recording(rtsp_url, outputFile, cts.Token));}void Recording(string url, string outputFile, CancellationToken cancellationToken){//输出视频的帧率,帧率设置为每秒25帧AVRational frameRate = new AVRational(25, 1);//输出视频的比特率。long bitRate = 16 * 1024 * 1024; // 16M//从文件夹读取//该字符串指定了源图像的文件夹和命名模式。%03d部分表示图像以三位数字命名(例如,001.jpg,002.jpg等)。//string sourceFolder = @".\src\%03d.jpg";//FormatContext srcFc = FormatContext.OpenInputUrl(sourceFolder, options: new MediaDictionary//{//    ["framerate"] = frameRate.ToString()//});FormatContext srcFc = FormatContext.OpenInputUrl(url);srcFc.LoadStreamInfo();MediaStream srcVideo = srcFc.GetVideoStream();CodecParameters srcCodecParameters = srcVideo.Codecpar;CodecContext videoDecoder = new CodecContext(Codec.FindDecoderByName("h264_cuvid"));{};videoDecoder.FillParameters(srcCodecParameters);videoDecoder.Open();//var d=  Codec.FindDecoders(AVCodecID.H264).Select(x => x.Name);//var e = Codec.FindEncoders(AVCodecID.H264).Select(x => x.Name);FormatContext dstFc = FormatContext.AllocOutput(OutputFormat.Guess("mp4"));dstFc.VideoCodec = Codec.FindEncoderByName("h264_nvenc");MediaStream vstream = dstFc.NewStream(dstFc.VideoCodec);CodecContext vcodec = new CodecContext(dstFc.VideoCodec){Width = srcCodecParameters.Width,Height = srcCodecParameters.Height,TimeBase = frameRate.Inverse(),PixelFormat = AVPixelFormat.Yuv420p,Flags = AV_CODEC_FLAG.GlobalHeader,BitRate = bitRate,};vcodec.Open(dstFc.VideoCodec);vstream.Codecpar.CopyFrom(vcodec);vstream.TimeBase = vcodec.TimeBase;IOContext io = IOContext.OpenWrite(outputFile);dstFc.Pb = io;dstFc.WriteHeader();// src        -- srcFc.ReadPackets()          -->// src Packet -- DecodePackets(videoDecoder)  -->// src Frame  -- ConvertFrames(vcodec)        -->// dst Frame  -- EncodeFrames(vcodec)         -->// dst Packet -- dstFc.InterleavedWritePacket -->// dstforeach (Packet packet in srcFc.ReadPackets().Where(x => x.StreamIndex == srcVideo.Index).DecodePackets(videoDecoder).ConvertFrames(vcodec).EncodeFrames(vcodec)){try{packet.RescaleTimestamp(vcodec.TimeBase, vstream.TimeBase);packet.StreamIndex = vstream.Index;dstFc.InterleavedWritePacket(packet);if (cancellationToken.IsCancellationRequested) break;}finally{packet.Unref();}}dstFc.WriteTrailer();io.Dispose();vcodec.Dispose();dstFc.Dispose();videoDecoder.Dispose();srcFc.Dispose();}/// <summary>/// 停止/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button2_Click(object sender, EventArgs e){button2.Enabled = false;button1.Enabled = true;cts.Cancel();}private void Form1_Load(object sender, EventArgs e){button2.Enabled = false;button1.Enabled = true;Sdcb.FFmpeg.Utils.FFmpegLogger.LogWriter = (level, msg) => Console.WriteLine(msg);}}}

下载

源码下载

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

助力外骨骼机器人动力学分析

目录 一、动力学分析 二、拉格朗日方程 三、参考文献 一、动力学分析 动力学是考虑引起运动所需要的力&#xff0c;使执行器作用的力矩或施加在操作臂上的外力使操作臂按照这个动力学方程运动。 目前机器人动力学分析中主要采用牛顿-欧拉动力学方程和拉格朗日动力学方程 […

基于大数据的水资源管理与调度优化研究【Web可视化、灰色预测、大屏设计】

需要本项目的私信博主 目录 1 引言 1.1 研究背景 1.2 国内外研究现状 1.3 研究目的 1.4 研究意义 2 关键技术理论介绍 2.1 Python语言 2.2 pandas 2.3 pyecharts 2.4 灰色预测 3 数据来源及处理 3.1 数据来源 3.2 数据处理 4 数据可视化分析及大屏设计 4.1 年度…

08 - debugfs

---- 整理自 王利涛老师 课程 实验环境&#xff1a;宅学部落 www.zhaixue.cc 文章目录 0. 什么是 debugfs1. debugfs 配置编译和注册运行2. 第一个 debugfs 编程示例3. 通过 debugfs 导出整型数据4. 通过 debugfs 导出 16 进制数据5. 通过 debugfs 到处数组6. 通过 debugfs 导出…

Ubuntu20.04可以同时安装ROS(Noetic)和ROS2(Humble)

Ubuntu系统确实可以同时安装ROS&#xff08;Robot Operating System&#xff09;和ROS2&#xff0c;但需要注意一些关键步骤和配置以确保两者能够顺利共存并独立运行。以下是在Ubuntu上同时安装ROS和ROS2的详细步骤和注意事项&#xff1a; 安装前准备 检查Ubuntu版本&#xff…

nacos 动态读取nacos配置中心项目配置

实现了项目稳定运行情况下不需要在项目中改配置&#xff0c;直接在nacos中修改更方便。 pom文件&#xff1a; <!--读取bootstrap文件--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap…

HarmonyOs应用权限申请,system_grant和user_grant区别。本文附头像上传申请user-grant权限代码示例

HarmonyOs应用权限申请&#xff0c;system_grant和user_grant区别。本文附头像上传申请user-grant权限代码示例 system_grant&#xff08;系统授权&#xff09; system_grant指的是系统授权类型&#xff0c;在该类型的权限许可下&#xff0c;应用被允许访问的数据不会涉及到用户…

大数据测试怎么做,数据应用测试、数据平台测试、数据仓库测试

本期内容由中通科技高级质量工程师龙渊在公益讲座中分享&#xff0c;他从大数据测试整体介绍、数据应用测试、数据平台测试以及数据仓库测试等方面&#xff0c;与大家共同探讨了大数据测试的方法实施与落地。 以下是讲座正文&#xff1a; 今天我们分享的内容主要从大数据简介…

二、基于Vue3的开发-环境搭建【Visual Studio Code】扩展组件

Visual Studio Code中的扩展组件 1、安装的扩展工具2、说明2.1 、代码规范性检查EsLint2.2 、代码语法高亮提示工具Vue - Official2.3 、阿里的AI代码开发提示工具 TONGYI Lingma 1、安装的扩展工具 2、说明 2.1 、代码规范性检查EsLint Visual Studio Code 中【设置】-setti…

基于springboot+vue+uniapp的使命召唤游戏助手小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

OSI七层模型中的数据链路层

图片&#xff1a;数据帧的格式 这里面的一个关键点是&#xff0c;数据的源IP和目标IP在哪里&#xff1f; 就在图中的“数据”里面&#xff0c;这个“数据”也就是网络层的数据包&#xff0c;如果是TCP类型的数据包&#xff0c;数据包里面就包含TCP类型的首部信息&#xff0c;…

使用excel把json文件转为表格

json文件格式 [ { "ID": "16", "名称": "测站", "管理ID": "3", "管理名称": "土", "辅助信息": { "百度经度&qu…

linux neo4j 切换知识图谱

neo4j 安装 linux neo4j的安装可以浏览这篇文章&#xff1a; ubuntu sudo apt-get install neo4j 配置安装与设置远程访问 引言 如果你是window用户&#xff0c;直接下载桌面版进行安装与使用即可&#xff1b; 我有一台linux的服务器&#xff0c;想部署在上面&#xff0c;不…

阿里云私有镜像仓库配置及使用

1 登录阿里云 阿里云访问地址&#xff1a;https://www.aliyun.com/ 右上角选择“控制台” 2 创建个人实例 搜索框搜索“容器镜像服务” 新建“个人实例” 选择“创建个人版” 同意协议&#xff0c;点击确定 3 个人实例配置 设置Registry登录密码 密码要求&#xff1…

[Arxiv 2024] Self-Rewarding Language Models

Contents IntroductionMethodExperimentsReferences Introduction 作者提出 Self-Rewarding 训练框架&#xff0c;LLM 在训练过程中同时担任 actor 和 critic&#xff0c;actor 负责合成新数据&#xff0c;critic 负责判断合成数据质量用于组成高质量的偏好数据集用于模型的下…

NoSql数据库Redis集群

一、关系型数据库和 NoSQL 数据库 1.1 数据库主要分为两大类&#xff1a;关系型数据库与 NoSQL 数据库 关系型数据库 &#xff0c;是建立在关系模型基础上的数据库&#xff0c;其借助于集合代数等数学概念和方法来处理数据库中的数据主流的 MySQL 、 Oracle 、 MS SQL Server…

ElasticSearch和Kibana的安全设置以及https设置

&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;ElasticSearch和Kibana的安全设置以及https设置 &#x1f468;‍&#x1f4bb;本文简述&#xff1a;跟着猿灰灰一起学Java&#xff01; &#x1f468;‍&#x1f4bb;上一篇文章&#xff1a; &#x1f468;‍&#x1f4bb;有任…

『功能项目』怪物受击的动画事件【10】

我们打开上一篇09着色器光透魔法球的项目&#xff0c; 本章要做的事情是在场景中创建一个怪物对象&#xff0c;当怪物被主角的魔法球击中后播放受击动画效果&#xff0c;此类技术用到动画事件帧&#xff0c;在动画上创建脚本。 首先打开资源商店选择一个免费资源的怪物模型加载…

apache httpclient速成

目录标题 快速使用连接池参数连接池状态清除闲置连接evictIdleConnections删除过期连接 timeToLive 和evictExpiredConnections 注意释放内存关闭流 http和netty的关系 导入依赖 <dependency><groupId>org.apache.httpcomponents.client5</groupId><artif…

【ceph学习】S3权限认证部分

认证过程简介 认证的过程是一个对用户信息进行解析并且判断前后得到的秘钥是否一致的过程。 auth_regitry的创建 在rgw_main.cc:main()中进行初始化auth_registry对象 /*rgw_main.cc*/ /* Initialize the registry of auth strategies which will coordinate * the dynamic…

浏览器中的开源SQL可视化工具:sqliteviz

sqliteviz&#xff1a; 在浏览器中&#xff0c;即刻开启数据可视化之旅。- 精选真开源&#xff0c;释放新价值。 概览 sqliteviz是一个专为数据可视化而设计的单页离线优先PWA&#xff0c;它利用了现代浏览器技术&#xff0c;让用户无需安装任何软件即可在本地浏览器中进行SQL…