Joseph Lust
Joseph Lust

Reputation: 20015

Create video from PNGs with FFMPEG and variable per image timestamps

I'm trying to take a pile of screenshot PNGs, and the timestamp of each screenshot, and create a video with ffmpeg that recreates the timing of the screenshots.

According to the ffmpeg help, -vsync 0 seems to be what I need,

-vsync parameter

0, passthrough Each frame is passed with its timestamp from the demuxer to the muxer.

Does anyone know how to pass this timestamp information into ffmpeg? Presently each screenshot has the recording time in milliseconds as the filename.

The below example doesn't accept any timing information that I can tell, so I'm looking for the proper format to pipe to the command.

ffmpeg -vsync 0 -pattern_type glob -i '*.png' -c:v libx264 output.mp4

Upvotes: 1

Views: 557

Answers (1)

Script: get time from filename, minus previous filetime = duration of temp video, then concat videos

#!/bin/bash
LST=($(ls -1tr Screenshot*.png))
TOT=${#LST[*]}
f="${LST[0]}"
#Screenshot_20201115_135335.png
FNM="${f%.*}"
SEC="${FNM:24:2}"
MIN="${FNM:22:2}"
HOU="${FNM:20:2}"
echo $f $HOU $MIN $SEC
BEG=$(echo "$HOU * 3600 + $MIN * 60 + $SEC" | bc -l)
echo $f $BEG
INP=("-i" "$f")
OUT="${f%.*}.mkv"
TXT=list.txt
echo "#png to mkv" > $TXT

for (( i=1; i<=$(( $TOT -1 )); i++ )); do
  f="${LST[$i]}"
  FNM="${f%.*}"
  SEC="${FNM:24:2}"
  MIN="${FNM:22:2}"
  HOU="${FNM:20:2}"
  TIM=$(echo "$HOU * 3600 + $MIN * 60 + $SEC" | bc -l)
  DUR=$(echo "$TIM - $BEG" | bc -l)
  echo $f $TIM $DUR
  ffmpeg -y -hide_banner -loop 1 "${INP[@]}" -t $DUR "/tmp/${OUT}"
  echo "file '/tmp/${OUT}'" >> $TXT
  BEG=$TIM
  INP=("-i" "$f")
  OUT="${f%.*}.mkv"
done

ffmpeg -y -hide_banner -loop 1 "${INP[@]}" -t 5 "/tmp/${OUT}"
echo "file '/tmp/${OUT}'" >> $TXT

cat "$TXT"
ffmpeg -hide_banner -f concat -safe 0 -i "$TXT" -c:v h264_nvenc -cq 20 -y /tmp/output.mkv
ffplay /tmp/output.mkv

Upvotes: 2

Related Questions