史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)

摘要:
Ffmpeg.exe是一个众所周知的视频处理软件,以命令行参数的形式运行。互联网上也有很多关于ffmpeg的信息。今天,石林峰将以实用的方式探索C#操作ffmpeg的奥秘。这里不会过多介绍ffmpeg及其参数命令的使用。当作者关闭调试Winform程序时,几秒钟后,ffmpeg.exe似乎再次工作,文件被成功处理。

ffmpeg.exe是大名鼎鼎的视频处理软件,以命令行参数形式运行。网上也有很多关于ffmpeg的资料介绍。但是在用C#做实际开发时,却遇到了几个问题及注意事项,比如如何无损处理视频?如何在转换格式的同时添加水印,以提升处理效率?,ffmpeg的版本应该选择什么版本?。今天史林峰将用实战的方式来探索C#操作ffmpeg的奥秘。

关于ffmpeg的使用及其参数命令,这里就不做过多介绍了。主要以项目实战中为主。

因工作需要,笔者手头有近300部短视频需要处理,在网上找了不少工具,虽然能用,但是用起来却有一种Hold不住的感觉。要么是处理后有软件水印或片花,要么是不能直接批量一次性处理完,视频要一个一个地去设置。

这里主要需求是给现有的视频做格式转换,如果视频格式已经满足要求,就直接在指定位置加水印(png图片),在处理完之后,为了解决磁盘空间,在视频处理完成之后要删除原视频。笔者对C#语言是最熟知的,因此选用C# Winform做一个简易的视频批处理软件。

先上一张完工的项目截图:

 

史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)第1张

 

在指定目录中读取视频,然后一件处理即可(中间的截取秒数的参数,属于视频剪切,暂时没有这块功能)

 

现有的视频均为flv格式的,通过C#调用ffmpeg,转换为mp4格式,并添加水印

C#调用ffmpeg的方法封装如下:

史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)第2张史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)第3张
 1 /// <summary>
 2 /// 视频处理器ffmpeg.exe的位置
 3 /// </summary>
 4 public string FFmpegPath { get; set; }
 5  
 6 /// <summary>
 7 /// 调用ffmpeg.exe 执行命令
 8 /// </summary>
 9 /// <param name="Parameters">命令参数</param>
10 /// <returns>返回执行结果</returns>
11 private string RunProcess(string Parameters)
12 {
13 //创建一个ProcessStartInfo对象 并设置相关属性
14 var oInfo = new ProcessStartInfo(FFmpegPath, Parameters);
15 oInfo.UseShellExecute = false;
16 oInfo.CreateNoWindow = true;
17 oInfo.RedirectStandardOutput = true;
18 oInfo.RedirectStandardError = true;
19 oInfo.RedirectStandardInput = true;
20  
21 //创建一个字符串和StreamReader 用来获取处理结果
22 string output = null;
23 StreamReader srOutput = null;
24  
25 try
26 {
27     //调用ffmpeg开始处理命令
28     var proc = Process.Start(oInfo);
29  
30     proc.WaitForExit();
31  
32  
33     //获取输出流
34     srOutput = proc.StandardError;
35  
36     //转换成string
37     output = srOutput.ReadToEnd();
38  
39     //关闭处理程序
40     proc.Close();
41 }
42 catch (Exception)
43 {
44     output = string.Empty;
45 }
46 finally
47 {
48     //释放资源
49     if (srOutput != null)
50     {
51         srOutput.Close();
52         srOutput.Dispose();
53     }
54 }
55 return output;
56 }
View Code

转换格式的命令参数:-i orignal.flv -y -b 1024k -acodec copy -f mp4 newFile.mp4

添加水印的命令参数:-i orignal.flv -i water.png -filter_complex \"overlay=10:10\" newFile.flv

参数简要说明和细节提示:

orignal.flv : 要处理的原始视频文件(最好是绝对路径)
-y : 覆盖已有文件(注意,加水印不可覆盖原始文件,否则只能生成1秒的视频)
-b:视频的码率 这里设置1024k 基本可满足无损处理 如不设置-b参数则默认为200k 视频会非常模糊
-acodec copy : 保持音频质量不变
-f mp4 : 表示转换的视频格式
 
-i water.png : 水印图片路径
overlay=10:10 : 水印距离视频的左上角坐标
其他位置参数:
右上角:main_w-overlay_w-10:10
左下角:10:main_h-overlay_h-10
右下角:main_w-overlay_w-10:main_h-overlay_h-10
 
newFile.mp4  要保存的文件路径

上面这个方法就是核心处理。笔者在实际执行的过程中,发现了以下问题:

  在使用cmd窗口执行以上命令时(cmd中参数前面要加 ffmpeg 注意文件位置),可以成功处理,但在运行Winform测试的时候,发现只有一个大小为0kb的新文件生成,但迟迟不见处理。给人一种假死的现象。而当笔者关掉调试的Winform程序时,过几秒钟,貌似ffmpeg.exe 又起作用了,文件处理成功了。这个不得其解。(在调用处理程序时,新开了一个线程执行的)

