非交错AVI上的FFmpeg音频流提取-与AviSynth相比慢

时间:2019-05-03 09:20:53

标签: ffmpeg avisynth

我想将avi文件的音频流提取为wav文件,它可以工作,但是虽然我只想复制流,但它的速度确实很慢(〜4-5fps)。

这是我要提取的流类型(ffprobe信息):
Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s

通过AviSynth可以使速度快大约100倍,但是我更喜欢纯FFmpeg解决方案。为什么会有这样的速度差异?看起来FFmpeg正在读取和处理整个文件,而AviSynth可以提取数据而无需读取数据。

示例:
ffmpeg -i file.avi -vn -ac 2 -c:a copy audio.wav

ffmpeg -i file.avi -map 0:a -ac 2 -c:a copy audio.wav
两者都工作正常,但需要时间。

使用AviSynth脚本作为输入:
ffmpeg -i script.avs -map 0:a -ac 2 -c:a copy audio.wav
与script.avs仅包含:
AviSource("file.avi")
做的差不多,但是几乎是瞬间!

有人知道为什么AviSynth这么快,以及是否有办法在FFmpeg中获得相同的速度吗?

编辑:添加日志
直接使用FFmpeg:

E:\>ffmpeg -i "file.avi" -map 0:a -c:a copy -y -benchmark "output.wav"
ffmpeg version N-92936-ged3b64402e Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.2.1 (GCC) 20181201
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  libavutil      56. 25.100 / 56. 25.100
  libavcodec     58. 43.100 / 58. 43.100
  libavformat    58. 25.100 / 58. 25.100
  libavdevice    58.  6.101 / 58.  6.101
  libavfilter     7. 47.100 /  7. 47.100
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
[avi @ 0000018d3c38a680] non-interleaved AVI
Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, avi, from 'file.avi':
  Duration: 00:18:37.49, start: 0.000000, bitrate: 534682 kb/s
    Stream #0:0: Video: rawvideo, bgr24, 1280x720, 533183 kb/s, 24.11 fps, 24.11 tbr, 24.10 tbn, 24.10 tbc
    Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Output #0, wav, to 'output.wav':
  Metadata:
    ISFT            : Lavf58.25.100
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:1 -> #0:0 (copy)
Press [q] to stop, [?] for help
size=  192445kB time=00:18:37.12 bitrate=1411.2kbits/s speed=4.77x
video:0kB audio:192445kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000040%
bench: utime=1.188s stime=50.766s rtime=234.254s
bench: maxrss=17468kB

使用AviSynth:

E:\>ffmpeg -i "soundout.avs" -map 0:a -c:a copy -y -benchmark "output.wav"
ffmpeg version N-92936-ged3b64402e Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.2.1 (GCC) 20181201
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  libavutil      56. 25.100 / 56. 25.100
  libavcodec     58. 43.100 / 58. 43.100
  libavformat    58. 25.100 / 58. 25.100
  libavdevice    58.  6.101 / 58.  6.101
  libavfilter     7. 47.100 /  7. 47.100
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, avisynth, from 'soundout.avs':
  Duration: 00:18:37.49, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[24] / 0x18524742), bgr24, 1280x720, 24.11 fps, 24.11 tbr, 24.10 tbn, 24.10 tbc
    Stream #0:1: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Output #0, wav, to 'output.wav':
  Metadata:
    ISFT            : Lavf58.25.100
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:1 -> #0:0 (copy)
Press [q] to stop, [?] for help
size=  192445kB time=00:18:37.11 bitrate=1411.2kbits/s speed= 155x
video:0kB audio:192445kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000040%
bench: utime=0.234s stime=1.047s rtime=7.236s
bench: maxrss=23792kB

编辑:“重新编码” AVI文件后进行测试:
在某事上...
说我的原始文件是f.avi。这是ffprobe的结果:

[avi @ 0x55a9c4b1e740] non-interleaved AVI
Input #0, avi, from 'f.avi':
  Duration: 00:00:38.18, start: 0.000000, bitrate: 1104582 kb/s
    Stream #0:0: Video: rawvideo, bgr24, 1632x1200, 1104265 kb/s, 23.47 fps, 23.47 tbr, 23.47 tbn, 23.47 tbc
    Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s

提取音频需要很长时间。
现在,如果我在另一个AVI中“重新编码”文件:

ffmpeg -i f.avi -c copy f2.avi

我可以在几毫秒内从f2.avi提取音频!
f2.avi上的FFprobe:

Input #0, avi, from 'f2.avi':
  Metadata:
    encoder         : Lavf57.56.101
  Duration: 00:00:38.18, start: 0.000000, bitrate: 1104456 kb/s
    Stream #0:0: Video: rawvideo, bgr24, 1632x1200, 1104265 kb/s, 23.47 fps, 23.47 tbr, 23.47 tbn, 23.47 tbc
    Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s

除了元数据之外,它是相同的,这没有什么区别,但是通过比较,我发现问题必须与原始数据是非交错的有关!
我认为从非交错文件中读取和提取音频会更容易,但这也许不符合AVI标准,因此需要额外的工作吗?

1 个答案:

答案 0 :(得分:0)

您自己回答了问题:看来您输入带宽出现瓶颈,ffmpeg只是将原始视频扔掉而已,而avisynth(可能会使用DirectShow的AVI Splitter)只能从磁盘读取音频数据。我没有办法让ffmpeg做到这一点。