rendered paste body#!/bin/bash
INFILES=( "$@" )
WORK_DIR=`pwd`/slideshow-$(date +%s)
TV_STANDARD="ntsc"
SLIDE_FRAMES=60
BINMAX=640
AR=1.333
FRAME_RATE=29.970
VIDSIZE=720x480
FFMOPTS="-b 8000k -maxrate 9000k -bufsize 224KiB -aspect 4:3"
IMGENC_CMD=(ffmpeg -f yuv4mpegpipe -r $FRAME_RATE \
-i - -s $VIDSIZE $FFMOPTS -r $FRAME_RATE -y "$WORK_DIR/slideshow.m2v")
get_binning_cmd()
{
inpic="$1"; outpic="$2"
dimensions=$(identify -format %wx%h "$inpic")
x=${dimensions/x*}
y=${dimensions/*x}
# only do binning resize if doing 'full screen' and image width is > 1440
# and user did not ask specifically not to
if { ((x>1440)) || ((y>1440)) ; }; then
for bin_size in 1 2 3 4 5 6 7 8; do
newx=$(( x / bin_size ))
# ppmtoy4m needs a multiple of 2 (hopefully doesn't affect binning)
newx=$(( (newx / 2) * 2 ))
((newx<=BINMAX)) && break
done
else
return 0
fi
checkx=$(( newx * bin_size ))
(( checkx != x )) && crop_flag="YES"
newy=$(( y / bin_size ))
newy=$(( (newy / 2) * 2 )) # must be multiple of 2 for ppmtoy4m
checky=$(( newy * bin_size ))
(( checky != y )) && crop_flag="YES"
[[ -n $crop_flag ]] && crop_args="-crop ${checkx}x${checky}+0+0 +repage"
unset PPM_ENC_CMD
BINNING_CMD=(convert "$inpic" $crop_args -depth 8 \
-filter box -resize ${newx}x${newy} $SLIDE_BLUR "$outpic")
echo "Resizing ${inpic##*/} to ${newx}x${newy}"
}
spin()
{
echo -ne "\r "
echo -ne "\r$@ "
}
mkdir -pv "$WORK_DIR"
mkdir "$WORK_DIR/animenu"
echo
# make a fifo to send raw yuv to, to be encoded by ffmpeg
mkfifo "$WORK_DIR/enc.fifo"
"${IMGENC_CMD[@]}" < "$WORK_DIR/enc.fifo" &
exec 3> "$WORK_DIR/enc.fifo"
for ((i=0; i<${#INFILES[@]}; i++)); do
CROP_CMD=()
IN_FILE="${INFILES[i]}"
if test -e "$IN_FILE"; then
IMG_STATS=( $(identify -format "%z %w %h" "$IN_FILE") )
DEPTH=${IMG_STATS[0]}
IMG_WIDTH=${IMG_STATS[1]}
IMG_HEIGHT=${IMG_STATS[2]}
IMG_AR=$(bc -l <<< "scale=2; $IMG_WIDTH / $IMG_HEIGHT")
if [[ $ASPECT_RATIO = "4:3" ]]; then
NEWSIZE=640x480
else
NEWSIZE=640x360
fi
if [[ ${IMG_AR:0:4} != ${AR:0:4} ]]; then
CROP_CMD=(-filter box -resize ${NEWSIZE}\> -size $NEWSIZE \
xc:black +swap -gravity center -composite)
fi
OUTBASE=${IN_FILE##*/} # basename of file
OUTFILE=${OUTBASE%.*} # basename of file less extention
OUTFILE="$WORK_DIR/${i}-${OUTFILE}"
OUTPPM="${OUTFILE}.ppm"
# ffmpeg image2 can't handle 16 bit depth - convert it
# also convert if not PNG or JPEG or wrong aspect ratio
# test IN_FILES for preview - group files tested later
if [[ $DEPTH = 16 || -n ${CROP_CMD[@]} ]]; then
echo "Converting $IN_FILE to proper image format"
IMG_CMD=(convert "$IN_FILE" -depth 8 "${CROP_CMD[@]}" "$OUTPPM")
"${IMG_CMD[@]}"
# replace IN_FILES[i]
INFILES[i]=$OUTPPM
fi
fi
done
for p in ${!INFILES[@]}; do
BINNING_CMD=(convert "${INFILES[p]}" -depth 8 \
-resize 640x480 "$WORK_DIR/${p}.ppm")
# BINNING_CMD modified after get_binning_cmd() if imaage>1440 etc
get_binning_cmd "${INFILES[p]}" "$WORK_DIR/${p}.ppm"
"${BINNING_CMD[@]}"
done
# effects unfinished - only dissolve in/out for now
for f in ${!INFILES[@]}; do
# encode still frames
ffmpeg -f image2 -loop_input -vframes $SLIDE_FRAMES -i "${INFILES[f]}" -pix_fmt yuv420p -f yuv4mpegpipe - >&3
if $SLIDE_FADE; then
if [[ $f -lt ${#INFILES[@]} ]]; then
base_ppm="$WORK_DIR/${f}.ppm"
if ((f == (${#INFILES[@]} - 1) )); then
overlay_ppm="$WORK_DIR/0.ppm"
else
overlay_ppm="$WORK_DIR/$((f+1)).ppm"
fi
[[ $TV_STANDARD = "ntsc" ]] && fade_frames=30 || fade_frames=25
fade_incr=$(bc -l <<< "scale=2; 100 / $fade_frames")
fade_slide=0
echo
for ((i=0; i<fade_frames; i++)); do
BLEND_AMT=$(bc -l <<< "scale=2; $fade_slide * $fade_incr")
composite_cmd=(composite -blend $BLEND_AMT -depth 8 "$overlay_ppm" \
"$base_ppm" "$WORK_DIR/animenu/$(printf %06d%s $i .ppm)")
"${composite_cmd[@]}"
spin "Compositing ${overlay_ppm##*/} over ${base_ppm##*/} with -blend $BLEND_AMT"
let fade_slide=fade_slide+1
done
let first_slide=first_slide+fade_frames+1
else
echo "Running ffmpeg to encode ppms"
ffmpeg -f image2 -i "WORK_DIR/animenu/%06d.ppm" -pix_fmt yuv420p -f yuv4mpegpipe - >&3
FFPID=?!
wait $FFPID
rm -f "WORK_DIR/animenu/*.ppm"
fi
fi
done
if hash ffmpeg 2>/dev/null; then
echo
echo "Encoding the slideshow with ffmpeg to DVD standard M2V"
# "${IMGENC_CMD[@]}" >/dev/null 2>&1
echo
echo "Removing the temporary ppms in $WORK_DIR/animenu"
rm -fr "$WORK_DIR/animenu"
echo
echo "Your slideshow video is: $WORK_DIR/slideshow.m2v"
else
echo "Sorry, ffmpeg not found, not encoding to video"
fi