How to split a long video into multiple shorter videos efficiently

ffmpegscriptvideovideo editing

Using ffmpeg I can specify the start time and duration of each segment. For example I wrote

ffmpeg -i "originalvideo.mp4" -ss 00:00 -t 2:34 -vcodec copy -acodec copy "smallervideo1.mp4"

I have a spreadsheet where I have 3 columns; name of smaller video, start time and end time. I could create each command separately for each video but that would take some time given I am splitting the sources files into close to 100 smaller videos.

Is there a method where i can pass the values from the spreadsheet into ffmpeg and output each video with the appropriate name automatically?

Best Answer

This can be done with a simple shell script, in this case a Bash script. If you have a whitespace-delimited file as input, which contains the output file name, the start timestamp and the end timestamp, e.g.:

$ cat cuts.txt
foo.mp4 00:00:00 00:00:01
bar.mp4 00:01:20 00:02:00

Then read this with a simple loop and construct your ffmpeg command:

while read -r filename start end; do
  ffmpeg -i "input.mp4" -ss "$start" -to "$end" -c copy "$filename"
done < cuts.txt

This just cuts the bitstream without encoding – -c copy is a shorthand for -vcodec copy -acodec copy (and it copies subtitles as well). You can specify a video encoder (e.g. -c:v libx264) and an audio encoder (e.g., -c:a aac -b:a 192k) to re-encode the video.

A more portable, but basic version with Python 3:

#!/usr/bin/env python3
import subprocess
with open("cuts.txt") as f:
  for line in f.readlines():
    filename, start, end = line.strip().split(' ')
    cmd = ["ffmpeg", "-i", "input.mp4", "-ss", start, "-to", end, "-c", "copy", filename]
    subprocess.run(cmd, stderr=subprocess.STDOUT)

Note: If you run this on Windows, you should add ffmpeg to your PATH, or specify its full path like C:/Program Files/ffmpeg/bin/ffmpeg.exe.

Related Question