首页 > 解决方案 > FFMPEG 合并多个视频:其中一个没有音频源

问题描述

我编写了一个 node.js 脚本来将多个视频文件合并到一个文件中。我遇到过没有为其中一个输入视频文件提供音频的情况。

我首先执行了 ffprobe以便我可以访问我称之为“视频文件规范”的内容。在这种情况下,我创建了一个基本模块来帮助我更好地理解我的问题:

Evaluation from all processes: [
  {
    fileName: 'input-0.mp4',
    isVideoAvailable: true,
    isAudioAvailable: false,
    width: 1920,
    height: 1080,
    sampleRateAspectRatio: '1/1',
    audioVolume: 1,
    duration: '13.140000'
  },
  {
    fileName: 'input-1.mp4',
    isVideoAvailable: true,
    isAudioAvailable: true,
    width: 1920,
    height: 1080,
    sampleRateAspectRatio: '1/1',
    audioVolume: 1,
    duration: '17.160000'
  },
  {
    fileName: 'input-2.mp4',
    isVideoAvailable: true,
    isAudioAvailable: true,
    width: 1920,
    height: 1080,
    sampleRateAspectRatio: '1/1',
    audioVolume: 1,
    duration: '20.280000'
  },
  {
    fileName: 'input-3.mp4',
    isVideoAvailable: true,
    isAudioAvailable: true,
    width: 1920,
    height: 1080,
    sampleRateAspectRatio: '1/1',
    audioVolume: 1,
    duration: '19.020000'
  },
  {
    fileName: 'input-4.mp4',
    isVideoAvailable: true,
    isAudioAvailable: true,
    width: 1920,
    height: 1080,
    sampleRateAspectRatio: '1/1',
    audioVolume: 1,
    duration: '9.480000'
  }
]

下一个代码块是我在这种情况下实际硬编码的参数。屏幕分辨率和纵横比是手动设置的,因为我发现我处理的每个视频都有不同的设置。这些参数允许 FFMPEG 在正常情况下成功执行:

let ffmpegParameters = [
  '-i',
  'input-0.mp4',
  '-i',
  'input-1.mp4',
  '-i',
  'input-2.mp4',
  '-i',
  'input-3.mp4',
  '-i',
  'input-4.mp4',
  '-f',
  'lavfi',
  '-t',
  '0.1',
  '-i',
  'anullsrc',
  '-filter_complex',
  '[0:v]scale=1920:1080,setsar=1/1[v0];[0:a]volume=1.0[a0];[1:v]scale=1920:1080,setsar=1/1[v1];[1:a]volume=1.0[a1];[2:v]scale=1920:1080,setsar=1/1[v2];[2:a]volume=1.0[a2];[3:v]scale=1920:1080,setsar=1/1[v3];[3:a]volume=1.0[a3];[4:v]scale=1920:1080,setsar=1/1[v4];[4:a]volume=1.0[a4];[v0][a0][v1][a1][v2][a2][v3][a3][v4][a4]concat=n=5:v=1:a=1[v][a]',
  '-map',
  '[v]',
  '-map',
  '[a]',
  '-c:v',
  'libx264',
  '-vsync',
  '2',
  'output.mp4'
]

来自不同线程的评论建议在我的情况下提供虚拟音频。我已经补充说没有盛行:

  '-f',
  'lavfi',
  '-t',
  '0.1',
  '-i',
  'anullsrc',

我不知道如何调整复杂过滤器以解决我第一个不包含音频的视频的情况。我在下面包含了整个日志:

Logs:
 ffmpeg version git-2020-02-03-1c15111
 Copyright (c) 2000-2020 the FFmpeg developers
  built with Apple clang version 11.0.0 (clang-1100.0.33.8)
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --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-appkit --enable-avfoundation --enable-coreimage --enable-audiotoolbox
  libavutil      56. 38.100 / 56. 38.100
  libavcodec     58. 67.100 / 58. 67.100
  libavformat    58. 37.100 / 58. 37.100
  libavdevice    58.  9.103 / 58.  9.103
  libavfilter     7. 73.100 /  7. 73.100
  libswscale      5.  6.100 /  5.  6.100
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.100

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input-0.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.37.100

  Duration: 00:00:14.80, start: 1.620000, bitrate: 1499 kb/s
    Stream #0:0(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1498 kb/s, 25 fps, 25 tbr, 1200k tbn, 2400k tbc (default)
    Metadata:
      handler_name    : VideoHandler

Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'input-1.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.37.100
  Duration: 00:00:18.48, start: 0.000000, bitrate: 977 kb/s
    Stream #1:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1440x876 [SAR 1:1 DAR 120:73], 903 kb/s, 15.21 fps, 16.67 tbr, 16k tbn, 32k tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #1:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 69 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from 'input-2.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.37.100
  Duration: 00:00:22.68, start: 0.000000, bitrate: 1795 kb/s
    Stream #2:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1718 kb/s, 29.54 fps, 50 tbr, 16k tbn, 32k tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #2:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 69 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

