Einführung
Manche Digitalkameras können Fotos in einem bestimmten Zeitintervall auslösen.
Nach ein paar Stunden sammeln sich viele Fotos in einem Ordner an, welche man
mit ffmpeg
in ein Video umwandeln kann. Ich habe einige Zeit gebraucht, bis
alles endlich funktioniert hat. Hier seht ihr, wie man das mit ffmpeg
machen
kann.
Schritt für Schritt
Ausgangslage
Als Ausgangslage habe ich viele Fotos in einem Verzeichnis:
$ ls
2011-07-08_13-59-58.jpg 2011-07-08_15-01-27.jpg 2011-07-08_16-02-57.jpg
2011-07-08_14-00-07.jpg 2011-07-08_15-01-38.jpg 2011-07-08_16-03-08.jpg
2011-07-08_14-00-17.jpg 2011-07-08_15-01-47.jpg 2011-07-08_16-03-17.jpg
[...]
In meinem Fall sind das 1104 Fotos:
$ ls *.jpg | wc -l
1104
Diese Fotos haben zusammen eine Grösse von 2.4 GB:
$ du -ch *.jpg
1.6M 2011-07-08_13-59-58.jpg
1.6M 2011-07-08_14-00-07.jpg
[...]
2.0M 2011-07-15_14-48-28.jpg
2.4G insgesamt
Ich möchte von diesen Fotos ein HD-Video umwandeln. Die Fotos haben eine Auflösung von 2592 x 1944
Pixel:
$ jhead 2011-07-15_14-47-51.jpg | grep Resolution
Resolution : 2592 x 1944
Fotos verkleinern
Da die Fotos zu gross sind, verkleinert man die Fotos auf zuerst auf 1080 Pixel in der Höhe:
for datei in *.jpg
do
convert -resize x1080 -quality 50 "$datei" "small_$datei"
done
Fotos umbenennen
Damit ffmpeg
die Fotos in ein Video umwandeln kann, müssen die Fotos im Format wie 0001.jpg
vorliegen. Die führenden Nullen sind für ffmpeg
wichtig. Die Fotos können mit convert
(aus dem Paket imagemagick
) konvertiert werden:
LENGTH=`ls | wc -l | wc -L`
NUMBER="1"
find *.jpg | while read foto
do
mv $foto "`printf %0${LENGTH}d $NUMBER`".jpg
NUMBER=$((NUMBER + 1))
done
Fotos in ein Video konvertieren
Jetzt kann man mit ffmpeg
die Fotos in ein Video umwandeln:
ffmpeg -f image2 -i %0${LENGTH}d.jpg -r 25 -vcodec libx264 output.mpg
Fertig: Video abspielen
Das Video ist nach dem Konvertieren 28 MB gross:
$ du -h output.mpg
28M output.mpg
Das Video kann jetz abgespielt werden
mplayer output.mpg
Automatisch mit einem Skript
Um diese Schritte zu vereinfachen, habe ich ein kleines Bash-Skript pic2vid
geschrieben, welches all diese Schritte schön ausführt:
#!/usr/bin/env bash
########################################################################
#
# pic2vid
# Konvertiert mehrere Fotos zu einem Video (Zeitraffer)
#
# GNU General Public License
# 2012 by Emanuel Duss
#
########################################################################
########################################################################
# Variabeln
DIR="$1"
PICDIR="pic2vid"
SMALLDIR="$DIR/$PICDIR"
SIZE="x1080"
QUALITY="90"
OUTPUTFILE="output.mpg"
CODEC="libx264"
FRAMESPERSECOND="25"
########################################################################
# Funktionen
Printusage () {
echo "Usage:
$0 directory"
}
########################################################################
# Main
# Prüfe Fehler
if [ -z "$1" ]
then
Printusage
exit 1
fi
if [ ! -d "$DIR" ]
then
echo "$DIR ist kein Verzeichnis"
Printusage
exit 1
fi
if [ -d "$SMALLDIR" ]
then
echo "Verzeichnis für aufzubereitende Fotos bereits vorhanden."
else
mkdir "$SMALLDIR"
fi
if [ ! -d "$SMALLDIR" ]
then
echo "Kann $SMALLDIR nicht anlegen. Bitte Berechtigungen prüfen."
exit 1
fi
cd $DIR
# Fotos verkleinern (nur, wenn noch nicht verkleinert)
TOTAL="`ls *.[Jj][Pp][Gg] | wc -l`"
COUNT="1"
for file in *.[Jj][Pp][Gg]
do
if [ -f "${PICDIR}/$file" ]
then
echo "Überspringe $file, da bereits konvertiert (${PICDIR}/$file)"
else
echo "$file: Foto $COUNT von $TOTAL ($((100 * $COUNT / $TOTAL))%)"
convert -resize $SIZE -quality $QUALITY "$file" "${PICDIR}/$file"
fi
((COUNT++))
done
# Fotos umbenennen (in Form wie 0001.jpg bis 2342.jpg)
cd $PICDIR
LENGTH="`ls *.[Jj][Pp][Gg] | wc -l | wc -L`"
NUMBER="1"
for file in *.[Jj][Pp][Gg]
do
NEWNAME="`printf %0${LENGTH}d $NUMBER`.jpg"
if [ -f "$NEWNAME" ]
then
echo "Datei $file bereits umbenannt. OK."
else
# Symlink statt umbenennen, damit die Prüfung ob schon konvertiert auch funktioniert
ln -s "$file" "`printf %0${LENGTH}d $NUMBER`".jpg
fi
((NUMBER++))
done
# Bilder mit ffmpeg zu Video zusammenfügen
ffmpeg -f image2 -i %0${LENGTH}d.jpg -r $FRAMESPERSECOND -vcodec $CODEC ../$OUTPUTFILE
# EOF
Das Skript sagt einem, wie man es anwenden muss:
$ pic2vid
Usage:
pic2vid directory
So erstelle ich z. B. im aktuellen Verzeichnis mit allen Bildern ein Video:
pic2vid .
Und schon hat man sein Zeitraffervideo.
Die aktuellste Version davon gibt es auf GitHub in meinem Scripts Repository: pic2vid.
Links und weitere Informationen
- ffmpeg: https://ffmpeg.org/
- ffmpeg Manpage: https://ffmpeg.org/ffmpeg.html