#!/bin/sh
set -x

####################### CONFIGURATION VARIABLES #########################

# System wide configuration file
GENCONF=/etc/nuv2mpeg.conf

# User configuration file
USRCONF=~/.nuv2mpeg

#########################################################################
#################### END OF CONFIGURATION VARIABLES #####################
#########################################################################

# Return status
E_NOCONFIG=10                    # No config file found
E_NOFILE=20                      # No file to proccess
E_NOPROFILE=30                   # No profile specified
E_NOPROFILE_OPTIONS_MPEG2ENC=41  # No profile options for mpeg2enc
E_NOPROFILE_OPTIONS_MPLEX=42     # No profile options for mplex
E_NOPROFILE_OPTIONS_TOOLAME=43   # No profile options for toolame
E_EXEC_MPEG2ENC=51  					# Error executing mpeg2enc
E_EXEC_MPLEX=52     					# Error executing mplex
E_EXEC_TOOLAME=53   					# Error executing toolame

PROFILE=${1}
FILE=${2} 

# Mensaje de bienvenida
echo "nuv2mpeg - NuppelVideo to MPEG(1|2) (S)VCD."

if [ "${1}" == "--help" ]; then
   echo <<EOF "
nuv2mpeg mini-HOWTO
===================

Commanline:
   nuv2mpeg <profile> <filename_without_extension>

Where:
   <profile> ....................... Options profile to use
   <filename_without_extension> .... Filename (without .nuv)

Description:
   This is a simple bash shell script for encoding NuppelVideo captured
   files into any MPEG format. I write it in the first place beacause
   nuvrec doesn't support over 2GB files, so I had to join the resulting
   files together with mpeg3cat or a similar program, but the resulting
   stream wasn't a nice pure 100% MPEG stream... I have some artifacts,
   and some error with vcdxminfo (from VCDImager). So I went to
   exportvideo's page and saw a tip about joining together the streams
   with exportvideo, before encoding them. As at the moment exportvideo's
   multiple file support is in TODO list, the only way I found to use
   this tip (about stripping headers of streams after the first) was with
   FIFOs. As I never used FIFOs before, I started to play a little and I
   decided to write a little script to make things easier. So this is the
   result. The I thought: I want a script to make a VCD, but sometimes I
   need to make a SVCD, so I thought that a general propose script would
   be nice :)

   So I think the best things about this script are:

	* Autodetect of multiple file captured video (in the form file.nuv,
     file-1.nuv, file-2.nuv, and so on).
   * Encoding the autodetected multiple files captured video in one
     stream.
   * Profiles support.

Profiles:
   What is a profile? It's simple, it's set of mpeg2enc, mplex and
   toolame options to encode your nuv file.
   To make sure that all will work, profiles names must be in lowercase.
   
Configuration:
   nuv2mpeg configuration is very easy. You have a system wide
   configuration file and a user wide. Default location for this files
   are '/etc/nuv2mpeg.conf' and '~/.nuv2mpeg', but they can be changed
   at the start of this script.
   The configuration file (both have the same format) is very simple. You
   just have to set your profiles. Profiles are simple shell variables,
   starting with the name of your profile and ending with the program
   that the options are for. Is hard to explain but easy to make, so
   let's go with an example:
   I have a good quality SVCD profile called 'svcd' so I have this in my
   ~/.nuv2mpeg:
   -------------------------------- CUT HERE ----------------------------
   # Good quality SVCD profile: svcd
   svcd_mpeg2enc="-f5 -F3 -b1750 -q1 -I3 -G15 -g6 -21 -41 -V230 -N"
   svcd_mplex="-b230 -f5"
   svcd_toolame="-s 44.1 -b 160 -p 2 -m j"
   ----------------------------------- END ------------------------------
   Where lines starting with '#' are comments, svcd_mpeg2enc are options
   to pass to mpeg2enc, svcd_mplex are options to pass to mplex and...
   guess what? yes, svcd_toolame are the options to pass to toolame.
   'svcd' is the name of the profile, so if I want to use this profile, I
   just have to type:
   nuv2mpeg svcd myfile
   As you think, the configuration file is just a definition of shell
   variables, and it's interpreted directly by bash so all bash syntax
   rules are aplicable.

   OK, that's all you have to know... I hope you understand. In case you
   don't, you can contact ask me. Critics and suggestions are welcome
   too.

Copyleft 2001 - Leandro Lucarella <luca@linuxmendoza.org.ar>
"
EOF
	exit 0;
fi

# Lee archivo de configuracion general
if [ -r ${GENCONF} ]; then
	HAYCONF="OK"
	source "${GENCONF}"
fi
# Lee archivo de configuracion del usuario
if [ -r ${USRCONF} ]; then
	HAYCONF="OK"
	source "${USRCONF}"
