2013-04-10 82 views
8

我试图在C#程序中使用ffmpeg(在Windows上用Cygwin编译),通过使用Process类生成一个ffmpeg实例。但是,我碰到了一个相当奇怪的错误,没有多大意义。从shell运行ffmpeg正常运行,但不从.NET内部调用时

当我直接从shell中运行的ffmpeg(无论是Cygwin的庆典,PowerShell中,CMD),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也给出了相同的问题。

+0

你有没有试过设置正确的*工作目录*?从shell运行应用程序时,shell路径(主要是应用程序目录)用作工作目录,当从.net运行它时,指定的工作目录是您的.net目录。 – 2013-04-10 10:33:18

+0

@Gam Erix - 文件路径传递给ffmpeg是绝对的,所以我认为在这方面没有任何问题。 – Bevin 2013-04-10 11:08:08

+0

@Bevin你如何试图用静态链接库编译ffmpeg?也许这会帮助解决这个问题。此外,ffmpeg可能正在寻找工作目录下的编解码器(或“libavcodec”)。你可以尝试在'proc.Start()之前设置工作目录(['Environment.CurrentDirectory'](http://msdn.microsoft.com/en-us/library/system.environment.currentdirectory.aspx) '打电话? – Jesse 2013-04-17 20:16:01

回答

8

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

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

这工作完美。

+0

我同意Omid,如果你想解决的问题,你必须使用所有特殊字符的转义字符。 – MarmiK 2013-04-23 10:40:27

+0

分配参数时不应该需要字面字符串或转义反斜杠,即'。\ sound1 .wav'会报错。 – 2016-04-16 21:40:03