FFmpeg-连接可变长度的插入/输出固定段和单独的音频曲目

FFmpeg-连接可变长度的插入/输出固定段和单独的音频曲目,ffmpeg,Ffmpeg,我正在尝试创建一个基于3个主要部分生成视频的应用程序:- 简介-可变长度视频(约20至30秒长) 片段-来自“片段视频”的3个片段-这是一个固定长度的视频(始终为400秒),其中包含100个单独的视频,所有视频的长度正好为4秒,例如,“片段1”从0到4秒,“片段3”从8到12秒 Outro可变长度视频(约10到20秒长) 用户从视频列表中选择介绍、片段和输出,应用程序将它们连接在一起(并随机提取3片段)。用户还可以选择一个音频文件,用于播放整个视频。生成的文件应如下所示:- 生成的视频 我已经能

我正在尝试创建一个基于3个主要部分生成视频的应用程序:-

  • 简介-可变长度视频(约20至30秒长)
  • 片段-来自“片段视频”的3个片段-这是一个固定长度的视频(始终为400秒),其中包含100个单独的视频,所有视频的长度正好为4秒,例如,“片段1”从
    0
    4
    秒,“片段3”从
    8
    12
  • Outro可变长度视频(约10到20秒长)
  • 用户从视频列表中选择介绍、片段和输出,应用程序将它们连接在一起(并随机提取
    3
    片段)。用户还可以选择一个音频文件,用于播放整个视频。生成的文件应如下所示:-

    生成的视频 我已经能够使用
    ffmpeg
    (有效)破解以下内容:-

    但是,此解决方案存在两个问题:-

    ffmpeg -y \
      -i audio/audio-19.m4a \
      -i videos/intro/intro-23.mkv \
      -i videos/segments/segments-88.mkv \
      -i videos/outro/outro-12.mkv \
      -filter_complex \
        "[2:v]trim=20:24,setpts=PTS-STARTPTS[s1]; \
         [2:v]trim=60:64,setpts=PTS-STARTPTS[s2]; \
         [2:v]trim=132:136,setpts=PTS-STARTPTS[s3]; \
         [1][s1][s2][s3][3]concat=n=5:v=1:a=0[outv]" \
      -map "[outv]" -map 0:a -shortest generated.mkv
    
  • 我必须定义介绍视频的长度(
    [1:v]trim=0:30…
    )和outro视频的长度(
    [3:v]trim=0:20…
    )-这些都是可变的,如果我可以简单地对整个视频进行压缩,那就更好了
  • 每个音轨都会被修剪(使用每个视频长度的运行总数),例如,
    [0:a]atrim=0:30…
    =>
    [0:a]atrim=30:34…
    =>
    [0:a]atrim=34:38…
    =>等。如果简单地说“这是音轨-修剪取决于生成的视频的长度”,就会容易得多

  • 任何建议都将不胜感激

    经过反复阅读和尝试,我找到了一个更好的解决方案:-

    ffmpeg -y \
      -i audio/audio-19.m4a \
      -i videos/intro/intro-23.mkv \
      -i videos/segments/segments-88.mkv \
      -i videos/outro/outro-12.mkv \
      -filter_complex \
        "[2:v]trim=20:24,setpts=PTS-STARTPTS[s1]; \
         [2:v]trim=60:64,setpts=PTS-STARTPTS[s2]; \
         [2:v]trim=132:136,setpts=PTS-STARTPTS[s3]; \
         [1][s1][s2][s3][3]concat=n=5:v=1:a=0[outv]" \
      -map "[outv]" -map 0:a -shortest generated.mkv
    
    使用此解决方案,我只修剪视频片段(例如,
    [2:v]trim=20:24
    ),并将时间戳重置为零(
    setpts=PTS-STARTPTS[s1]
    -请参阅为什么需要这样做)。对3个分段执行3次

    然后,
    concat
    复合过滤器仅连接视频

    它从介绍视频(
    [1]
    )、新创建的片段剪辑视频(
    [s1][s2][s3]
    )以及最后的outro视频(
    [3]
    )中获取视频并将它们连接在一起。但是,它会忽略音频,即
    concat=n=5:v=1:a=0
    (与先前解决方案中的
    concat=n=5:v=1:a=1
    相比),并将其保存到名为
    [outv]
    的新的纯视频流中

    有关连接的更多信息,请参阅

    最后,我们使用这个新的仅连接视频的流
    “[outv]”
    和来自第一个输入文件(
    0:a
    )的音频映射视频,即

    假设音频轨迹长于生成视频的长度,因此
    -shortest
    参数将输出修剪为最短流(即生成视频的长度)

    这有助于我理解
    -map
    命令-

    ffmpeg -y \
      -i audio/audio-19.m4a \
      -i videos/intro/intro-23.mkv \
      -i videos/segments/segments-88.mkv \
      -i videos/outro/outro-12.mkv \
      -filter_complex \
        "[2:v]trim=20:24,setpts=PTS-STARTPTS[s1]; \
         [2:v]trim=60:64,setpts=PTS-STARTPTS[s2]; \
         [2:v]trim=132:136,setpts=PTS-STARTPTS[s3]; \
         [1][s1][s2][s3][3]concat=n=5:v=1:a=0[outv]" \
      -map "[outv]" -map 0:a -shortest generated.mkv
    
    [1][s1][s2][s3][3]concat=n=5:v=1:a=0[outv]
    
    -map "[outv]" -map 0:a -shortest generated.mkv