fi
# Verifica que exista al menos un archivo de configuracion
if [ "${HAYCONF}" != "OK" ]; then
	echo "ERROR: No user or system configuration file found. nuv2mpeg --help for more info." > /dev/stderr
	exit ${E_NOCONFIG}
fi
# Chequea que se haya especificado un archivo de entrada.
if [ ! -r ${FILE}.nuv ]; then
	echo "ERROR: You have to specify a nuv file. nuv2mpeg --help for more info." > /dev/stderr
	exit ${E_NOFILE}
fi

# Chequea que se haya especificado el perfil.
if [ -z ${PROFILE} ]; then
	echo "ERROR: You have to specify a profile. nuv2mpeg --help for more info." > /dev/stderr
	exit ${E_NOPROFILE}
fi

# Chequea que exista el perfil.
eval O_MPEG2ENC=\$${PROFILE}_mpeg2enc
if [ -z "${O_MPEG2ENC}" ]; then
	echo "ERROR: Profile '${PROFILE}' have no options for 'mpeg2enc'. nuv2mpeg --help for more info." > /dev/stderr
	exit ${E_NOPROFILE_OPTIONS_MPEG2ENC}
fi
eval O_MPLEX=\$${PROFILE}_mplex
if [ -z "${O_MPLEX}" ]; then
	echo "ERROR: Profile '${PROFILE}' have no options for 'mplex'. nuv2mpeg --help for more info." > /dev/stderr
	exit ${E_NOPROFILE_OPTIONS_MPLEX}
fi
eval O_TOOLAME=\$${PROFILE}_toolame
if [ -z "${O_TOOLAME}" ]; then
	echo "ERROR: Profile '${PROFILE}' have no options for 'toolame'. nuv2mpeg --help for more info." > /dev/stderr
	exit ${E_NOPROFILE_OPTIONS_TOOLAME}
fi

# Crea FIFOS
mkfifo "${FILE}_video.fifo" "${FILE}_audio.fifo"
nuvplay -e "${FILE}.nuv" > "${FILE}_audio.fifo" &
exportvideo "${FILE}.nuv" "${FILE}_video.fifo" &
EXPORTVIDEO="${FILE}_video.fifo"
NUVPLAY="${FILE}_audio.fifo"

# Busca si se generaron varios archivos
N=1
while [ -r ${FILE}-${N}.nuv ]; do
	mkfifo "${FILE}-${N}_video.fifo" "${FILE}-${N}_audio.fifo"
	nuvplay -e "${FILE}-${N}.nuv" > "${FILE}-${N}_audio.fifo" &
	exportvideo "${FILE}-${N}.nuv" "|grep -v YUV4MPEG > ${FILE}-${N}_video.fifo" &
	EXPORTVIDEO="${EXPORTVIDEO} ${FILE}-${N}_video.fifo"
	NUVPLAY="${NUVPLAY} ${FILE}-${N}_audio.fifo"
	N=$(( ++N ))
done

# Encodea video y verifica errores
cat ${EXPORTVIDEO} | buffer -b 4M | mpeg2enc ${O_MPEG2ENC} -o "${FILE}.m2v"
#EXIT_CODE=${?}
#if [ ${EXIT_CODE} -ne 0 ]; then
#	echo "ERROR: Error executing '${EXPORTVIDEO}'. Exit code: ${EXIT_CODE}" > /dev/stderr
#	killall nuvplay
#	exit ${E_EXEC_MPEG2ENC}
#fi

# Encodea audio y verifica errores
cat ${NUVPLAY} | buffer -b 4M | toolame ${O_TOOLAME} /dev/stdin "${FILE}.mp2"
#EXIT_CODE=${?}
#if [ ${EXIT_CODE} -ne 0 ]; then
#	echo "ERROR: Error executing '${NUVPLAY}'. Exit code: ${EXIT_CODE}" > /dev/stderr
#	exit ${E_EXEC_TOOLAME}
#fi

# Multiplexa y verifica errores
mplex ${O_MPLEX} -o "${FILE}.mpg" "${FILE}.m2v" "${FILE}.mp2"
#EXIT_CODE=${?}
#if [ ${EXIT_CODE} -ne 0 ]; then
#	echo "ERROR: Error executing '${MPLEX}'. Exit code: ${EXIT_CODE}" > /dev/stderr
#	exit ${E_EXEC_MPLEX}
#fi

# Borra archivos temporales
#rm -f "${FILE}.fifo" "${FILE}.m2v" "${FILE}.mp2"
#for (( I=1; $(( I < N )); I=$(( ++I )) )); do
#	rm -f "${FILE}-${N}.fifo"
#done	

exit 0

