Bilder von einem Kartenleserautomatisch laden

systematisch umbenennen, EXIF Daten ergänzen und mehr

Unter Linux schliesse ich meinen Kartenleser, und unter Ubuntu bekomme ich ein Dialog in dem ich festlegen kann welche Aktion ausgeführt wird. Ich habe folgende Scripte eingebunden, die mir die Bilder und Filme vollautomatisch von der Karte laden, in ein von mir bevorzugtes Dateinamenschema umbenennen, und die Filme, die in AVI Format daherkommen in ein Standard h.264/MKV umwandeln. Das Ende der Aktion wird mir akustisch gemeldet. Damit wird gleich beim Laden der Bilder ein Copyright-Eintrag und ein paar andere EXIF-Tags auf sinnvolle Werte gesetzt und das Dateidatum um die Zeitdifferenz zur lokalen Zeitzone korrigiert. Man könnte an dieser stelle auch noch eine Auto-Rotation der Bilder einbinden, aber ich selber benötige das nicht, weil ich konsequent nur querformat fotografiere. Das Script ist: /usr/local/bin/lade-bilder: (2009-11-02)

download

#!/bin/sh
# 
# Läd Bilder vom Medium im Kartenleser in ein vorbestimmtes Verzeichnis.
# Die Verzeichnisstruktur besteht aus hierarchischen Ebenen mit Jahr/Jahr-Monat-Tag.
# Wandelt dabei avi Filme (mjpeg einer Canon Powershot A60 oder einer Olympus SP-560UZ)
#  in MPEG, MOV oder MKV filme
# bringt alle Dateinamen in die Form "[Zeitstempel][Nummer].[jpg|mpeg]"
#   damit der DVD Player Bilder und Filme einfach chronologisch wiedergibt
#  und es einfach ist Bilder aus verschiedenen Kameras in chronologische Reihenfolge zu bringen..
# Benötigt: sed, mount, cp, echo, find, chmod, avi-mjpeg2mpeg
# unter Debian die Pakete mplayer, exifprobe und ffmpeg
# 2010-09-04 transcode wird nicht mehr benötigt
#
. /etc/colorcontrol    # entbehrliche Kosmetik
LOG=/tmp/lade-bilder$$.log
JAHR=$(date +%Y)
#TAG=$(date +%m%d)
TAG=$(date -I)
QPFAD=/media
ZIELVW=/home/$USER/Bilder
ZIELDIR=${ZIELVW}/$JAHR/${TAG}
# Audio-Wiedergabe mit mplayer (aplay wäre auch moglich, kann aber kein ogg...)
AUDIO_PLAYER="mplayer -nolirc -nomouseinput -nojoystick -noterm-osd -vo null"
KLANG_FEHLER=/usr/local/share/sounds/eigene/platsch_voll.wav
KLANG_FERTIG=/usr/local/share/sounds/eigene/Die_Übertragung_ist_beendet.ogg
#  Es werden ein paar EFIX-Daten angepasst.
if [ -z "$EXIF_AUTHOR" ]
then
    EXIF_AUTHOR=$(getent passwd $USER|cut -d: -f5|cut -d',' -f1)
