Home > other >  Call shell script for each image ffmpeg processes (timelapse)
Call shell script for each image ffmpeg processes (timelapse)

Time:01-13

I'd like ffmpeg to call a shell script each time it processes a new image, and to send that filename to the script and ideally also send the filename of the next image it'll process (if any).

This is my ffmpeg command so far (for a jpg -> mov timelapse).

ffmpeg -framerate 25 -pattern_type glob -i "/images/*.jpg" -c copy "lapse.mov"

I've had a look through some of the ffmpeg documentation, but nothing shows up on my keyword searches, but there is a lot of documentation, so maybe I'm missing something?

My ultimate goal with this is so I can put the next filename into a text file for ffmpeg's drawtext textfile to read, and thus render onto the next frame. I realise this can be done in a split step process, but I'm seeing how far I can push a single ffmpeg command.

CodePudding user response:

I don't think that you can do it the way that you're asking for, but the updating of drawtext can be achieved with sendcmd by generating a command file with the time intervals and the filenames hard-coded in it.

That said, given the frame rate and the glob (expanding to the image files) you can generate the corresponding command file programmatically:

#!/bin/bash

framerate=25
imglob='images/*.jpg'

awk -v framerate="$framerate" '
    BEGIN {
        OFS = "\t"
        time = 0
        step = 1 / framerate
        for (i = 1; i < ARGC; i  ) {
            n = split(ARGV[i],path,"/")
            filename = path[n]
            print time, "[enter]", "drawtext", "reinit", "text="filename";"
            time  = step
        }
        exit
      }
' $imglob > cmd.txt

ffmpeg -framerate "$framerate" \
       -pattern_type glob -i "$imglob" \
       -vf "sendcmd=f=cmd.txt" \
       -c copy "lapse.mov"

Note: bash doesn't have any floating point capabilities, that's why I hijacked awk here.


If your filenames contain characters that can break the command file format then you'll have to store each filename in a different text file and use textfile=textfile_with_the_filename.txt instead of text=literal_filename in the command file.

  •  Tags:  
  • Related