Input #3, mov,mp4,m4a,3gp,3g2,mj2, from 'input-3.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.37.100
  Duration: 00:00:54.60, start: 
0.000000, bitrate: 404 kb/s
    Stream #3:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1440x876 [SAR 1:1 DAR 120:73], 330 kb/s, 15.24 fps, 16.67 tbr, 16k tbn, 32k tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #3:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 69 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

Input #4, mov,mp4,m4a,3gp,3g2,mj2, from 'input-4.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.37.100
  Duration: 00:00:09.36
, start: 0.000000, bitrate: 1794 kb/s
    Stream #4:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1717 kb/s, 29.38 fps, 50 tbr, 16k tbn, 32k tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #4:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 69 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

Stream specifier ':a' in filtergraph description [0:v]scale=1920:1080,setsar=1/1[v0];[0:a]volume=1.0[a0];[1:v]scale=1920:1080,setsar=1/1[v1];[1:a]volume=1.0[a1];[2:v]scale=1920:1080,setsar=1/1[v2];[2:a]volume=1.0[a2];[3:v]scale=1920:1080,setsar=1/1[v3];[3:a]volume=1.0[a3];[4:v]scale=1920:1080,setsar=1/1[v4];[4:a]volume=1.0[a4];[v0][a0][v1][a1][v2][a2][v3][a3][v4][a4]concat=n=5:v=1:a=1[v][a] matches no streams.


当我删除流说明符[a0]时,我收到了一个不同的错误:

FFmpeg Video Merge - STDERR: [Parsed_setsar_3 @ 0x7f87c7709100] Media type mismatch between the 'Parsed_setsar_3' filter output pad 0 (video) and the 'Parsed_concat_14' filter input pad 1 (audio)
[AVFilterGraph @ 0x7f87c7430c00] Cannot create the link setsar:0 -> concat:1

我的问题是如何调整我定义的参数列表的 filter-complex 值以处理没有音频的第一个视频?

标签: audiovideoffmpeg

解决方案


Stream specifier ':a' in filtergraph description … matches no streams

您正在引用一个不存在的流。在这种情况下,这是由于[0:a]volume=1.0[a0]. 您正在尝试从中选择音频input-0.mp4,但此输入没有音频。

Media type mismatch

我不知道您的确切命令,所以我无法指出实际原因,但您的视频和音频过滤器标签可能在某个地方混淆了。


工作示例

ffmpeg -i input-0.mp4 -i input-1.mp4 -i input-2.mp4 -i input-3.mp4 -i input-4.mp4 -f lavfi -t 0.1 -i anullsrc=channel_layout=mono:sample_rate=44100 -filter_complex "[0:v]scale=1920:1080,setsar=1/1[v0];[1:v]scale=1920:1080,setsar=1[v1];[2:v]scale=1920:1080,setsar=1[v2];[3:v]scale=1920:1080,setsar=1[v3];[4:v]scale=1920:1080,setsar=1[v4];[v0][5][v1][1:a][v2][2:a][v3][3:a][v4][4:a]concat=n=5:v=1:a=1[v][a]" -map "[v]" -map "[a]" -movflags +faststart output.mp4
  • 由于volume=1绝对没有任何作用,因此您可以消除该过滤器。
  • 对于没有音频的视频输入,将其与 concat 中的 anullsrc 输出配对(如上[v0][5]例所示)。
  • concat 过滤器会自动为音频流选择一个通用的采样率和通道布局,但我仍然更喜欢在 anullsrc 中手动设置它们,这样我就知道我会得到什么。
  • 您的输入在 DAR 中有所不同,因此 1440x876 视频在输出中看起来会被挤压。您可以通过添加scale + croppad来避免这种情况。由于它们都具有相同的 SAR,请参阅Resizing videos with ffmpeg to fit into static size
  • 升级通常不是一个好主意。考虑缩小到 1280x720,因为一半的输入是这个大小。

推荐阅读