#! /bin/bash
#
# $Date: 2006-01-11 12:01:03 -0800 (Wed, 11 Jan 2006) $
# $Revision: 223 $
# $Author: beirdo $
#
# Cut MPEG2 files to remove cutlists...
# Written by Gavin Hurlbut <gjhurlbu@gmail.com>
# $Revision: 223 $
#
# Prerequisites:
#    avidemux2   - http://fixounet.free.fr/avidemux/
#    transcode   - http://zebra.fh-weingarten.de/~transcode/
#    lvemux      - http://lvempeg.sourceforge.net/
#    Xvfb	 - http://www.xfree86.org/
# or gdk2-cursed - http://zemljanka.sourceforge.net/cursed/
#
# Usage: mpeg2cut inputfile outputfile lastFrame segmentList
#	where segmentList is a space separated list of frame regions to keep
#		(i.e.  -1999 3000-5000 6000-)

VERSION=`echo '$Revision: 223 $' | sed -e 's/\$Revision\(\: \)*\([^ $]*\).*\$/\2/'`

function displayUsage {
    cat << EOF

mpeg2cut v${VERSION}-svn (c) 2005-2006 Gavin Hurlbut

Usage: $0 inputfile outputfile lastFrame segmentList
    where segmentList is a space separated list of frame regions to keep
    (i.e.  -1999 3000-5000 6000-)

To run mpeg2cut, you need to use avidemux2, which requires gdk support.  To
fill this dependancy, you will need one of (in order of preference):

    Xvfb        (virtual framebuffer X server)
    gdk-cursed  (GDK for curses)
    run under X (have a DISPLAY= environment variable)

EOF

    exit 1
}

LOCAL_PRELOAD=

# Use Xvfb if it's installed
XVFB=`which Xvfb`
if [ .${XVFB}. != .. ]
then
    # We have Xvfb, we will be using a X at :13.0
    export DISPLAY=:13.0
    MODE=Xvfb
else
    # No Xvfb, try cursed next
    for i in /lib /usr/lib /usr/local/lib
    do
        if [ -f $i/libgdk-cursed-2.0.so -a -f $i/libgtk-cursed-2.0.so ]
        then
            LOCAL_PRELOAD=libgdk-cursed-2.0.so:libgtk-cursed-2.0.so
            break
        fi
    done

    if [ .${LOCAL_PRELOAD}. != .. ]
    then
	# we have gdk-cursed, use it
        export LD_PRELOAD=${LOCAL_PRELOAD}
        MODE=gdk-cursed
    else
        if [ .${DISPLAY}. != .. ]
        then
            MODE=X
        else
            # Don't even have a display, we can't run avidemux2, give up!
            displayUsage
        fi
    fi
fi

# Check command line so we don't get odd issues
if [ $# -lt 4 ] ; then
    displayUsage
fi 


FILENAME=$1
OUTFILE=$2
LASTFRAME=$3

# This will catch the old-style filenames
BASENAME=`basename ${FILENAME} .nuv`
# This will catch the new-style filenames.
BASENAME=`basename ${BASENAME} .mpg`
OUTPUTDIR=`dirname "${OUTFILE}"`
OUTPUTBASE="${OUTPUTDIR}/${BASENAME}"

SPACEAVAIL=`df -k -P "${OUTPUTDIR}" | tail -1 | tr -s " " | cut -d " " -f 4`
FILESIZE=`du -k ${FILENAME} | tr "\t" " " | tr -s " " | cut -d " " -f 1`
SPACENEED=$((${FILESIZE} * 2))


echo mpeg2cut "v${VERSION}-svn (c) 2005-2006 Gavin Hurlbut"
echo Using mode ${MODE}
echo Filename \"${FILENAME}\"
echo OutFile \"${OUTFILE}\"
echo Output Dir \"${OUTPUTDIR}\"
echo Space needed: ${SPACENEED}, Space available: ${SPACEAVAIL}

if [ ${SPACENEED} -ge ${SPACEAVAIL} ] ; then
    echo -n "You are short on drive space in the output dir, continue? "
    read answer crap
    case ${answer}. in
        y*|Y*)
            # OK, suckers.   I wish you luck
            echo "OK, but you might get odd results."
            ;;
        *)
            # anything else, abort!
            echo "Aborting..."
            exit 1
            ;;
    esac
