videoffmpegvideo-editing

FFMPEG select between and setpts creates copies of streams


I need to trim some clips in the video, the best way I found (without unpacking frames, or trimming only the keyframe, although with the ability to do so without transcoding) I do not quite understand the meaning of such setpts, and ffmpeg writes that there is something wrong with ',', but nevertheless it works.

ffmpeg -y -i 0310.mp4 -vf "select='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)',asetpts=N/SR/TB" -vcodec libx264 -b:v 978k -acodec aac -b:a 242k 0310_TT.mp4

But here it was necessary to make a long list of such betweens, which even did not accept the console windows, started looking, found -filter_complex_script, but as I understand it is not a full replacement for -vf -af. But through experiments it seems to adapt.

ffmpeg -y -i 0310.mp4 -filter_complex_script mysavedscript.txt -vcodec libx264 -b:v 978k -acodec aac -b:a 242k 0310_TT.mp4

mysavedccript.txt:

[0:v:0]select='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)';
[0:v:0]setpts=N/FRAME_RATE/TB;
[0:a:0]aselect='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)';
[0:a:0]asetpts=N/SR/TB

As a result, it creates duplicates of the original video and audio tracks. I tried something with mapping, nothing worked yet. Filters from filter_complex create some other streams.

Stream mapping:
  Stream #0:0 (h264) -> select
  Stream #0:0 (h264) -> setpts
  Stream #0:1 (aac) -> aselect
  Stream #0:1 (aac) -> asetpts
  select -> Stream #0:0 (libx264)
  setpts -> Stream #0:1 (libx264)
  aselect -> Stream #0:2 (aac)
  asetpts -> Stream #0:3 (aac)

As a result I get this, and the broken duration of the video:

Video: MPEG4 Video (H264) 1920x1080 60fps 1226kbps [V: h264 high L4.2, yuv420p, 1920x1080, 1226 kb/s]
Video: MPEG4 Video (H264) 1920x1080 60fps 975kbps [V: h264 high L4.2, yuv420p, 1920x1080, 975 kb/s]
Audio: AAC 48000Hz stereo 150kbps [A: SoundHandler (aac, 48000 Hz, stereo, 150 kb/s)]
Audio: AAC 48000Hz stereo 243kbps [A: SoundHandler (aac lc, 48000 Hz, stereo, 243 kb/s)]

What can be done about it? Or maybe there is some better way to do something like this, having a list of ranges to leave (in time format or frame format start:end)


Solution

  • All unlabeled filtergraph output streams will be added to the first output file. You had 4 unlabeled filtergraph output streams.

    You can use:

    ffmpeg -i input -filter_complex "[0:v:0]select='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)',setpts=N/FRAME_RATE/TB[outv]; [0:a:0]aselect='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)',asetpts=N/SR/TB[outa]" -map "[outv]" -map "[outa]" output.mp4
    

    Or omit the final filter output labels to rely on default stream selection behavior:

    ffmpeg -i input -filter_complex "[0:v:0]select='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)',setpts=N/FRAME_RATE/TB; [0:a:0]aselect='between(t,10.5,12.0)+between(t,12.5,15.0)+between(t,17.5,20.5)+between(t,23.0,25.0)',asetpts=N/SR/TB" output.mp4
    

    See FFmpeg Filtering Documentation: Introduction.