http://moviebarcode.tumblr.com
I wanted to try something involving making an animation based on this movie barcode idea, so (having found tutorials online describing how to dump frames from a video and ImageMagick to process them to generate a barcode) I decided to hack together a bash script to do it. I say “hack together” because I have no formal training in scripting—I mostly accomplished this by watching some tutorials, and a LOT of Googling/copying and pasting/adapting other people’s script code. In any case, the script I have now works, but it’s pretty slow. This isn’t a problem when you’re making one static movie barcode, but when you want to make a sequence of nearly 2000 of them to play as an animation, taking between 1 - 2 minutes to generate each one is prohibitively costly in terms of time. So I was wondering if anyone had any ideas on how to speed this up.
Right now the basic flow of the script is:
- Take user input to figure out which movie file (currently only supports MKVs) to generate a barcode from, the width of the final barcode (which determines how many frames to dump), and what mode to use (resize/crop/random, which generate 1 barcode; or animation, which generates a sequence).
- Dump desired number of frames to temporary directory using ffmpeg
- Use a loop to either resize or crop all the frames without altering the original files (necessary for the animation idea) and then assemble the barcode.
- If in animation mode, do the above as many times as the original frame is wide.
Code: Select all
FILES=($(find "${1}" -type f | egrep -i "\.bmp$" | sort))
if [[ ${3} == "crop" && -n ${4} ]]; then
for f in ${FILES[*]}; do
convert ${f} -resize ${src_frameheight}x\! -crop 0x1+0+${4} +repage miff:-
done |\
montage - -mode Concatenate -tile 1x ${2}.png
…
done
mogrify -rotate -90 -sample ${slicecount}x\! ${2}.png
- the temporary directory (where the dumped frames live),
- the output file name,
- the desired mode, and
- if the mode is crop-based, a crop offset value (AKA the position in the source frame I want to pull a row of pixels from)
As you can probably see I’m currently doing this vertically—that was my first attempt at optimization, since I read that ImageMagick works on a scanline basis. So now my script outputs the frames rotated 90° clockwise, assembles the barcode vertically, and then rotates it back into the proper orientation at the end. However, this does not seem to have sped things up as far as I can tell. The interesting thing is that neither my CPU nor my I/O appear to be under significant strain during this loop, so I’m really not sure why it’s taking so long. Am I just out of luck in trying to make this go faster using bash scripting? Is this the kind of thing that only a proper, self-contained program in a C-like language using IM libraries could accomplish? Or is there a smarter way to design this loop that I haven’t thought of that would be quicker?