fi

shift 3
CUTLIST=$*

echo Last Frame ${LASTFRAME}
echo Cutlist \"${CUTLIST}\"

echo -n "Finding the AV Offset to use with lvemux: "
OFFSET=`(tcprobe -i ${FILENAME} 2> /dev/null) | grep av_fine_ms | \
    sed -e 's/^.*av_fine_ms //' | cut -d " " -f 1`
if [ .${OFFSET}. = .. ]
then
    echo "0 (not detected)"
    OFFSET=0
else
    OFFSET=$((-1 * ${OFFSET}))
    echo ${OFFSET}
fi

if [ .${MODE}. = .Xvfb. ]
then
    # Let's start up the Xvfb server
    ${XVFB} :13 -screen 0 640x480x8 2> /dev/null > /dev/null &
    XVFB_PID=$!
fi

if [ ! -f ${FILENAME}.idx ]
then
    echo Indexing the file with avidemux2
    nice -n 19 avidemux2 --index-mpeg ${FILENAME} ${FILENAME}.idx C0 \
        --audio-codec MP2 --quit 2> /dev/null > /dev/null
fi


cat > "${OUTPUTBASE}".cut << EOF
ADMW0002
01 videos
Name : ${FILENAME}.idx
EOF

cat /dev/null > "${OUTPUTBASE}".cut2

count=0
for i in ${CUTLIST}
do
    START=`echo $i | cut -d '-' -f 1`
    END=`echo $i | cut -d '-' -f 2`

    if [ .${START}. = .. ]
    then
        START=0
    fi

    if [ ${START} -ge ${LASTFRAME} ]
    then
        continue
    fi

    if [ .${END}. = .. ]
    then
        END=${LASTFRAME}
    fi
    LENGTH=$((${END} - ${START} + 1))

    cat >> "${OUTPUTBASE}".cut2 << EOF
Start : ${START}
Size : ${LENGTH}
Ref :   0
EOF
    count=$((${count} + 1))
done
echo ${count} segments >> "${OUTPUTBASE}".cut

cat "${OUTPUTBASE}".cut2 >> "${OUTPUTBASE}".cut
cat >> "${OUTPUTBASE}".cut << EOF
Audio codec : none
Audio filter : audioNormalizeMode=0 audioResampleMode=0 audioDRC=0 audioShift=0
audioDelay=0 audioFreq=48000
Audio conf : audioProcessMode=0 audioMP3mode=0 audioMP3bitrate=128
EOF

echo Cutting out commercials with avidemux2
nice -n 19 avidemux2 --load-workbench "${OUTPUTBASE}".cut \
    --audio-codec MP2 --save-raw-video "${OUTPUTBASE}".m2v \
    --save-raw-audio "${OUTPUTBASE}".mp2 --quit 2> /dev/null > /dev/null

# Shut down Xvfb if we used it
if [ .${MODE}. = .Xvfb. ]
then
    kill ${XVFB_PID}
fi

echo Remultiplexing video
nice -n 19 lvemux -r -1 -sh ${OFFSET} -v "${OUTPUTBASE}".m2v \
    -a "${OUTPUTBASE}".mp2 -o "${OUTFILE}"

echo Cleaning up
rm ${FILENAME}.idx "${OUTPUTBASE}".m2v "${OUTPUTBASE}".mp2 
rm "${OUTPUTBASE}".m2v.idx "${OUTPUTBASE}".cut "${OUTPUTBASE}".cut2

# vim:ts=4:sw=4:ai:et:si:sts=4

