Faster way to generate exact time segments with ffmpeg

38 Views Asked by At

I am in the need of creating exact seconds segments of a video

Currently I am using this command (Javascript string) where I read from a folder multiple videos segmentLenght is usually obtained through computations, so its value is a float like 1.66666 or 1.5 seconds or even whole numbers like 2

ffmpeg -hide_banner -err_detect ignore_err -i "${inputFolder + '/' + video}" -r 24 -codec:v libx264 -vsync 1 -codec:a aac -ac 2 -ar 48k -f segment -preset fast -segment_format mpegts -segment_time ${segmentLenght} -force_key_frames "expr: gte(t, n_forced * ${segmentLenght})" "${outputFolder + '/' + video.split('.')[0] + '_%d.' + ext}"

This command works almost as expected, it generates segments exactly with the segmentLenght I give it (some few milliseconds of error, I'm guessing from the float number of seconds)

The problem is that it takes a very long time to process these segments. Do you know a faster way for the same result?

1

There are 1 best solutions below

0
JayCravens On

This will output the frame number for a video.

ffmpeg -i your_file.mp4 -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1

Like this: enter image description here

This video is 400 frames.

This would be an example of how to incorporate it into a script.

  for file in "${file_list2[@]}"; do
    frame_count=$(ffmpeg -i $file -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
      frame_start=$((frame_count - 30))
      ffmpeg -i "$file" -y -vf fade=out:"$frame_start":30 -hide_banner -preset ultrafast "to_mux_$file"
  done

This is an excerpt from a script that merges all the videos in the directory with fade in/out effect. I had to use frames to make this work properly and, subsequently, where I grabbed the code from.