C# 和 FFmpeg 最好没有 shell 命令?

Posted

技术标签:

【中文标题】C# 和 FFmpeg 最好没有 shell 命令?【英文标题】:C# and FFmpeg preferably without shell commands? 【发布时间】:2010-12-15 00:25:39 【问题描述】:

我希望能够使用 FFmpeg 从我的 C# 程序中转换视频文件。我知道我可以调用一个 shell 命令,但是有更好的方法吗?

通过 shell 调用命令的问题是,我不确定您是否可以执行诸如进度条之类的操作……或者您可以吗?

如果没有办法,任何人都可以建议最好的方法来布局一些框架以执行 shell 命令。传递一个大长字符串是非常麻烦的atm。

【问题讨论】:

有人吗?来吧,一定有人在 .net 中使用过 ffmpeg 【参考方案1】:

如果运行 ffmpeg,您可以轻松实现进度条。 ffmpeg 运行时的输出是这样的:

frame= 3366 fps=465 q=31.0 Lsize=    6474kB time=140.35 bitrate= 377.9kbits/s

它每秒刷新两次。您可以解析该行并获取显示进度所需的数据。当你在命令行中运行时,你只会看到一直在更新的一行,但 ffmpeg 所做的就是写一行后面跟着 \r。这就是为什么你看不到多行。但是,当在程序的错误输出上使用 StreamReader.ReadLine() 时,每次更新都会得到一行。

读取输出的示例代码如下。您将不得不忽略任何不以 'frame' 开头的行,如果您希望读取行异步等,可能使用BeginErrorReadLine()+ErrorDataReceived,但您明白了(我已经实际测试过了) :

using System;
using System.Diagnostics;
using System.IO;

class Test 
        static void Main (string [] args)
        
                Process proc = new Process ();
                proc.StartInfo.FileName = "ffmpeg";
                proc.StartInfo.Arguments = "-i " + args [0] + " " + args [1];
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.UseShellExecute = false;
                if (!proc.Start ()) 
                        Console.WriteLine ("Error starting");
                        return;
                
                StreamReader reader = proc.StandardError;
                string line;
                while ((line = reader.ReadLine ()) != null) 
                        Console.WriteLine (line);
                
                proc.Close ();
        

【讨论】:

啊...我一直在尝试重定向到标准输出...不是错误。它突然起作用了:P +1:我在 Java 中做过同样的事情,对结果非常非常满意。但是有一些问题:像time 值,可以是第一次更新的进度行输出的 100000000 int 之类的东西。我的直觉说这是一个内部初始化值。 可能是的。只需使用谓词语句来消除高于某个合理范围的值。脏,但它会工作【参考方案2】:

在 .NET 的 FFmpeg 上有一个 wrapper 库。

【讨论】:

"目前音频解码和编码已经成熟,视频功能正在开发中(我们目前有视频解码工作,但还没有同步音频)。"我需要音频正常工作。 不幸的是,该项目自 +2 年前的上述 cmets 以来一直没有更新。并且没有二进制分布;你必须检查代码并自己构建它。【参考方案3】:

几周前我在寻找问题的答案时发现了这篇文章。 我试图启动 ffmpeg 进程并将参数传递给它,但是做所有事情都需要很长时间。此时我使用Xabe.FFmpeg,因为它开箱即用,不必担心 ffmpeg 可执行文件,因为它具有下载最新版本的功能。

bool conversionResult = await new Conversion().SetInput(Resources.MkvWithAudio)
  .AddParameter(String.Format("-f image2pipe -i pipe:.bmp -maxrate 0k -r 1 -an -y 2",bitrate, fps, outputfilename))
  .Start();

有可用的文档here 显示如何获取当前的转化百分比。

【讨论】:

【参考方案4】:

我刚刚在 sourceforge 找到了fflib。看起来很有前途,不过还没用过。

【讨论】:

【参考方案5】:

如何围绕 ffmpeg 的本机接口编写 C++/CLI 包装器,然后从应用程序调用包装器接口?

【讨论】:

VC 编译器不支持 ffmpeg 中使用的许多 C 语言结构。 ffmpeg 团队有兴趣看到有人成功将代码移植到 VC。

以上是关于C# 和 FFmpeg 最好没有 shell 命令?的主要内容,如果未能解决你的问题,请参考以下文章

如何用C#处理视频!

检测 FFmpeg 安装和版本

ffmpeg在shell循环中只执行一次问题

命令在控制台中能正常执行但在shell脚本中却无法执行?

使用JAVA调用ffmpeg组件进行视频转换时不成功

在ubuntu下怎么用php代码自动调用ffmpeg命令来进行视频采集录制,抽帧!!是要调用shell脚本吗??急!!