排查情况:

  可能是ffmpeg的版本问题,于是下载了2.8.2版本(应该是最新的),测试,没有任何变化

  检查程序的调用流程,将调用过程cmd窗口显示出来。结果一片空白,什么也没有,依然是没有效果。

最后在经过各种资料的查找之后,在不经意间看到有人说 proc.WaitForExit(); 这句执行会造成程序一直处于等待状态。是的,没错,以前做类似程序调用也是这样做的,也没出现过这种问题。于是,抱着试试看的态度,注释了这一句。当然,程序不再等待执行完毕,proc.Close(); 这一句也要注释一下。测试结果成功!!(懂得底层原理的大牛,望告知一二)

 

问题解决了,但是还有一个处理效率的问题:如何更快的处理?

笔者尝试了各种命令的组合,发现对于不同版本的ffmpeg,有的参数是不能使用的,就笔者使用的2.8.2版本最终 找了一个比较好的解决方案:

可以选择使用以下命令参数:

-i orignal.flv -i water.png -filter_complex \"overlay=10:10\" -y -b 1024k -acodec copy -f mp4

 

-i orignal.flv -i water.png -filter_complex \"overlay=10:10\" -b 1024k -acodec copy

 

上面一个适合同时转换格式和加水印

下面一个适合只加水印,不做格式转换

这些核心问题解决了,剩下的就是文件的读取,保存,判断等等细节了。

 

总结:                                                          

  1. C#调用ffmpeg时 不要使用proc.WaitForExit();方法,否则会假死

  2. ffmpeg的版本最好使用最新版本,并参考命令参数说明

  3. 无损转换,无损加水印 要注意保证视频的码率 和音频的参数(直接copy,视频不能这样写-avcodec copy  会报错,只能用-b设置视频码率) 

  4. 一步到位的处理方法(转换的同时加水印,参考上面的命令参数)

 

程序开发好之后,笔者不用再苦逼地一个一个去设置,处理了,电脑开着,显示器关闭,只听见主机嗷嗷叫的处理,等吃完饭,所有事情均已搞定。。。

 

 

 

 

免责声明:文章转载自《史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇网页支付页面代码Windows系统使用QEMU虚拟机安装树莓派下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

玩转FFmpeg的7个小技巧

原文链接:http://www.linuxidc.com/Linux/2011-06/36973.htm FFmpeg堪称音频和视频应用程序的瑞士军刀,提供了丰富的选项和灵活性.很多时候用户为了看视频和听音乐都安装了ffmeg.更多关于ffmeg的详细介绍:here,可以通过ffmpeg -formats查看FFmpeg支持的视音频格式,左侧若是E表明可...

C# Emgucv3.0的安装与配置

环境:vs2015+Emgucv3.0 Emgu Cv简介: Emgu CV是.NET平台下对OpenCV图像处理库的封装。也就是OpenCV的.NET版。它运行在.NET兼容的编程语言下调用OpenCV的函数,如C#、VB、VC++等。同时这个封装库可以在Mono下编译和在Linux / Mac OS X上运行。Emgu Cv的优势在于.net非常完美的...

C#使用FFmpeg的总结

上篇文章提到FFmpeg解决项目中视频和语音问题,说道C#和FFmpeg不得不提的2个类库。 1、Xabe.FFmpeg 简单查看了下源码和demo,发现基于ffmpeg.exe的命令行参数进行处理。 2、FFmpeg.AutoGen 把C语言对外API和类型翻译成C#的API和对象。 看了一下这个源码生成,其中使用了CppSharp来生成g.cs的文件,...

C#基础(六)——值类型与引用类型

CLR支持两种类型:值类型和引用类型。 值类型包括C#的基本类型(用关键字int、char、float等来声明),结构(用struct关键字声明的类型),枚举(用enum关键字声明的类型);而引用类型包括类(用class关键字声明的类型)和委托(用delegate关键字声明的特殊类)等。 C#中的每一种类型要么是值类型,要么是引用类型。所以每个对象要么是值...

在mac环境下用c#进行SDL2游戏开发

虽然笔者是在Rider下实现的,不过VS下也是可以用的 最近为了折腾这SDL2,可是废了点时间,尝试用C/C++/Go/C#进行开发,结果发现: C/C++环境好设置,但是cmake配置麻烦(对于没用过的我来说),而且我受够了引入文件总要include Go最省心,go mod包管理永远的神!sdl2库的api封装也是用起来最舒服的 C#在windows...

C# 连接Oracle数据库,免安装oracle客户端

一、方案1 首先下面的内容,有待我的进一步测试和证实。18.12.20 被证实了,还需要安装Oracle客户端,或者本机上安装oracle数据库软件。 18.12.20 1.下载Oracle.ManagedDataAccess.dll 2.添加到C#引用 3.命名空间引用 using Oracle.ManagedDataAccess.Client; 4....