Reputation: 128829
I'm using ffmpeg filtergraphs to extract and concatenate chunks of videos. As a simple example, consider this, which takes an input file with a video stream and an audio stream and produces a 20-second output that includes timestamps 00:10-00:20 and 00:30-00:40 of the input:
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
Is there a way to process subtitle streams in a similar way so that the subtitles will match the other, trimmed streams? I'm looking for something that'll work from the command line to be part of a non-interactive batch process.
With feedback from @kesh, we arrived at using the concat
demuxer to process the subtitles and combine that with reading the audio and video streams into a complex filtergraph. First, you need a concat input file like:
file 'in.mkv'
inpoint 10
outpoint 20
file 'in.mkv'
inpoint 30
outpoint 40
Then, if subtitles are stream 5, for example, just:
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
Upvotes: 2
Views: 1702
Reputation: 5463
No, you cannot. FFmpeg filtergraph can only add subtitle text to video (e.g., subtitle
and ass
filters). It has no way of manipulating subtitle streams.
Your best bet is the concat
demuxer. You can list the same file multiple times with different start and end times. In your batch file, you can create the concat list in memory and pipe it into FFMpeg.
[edit]
Assuming that in.mkv
has it all: video, audio, and subtitle streams. Then you can prepare a concat demuxer file like:
listing.txt
ffconcat version 1.0
file in.mkv
inpoint 10
outpoint 20
file in.mkv
inpoint 30
outpoint 40
Basically, list the input file multiple times with different start and end timestamps.
Then,
ffmpeg -f concat -i listing.txt -map [v] -map [a] -map [s] -c copy out.mkv
would copy all 3 streams to out.mkv
.
Disclaimer: I have not verified it myself, but it should work on paper.
Upvotes: 1