FFmpeg不准确的输出[重复]。

问题描述 投票:0回答:1

可能是重复的。 ffmpeg:转换前和转换后的视频长度不一样。

最近,我一直在尝试在一个应用程序中使用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的相关输出。以下是'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毫秒。

我尝试了很长时间,研究这个问题,但没有任何成功。当我用audacity做同样的功能时,它做得非常准确!有谁知道如何解决这个问题?

有人知道如何解决这个问题吗?

audio video ffmpeg video-capture video-processing
1个回答
12
投票

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 在您的输出中。 从 文献 那是多少 微秒 将会在FFmpeg之前实际读取文件。估计数 的总长度。 同样,对于大多数目的来说,精确到微秒的文件长度是不可行的,也是不可取的,而且它是 昂贵。 如果你想要超精度,请确保该参数设置得更高,可能比你的实际输入更长。

  • 对你的选项位置要更加小心。 这是相当小的问题,但我想我应该把它提出来,以防你不知道。 FFmpeg的许多选项根据输入和输出的顺序而表现不同。 值得注意的是 -ss 的选项。 你把它放在输入之后,这是你想要的,但你也有只输出的选项。-t 在开头,这是... 奇怪的。 更自然的排序方式应该是。

    ffmpeg -i foo.wav -ss 00:00:25.000 -t 00:00:10.000 trimmed_foo.wav
    
  • 所有的计时命令都接受以秒为单位的输入 (包括小数点的秒), 所以你不必在所有的指令前加上 00:00:.

  • 区分容器长度和实际流长度。 我不用Audacity,但如果它显示出极高的准确性,我不会感到惊讶,因为它在对你撒谎,它在做什么。 实际上,修剪音频或视频数据的毫秒级精度,不仅需要选择哪些帧从输入包括在输出(这是精确到40毫秒,25fps!),但改变帧数据插入沉默的结束。 更容易的是,只是基于帧包括修剪,然后把超精确的长度在容器文件元数据。 一些播放软件可能会实际削减基于该数字,但再次,大多数AV软件只是没有设计的准确性水平。 我会很好奇,看看FFmpeg显示的Audacity修剪文件的长度。

这是所有现在想到的,但我很高兴给更多的反馈,一旦你有机会结合上述的一些。 我的猜测是,这种精确性是需要研究的,在这种情况下,快乐的研究!

© www.soinside.com 2019 - 2024. All rights reserved.