2012-07-27 32 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