文章目录
需求
实现
需求
在正式开始之前,先介绍下我的需求是怎么样的,基于此需求如何使用ffmpeg实现。仅供参考。

需求点:

将图片保存为视频
图片数量不是固定的,是由上游的webrtc传下的帧数据,转成的bitmap。所以只要webrtc开着,图片流就一直会有。
每帧图像的间隔时间依赖于不同的网络环境,所以不是固定的时间间隔。
实现
在使用原生ffmpeg之前,笔者使用了几个第三方的nuget库,如:FFmpeg.AutoGen、Xabe.FFmpeg、Accord.Video.FFMPEG。前两个库要么只支持将文件夹里现有的图片保存为mp4,要么不支持设置每帧的PTS,导致生成的mp4播放速度太快。最后选用了Accord.Video.FFMPEG,这个库能满足上述的三个需求点。无奈此库已长期不维护,当上游的FPS>15时,WriteVideoFrame方法抛出异常的频率会大大提升,导致内存泄漏,而且当前帧也会被丢掉。

然后项目使用的是.net452,一时半会版本也升级不上去,这就过滤大多数的nuget库。最后,只能使用的原生的ffmpeg了。
ffmpeg只是提供了一个exe,并没有官方的API可供我们调用,只提供了一大堆的参数说明,真是令人头大。经过不断的看文档和搜索调试之后,发现配置以下参数可以达到我们的需求。

-f image2pipe -use_wallclock_as_timestamps 1 -i - -c:v libx264 -pix_fmt yuv420p -vsync passthrough -maxrate 5000k -an -y 123.mp4
1
以下对各参数做个简单介绍:

image2pipe:使用图片管道,我们可以将图片数据一直往管道里塞,ffmpeg会不断将其添加到mp4文件中。用来满足需求1和2.
use_wallclock_as_timestamps 1:开启此选项,ffmpeg就会将接收此图片的时间作为该帧的timestamp。这样生成的MP4播放速度才正常,满足需求3.
pix_fmt yuv420p:设置像素格式,解决生成的视频无法使用windows media player播放的问题。
-vsync passthrough:可以理解为动态帧率,根据上游的帧率来决定输出mp4的帧率。默认有以下几个选项:
passthrough :使用帧原始的timestamp.
cfr (1):根据输出帧率的配置,进行自动插帧(上游帧率小于输入帧率)或者丢帧(上游帧率大于输入帧率)。
vfr (2):类似于passthrough, 不过当两帧具有timestamp时会丢弃其中一个。
drop:类似于passthrough,只不过会丢弃帧原始的timstamp,然后重新生成符合帧率要求的timestamp。
auto (-1):默认行为。在cfr和vfr之前自动选择。
maxrate:设置最大比特率
123.mp4:保存的文件名或者路径,注意里面不要有空格。
最后的C#代码如下,我们需要使用Process类来启动ffmpeg.exe。

public class FfmpegToVideoService
{
private bool _isRunning = false;
private int _fps;
private readonly Process _proc; /// <summary>
/// Bitmap保存为MP4
/// </summary>
/// <param name="filePath">mp4要保存的路径,如:D:\\a\b\123.mp4</param>
/// <param name="maxBitRate">最大比特率,单位K</param>
public FfmpegToVideoService(string filePath,int maxBitRate = 5000)
{
var formattedPath = Path.GetFullPath(filePath);
_proc = new Process();
//-pix_fmt yuv420p -movflags +faststart -r {30} -i pipe:.bmp -r {_fps} -timecode 00:00:00.000
//-vsync cfr自动差值 vfr根据timestamp,重复的丢弃 passthrough根据timestamp重复的不丢 -vsync passthrough
//-r 30 入帧出帧都是30
_proc.StartInfo.FileName = @"ffmpeg.exe";
_proc.StartInfo.Arguments = $"-f image2pipe -use_wallclock_as_timestamps 1 -i - -c:v libx264 -pix_fmt yuv420p -vsync passthrough -maxrate {maxBitRate}k -an -y {formattedPath}";
_proc.StartInfo.WorkingDirectory = CommonFunctions.BasePath;
_proc.StartInfo.UseShellExecute = false;
_proc.StartInfo.RedirectStandardInput = true;
_proc.StartInfo.RedirectStandardOutput = true;
_proc.Start();
} // 将Bitmap数据写入管道
private void SendToPipe(Bitmap bitmap)
{
if (_proc.StartInfo.RedirectStandardInput)
{
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, ImageFormat.Png);
ms.WriteTo(_proc.StandardInput.BaseStream);
}
}
} /// <summary>
/// 异步线程启动服务
/// </summary>
public override void StartAsync()
{
_isRunning = true;
} /// <summary>
/// 停止服务
/// </summary>
public override void Stop()
{
_isRunning = false;
try
{
_proc.StartInfo.RedirectStandardInput = false;
_proc.StartInfo.RedirectStandardOutput = false;
_proc.StandardInput.Close();
_proc.StandardOutput.Close();
_proc.Close();
}
catch (Exception ex)
{
Log.Error(ex, "");
}
} /// <summary>
/// 添加item
/// </summary>
/// <param name="item"></param>
public override void Add(FrameInfo item)
{
if(_isRunning)
{
SendToPipe(item.Bitmap);
}
}
}

