Blog of Malte Kraus

home

Archive: Video-Thumbnails für WD TV Live erstellen

17 Jan 2010

Mein neues Spielzeug, der WD TV Live, kann Thumbnails (Vorschau-Bilder) zu einer Video-Datei anzeigen, wenn im selben Ordner eine jpg-Datei (am besten mit 120x180 Pixeln) mit dem selben Namen wie das Video liegt. Zur Datei video.mkv wird also z.B. video.jpg angezeigt.

Ich hab mir also ein Shell-Script besorgt, dass aus den Videos automatisch die Bilder generiert. Ich hab mich da für Sekunde 45 entschieden, weil bei einigen Filmen ganz am Anfang ja erstmal nutzlose Trailer der beteiligten Unternehmen laufen... Weil es vor a120llem bei 720p- oder 1080p-Videos ne Weile dauern kann, bis da ein einzelnes Bild generiert ist, hab ich dann (weil ich nicht so lang warten wollte ;) heute ein Shell-Script geschrieben, das vier Dateien auf einmal abarbeitet (ich hab nen Quad-Core). Das Script sollte man auch ohne allzu großen Aufwand anpassen können, dass es andere Aufgaben mit mehr oder weniger gleichzeitigen Jobs parallel abarbeitet (bald vielleicht auch meine Log-Files...).

Vorraussetzungen: ffmpeg, imagemagick

#!/bin/bash

set -x

file types:

TYPES='.+.(mkv|avi|mpg|mpeg|mov|wmv|mp4|flv)$'

make thumbnail at second ## of the movie

OFFSET=45

number of parallel processes

WORKERS=4

NL=' '

queueput() { queuename=$1 value=$2 if [ -n "${!queuename}" ]; then queueval="${!queuename}" eval "$queuename=\"$queueval$NL$value\"" #read $queuename <<< "$queueval$NL$value" else read $queuename <<< "$value" fi } queuepop() { queuename=$1 var=$2

queue="${!queue_name}" if [ -n "$queue" ]; then index=$(expr index "$queue" "$NL")

read $var <<< "${queue%%$NL}" if [ $index -eq 0 ]; then read $queuename <<< '' else eval "$queuename=\"${queue#$NL}\"" fi fi }

echo "searching for missing thumbnails..."

allfiles=$(find . -regextype posix-extended -iregex "$TYPES" -exec /bin/bash -c "file=\"{}\"; exit \$(test ! -f \"\${file%.*}.jpg\")" \; -printf '%p\n')

dir=$(mktemp -d)

work() { echo "worker $workerid is starting up..." sleep .25

pipe="$dir/job$workerid"
while [ -p "$pipe" ]; do
    echo READY &gt; "$pipe"
    read file &lt; "$pipe"
    if [ "$file" = "DONE" ]; then
        echo "worker $workerid is shutting down."
        exit 0
    fi

    thumb=${file%.*}.jpg

    echo
    echo
    echo
    echo "worker $workerid processing $file..."
    ffmpeg -itsoffset -$OFFSET -i "$file" -vcodec mjpeg -vframes 1 -an -f rawvideo -y -v -1 "$thumb"
    mogrify -resize 120x180 "$thumb"
done
return 0

}

masterpid=$$

workerid=0 workers=( ) while [ $workerid -lt $WORKERS ]; do mkfifo "$dir/job$workerid" work & workers[$workerid]=$!

let workerid++

done

sleep 3 while [ -n "$allfiles" ]; do workerid=0 while [ -n "$allfiles" -a $workerid -lt $WORKERS ]; do pipe="$dir/job$workerid" if [ -p $pipe ]; then response=$(cat < $pipe) if [ "$response" = "READY" ]; then queue_pop allfiles file echo $file > "$pipe" fi fi let workerid++ done

sleep .25

done

workerid=0 while [ $workerid -lt $WORKERS ]; do cat "$dir/job$workerid" > /dev/null echo DONE > "$dir/job$workerid" wait ${workers[$workerid]}

let workerid++

done

rm -rf "$dir"

Übrigens: Ordnern kann man mit einem folder.jpg ein Bild zuordnen.