在 ffmpeg 中,当使用 filter_complex 与 trim 和 atrim 时如何处理字幕流?

In ffmpeg, how do I process subtitle streams when using filter_complex with trim and atrim?

我正在使用 ffmpeg 滤镜来提取和连接视频块。作为一个简单的例子,考虑一下这个,它接受一个带有视频流和音频流的输入文件,并产生一个 20 秒的输出,其中包括时间戳 00:10-00:20 和 00:30-00:40输入的:

ffmpeg -i in.mkv \
    -filter_complex "\
        [0:0]trim=start=10:end=20,setpts=PTS-STARTPTS[v1]; \
        [0:1]atrim=start=10:end=20,asetpts=PTS-STARTPTS[a1]; \
        [0:0]trim=start=30:end=40,setpts=PTS-STARTPTS[v2]; \
        [0:1]atrim=start=30:end=40,asetpts=PTS-STARTPTS[a2]; \
        [v1][a1][v2][a2]concat=n=2:v=1:a=1[v][a]\
    " -map [v] -map [a] \
    -c:0 libx264 -preset:0 ultrafast \
    -c:1 ac3 -b:1 128k -ac:1 2 out.mkv

有没有办法以类似的方式处理字幕流,使字幕与其他经过修剪的流相匹配?我正在寻找可以从命令行运行的东西,成为非交互式批处理过程的一部分。

更新 - 解决方案

根据@kesh 的反馈,我们决定使用 concat 多路分离器来处理字幕,并将其与将音频和视频流读取到一个复杂的过滤图中相结合。首先,您需要一个 concat 输入文件,例如:

file 'in.mkv'
inpoint 10
outpoint 20

file 'in.mkv'
inpoint 30
outpoint 40

那么,如果字幕是流5,例如:

ffmpeg -i in.mkv \
    -f concat -i concat-file \
    -filter_complex "\
        [0:0]trim=start=10:end=20,setpts=PTS-STARTPTS[v1]; \
        [0:1]atrim=start=10:end=20,asetpts=PTS-STARTPTS[a1]; \
        [0:0]trim=start=30:end=40,setpts=PTS-STARTPTS[v2]; \
        [0:1]atrim=start=30:end=40,asetpts=PTS-STARTPTS[a2]; \
        [v1][a1][v2][a2]concat=n=2:v=1:a=1[v][a]\
    " -map [v] -map [a] -map 1:5 \
    -c:0 libx264 -preset:0 ultrafast \
    -c:1 ac3 -b:1 128k -ac:1 2 \
    -c:2 copy out.mkv

不,你不能。 FFmpeg filtergraph 只能向视频添加字幕文本(例如,subtitleass 过滤器)。它无法操纵字幕流。

您最好的选择是 concat demuxer。您可以使用不同的开始和结束时间多次列出同一文件。在您的批处理文件中,您可以在内存中创建连接列表并将其通过管道传输到 FFMpeg。

[编辑]

假设 in.mkv 拥有一切:视频、音频和字幕流。然后你可以准备一个 concat demuxer 文件,如:

listing.txt

ffconcat version 1.0

file in.mkv
inpoint 10
outpoint 20

file in.mkv
inpoint 30
outpoint 40

基本上,使用不同的开始和结束时间戳多次列出输入文件。

然后,

ffmpeg -f concat -i listing.txt -map [v] -map [a] -map [s] -c copy out.mkv

会将所有 3 个流复制到 out.mkv

免责声明:我自己没有验证过,但纸面上应该可以。