在 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 只能向视频添加字幕文本(例如,subtitle
和 ass
过滤器)。它无法操纵字幕流。
您最好的选择是 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
。
免责声明:我自己没有验证过,但纸面上应该可以。
我正在使用 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 只能向视频添加字幕文本(例如,subtitle
和 ass
过滤器)。它无法操纵字幕流。
您最好的选择是 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
。
免责声明:我自己没有验证过,但纸面上应该可以。