All pastes #899947 Raw Edit

Unnamed

public text v1 · immutable
·published 2008-02-11 15:36 UTC
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
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<fade_frames; i++)); do
            BLEND_AMT=$(bc -l <<< "scale=2; $fade_slide * $fade_incr") >&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>&-