https://trac.ffmpeg.org/wiki/Slideshow
https://ffmpeg.org/ffmpeg.html#filter_005foption
https://stackoverflow.com/questions/60977555/adding-current-time-as-timestamp-in-h-264-raw-stream-with-few-frames
————————————————
版权声明:本文为CSDN博主「JimCarter」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/catshitone/article/details/126930470

【C#】使用ffmpeg image2pipe将图片保存为mp4视频的更多相关文章

  1. 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码

    ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...

  2. FFMPEG,将字幕“烧进”MP4视频中

    原文地址:http://blog.csdn.net/ufocode/article/details/75475539 由于mp4容器,不像MKV等容器有自己的字幕流. MKV这种容器的视频格式中,会带 ...

  3. FFmpeg解码视频帧为jpg图片保存到本地

    FFmpeg解码视频帧为jpg图片保存到本地 - CSDN博客 https://blog.csdn.net/qq_28284547/article/details/78151635

  4. ffmpeg 推送、保存rtmp 流命令

    1.将文件当做直播送至live ffmpeg -re -i localFile.mp4 -c copy -f flv rtmp://server/live/streamName 2.将直播媒体保存至本 ...

  5. php 获取远程图片保存到本地

    php 获取远程图片保存到本地 使用两个函数 1.获取远程文件 2.把图片保存到本地 /** * 获取远程图片并把它保存到本地 * $url 是远程图片的完整URL地址,不能为空. */ functi ...

  6. 用qt代码怎样编写图片保存格式[qt4.6]

    用qt代码怎样编写图片保存格式 qt提供了多个保存图片的接口,比较常用的接口如下 bool QPixmap::save ( const QString & fileName, const ch ...

  7. iOS 将图片保存到本地

    //将图片保存到本地 + (void)SaveImageToLocal:(UIImage*)image Keys:(NSString*)key {     NSUserDefaults* prefer ...

  8. C# 图片保存到数据库和从数据库读取图片并显示

    图片保存到数据库的方法: public void imgToDB(string sql)        {   //参数sql中要求保存的imge变量名称为@images            //调 ...

  9. file_put_contents() 图片保存 函数成功之后返回值

    今天弄图片保存时,用到file_put_contents()来保存图片,运行了几次,发下一直没有数据出来,以为是这个函数没操作成功 于是查看了下这个函数的用法和返回值,发现我输出的返回都正确,后来才发 ...

  10. iOS9中将图片保存到照片中的某个相册的方法说明

    iOS9中将图片保存到照片中的某个相册的方法说明 在App中很经常遇到的就是用户点击某张图片后将图片保存到本地,下面介绍下iOS中保存图片的一些东西 1.首先,在iOS中把图片保存到系统照片是比较简单 ...

随机推荐

  1. Leetcode-最小覆盖子串

    题目描述 给你一个字符串 s .一个字符串 t .返回 s 中涵盖 t 所有字符的最小子串.如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" . 注意:如果 s 中 ...

  2. SpringCloud整体架构概览

    什么是SpringCloud #目标 协调任何服务,简化分布式系统开发. #简介 构建分布式系统不应该是复杂的,SpringCloud对常见的分布式系统模式提供了简单易用的编程模型,帮助开发者构建弹性 ...

  3. 在centOS上配置web服务器

    centos,web服务,apache,ftp服务器,mysql,makefile (1). 检查系统是否正常 # more /var/log/messages //检查有无系统内核级错误信息 # d ...

  4. BI、OLAP、多维分析、CUBE 这几个词是什么关系?

    这些词我们在建设分析型应用时经常会听到,这几个词也经常被弄混,这里来梳理一下. BIBI 是 Business Intelligence(商业智能)的缩写,是指企业利用已有数据进行数据分析从而指导商业 ...

  5. docker 应用篇————docker 网络[十七]

    前言 简单介绍一下docker 网络. 正文 使用ip addr. 可以看到网络. 有一个虚拟网卡: 那么基本上容器就处于这样的模式了. 那么也就是所有容器都在同一网关下面了. 那么问题来了,理论上容 ...

  6. Asp-Net-Core开发笔记:使用alpine镜像并加入健康检查

    前言 使用 docker 部署 AspNetCore 应用已经是标配了,之前我一直使用 mcr.microsoft.com/dotnet/aspnet:8.0 这类镜像,简单粗暴,不过可以使用 alp ...

  7. Docker部署Node应用简单实践

    简介: 本文将从零至一,介绍如何在云服务器上通过 Docker 容器运行一个简单的Node应用. 前言 本文将从零至一,介绍如何在云服务器上通过 Docker 容器运行一个简单的Node应用.本文假设 ...

  8. [FAQ] 设置 npm 镜像源

    查看 npm 源: $ npm config get registry> http://registry.npmjs.org/ 修改 npm 源: $ npm config set regist ...

  9. 2019-10-14-云之幻-UWP-视频教程

    title author date CreateTime categories 云之幻 UWP 视频教程 lindexi 2019-10-14 21:8:26 +0800 2019-10-14 21: ...

  10. 魔方OA 数据字典

    https://gitee.com/mojocube/mc-oa/blob/master/Data/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%84%9A%E6%9C%AC.sql ...