0

我想将 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
使用包含 just:
AviSource("file.avi")
的 script.avs 执行相同但几乎瞬间完成!

知道为什么 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 标准,因此需要额外的工作吗?

4

1 回答 1

0

您自己回答了您的问题:看起来您的输入带宽遇到瓶颈,ffmpeg 读取原始视频只是为了将其丢弃,而 avisynth(可能会使用 DirectShow 的 AVI 拆分器)仅从磁盘读取音频数据。我没有办法让 ffmpeg 做同样的事情。

于 2019-05-06T06:50:41.357 回答