我試圖在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也給出了相同的問題。
你有沒有試過設置正確的*工作目錄*?從shell運行應用程序時,shell路徑(主要是應用程序目錄)用作工作目錄,當從.net運行它時,指定的工作目錄是您的.net目錄。 – 2013-04-10 10:33:18
@Gam Erix - 文件路徑傳遞給ffmpeg是絕對的,所以我認爲在這方面沒有任何問題。 – Bevin 2013-04-10 11:08:08
@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