0

I am trying to make a script to turn a bunch of timelapse images into a movie, using ffmpeg.

The latest problem is how to loop thru the images in, say, batches of 500.

There could be 100 images from the day, or there could be 5000 images.

The reason for breaking this apart is due to running out of memory.

Afterwards I would need to cat them using MP4Box to join all together...

I am entirely new to bash, but not entirely programming.

What I think needs to happen is this

1) read in the folders contents as the images may not be consecutively named

2) send ffmpeg a list of 500 at a time to process (https://trac.ffmpeg.org/wiki/Concatenate)

2b) while you're looping thru this, set a counter to determine how many loops you've done

3) use the number of loops to create the MP4Box cat command line to join them all at the end.

the basic script that works if there's only say 500 images is:

#!/bin/bash

dy=$(date '+%Y-%m-%d')

ffmpeg -framerate 24 -s hd1080 -pattern_type glob -i "/mnt/cams/Camera1/$dy/*.jpg" -vcodec libx264 -pix_fmt yuv420p Cam1-"$dy".mp4

MP4Box's cat command looks like:

MP4Box -cat Cam1-$dy7.mp4 -cat Cam1-$dy6.mp4 -cat Cam1-$dy5.mp4 -cat Cam1-$dy4.mp4 -cat Cam1-$dy3.mp4 -cat Cam1-$dy2.mp4 -cat Cam1-$dy1.mp4 "Cam1 - $dy1 to $dy7.mp4"

Needless to say help is immensely appreciated for my project

molly78
  • 23
  • 3

1 Answers1

0

Here is something to get you started. It sorts the individual frames into time order, and then chunks them up into chunks of 500 and loops through all the chunks:

#!/bin/bash

# User-changeable number of frames per chunk
chunksize=500

# Rename files by date/time so they collate in order
jhead -n%Y-%m-%d_%H-%M-%S *.jpg

# Remove any remnants from previous runs (which may have been longer)
rm chunk* sub-*mp4

# Split filename list into chunks - chunkaa, chunkab, chunkac ...
ls *jpg | split -l $chunksize - chunk

# Put 'file' keyword before each filename
sed -i.bak 's/^/file /' chunk*

n=0
for c in chunk*; do
   # Generate zero-padded output filename so that collates for final assembly too
   out=$(printf "sub-%03d.mp4" $n)
   echo Processing chunk $c into sequence $out
   ffmpeg -f concat -i "$c" ... "$out"
   ((n+=1))
done

# Final assembly of "sub-*.mp4"
ffmpeg ... sub-*mp4 ...
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Huge thanks for the reply Mark - I'll read through this until I get what it's doing! – molly78 Mar 02 '17 at 17:54
  • No problems :-) Ask if you have any questions. – Mark Setchell Mar 02 '17 at 19:08
  • OK, if the file names are already like such: 18-06-30.jpg 18-06-31.jpg 18-06-47.jpg 18-06-49.jpg 18-06-50.jpg is there a need to rename? - the problem is they will be random, and not consecutive for the HH-MM-SS – molly78 Mar 03 '17 at 02:19
  • It seems to me to be the easiest way to get them to list in order with just a one-liner. If you have a simpler method that's fine, use it :-) – Mark Setchell Mar 03 '17 at 07:24