我想将 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 标准,因此需要额外的工作吗?