fi
export EXIF_AUTHOR
EXIF_COPYRIGHT="Copyright (c) $JAHR, $EXIF_AUTHOR"
EXIF_COMMENT="batch processing on $HOSTNAME"
#--------------------------------------------
myexit() {
    echo "$1">>$LOG
    $AUDIO_PLAYER $KLANG_FEHLER 2>/dev/null
    exit $2
}
#=====================
debug() {
    case $2 in
    0)	echo " $1"
    ;;
    1)	echo "${VRED}! $1 !${VRESET}"
    ;;
    2)	echo "${VGREEN} $1${VRESET}"
    ;;
    *)	echo "${VBLUE} $1${VRESET}"
    ;;
    esac
}
#=====================
erstelle_verzeichnisse() {
    # ggf Zielverz. erstellen
    [ -d ${ZIELVW} ] || mkdir -p ${ZIELVW}/
    [ -d ${ZIELDIR} ] || mkdir -p ${ZIELDIR}/
}
#=====================
# gibt den Datumstempel der Datei $1 zurück
time_stamp() {
    ls --full-time "$1"|cut -d " " -f 6-7|sed -e "s/ /T/" -e "s/://g" -e "s/\..*//"
}
#=====================
# gibt den EXIF-Datumstempel der Datei $1 zurück
# Die Kameras kennen keine Zeitzone, weshalb man die Kamera eigentlich immer auf GMT einstellen sollte.
# .... das macht aber niemand....
exif_time_stamp() {
    exifgrep 'DateTimeOriginal' "$1"|cut -d "'" -f2|sed -e "s/:/-/" -e "s/:/-/" -e "s/ /T/" -e "s/://g"
}
#=====================
kopiere_dateien() {
debug "kopiere Bilder und Filme nach ${ZIELDIR}..." 0
find "${QPFAD}" -regextype posix-extended -type f -iregex '.*/dcim/.*/????[[:digit:]]*\.(jpg|avi|mpg|wav)'|sort|while read X
do
   echo -e -n "\r$X   "
   cp -p "$X" ${ZIELDIR}/
done
}
#=====================
korrigiere_dateirechte() {
    debug "korrigiere Dateiflags auf nicht ausführbar..." 0
#    chmod -x ${ZIELDIR}/*
    if [ -z "$ZEITKORR" ]
    then
# wir nehmen eine JPEG Datei um die Zeitzone mit der der Kernel den KArtenleser gemountet hat rauszufinden
        TEST=$(find "${QPFAD}" -regextype posix-extended -type f -iregex '.*/dcim/.*/????[[:digit:]]*\.(jpg|avi|mpg|wav)'|sort|head -1)      #'
        MTZ=$(ls --full-time "$TEST"|cut -d ' ' -f 8|tr '+' ' ' )
        UTZ=$(date +%z|tr '+' ' ')              # Zeitzone des ausführenden Benutzers
        KORRTZ=$( expr $MTZ + $UTZ )
        [ $KORRTZ -lt 1000 ] && [ $KORRTZ -gt -1000 ] && KORRTZ=0$KORRTZ
        [ $KORRTZ -ge 0 ] && KORRTZ=+$KORRTZ
        if [ "$MTZ" -ne 0 ]
        then
            ls -1 ${ZIELDIR}/* |while read XX 
            do  # Korrektur der Zeit des vfat Systems das beim mounten als SystemZeizZone angenommen wird, meistens
            # aber die Lokale Zeit ist, weil man diese an der Kamera einstellt...
            #
            touch --date="$(ls --full-time $XX|cut -d ' ' -f 6-7|cut -d '.' -f1) $KORRTZ" $XX
            done
        debug "Korrektur der Zeitzone um  $KORRTZ" 1
        else debug "keine Zeitzonenkorrektur notwendig!" 1
        fi
    fi
}
#=====================
konvertiere_filme() {
debug "konvertiere Filme von avi nach mkv..." 0
cd ${ZIELDIR}/
while ls -1 *.avi 2>/dev/null 1>/dev/null
do
   DATEI=$(ls -1 *.avi|head -1)
   debug "${VBLUE}konvertiere ${DATEI}${VRESET}" 0
   avi-mjpeg2mkv "$DATEI" && mv $DATEI $DATEI.
done
while ls -1 *.mpg 2>/dev/null 1>/dev/null
do
   DATEI=$(ls -1 *.mpg|head -1)
   NDATEI=$(basename $DATEI .mpg).mkv
   debug "${VBLUE}konvertiere ${DATEI}${VRESET}" 0
   # Die Video-Dateien der HP Kamera werden in DVD Playern ohne Ton wiedergegeben, also konvertieren wir
#   ffmpeg -i "$DATEI" -threads 4 -r 25 -b 1000000 -vcodec libx264 -vpre medium -bufsize 5000k -maxrate 1200000 -ab 128000 -ar 48000 -ac 1 -acodec libvo_aacenc "$NDATEI"
   avconv -i "$DATEI" -threads 4 -r 25 -b 1000000 -vcodec libx264 -vpre medium -bufsize 5000k -maxrate 1200000 -ab 128000 -ar 48000 -ac 1 -acodec libvo_aacenc "$NDATEI"
   touch -r $DATEI $NDATEI
   rm -f $DATEI
done
}
#=====================
exif_fix() {
ls -1 *.jpg|while read XX
do
    exiftool -ThumbnailImage= -comment="$EXIF_COMMENT" -copyright="$EXIF_COPYRIGHT" -author="$EXIF_AUTHOR" $XX
    touch -r ${XX}_original $XX &&  rm -f ${XX}_original
done
}
#-------- START -----------------------------------------------
##echo "$(date -I), $0 $1 $2 $3">$LOG
NUMM=$(mount|grep '/media/'|wc -l)
case $NUMM in
    0)
    echo "nix unter $QPFAD gemounted, ist der Kartenleser eingesteckt??"
    exit
    ;;
    1)
    echo "ok, ein Mount gefunden"
    ;;
    *)
    echo "zu viele mounts unter /media/"
    ;;
esac
#
erstelle_verzeichnisse
kopiere_dateien
korrigiere_dateirechte
if [ -z "$1" ]
then
    cd $ZIELDIR/ && bulk-rename2timestamp
    konvertiere_filme
fi
#exif_fix
debug "fertig." 2
$AUDIO_PLAYER $KLANG_FERTIG 2>/dev/null &

Es benutzt zum Konvertieren der Videos /usr/local/bin/avi-mjpeg2mkv:

download

#!/bin/sh
# 
# 2004-07-11, J. Schwender
#
# Konvertiert die Filme die eine 
#    Canon Powershot A60 
# erzeugt (AVI mit codec mjpeg / pcm) in ein Matroska Video
#             fps   x   y   bit/s 
# PAL DVD HQ  25   720x576  7200, 48000/16/2
# PAL DVD GQ  25   720x576  6500, 48000/16/2
# PAL DVD SP  25   352x576  3600, 48000/16/2
# PAL DVD LP  25   352x576  3000, 48000/16/2
# PAL VCD     25   352x288  1090, 44100/16/2
# PAL SVCD    25   480x576  2419, 44100/16/2
# 
# 2007-04-15: anpassung an etch: neue ffmpeg Version benötigt Datenraten in bit/s anstatt wie bisher in kbit/s 
# 2008-01-12: anpassung an ubuntu gutsy, 
myexit() {
  echo "$1"
  exit 1
}
# Eingabedatei muss *.avi sein
#echo "$1" |grep -q ".avi" || myexit "Kein avi-Datei angegeben!"
echo -e -n "Teste: AVI Dateiename, "
FN=`basename $1 .avi`
EXIF_AUTHOR=$(getent passwd $USER|cut -d: -f5|cut -d',' -f1)
#
PROBE=$(avprobe "$1" 2>&1|grep Video)

echo $PROBE |grep -q ' 1280x720' && TRATE=3600000 # diese Kamera liefert ca 22Mbps @ 30fps
echo $PROBE |grep -q ' 640x480'  && TRATE=3000000 # diese Kamera liefert ca 14Mbps @ 30fps
echo $PROBE |grep -q ' 320x240'  && TRATE=750000  # 1/4 Rohdatenstrom im Vergleich zu VGA erfordert letztlich auch 1/4 des Enddatenstroms
echo $PROBE |grep -q ' 160x120'  && TRATE=200000  # 1/16 Rohdatenstrom im Vergleich zu VGA erfordert letztlich auch 1/16 des Enddatenstroms

CTIME=$(avprobe "$1" 2>&1|grep creation_time|head -1|cut -d":" -f2-	)
ENCODER=$(avprobe "$1" 2>&1|grep encoder|head -1|cut -d":" -f2-	)
echo $CTIME

  avconv -i "${1}" -threads 4 -b:v $TRATE -c:v libx264 -trellis 2 -me_range 24 -b:a:0 128000 -ar:a:0 48000 -c:a:0 libvorbis -ac:a:0 1 \
-metadata creation_time="$CTIME" -metadata comment="$ENCODER"  -metadata:s:v:0 encoder="avconv libx264" -metadata:s:a:0 encoder="avconv libvorbis" -metadata author="$EXIF_AUTHOR" -metadata copyright="copyright $EXIF_AUTHOR" "${FN}.mkv" || myexit "avconv fehlgeschlagen"
  touch -r "$1" "${FN}.mkv"
  exit 0