Recently, I accepted a Fiverr project to needed to sharpen and enhance a video. My Topaz Labs Video AI was unable to do anything useful, so I tried converting the entire video to photos and running through through their photo tools like Photo AI. Using the open source ffmpeg, I did it like this:
Movie to Images using ffmpeg
ffmpeg -i “input.mp4 frames-full/frame%d.jpg
That command creates jpg image files in a subfolder called “frames-full” for every frame of the original video. In my case, the original video was shot at 59.94 frames per second and created a ton of image files.
Processing 20,000+ images was going to take days, so I decided to just process it as 29.97 frames per second (standard US video rate) which would cut my processing time in half. To do this, I needed to delete every other image. I was able to use the “find” command to search for any matching filename that ended in 0, 2, 4, 6 or 8 (an even number):
find . -name "frame[0-9]*[02468].jpg"
One neat thing about the modern macOS file system is you can make a duplicate of a folder before doing something dangerous like command line deletes! The duplicate doesn’t take up extra space (beyond a bit of directory overhead) so that let me experiment over and over until I figured it out.
Now I had frame1.jpg, frame3.jpg, frame5.jpg and so on. After processing these files, I would need to re-assemble them using ffmpeg at the 29.97 frame rate. Here is the command for that:
ffmpeg -framerate 29.97 -I frames-full/frame%d.jpg -pix_fmt yuv420p output.m4v
Unfortunately, it expects all the files to be sequentially numbered (1, 2, 3, 4) and would not work with every other file missing.
To fix that, I needed a script that would rename files down from…
frame1.jpg frame3.jpg frame5.jpg frame6.jpg frame9.jpg
…to…
frame1.jpg frame2.jpg (was 3) frame3.jpg (was 5) frame4.jpg (was 7) frame5.jpg (was 9)
A bit of trail and error led me to this simple script that divides the number by 2, and since there is no floating point, all I needed to do was add one to the number and then do the division. 3 became 1+3 which is 4, which divided by 2 became 2:
1 -> 1+1 = 2 / 2 = 1 3 -> 3+1 = 4 / 2 = 2 5 -> 5+1 = 6 / 2 = 3 7 -> 7+1 = 8 / 2 = 4 9 -> 9+1 = 10 / 2 = 5
That let me simply rename the original number to the new number and get what I wanted. Here is the script, though it is hard coded to the number of files I needed. You’d have to change that since it’s not smart enough to figure this out (like, “stop when you find a file that doesn’t exist”). Also, it starts at 3 since frame1.jpg would be renamed to frame1.jpg which probably produces an error:
#!/bin/bash
# find . -name "frame[0-9]*[02468].jpg"
# Delete even-numbered files
for ((i=3;i<=26999;i=i+2))
do
file="frame${i}.jpg"
j=$((i/2+1))
if [ -f "$file" ]; then
echo "Renaming $file"
mv "$file" "frame${j}.jpg"
fi
done
I just wanted to post this here in case anyone else ever needs to do the same thing…
Until next time…