2012-07-27 81 views
0

可能重複:
ffmpeg: videos before and after conversion aren't the same lengthFFmpeg的不準確的輸出

最近,我一直在試圖使用的FFmpeg對於需要非常精確的操控應用程序時涉及到的時間參數(毫秒分辨率)。不幸的是,我驚訝地發現FFmpeg的操作功能返回了一些不準確的結果。

這裏是「的ffmpeg」的輸出:

ffmpeg version 0.11.1 Copyright (c) 2000-2012 the FFmpeg developers 
    built on Jul 25 2012 19:55:05 with gcc 4.2.1 (Apple Inc. build 5664) 
    configuration: --enable-gpl --enable-shared --enable-pthreads --enable-libx264 --enable-libmp3lame 
    libavutil  51. 54.100/51. 54.100 
    libavcodec  54. 23.100/54. 23.100 
    libavformat 54. 6.100/54. 6.100 
    libavdevice 54. 0.100/54. 0.100 
    libavfilter  2. 77.100/2. 77.100 
    libswscale  2. 1.100/2. 1.100 
    libswresample 0. 15.100/0. 15.100 
    libpostproc 52. 0.100/52. 0.100 

現在,讓我們假設我想撕毀的「foo.mov」音軌。這裏是 '的ffmpeg -i foo.mov' 的相關輸出:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'foo.mov': 
    Metadata: 
    major_brand  : qt 
    minor_version : 0 
    compatible_brands: qt 
    creation_time : 2012-07-24 23:16:08 
    Duration: 00:00:40.38, start: 0.000000, bitrate: 805 kb/s 
    Stream #0:0(und): Video: h264 (Baseline) (avc1/0x31637661), yuv420p, 480x360, 733 kb/s, 24.46 fps, 29.97 tbr, 600 tbn, 1200 tbc 
    Metadata: 
     rotate   : 90 
     creation_time : 2012-07-24 23:16:08 
     handler_name : Core Media Data Handler 
    Stream #0:1(und): Audio: aac (mp4a/0x6134706D), 44100 Hz, mono, s16, 63 kb/s 
    Metadata: 
     creation_time : 2012-07-24 23:16:08 
     handler_name : Core Media Data Handler 

正如你可能已經注意到,視頻文件的時間爲00:00:40.38。使用下面的命令,我撕開它的音軌:

'的ffmpeg -i foo.mov foo.wav'

輸出:

Output #0, wav, to 'foo.wav': 
    Metadata: 
    major_brand  : qt 
    minor_version : 0 
    compatible_brands: qt 
    creation_time : 2012-07-24 23:16:08 
    encoder   : Lavf54.6.100 
    Stream #0:0(und): Audio: pcm_s16le ([1][0][0][0]/0x0001), 44100 Hz, mono, s16, 705 kb/s 
    Metadata: 
     creation_time : 2012-07-24 23:16:08 
     handler_name : Core Media Data Handler 
Stream mapping: 
    Stream #0:1 -> #0:0 (aac -> pcm_s16le) 
Press [q] to stop, [?] for help 
size=3482kB time=00:00:40.42 bitrate= 705.6kbits/s  
video:0kB audio:3482kB global headers:0kB muxing overhead 0.001290% 

正如你所看到的,輸出文件長於輸入中的文件。

另一個例子是音頻(和視頻)文件修整: 我們假設我想使用ffmpeg來修剪音頻文件。我使用的下一個命令:

'的ffmpeg -t 00:00:10.000 -i foo.wav trimmed_foo.wav -ss 00:00:25.000'

輸出:

[wav @ 0x10180e800] max_analyze_duration 5000000 reached at 5015510 
Guessed Channel Layout for Input Stream #0.0 : mono 
Input #0, wav, from 'foo.wav': 
    Duration: 00:00:40.42, bitrate: 705 kb/s 
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0]/0x0001), 44100 Hz, mono, s16, 705 kb/s 
Output #0, wav, to 'trimmed_foo.wav': 
    Metadata: 
    encoder   : Lavf54.6.100 
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0]/0x0001), 44100 Hz, mono, s16, 705 kb/s 
Stream mapping: 
    Stream #0:0 -> #0:0 (pcm_s16le -> pcm_s16le) 
    Press [q] to stop, [?] for help 
