dietzens.de

Bash-Skripte

Bilderserien mit Überblendung

Es gibt sicher tausend Tools, um aus Bildersammlungen Videosequenzen zu machen. Am schnellsten ist man garantiert mit diesem kleinen Bash-Skript, welches ffmpeg, das Schweizer Multimedia-Taschenmesser der Open Source Community, steuert. ffmpeg benötigt die Bildaten dummerweise in aufsteigender Zahlenfolge, daher kopiert das Skript die Bilder unter neuem Namen - löscht sie aber auch wieder. D.h. für die Ausführung des Skriptes verdoppelt sich der Festplattenspeicherbedarf. Die Sortierung des Dateisystems (bei Linux nach Namen) steuert die Abfolge der Bilder.

in neuem Fenster öffnen
#! /bin/bash
#
# stand: Standzeit des Bildes in Sekunden
# fade:  crossfade Dauer in Sekunden
# svar:  Abmessungen des Video - sollte mit den Bildgrößen übereinstimmen

stand=0
fade=1
svar=1500x1000

dvar=($stand+$fade)/$fade
targetdir="img"
targetfile="../imgfade.mp4"
if [ ! -d $targetdir ]; then
    mkdir $targetdir
fi

if [ $# -gt 0 ]; then
	quelltype=${1##*.}							# Dateityp abtrennen
	dateipfad=${1%/*};
	dateiname=${1##*/};
    zieltype=${quelltype,,}        # lowercase
   	nummer=0
    while [ $# -gt 0 ]; do
		quellname=$1
		zielname="$(printf "%03d" $nummer)";
		zielname=$targetdir"/img_"$zielname"."$zieltype
		echo $quellname" -> "$zielname;
 		cp "$quellname" "$zielname";
		nummer=$[$nummer+1];
		shift
	done
fi

cd $targetdir
ffmpeg -i "img_%03d.$zieltype" -vf zoompan=d=$dvar:s=$svar:fps=1/$fade,framerate=25:interp_start=0:interp_end=255:scene=100 -c:v mpeg4 -maxrate 5M -q:v 2 $targetfile
rm img_*
cd ..
rmdir $targetdir

GoPro-Tools

Eine Action-Cam produziert unglaublich viele Daten und niemand möchte sich stundenlange Videos mit wenig Action angucken. Ich hab' daher eine Möglichkeit gesucht, Videoschnipsel aus einer langen Aufnahme zu machen und diese so zusammenzusetzen, dass man einen Eindruck der - in meinem Fall - gefahrenen Strecke bekommt. Und das geht mit ffmpeg und dem MLT-Framework

Schnipsel aus Video herausschneiden

Der Aufruf dieses Shellscripts erzeugt aus einer Menge von mp4-Dateinen Videoschnipsel im Ordner "slices".

in neuem Fenster öffnen
#!/bin/bash

slicelength=2000       # length of videoslice in milliseconds
slicegap=30000          # gap between videoslices in milliseconds

profile="-preset medium"            # ultrafast,superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo
metadata="-map_metadata 0"
vcodec="-vcodec libx264"
crf="-crf 23"
format="-vf format=yuvj420p"
acodec="-acodec aac -ab 96k"
faststart="-movflags +faststart"
loglevel="-loglevel error"       # quiet, panic, fatal, error, warning, info, verbose, debug
slicedir="slices"
if [ ! -d $slicedir ]; then
	mkdir $slicedir
fi

############################
# gets "$inputfile" duration and returns total number of seconds: secondstotal
############################
getduration () {
    fileinfo=$(mktemp)                      # use tempfile for fileinfo
	ffmpeg -i "$inputfile" 2> $fileinfo        # ffmpeg without parameters throws the videocharacteristics, esp. duration
	info=`cat $fileinfo | grep -Eo "Duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})"`  # Duration in hh:mm:ss format
	rm $fileinfo
    time=${info##*Duration: }
	seconds=${time##*:}
    time=${time%:*}
    minutes=${time##*:}
    time=${time%:*}
    hours=${time##*:}
    secondstotal=`echo "(($hours*60 + $minutes)*60 + $seconds )" | bc`
    millisecondstotal=`echo "1000*(($hours*60 + $minutes)*60 + $seconds )" | bc`
}
############################
# gets "$inputfile" creation date and time of video and returns string with date and time: creationtime
############################
getcreation () {
    fileinfo=$(mktemp)                      # use tempfile for fileinfo
    ffprobe -show_format "$inputfile" > $fileinfo
	creation=`cat $fileinfo | grep "creation_time"`
    creationtime=${creation##*=}
    creationtime=${creationtime%%.*}
	rm $fileinfo
}
############################
# makes at string-timestamp out of a number of seconds
############################
makestamp() {
    millis=`echo "scale=0; (($1*1000/1.0))" | bc`
    millis=$1
    printf '%02d:%02d:%02d.%03d' $(($millis%86400000/3600000)) $(($millis%3600000/60000)) $(($millis%60000/1000)) $(($millis%1000))
}

while [ $# -gt 0 ]      # loop through commandline patterns
do
    inputfile=$1        # we just need one argument
    getduration
    getcreation
    # creationmetadata="-metadata creation_time=\"$creationtime\""
    creationmetadata="-metadata creation_time=$creationtime"    # needed for target-video of slices

    filetrunc=${inputfile%%.*}                                  # use filename for result
    filetype=${inputfile##*.}                                   # use filetype for result
    filetrunc_nws=`echo $filetrunc | sed 's/\s/_/g'`            # ensure no whitespaces "safe" characters in filename

    position=0
    slicenumber=0
    slicelengthstamp=`makestamp $slicelength`
    echo "slicelengthstamp".$slicelengthstamp."\n"

    segments=segments.txt                                       # segments=$(mktemp) does not work because of security issues of ffmpeg

    while [ $position -lt $(( $millisecondstotal-$slicelength )) ]; do
        slicenummerstring=`printf '%03d' $slicenumber`
        positionstamp=`makestamp $position`
        echo "start:" $positionstamp " length:" $slicelengthstamp " filename:" $filetrunc_nws"_"$slicenummerstring"."$filetype
        ffmpeg -ss $positionstamp -i "$inputfile" -t $slicelengthstamp  $format $profile $vcodec $acodec $loglevel "$filetrunc_nws""_"$slicenummerstring"."$filetype
        echo "file "$filetrunc_nws"_"$slicenummerstring"."$filetype >> $segments
        position=$(( $position + $slicegap))
        slicenumber=$(($slicenumber + 1));
    done
    # ffmpeg -f concat -i $segments -c copy $filetrunc_nws"_"$slicelength"s_after_"$slicegap"s."$filetype
    # ffmpeg -f concat -i $segments $acodec $crf $format $faststart $creationmetadata $loglevel $filetrunc_nws"_"$slicelength"s_after_"$slicegap"s."$filetype

    rm $segments
    position=0
    slicenumber=0
    ######################
    # cleanup slices - if desired
    ######################
    while [ $position -lt $millisecondstotal ]; do
        slicenummerstring=`printf '%03d' $slicenumber`
    #     rm $filetrunc_nws"_"$slicenummerstring"."$filetype
        mv $filetrunc_nws"_"$slicenummerstring"."$filetype $slicedir
        position=$(( $position + $slicegap))
        slicenumber=$(($slicenumber + 1))
    done
    shift
done

Schnipsel zu Video zusammenfügen

Der dieses Shellscripts verschmilzt Videoschnipsel zu einem einzigen Video

in neuem Fenster öffnen
#!/bin/bash

fadeframes=15       # num of frames for fading
#fadeframes=7       #quicker
x=""
first=1

if [ $# -gt 0 ]; then
    while [ $# -gt 0 ]; do
        if [ $first -eq 1 ]; then
            x="$1"
            first=0
        else
            x="$x $1 -mix $fadeframes -mixer luma -mixer mix:-1" # -mixer mix:-1 = crossfade audiochannels
        fi
        shift
    done
    echo "$x"

    x="melt $x -consumer avformat:fade_$(date +%y-%m-%d_%H%M%S).avi vcodec=libx264 vb=8000K ab=96k"         # an=1 disable audio
    eval $x
else
    echo "generates a crossfaded video out of several single videos (AD 2017-08-05), needs 'melt'"
    echo "syntax: videofade *.mp4"
fi

Echtzeituhr auf Fotos einblenden

Dieses Shellscript blendet eine Uhr in die rechte untere Ecke der Fotos ein

in neuem Fenster öffnen
#!/bin/bash
# create timelapsevideo with moving big and little hands

######################################
uses=1		# every n-th image
######################################
if [ $# -gt 0 ]; then                               # work within directory
    filepath=${1%/*};
    filename=${1##*/};
    if [ "$filepath" != "$filename" ]; then
        cd $filepath;
    fi
fi
workingdirectory=$(pwd)
processdir="interval_"$uses
if [ ! -d $processdir ]; then
	mkdir $processdir
fi
prefix="clocked"

fontcolor="'#444444'"
transparency="'#888888'"

if [ $# -gt 0 ]; then                                       # get videodimensions from first image
	imgwidth=`identify -format "%w" "$1"`
	imgheight=`identify -format "%h" "$1"`
fi;

destinationframerate=30
font="/usr/share/fonts/truetype/liberation/LiberationMono-Bold.ttf"
font="/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf"
font="/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf"
fontsize=`echo "scale=0; $imgheight/50" | bc`

dialsize=`echo "scale=0; $imgheight/5" | bc`
fontsize=`echo "scale=0; $dialsize/8" | bc`
textsize=`echo "scale=0; $dialsize*0.7" | bc`   # text will be centered in the dial, with 70% of the diameter

radius=`echo "scale=0; $dialsize/2" | bc`
mhandlength=`echo "scale=0; $dialsize*0.45/1" | bc`
hhandlength=`echo "scale=0; $dialsize*0.3/1" | bc`
mhandwidth=`echo "scale=0; $dialsize/60" | bc`
hhandwidth=`echo "scale=0; $dialsize/40" | bc`
dialx=`echo "scale=0; ($imgwidth-1.1*$dialsize)/1.0" |bc`		# just division takes care of trailing numbers
dialy=`echo "scale=0; ($imgheight-1.1*$dialsize)/1.0" |bc`
datex=`echo "scale=0; $radius/2.2" |bc`
datey=`echo "scale=0; $radius*1.5" |bc`

dialplate=$processdir"/dialplate.png"
dialalpha=$processdir"/dialalpha.png"
bighand=$processdir"/bighand.png"
littlehand=$processdir"/littlehand.png"
hour_r=$processdir"/hour_r.png"
minute_r=$processdir"/minute_r.png"
dial=$processdir"/dial.png"
date=$processdir"/date.png"

s_dialplate="convert -size "$dialsize"x"$dialsize" xc:transparent -fill grey -stroke black "
s_dialplate+="-strokewidth "$mhandwidth" -draw 'circle "$radius","$radius" "$radius","$mhandwidth"' "$dialplate
eval ${s_dialplate}

# s_dialalpha="convert -size "$dialsize"x"$dialsize" xc:transparent -fill '#444444' alpha set"
s_dialalpha="convert -size "$dialsize"x"$dialsize" xc:transparent -fill $transparency"
s_dialalpha+=" -draw 'circle "$radius","$radius" "$radius","$mhandwidth"' "$dialalpha
eval ${s_dialalpha}
# convert $dialalpha alpha on

# bighand 6:00 Nullstellung rectangle-Koordinaten ul or
s_bighand="convert -size "$dialsize"x"$dialsize" xc:transparent -fill black -stroke black "
s_bighand+="-draw 'roundrectangle "$[$radius-$hhandwidth]","$[$radius-$hhandlength]" "
s_bighand+=$[$radius+$hhandwidth]","$[$radius+$hhandwidth]" $hhandwidth,$hhandwidth' "$bighand
eval ${s_bighand}

# littlehand 6:00 Nullstellung rectangle-Koordinaten ul or
s_littlehand="convert -size "$dialsize"x"$dialsize" xc:transparent -fill black -stroke black "
s_littlehand+="-draw 'roundrectangle "$[$radius-$mhandwidth]","$[$radius-$mhandlength]" "
s_littlehand+=$[$radius+$mhandwidth]","$[$radius+$mhandwidth]" $mhandwidth,$mhandwidth' "$littlehand
eval ${s_littlehand}

# convert -size 80x80 xc:transparent -fill black -stroke black -draw "roundrectangle 38,10 42,40 2,2" $bighand
# convert -size 80x80 xc:transparent -fill black -stroke black -draw "roundrectangle 39,3 41,40 2,2"  $littlehand

if [ $# -gt 0 ]; then
	sourcetype=${1##*.}
	case "$sourcetype" in
		jpg|JPG ) destinationtype="jpg";;
		tif|TIF ) destinationtype="tif";;
	esac
    counter=0
    intervall=$uses
    numimages=$#
    echo "generating video "$imgwidth"x"$imgheight" "$destinationframerate"fps out of $numimages images with every "$uses"th image";
    while [ $# -gt 0 ]; do
		if [ $intervall -eq $uses ]; then                  # we got the n-th image
			sourcename=${1##*/};                              # we are already in the working directory
			echo $sourcename
	    	counterstring="$(printf "%05d" $counter)";
			processedname=$processdir"/"$prefix$counterstring"."$destinationtype
# 			echo $processedname
       		echo -ne $sourcename" -> "$processedname"\r"
         	cp "$sourcename" "$processedname"

############ fetch datetime ################
            datetime=$(exiftool -b -DateTimeOriginal "$sourcename" 2> /dev/null);        # usually 2005:04:11 19:06:52.
            year=$(echo     "$datetime" | cut -c 1-4)              # 4-digits to check for correct year
            month=$(echo    "$datetime" | cut -c 6-7)
            day=$(echo      "$datetime" | cut -c 9-10)
            hour=$(echo   "$datetime" | cut -c 12-13)
            minute=$(echo   "$datetime" | cut -c 15-16)
            second=$(echo  "$datetime" | cut -c 18-19)
############ create date label ################
 			text=$day"."$month"."${year#20}
 			text=$day"."$month"."$year
#   			stext="mogrify -font $font -pointsize $fontsize "
#   	        stext+=" -fill $fontcolor -draw \"text $datex,$datey '$text'\""
#   	        stext+=" $dial2 "
            stext="convert -font $font -fill $fontcolor "
  	        stext+=" -size $textsize""x""$textsize -gravity center label:'\n\n$text' "
  	        stext+=" -transparent white $date "
			eval ${stext}

 	        ############ create time-hands ################
			hourangle=`echo "scale=2; (($hour+($minute/60))*360/12)/1" | bc`;
			minuteangle=`echo "scale=2; ($minute*6 + $second/10)/1" | bc`;

			convert $littlehand -distort SRT $minuteangle -transparent white $minute_r
			convert $bighand -distort SRT $hourangle -transparent white $hour_r

			composite -gravity center            $hour_r   $dialplate $dial      # add hour
			composite -alpha set -gravity center $minute_r $dial      $dial     # add minute
			composite -alpha set -gravity center $date     $dial      $dial     # add Date

			# make transparent
#			transparent="convert $dial2 $dialalpha -alpha off -compose CopyOpacity -composite $dial"
			transparent="convert $dial $dialalpha -alpha off -compose CopyOpacity -composite $dial"
 			eval ${transparent}
            # copy dial to image preserve transparency
 			composite -alpha set -geometry +$dialx+$dialy $dial "$sourcename" "$processedname"

############ dial finished ################
			counter=$[$counter+1];					               # next used image
			intervall=0;							               # start over at 0
		fi
		intervall=$[$intervall+1];					               # next interval-image
		shift
	done
	echo "";
	echo "cleaning up tempfiles"
	                                                               # cleanup
	rm $dialplate
	rm $dialalpha
	rm $bighand
	rm $littlehand
	rm $hour_r
	rm $minute_r
	rm $dial
	rm $date
	##### create the video out of the images
    workingsubdir=${workingdirectory##*/}
	videoname="../"$workingsubdir".mp4"
#	videoname="../test_"$uses".mp4"
	echo $workingsubdir" "$videoname


	if [ -f "$videoname" ]; then          # file exists?
		echo -e "\E[1;33;40m "$videoname" already in use, attach date-time to filename\E[0m";
		datetime=$(date +%Y-%m-%d %H%M%S)				# 2016-12-23 184533
		videoname=${videoname%.*}"_"$datetime".mp4";
    fi
	verbosity="-v quiet -stats -hide_banner"     # quiet, just stats
#   verbosity=""
    quality="23"          # stanard is 23, 29 gives vids aprox. half the size
    command_line=( ffmpeg -r 30 -i $processdir/$prefix%05d.jpg -r $destinationframerate -vf format=yuv420p  -vcodec libx264 -crf $quality $verbosity "$videoname" )
#     echo "--------- for debugging --------------"
#     echo "${command_line[@]}"
#     echo "--------------------------------------"
    "${command_line[@]}"
# 	ffmpeg -v quiet -stats -r 10 -i $processdir/$prefix%05d.jpg -r $destinationframerate -vf format=yuv420p -crf 23 $videoname
#	ffmpeg -v quiet -stats -r 10 -i $processdir/$prefix%05d.jpg -r $destinationframerate -vf format=yuv420p -crf 19 "$videoname"
# you probably want to cleanup automatically
  	rm $processdir/$prefix*.jpg
  	rmdir $processdir

else
echo "generates a timelapsevideo out of images, enblends a dial based ont the exif-dates given (AD 2017-08-05)"
echo "Syntax: timelapse *.jpg"
fi

Echtzeituhr auf Videos einblenden

Dieses Shellscript blendet eine Uhr in die rechte untere Ecke der Videos ein

in neuem Fenster öffnen
#!/bin/bash
# create dial with moving big and little hands to mix in videofiles

function secure_filename (){
    filename=$1
    if [ -f "$filename" ]; then          # file exists, don't overwrite
        filetype=${filename##*.}
        datetime=$(date +'%Y%m%d%H%M%S')				# 20161223184533
        filename=${filename%.*}"_"$datetime"."$filetype
    fi
    echo "$filename"
}
####################################################
# Note: Encoded_Date is often marked as 'UTC'
# but some cameras (for examples GoPro, Nikon DSLR, Videocams) dont respect timezones - mobile phones usually do!
# So better check, if the timestamp is UTC or "cameratime"
################################################
timezone="TZ=CEST"             # recalculate real UTC to Central European Summer Time
timezone="TZ=CET"              # recalculate real UTC to Central European Time
# comment out, what's not needed
#ignoretimezone="no"            # mobile phones
ignoretimezone="yes"           # gopro, cameras

fontcolor="'#dddddd'"
dialbackground="'#888888'"            # this is the dialbackground of the grey background of the dial
bighandcolor="'#000000'"
littlehandcolor="'#000000'"
opacity="0.7"                       # opacity of the final dial
font="/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf"

processdir="dial"
if [ ! -d $processdir ]; then
    mkdir $processdir
fi
prefix="clocked"
destinationtype="png";
dialplate=$processdir"/dialplate.png"
dialalpha=$processdir"/dialalpha.png"
hourplate=$processdir"/hourplate.png"
homiplate=$processdir"/homiplate.png"
bighand=$processdir"/bighand.png"
littlehand=$processdir"/littlehand.png"
hour_r=$processdir"/hour_r.png"
minute_r=$processdir"/minute_r.png"
dial=$processdir"/dial.png"
date=$processdir"/date.png"

if [ $# -gt 0 ]; then

    filepath=${1%/*};
    filename=${1##*/};
    if [ "$filepath" != "$filename" ]; then
        cd $filepath;
    fi
    while [ $# -gt 0 ]; do
        filename=${1##*/}
        sourcename=${filename%%.*}
        sourcetype=${filename##*.}
        lowersourcetype=${sourcetype,,}

        if [ -f "$filename" ]; then             # if exists
            if  [ $lowersourcetype == "mp4" ] ||
                [ $lowersourcetype == "mov" ] ||
                [ $lowersourcetype == "mts" ] ||
                [ $lowersourcetype == "avi" ] ||
                [ $lowersourcetype == "mpg" ]
            then
                datetime=$(mediainfo --Inform="Video;%Encoded_Date%" "$filename")  # starttime
                if [ "$datetime" == "UTC 1904-01-01 00:00:00" ] ||
                   [ "$datetime" == "" ]            # there's no Encoded_Date given,
                then                                # look for filename 2017-08-23 145110, no colons allowed in filenames
                    filedatetime=$(echo $filename | grep -Eo "([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}[0-9]{2}[0-9]{2})")
                    if [ "$filedatetime" != "" ]
                    then
                        datetime=$(echo "$filename" | cut -c 1-10)
                        datetime=$datetime" "$(echo "$filedatetime"|cut -c 12-13);
                        datetime=$datetime":"$(echo "$filedatetime"|cut -c 14-15);
                        datetime=$datetime":"$(echo "$filedatetime"|cut -c 16-17);
                        echo "no Encoded_Date given, using filename-date $datetime"
                    else
                        datetime=$(exiftool -b -FileModifyDate "$filename")
                        filedatetime=$(echo $datetime | grep -Eo "([0-9]{4}:[0-9]{2}:[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})") # filter out 'Timezone-marker, usualy UTC
                        datetime=$(echo "$filedatetime" | cut -c 1-4)
                        datetime=$datetime"-"$(echo "$filedatetime"|cut -c 6-7);
                        datetime=$datetime"-"$(echo "$filedatetime"|cut -c 9-19);
                        echo "no info in filename, using filesystem date $datetime"
                    fi
                fi
                 if [ $ignoretimezone == "yes" ]
                then
                    datetime=$(echo $datetime | grep -Eo "([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})") # filter out 'Timezone-marker, usualy UTC
                    timezone=""
                fi
                # request some info about the video
                framerate=$(mediainfo --Inform="Video;%FrameRate%" "$filename")    # average framerate per second
                framestotal=$(mediainfo --Inform="Video;%FrameCount%" "$filename")   # frames in video, same number of frames needed for dial
                duration=$(mediainfo --Inform="Video;%Duration%" "$filename")      # milliseconds
                imgheight=$(mediainfo --Inform="Video;%Height%" "$filename")          # height of video will determine size of dial
                frametime=`echo "scale=4; 1/$framerate" | bc`

                # initialize dimensions of dial, size, length of hands etc
                dialsize=`echo "scale=0; $imgheight/5" | bc`
                textsize=`echo "scale=0; $dialsize*0.7/1" | bc`   # text will be centered in the dial, with 70% of the diameter
                radius=`echo "scale=0; $dialsize/2" | bc`
                mhandlength=`echo "scale=0; $dialsize*0.45/1" | bc`
                hhandlength=`echo "scale=0; $dialsize*0.3/1" | bc`
                mhandwidth=`echo "scale=0; $dialsize/60" | bc`
                hhandwidth=`echo "scale=0; $dialsize/40" | bc`

                # draw the raw elements of the dial
                # black circle
#                s_dialplate="convert -size "$dialsize"x"$dialsize" xc:white -fill $dialbackground -stroke black "                        # white background
                s_dialplate="convert -size "$dialsize"x"$dialsize" xc:transparent -fill $dialbackground -stroke black "                   # transparent background
                s_dialplate+="-strokewidth "$mhandwidth" -draw 'circle "$radius","$radius" "$radius","$mhandwidth"' "$dialplate
                eval ${s_dialplate}

                # dial with alphachannel, probably not neccessary
                # s_dialalpha="convert -size "$dialsize"x"$dialsize" xc:transparent -fill '#444444' alpha set"
                s_dialalpha="convert -size "$dialsize"x"$dialsize" xc:transparent -fill $dialbackground"
                s_dialalpha+=" -draw 'circle "$radius","$radius" "$radius","$mhandwidth"' "$dialalpha
                eval ${s_dialalpha}
                # convert $dialalpha alpha on

                # bighand drawn at 6:00 clock, rectangle-coordinates lower left to upper right
                s_bighand="convert -size "$dialsize"x"$dialsize" xc:transparent -fill $bighandcolor -stroke black "
                s_bighand+="-draw 'roundrectangle "$[$radius-$hhandwidth]","$[$radius-$hhandlength]" "
                s_bighand+=$[$radius+$hhandwidth]","$[$radius+$hhandwidth]" $hhandwidth,$hhandwidth' "$bighand
                eval ${s_bighand}

                # littlehand drawn 6:00 clock, rectangle-coordinates lower left to upper right
                s_littlehand="convert -size "$dialsize"x"$dialsize" xc:transparent -fill $littlehandcolor -stroke black "
                s_littlehand+="-draw 'roundrectangle "$[$radius-$mhandwidth]","$[$radius-$mhandlength]" "
                s_littlehand+=$[$radius+$mhandwidth]","$[$radius+$mhandwidth]" $mhandwidth,$mhandwidth' "$littlehand
                eval ${s_littlehand}

                echo "generating clockvideo $dialsize"x"$dialsize pixels with $framestotal frames at "$framerate"fps ";
                echo "video starts at:"$datetime
                echo "now generating $framestotal images with dials"
                startsecs=$(eval "$timezone date -d '$datetime' +%s")
                oldtimesecs=0
                oldday=0
                for((i=0; i<$framestotal; i++))
                do
                    timesecs=`echo "scale=0; $startsecs+$i*$frametime/1" | bc`
                    if (( timesecs != oldtimesecs )); then             # just calculate frames which differ from each other
                        oldtimesecs=$timesecs

                        year=$(  date -d @$timesecs +%Y)
                        month=$( date -d @$timesecs +%m)
                        day=$(   date -d @$timesecs +%d)
                        hour=$(  date -d @$timesecs +%H)
                        minute=$(date -d @$timesecs +%M)
                        second=$(date -d @$timesecs +%S)
#                         echo $hour

                        # date changes are seldom needed, so we do not update this regularly
                        if [ $day -ne $oldday ]; then
                            oldday=$day
                            text=$day"."$month"."$year
                            stext="convert -background transparent -size $textsize""x""$textsize  -font $font -fill $fontcolor "
                            stext+=" -gravity center label:'\n\n$text' "
                            stext+=" $date "
                            eval ${stext}
                        fi
                        ############ create analogue time-hands ################
#                        hourangle=`echo "scale=2; (($hour+($minute/60))*360/12)/1" | bc`;
                        hourangle=`echo "scale=2; (($hour+($minute/60))*30)/1" | bc`;
                        minuteangle=`echo "scale=2; ($minute*6 + $second/10)/1" | bc`;
                        convert $bighand -distort SRT $hourangle $hour_r            # rotate hands in degrees around center
                        convert $littlehand -distort SRT $minuteangle $minute_r

                        composite -gravity center            $hour_r   $dialplate $hourplate      # add hour
                        composite -alpha set -gravity center $minute_r $hourplate $homiplate      # add minute
                        composite -alpha set -gravity center $date     $homiplate $dial     # add Date
                        echo -ne "generated "$processedname"\r"
                    fi
                    counterstring="$(printf "%06d" $i)";
                    processedname=$processdir"/"$prefix$counterstring"."$destinationtype
                    cp $dial "$processedname"                                   # existing frames with identical secs need just to be copied
                done
                echo

                dialvideo=$(secure_filename "$sourcename""_dial.mov")
                echo "ok, images completed, now generating dialvideo $dialvideo"

                ##### create the video out of the images
                verbosity="-v quiet -stats -hide_banner"     # quiet, just stats
#                verbosity=""

                ffmpeg $verbosity -framerate $framerate -i $processdir/$prefix%06d.png -codec:v copy "$dialvideo"       # video with alphachannel, don't forget the framerate!
                videoname=$(secure_filename "$sourcename""_withdial.mp4")
                echo "ok, dialvideo completed, now mixing $dialvideo over $filename as $videoname"

                quality="29"          # standard is 23, 29 gives vids aprox. half the size
                filter_complex="[0:v]setpts=PTS-STARTPTS[video];[1:v]setpts=PTS-STARTPTS,colorchannelmixer=aa="$opacity"[dial];[video][dial]overlay=main_w-overlay_w-10:main_h-overlay_h-10:shortest=1"
                command_line=( ffmpeg -i "$filename" -i "$dialvideo" -filter_complex $filter_complex -vcodec libx264 -crf $quality $verbosity "$videoname" )
#                 echo "--------- for debugging --------------"
#                 echo "${command_line[@]}"
#                 echo "--------------------------------------"
                "${command_line[@]}"

                # you probably want to cleanup automatically
                echo "cleaning up tempfiles"
                rm $dialplate
                rm $hourplate
                rm $homiplate
                rm $dialalpha
                rm $bighand
                rm $littlehand
                rm $hour_r
                rm $minute_r
                rm $dial
                rm $date
                rm $processdir/$prefix*.png
                rm "$dialvideo"
            fi
        fi
        shift
    done
    rmdir $processdir
else
    echo "videodial4vids creates dial with moving big and little hands over existing videofiles"
    echo "at least one videofilename is needed as input"
fi