Saturday, January 28, 2012

Magic Folder for pictures and videos

Every time I decide to move pictures from my camera to the computer, I spend several hours... And that's quite annoying..
I have to rename the pictures, so they include the shot date into the filename, rename the video files for the same reason, and finally re-encode the video files to MPEG-4 in order to save some space.

Wouldn't it be nice if all these happened automatically?
Here is the way to create a so called "Magic Folder" that does the job for you.

Every time you copy a picture or a video file into this folder, the picture is renamed and the video file is renamed and encoded.
As an extra step, I move the original video file to another storage.

You will need the following packages


In order continuously monitor a folder for new files you can use incron

sudo aptitude install incron

You also need jhead, to rename the pictures

sudo aptitude search jhead

In order to be able to encode video files using the H.264 encoder, you can enable the medibuntu repositories and install the following

sudo aptitude install ffmpeg libavcodec-extra-52

To enable notifications, you have to install the following

sudo aptitude install libnotify-bin

The script that does the job is the following


#!/bin/bash

# This script gets a filepathname and a target folder as input
# If the filename does not start with a number, the file is renamed, including the modification date of the file
# If the file is an AVI video file, it is encoded into mp4 (h.264) using ffmpeg
# After the encoding process completes, the original file is moved to the target folder and a notification is sent

PARAM=$1
MOVETOPATH=$2
echo ${PARAM}

DIR="`dirname ${PARAM}`"
FNAME="`basename ${PARAM}`"
EXT=${FNAME##*.}
FILENAME=${FNAME%.*}
OLDIFS=$IFS

IFS='
'
FC="`echo ${FNAME} | cut -c1-1`"

if [ "${FC}" -eq "${FC}" ] 2>/dev/null; then
echo "${FNAME} starts with an integer, skipping everything"
else

if [ "x${EXT}" = "xjpg" -o "x${EXT}" = "xJPG" ] ; then
jhead -exonly -n%Y_%m_%d_%f ${PARAM}
# notify-send ["${FNAME}"] "File has been encoded." -t 1000
fi

if [ "x${EXT}" = "xAVI" -o "x${EXT}" = "xavi" ] ; then

MODDATE=`stat -c %y "${PARAM}"`
FDATE=`date -d "${MODDATE}" "+%Y_%m_%d"`
NEWFNAME=${FDATE}_${FNAME}
NEWPATHNAME=${DIR}/${NEWFNAME}

echo ---- Renaming file: $FNAME to ${NEWFNAME}..
mv ${PARAM} ${NEWPATHNAME}

ENCODEDPATHNAME=${NEWPATHNAME%.*}.mp4
echo ---- Encoding file ${NEWPATHNAME} to ${ENCODEDPATHNAME}..
ffmpeg -i "${NEWPATHNAME}" -vcodec libx264 -vpre hq -acodec libfaac -ac 2 -ab 160k -threads 0 "${ENCODEDPATHNAME}"
echo ---- Moving old video file to a backup folder..
mv "${NEWPATHNAME}" "${MOVETOPATH}/${NEWFNAME}"
# notify-send ["${FNAME}"] "File has been encoded." -t 1000
fi
fi
echo Done!
echo " "
IFS=$OLSIFS

The hq preset being used in the encoding command is the following.
I have changed it a little bit to improve quality.
You can adjust b & bt to reduce file size or improve quality

cat /home/USERNAME/.ffmpeg/libx264-hq.ffpreset
coder=1
flags=+loop
cmp=+chroma
partitions=+parti8x8+parti4x4+partp8x8+partb8x8
me_method=umh
subq=8
me_range=16
g=250
keyint_min=25
sc_threshold=40
i_qfactor=0.71
b_strategy=2
qcomp=0.6
b=4500k
bt=5500k
qmin=10
qmax=51
qdiff=4
bf=3
refs=4
directpred=3
trellis=1
flags2=+wpred+mixed_refs+dct8x8+fastpskip
wpredp=2


Now we need to tell the system the we need to monitor a specific folder and whenever a new file is copied in it, to run our script

Enter incrontab -e in your terminal and an editor will appear

Enter the following line, changing the paths appropriately


MAGIC_FOLDER_PATH IN_CREATE sh MAGIC_FOLDER_SCRIPT_PATH/magicfolder.sh $@/$# PATH_TO_STORAGE

Save the file in the editor and your Magic Folder should be working

!! Warning !!
Do not delete the original pictures/videos from your camera, until you make sure everything is working as expected