Archive for the ‘bash’ Category

Bash Video Thumbnailer

September 1, 2012

Video thumbnail: a montage of screenshots from a video file, often accompanied by some file info.  Like this:

I wasn’t satisfied with the thumbnailers I had tried for a few reasons:

  • usually incredibly slow
  • work with some files/formats but not others
  • usually don’t understand anamorphic video and make shots with bad aspect ratio
  • often require X and a graphical desktop

So I decided to make my own bash script, videothumbs, that:

  • is quicker than the stuff I already tried
  • works with every video codec and container that my OS supports
  • gets the damn aspect ratio right!
  • works on headless or non-gui systems

And here it is: http://pastebin.com/x96WYVTx

20 March 2013: New version at http://pastebin.com/2iVWDEkx now makes all thumbs with ffmpeg as changes in newer versions of mplayer and some containers caused problems.

As you can see from the image above (click for full size), videothumbs creates an image identically named as the input file except for the file extension, 1024 pixels wide with 4 columns of 10 images.  At the top is some basic file info: file name, video codec and dimensions, audio codec and number of channels.

There is only one user option -o

“videothumbs -o  path  mymovie.mkv”

to have the thumbnail image output to path instead of the same directory as mymovie.mkv.

It uses mplayer or ffmpeg (depending on file type) to grab/create the images and imagemagick’s montage command to make the thumbnail sheet.  It’s quickest with files in Matroska (.mkv) or .mpg/.mpeg  containers.  MPlayer grabs uncompressed png frames really quickly from mkv or mpg but can choke seeking to a specific point in avi files (I think because a position specified in seconds doesn’t always correspond to a keyframe) and on some mp4 files (I don’t know why).  So, for everything that isn’t in mkv/mpg, videothumbs falls back to using ffmpeg to create the images.  This is slower, but still better than hanging….  For a quick comparison I booted Windows XP and made a thumbnail sheet using Media Player Classic: it took absolutely ages and was much slower than my script.

I’ve tested videothumbs on the following containers:

mkv, mp4, avi, vob, wmv, mov, divx, mpg

which contained various codecs:

video: h264, divx/xvid, wmv3, Sorenson Media Video 3 (Apple QuickTime), mpeg2 (DVD), ogv, ogg

audio: aac, ac3, dts, mp3, ogg vorbis, mp2, ima4 (Quicktime)

and probably some others too.  So far everything worked.  YMMV.  I’m running Debian Stable (Squeeze) with (proper) ffmpeg and mplayer from the unofficial deb-multimedia.org repositories.  I have no idea if this script will work with libav as it does with ffmpeg.

Automatically convert tracks or entire directories to Ogg, MP3, Flac, M4A (Nero or FAAC), with tags.

May 26, 2012

Edit: New version uses multiple parallel processes for huge performance gain on dual/multicore processor systems, and on single core systems it’s recommended to run the new version with “PROCESSES=2” (see below) for proportionately similar benefit.

foma:  [f]lac [o]gg [m]p3 [a]ac

foma will convert any audio track (or the audio track from a video file) to any of Ogg Vorbis, MP3, Flac, or M4A.  It writes the tags to the new files.  You can choose to convert the files in situ, or to output them to a different directory.  It never overwrites any audio file.  If you input files it will convert the files ; if you input a directory it will create a new identically named directory (either as a nested subdirectory, or to your specified output destination) and then find and convert all the contained audio files to the new directory, writing the metadata and also an extended .m3u playlist, and copy over any images.  Optionally it will then run replaygain on the new directory.  foma can handle multiple files or directories, or a mix of files and directories, as input.  It’s very easy to use as a simple command,  or as an -exec or -execdir find command, or as  file manager context menu item/custom action.

Original foma: http://pastebin.com/Ctyz2uWa

Updated for multicore: http://pastebin.com/jC3Nhj8F

This is also usable for single core machines: change “PROCESSES=5” to “PROCESSES=2”.  If you do only want one process running then use the original script.

foma decodes with ffmpeg,  so you can convert audio from any file that ffmpeg understands.

It encodes using flac, oggenc,  lame,  faac or neroaacenc.

It tags using metaflac, vorbiscomment,  (m)id3v2, neroaactag/mp4tags.

It runs replaygain using metaflac, vorbisgain, mp3gain or aacgain.

It writes an extended m3u playlist using just ffmpeg’s metadata output and some shell commands.

After completing a directory conversion foma can automatically update your mpd library.

foma never overwrites your existing audio or image files (it will overwrite .m3u files).  If any target conversions already exist then they are skipped and a log appended to ~/foma.log.

foma script is short, modular and well commented so you can easily understand what it does and why.  It’s simple to add,  remove or modify encoders or taggers.  For example you might prefer to completely remove calls to Nero’s proprietary tools, or perhaps  add musepack or wavpack encoding and tagging.

Q: Why not just use ffmpeg without calling external encoders?

A: ffmpeg is great for decoding audio and grabbing metadata but it doesn’t support all encoders, or all the options of each supported encoder, and it can have trouble writing tags with some formats.  For example my installed version of ffmpeg loses all metadata at the writing stage on converting from ogg (libvorbis) to m4a (libfaac), though flac to m4a works fine.  With some formats you might find that writing  some metadata fields you want to use is unsupported and the data has been discarded.

I also want to strip replaygain data when converting to a lossy format because almost every lossy codec slightly raises the levels*.  Not only does this render the copied replaygain data inaccurate,  on a few tracks this will take a brickwall loudness mix into clipping.

By using ffmpeg to decode to PCM WAV then it’s possible to use any encoder that can read from STDIN or a named pipe. In this case it means neroAacEnc is scripted for automated/batch conversions but you could just as well do the same with whatever new encoder comes along, or with other encoders which are unsupported or incompletely supported in free software operating systems (ape and tak come to mind).

Q: Isn’t this an awful lot slower than just using ffmpeg or oggenc or whatever?

edit: following was for the original script.  foma is now massively faster than ffmpeg or oggenc or any other script or application which doesn’t run multiple parallel decode/encode processes.

A: Even with the extra metadata handling this script completes (on my 32-bit Debian stable system) almost as quickly as performing the same conversion with the ffmpeg binary; the time penalty is only about 5%).  I was also surprised to find that this script can be faster than the K.I.S.S**  solution, for example `oggenc -q 4 file.flac` is slower than `foma file.flac` every time.   ***On a less positive note if I perform the same conversion on the same machine running Windows XP SP3 32-bit using foobar2k as a frontend for oggenc.exe then the conversion takes only about 70% of the time as ffmpeg in Debian (edit:  I had another look at this and foobar achives its good performance by running two processes in parallel;  the Windows oggenc binaries don’t really perform any differently to those compiled using GCC, so the following sentence is redundant).  It may finally be time to head over to http://funroll-loops.info  or http://www.microsoft.com and bow down before the power of the teenagers||greysuits…..

*The only lossy format I’ve encountered which has no effect on the levels is lossy/hybrid wavpack but for compatibility and convenience reasons it’s not a codec I use for lossy compression.

**UNIX mantra: Keep It Simple, Stupid!

***No longer true.  New foma with parallel processes now easily outperforms other methods in Debian and in Windows XP.