【问题标题】:ffmpeg run from shell runs properly, but does not when called from within .NET从 shell 运行的 ffmpeg 运行正常,但从 .NET 中调用时不能正常运行
【发布时间】:2013-04-02 01:51:40
【问题描述】:

我正在尝试在 C# 程序中使用 ffmpeg(使用 Cygwin 在 Windows 上编译),方法是使用 Process 类生成 ffmpeg 实例。但是,我遇到了一个没有多大意义的奇怪错误。

当我直接从 shell(无论是 Cygwin 的 bash、PowerShell、cmd)运行 ffmpeg 时,ffmpeg 可以正确解码和重新编码文件而不会出现任何问题:

PS C:\audio> ffmpeg -i .\sound1.wav -acodec libvorbis -f ogg abc.ogg
ffmpeg version 1.2 Copyright (c) 2000-2013 the FFmpeg developers
  built on Apr  8 2013 15:10:40 with gcc 4.5.3 (GCC)
  configuration: --disable-encoder=vorbis --enable-libvorbis
  libavutil      52. 18.100 / 52. 18.100
  libavcodec     54. 92.100 / 54. 92.100
  libavformat    54. 63.104 / 54. 63.104
  libavdevice    54.  3.103 / 54.  3.103
  libavfilter     3. 42.103 /  3. 42.103
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
[wav @ 0x800538a0] max_analyze_duration 5000000 reached at 5015510 microseconds
Guessed Channel Layout for  Input Stream #0.0 : stereo
Input #0, wav, from '.\sound1.wav':
  Metadata:
    encoder         : Lavf54.63.104
  Duration: 00:00:05.76, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Output #0, ogg, to 'abc.ogg':
  Metadata:
    encoder         : Lavf54.63.104
    Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le -> libvorbis)
Press [q] to stop, [?] for help
size=      55kB time=00:00:05.74 bitrate=  78.5kbits/s
video:0kB audio:51kB subtitle:0 global headers:4kB muxing overhead 0.817473%

文件播放良好,我可以编码为 WAV 或我喜欢的任何其他格式。但是,当我使用以下代码从 C# 调用 ffmpeg 时:

string tempfile = Path.GetTempFileName();
FileStream tempfilestr = File.OpenWrite(tempfile);
input.CopyTo(tempfilestr);

ProcessStartInfo pstart = new ProcessStartInfo("ffmpeg", string.Format("-i \"{0}\" -v verbose -y -f wav -", tempfile));
pstart.CreateNoWindow = true;
pstart.ErrorDialog = false;
pstart.RedirectStandardOutput = true;
pstart.RedirectStandardError = true;
pstart.UseShellExecute = false;


Process proc = new Process();
proc.StartInfo = pstart;
proc.Start();
StreamReader stdout = proc.StandardOutput;
StreamReader stderr = proc.StandardError;

outtempfilestr = File.OpenRead(outtempfile);
MemoryStream output = new MemoryStream();

stdout.BaseStream.CopyTo(output);

try {
    proc.Kill();
}
catch(InvalidOperationException) { }
catch(Win32Exception) { }

File.Delete(tempfile);

return output.ToArray();

这个随机会在输出中产生错误:

ffmpeg version 1.2 Copyright (c) 2000-2013 the FFmpeg developers
  built on Apr  8 2013 15:10:40 with gcc 4.5.3 (GCC)
  configuration: --disable-encoder=vorbis --enable-libvorbis
  libavutil      52. 18.100 / 52. 18.100
  libavcodec     54. 92.100 / 54. 92.100
  libavformat    54. 63.104 / 54. 63.104
  libavdevice    54.  3.103 / 54.  3.103
  libavfilter     3. 42.103 /  3. 42.103
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
[wav @ 0x80053860] parser not found for codec pcm_s16le, packets or times may be invalid.
    Last message repeated 1 times
[wav @ 0x80053860] max_analyze_duration 5000000 reached at 5015510 microseconds
Guessed Channel Layout for  Input Stream #0.0 : stereo
Input #0, wav, from 'C:\Users\Bevin\AppData\Local\Temp\tmp1CCE.tmp':
  Duration: 00:00:05.20, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
[graph 0 input from stream 0:0 @ 0x8011f320] tb:1/44100 samplefmt:s16 samplerate:44100 chlayout:0x3
Output #0, wav, to 'pipe:':
  Metadata:
    ISFT            : Lavf54.63.104
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le -> pcm_s16le)
Press [q] to stop, [?] for help
Multiple frames in a packet from stream 0
[pcm_s16le @ 0x8005c160] Invalid PCM packet, data has size 3 but at least a size of 4 was expected
Error while decoding stream #0:0: Invalid data found when processing input
No more output streams to write to, finishing.
size=     896kB time=00:00:05.20 bitrate=1411.3kbits/s    
video:0kB audio:896kB subtitle:0 global headers:0kB muxing overhead 0.008719%

请注意,这些错误并不总是发生。有时它们会针对某些文件发生,有时则不会。我尝试了流重定向和临时文件的各种组合,但它们都不起作用。我还验证了临时文件的完整性,并且全部检查完毕。我什至在它被删除之前提取了临时文件,并在 shell 中顺利解码。

有什么想法吗?

编辑:我尝试从通过 C# 运行的 shell 脚本运行 ffmpeg。它给出了同样的问题。通过 MinGW 编译 ffmpeg 也会出现同样的问题。

【问题讨论】:

  • 您是否尝试过设置正确的工作目录?当您从 shell 运行应用程序时,shell 路径(主要是应用程序目录)用作工作目录,当您从 .net 运行它时,指定的工作目录是您的 .net 应用程序的目录
  • @Gam Erix - 传递给 ffmpeg 的文件路径是绝对的,所以我认为这没有任何问题。
  • @Bevin 您如何尝试使用静态链接库编译 ffmpeg?也许这将有助于解决这个问题。此外,ffmpeg 可能正在工作目录下寻找编解码器(或libavcodec)。您可以尝试在proc.Start() 调用之前设置工作目录(Environment.CurrentDirectory)吗?

标签: c# .net ffmpeg cygwin


【解决方案1】:

这是因为您传递参数的方式。这样做:

Process process = new Process();
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.FileName = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) +
                        @"\bin\ffmpeg.exe";

process.StartInfo.Arguments = "-i .\sound1.wav -acodec libvorbis -f ogg abc.ogg";


process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();

这很完美。

【讨论】:

  • 我同意 Omid 的观点,如果你想解决一些问题,你必须对所有特殊字符使用转义字符..
  • 在分配参数时是否应该需要文字字符串或转义反斜杠,即.\sound1.wav会出错。
猜你喜欢
  • 2018-12-27
  • 1970-01-01
  • 2019-11-30
  • 2020-01-02
  • 2018-06-19
  • 2020-09-21
  • 2019-01-23
  • 2018-09-02
  • 2019-12-07
相关资源
最近更新 更多