从外壳的ffmpeg运行正常运行,但不会从内部.NET调用时 [英] ffmpeg run from shell runs properly, but does not when called from within .NET

查看:680
本文介绍了从外壳的ffmpeg运行正常运行,但不会从内部.NET调用时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在C#程序中使用的ffmpeg(编译在Windows上使用Cygwin的),通过使用过程类产卵的ffmpeg的实例。不过,我已经打了一个相当奇怪的错误,并没有多大意义。

I'm attempting to use ffmpeg (compiled on Windows with Cygwin) in a C# program, by using the Process class to spawn an ffmpeg instance. However, I've hit a rather odd bug that doesn't make much sense.

当我直接从shell中运行的ffmpeg(无论是Cygwin的bash中,PowerShell中,CMD ),ffmpeg的可正确地解码和重新编码文件,没有任何问题:

When I run ffmpeg directly from a shell (be it Cygwin's bash, PowerShell, cmd), ffmpeg can properly decode and reencode files without any issues:

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用下面的代码:

The file plays fine, and I can encode to WAV or any other format I like. However, when I call ffmpeg from C# with the following code:

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%

请注意,并不总是出现这些错误。有时,他们发生了某些文件,有时候他们不这样做。我试过流重定向文件和临时文件的各种组合,他们没有工作。我也验证了临时文件的完整性,而且所有检查出来。我甚至提取被删除之前的临时文件,并解码它的外壳顺利。

Note that these errors don't always occur. Sometimes they happen for certain files, sometimes they don't. I've tried various combinations of stream redirects and temp files, none of them work. I've also verified the integrity of the temp files, and it all checks out. I've even extracted the temp file before it was deleted, and decoded it in shell without a hitch.

任何想法?

编辑:我试过从通过的C#运行一个shell脚本运行的ffmpeg。它提供了相同的问题。编译通过的ffmpeg MinGW的给出了同样的问题也是如此。

I've tried running ffmpeg from a shell script that's run through C#. It gives the same issues. Compiling ffmpeg via MinGW gives the same issue as well.

推荐答案

这是因为你正在传递参数的方式。做到这一点:

It's because of the way you are passing the arguments. Do this:

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();

这完美的作品。

这篇关于从外壳的ffmpeg运行正常运行,但不会从内部.NET调用时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