Bash script to run FFmpeg concat on MP4 files in batches of 5

I think the following script will work.

  • First try it as it is and check that it seems to do what you want
  • Then remove echo from the line with ffmpeg to make it do its thing.

Check that the content of the temporary files xaa' ... xat` matches the names (and content) of the output files.

#!/bin/bash

> mylist.txt
for f in *.mp4
do
 echo "file '$f'" >> mylist.txt
done

< mylist.txt sort -t \' -n -k2 | split -l 5

k=1
for j in x*
do
 inc=$(wc -l "$j" | cut -d ' ' -f 1)
 m=$(printf "%03d" $((k)))
 n=$(printf "%03d" $((k+inc-1)))
 name="${m}_${n}.mp4"
 echo ffmpeg -f concat -safe 0 -i "$j" -c copy "$name"
 k=$((k+5))
done

Another solution is to use nested loops.

As long as there are files remaining, the inner loop uses ${@:1:5} to take the next slice of (up to) 5 files.

#!/bin/bash
cd /home/admn/Downloads/MP4_Files;

shopt -s failglob
set -- *.mp4
while [[ $# -gt 0 ]]; do
    from=$(basename "$1" .mp4)
    for f in "${@:1:5}"; do
        #not essential in your case, but use @Q to quote/escape special characters
        echo "file ${f@Q}" >> mylist.txt
        shift
    done
    to=$(basename "$f" .mp4)
    ffmpeg -f concat -safe 0 -i mylist.txt -c copy "${from}_${to}.mp4"
    rm mylist.txt
done