#!/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 SLIDE_FADE=: 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>1400)) || ((y>1400)) ; }; 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$@ " } # strip every yuv file except the first yuvstrip() { read junk cat return 0 } 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" #cat "$WORK_DIR/enc.fifo" | yuvcorrect | "${IMGENC_CMD[@]}" & "${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=3; $IMG_WIDTH / $IMG_HEIGHT") echo IMG_AR is $IMG_AR 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="$WORK_DIR/${i}.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[@]}" INFILES[p]=$WORK_DIR/${p}.ppm done echo INFILES are ${INFILES[@]} # effects unfinished - only dissolve in/out for now for f in ${!INFILES[@]}; do # encode still frames if ((f==0)); then ppmtoy4m -n $SLIDE_FRAMES -A 10:11 -I p -r -S 420mpeg2 -r "${INFILES[f]}" 2>&1 >/dev/null else ppmtoy4m -n $SLIDE_FRAMES -A 10:11 -I p -r -S 420mpeg2 -r "${INFILES[f]}" | yuvcorrect -T NO_HEADER 2>&1 >/dev/null fi 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") >&2 fade_slide=0 echo >&2 for ((i=0; i&2 composite_cmd=(composite -blend $BLEND_AMT -depth 8 "$overlay_ppm" \ "$base_ppm" "$WORK_DIR/animenu/$(printf %06d%s $i .ppm)") "${composite_cmd[@]}" >&2 spin "Compositing ${overlay_ppm##*/} over ${base_ppm##*/} with -blend $BLEND_AMT" >&2 let fade_slide=fade_slide+1 done echo >&2 echo "Running ppm2y4m to encode ppms" >&2 #ffmpeg -f image2 -i "$WORK_DIR/animenu/%06d.ppm" -pix_fmt yuv420p -f yuv4mpegpipe - cat "$WORK_DIR"/animenu/*.ppm | ppmtoy4m -n $fade_frames -A 10:11 -I p -r -S 420mpeg2 | yuvcorrect -T NO_HEADER 2>&1 >/dev/null rm -f "$WORK_DIR"/animenu/*.ppm if ((f == (${#INFILES[@]} - 1) )); then ppmtoy4m -n $SLIDE_FRAMES -A 10:11 -I p -r -S 420mpeg2 -r "${INFILES[0]}" | yuvcorrect -T NO_HEADER 2>&1 >/dev/null fi done >&3 # close the pipe exec 3>&-