size=864kB time=00:00:10.03 bitrate= 705.6kbits/s  
video:0kB audio:864kB global headers:0kB muxing overhead 0.005199% 

同樣,輸出文件比我預期的要長30毫秒。

我試了很長時間,沒有任何成功的研究這個問題。當我使用大膽的功能時,它非常準確!

有沒有人有任何想法如何解決這個問題?

回答

10

TL; DR:FFmpeg和您的iOS設備是您需要的錯誤工具。

有一臺主機的問題涵蓋,所以沒有特定的順序:

  • 首先,無論是FFmpeg的或你與被設計用於排序時間分辨率的工作的基本編解碼器你要。 40ms是25fps的1幀,在大多數視頻和音頻文件的情況下並不多。超量精確計時不是常用音頻編解碼器的設計特徵,就像您的源AAC數據一樣,並且FFmpeg也如此。

  • 不要做任何轉碼!如果你想盡可能少地改變數據......不要改變它。您可以使用ffmpeg -i in.mov -c:a copy out.m4a精確提取音頻流,而不是將其轉碼爲wav格式。

  • 使用FFprobe代替FFmpeg來獲取文件信息。 FFmpeg只是給出了一些關於輸入和輸出文件的粗略信息,因爲它的默認日誌過於冗長。 FFprobe通常與FFmpeg捆綁在一起,專門用於以便捷的形式提取信息。使用ffprobe -show_streams -show_format in.mov獲取信息。

  • 增加你的-analyzeduration!您可能已經注意到輸出中關於max_analyze_duration reached的註釋。從the docs這是多少微秒實際將被讀取的文件之前FFmpeg 估計總長度。同樣,對於大多數目的而言,知道文件長度爲微秒精度是不可行的或不可取的,並且其價格昂貴。如果你想超精確度,請確保該參數設置得高得多,可能比實際輸入更長。

  • 請謹慎選擇您的選項。這是相當小的,但我認爲我應該提起來以防萬一你不知道。 FFmpeg的許多選項根據它們在輸入和輸出方面的順序而表現不同。值得注意的是您使用的-ss。你在輸入之後就有了它,這是你想要的地方,但你在開始時也有輸出選項-t ......這很奇怪。更自然的方式來下令命令是:

    ffmpeg -i foo.wav -ss 00:00:25.000 -t 00:00:10.000 trimmed_foo.wav 
    
  • 僅供參考,所有的時序命令接受秒(包括小數秒)輸入,所以你不必與00:00:前面加上了一切。

  • 區分容器長度和實際流長度。我不使用Audacity,但如果它顯示出極高的準確性,我不會感到驚訝,因爲它向你說謊它正在做什麼。實際上,以毫秒級精度調整音頻或視頻數據不僅需要從輸入中選擇哪些幀包含在輸出中(在25fps下精確到40ms!),而且還要改變幀數據以在最後插入靜音。更簡單的方法是僅基於幀包含進行修剪,然後將超精確的長度放入容器文件元數據中。一些播放軟件可能實際上根據該數字中斷,但是再一次,大多數AV軟件並不是爲這種準確度而設計的。我很想知道FFmpeg顯示的是由Audacity修剪的文件的長度。

這就是我們現在想到的一切,但我很樂意在您有機會合並上述某些內容時提供更多反饋。我的猜測是,這種準確性對研究來說是必需的,在這種情況下,快樂的研究!

+0

非常感謝,您的指導非常幫助我! – Shlomi 2012-07-28 16:02:58

+0

關於命令選項順序的問題解決了我的問題,即粗略的問題(小數分鐘而不是秒)。 – klausnrooster 2016-06-12 03:15:31