#!/bin/bash 
#################################################################
#    Script pro převod videa formátu DV2.avi na formát mpge2 DVD 
#################################################################
# Používat ffmpeg nebo mp2enc ?  
USEFFMPEG=0

# Na jakou bitrate mám kódovat ? 
BITRATE=6500

# ffmpeg nastavení
MAXRATE=9800
MINRATE=150
PASSLOGFILE="passlog"
TMPFILE="tmpfile"
FILESFOUND=0

# mpeg2enc options 
MPEG2ENCOPTS=" -v 0 -f 8 -M 2 -b ${BITRATE} "

# ffmpeg options
FFMPEGOPTS="-maxrate ${MAXRATE} -b ${BITRATE} -minrate ${MINRATE} -aspect 2 -passlogfile ${PASSLOGFILE} -an "
# !!!! Pokud možno, vždy používejte TWOPASS. ffmpeg generuje při pouze jednom průchodu velky rozptyl bitrate, který 
# při multiplexování do mpeg containeru působí problémy. Tento rozkmit může být až 2.5 násobkem zakladní bitrate. 
# Při dvojprůchodovém kódování tento problem nenastává a bitrate nepřekračuje maxbitrate. 
TWOPASS=1
# ----------------------------------------------------
# Funkce na testování chyb, případné ukončení programu 
TestError ()
{
case $* in 
	0) 
		#echo "OK"
		return 0
	;;
	1) echo "ERROR: Input file does not exist!";;
	2) echo "ERROR: Encoded video file not found!";;
	3) echo "ERROR: Encoded audio file not foudn!";;
	4) echo "ERROR: Video dump file not found!";;
	5) echo "ERROR: Mplex input files not found!";;
	6) echo "ERROR: Mplex output not found!";;
	7) 	echo "********************************************";
		echo "	ERROR: Mplex output obsahuje chyby!";
		echo "	(Skus snížit vzorkovací frekq.videa, ..";
		echo "********************************************";;
	8) echo "ERROR: Předaný parametr 1 není platným vstupním adresářem!";;
	9) echo "ERROR: Předaný parametr 2 není platným výstupním adresářem!";;
	ZZ10) echo "ERROR: Cílový adresář pro mplex je neplatný!";;
	*) echo "ERROR: Unknown error: $*!";;
esac;
# Končím proceduru s chybou
exit 1
}

# ----------------------------------------------------------------------------------
# Funkce zpracuje do formátu DVD jeden soubor.Jméno souboru je předáno jako parametr 
EncAudio()
{
	# Mažu dočasný audio soubor
	if [[ -f ${TMPFILE}.mp2 ]]; then rm ${TMPFILE}.mp2; fi;
	# Pokouším se zakódovat video
	if [[ -f $* ]]; then 
		# Kóduji audio do mpeg2
		lav2wav -v 0 +p $* 2>/dev/null | mp2enc -v 0 -r 44100 -o ${TMPFILE}.mp2 
		# Můžu to udělat i pomocí ffmpeg
		#ffmpeg -y -i $* -hq -ac mp2 -ar 44100 -ab 224  -ac 2 ${TMPFILE}.mp2
		# A jak to dopadlo ?
		if [[ -f ${TMPFILE}.mp2 ]]; then 
			return 0;
		else 
			# Encoded audio file does not exist!;
			return 3;
		fi;
	else 
		# Input file does not exist
		return 1;
	fi;
}

# ----------------------------------------------------------------------------------
# Funkce zpracuje do formátu DVD jeden soubor.Jméno souboru je předáno jako parametr 
EncVideo()
{
	# Tento rádek vynechává počítání videa pro testovací účely.	
#	return 0
	# Mažu dočasný soubor videa
	if [[ -f ${TMPFILE}.m2v ]]; then rm ${TMPFILE}.m2v; fi;
	if [[ -f "${PASSLOGFILE}-0.log" ]]; then rm "${PASSLOGFILE}-0.log"; fi;
	# Pokouším se zakódovat video
	if [[ -f $* ]]; then 
		ls -lh $* | awk '{print $8,"....",$5}'
		if ! [[ "${USEFFMPEG}x" == "1x" ]]; then 
			# Tato část používá encodér z mjpegtools - mpeg2enc . 
			# Kodér podává slušné výsledky, bohužel je dost pomalý. Až 4x pomalejší než ffmpeg
			lav2yuv -v 0 +p $* | mpeg2enc ${MPEG2ENCOPTS} -o ${TMPFILE}.m2v;
		else 
			# Velmi rychlý kodek, bohužel při omezení bitrate ma problem vytvořit slušnou kvalitu obrazu
			if [[ "${TWOPASS}x" == "1x" ]]; then 
				# První a druhý průchod kódováním pomocí ffmpeg
				ffmpeg -y  -i $* -vcodec mpeg2video $FFMPEGOPTS -pass 1 -f mpeg /dev/null;
				ffmpeg -y  -i $* -vcodec mpeg2video $FFMPEGOPTS -pass 2 -f mpeg ${TMPFILE}.m2v;
			else 
				ffmpeg -y  -i $* -vcodec mpeg2video $FFMPEGOPTS -f mpeg ${TMPFILE}.m2v;
			fi;
			# Smažu dočasný soubor
			if [[ -f $PASSLOGFILE  ]]; then rm $PASSLOGFILE; fi;
			# Zjistím, jak to dopadlo
			if [[ -f ${TMPFILE}.m2v ]]; then 
				# Pomocí mplayeru dumpnu mpeg-ps na mpeg-es 
				rm -f stream.dump
				mplayer -dumpvideo ${TMPFILE}.m2v -ao null -cache 1024 -ni -mc 0 -noframedrop -vo null;
				# Smažu původní ${TMPFILE}.m2v
				if [[ -f ${TMPFILE}.m2v ]]; then rm ${TMPFILE}.m2v; fi;
				# Pokud stream vznikne, přejmenuji stream na ${TMPFILE}.m2v
				if [[ -f stream.dump ]]; then 
					mv stream.dump ${TMPFILE}.m2v
				else 	
					# Stream dump neexistuje..
					return 4;
				fi;
			else 
				# Encoded video file does not exist!;
				return 2; 
			fi;
		fi;
	else 
		# Vstupní soubor neexistuje
		return 1;
	fi 
	# Uklidím po sobě dočasný soubor logu dvojprůchodového kódování
	if [[ -f "${PASSLOGFILE}-0.log" ]]; then rm "${PASSLOGFILE}-0.log"; fi;
}


# ----------------------------------------------------------------------------------
# Funkce zpracuje do formátu DVD jeden soubor.Jméno souboru je předáno jako parametr 
# jako parametr předávám adresář, kam mám vkopírovat výsledny mpeg soubor
MplexVideo()
{
	# Pokud je předané jméno výstupního adresáře neplatné, tak končí
	if ! [[ -d ${1} ]]; then return 10;fi;
	# Pomocná proměnná
	MPLEXTEXT="plextext.txt"
	# A můžeme skusit multiplexovat	
	if [[ -f ${TMPFILE}.m2v && -f ${TMPFILE}.mp2 ]]; then 
		# Mám audio i video, takže vše multiplexuji do jednoho MPEG containeru
		mplex -S 0 -v 1 -f 8 ${TMPFILE}.m2v ${TMPFILE}.mp2 -o ${TMPFILE}.mpg 2> $MPLEXTEXT 
		# A jak to dopadlo ? Mám vytvořen VOB soubor ? 
		if ! [[ -f ${TMPFILE}.mpg ]]; then 
			# Multiplexed mpeg not created!;
			return 6;
		fi;
		# Dopadl výstupní multiplex OK ?  
		MPLEXSTAT=`cat $MPLEXTEXT|grep -i "no under-runs detected"`
		if [[ "${MPLEXSTAT}x" == "x" ]]; then 
			# Výstpní multiplex obsahuje chyby
			cat $MPLEXTEXT;
			return 7;
		fi 
	else 	
		# Chybí soubory pro multiplex
		return 5;
	fi;
	# Smažu výstup mplexu
	if [[ -f $MPLEXTEXT ]]; then rm $MPLEXTEXT; fi;
}

# ----------------------------------------------------------------------------------
# Funkce prochází adresář a pokouší se v něm encodovat všechny soubory
# Předpokládám, že soubor je typu DV, pokud ne, funkce padne 
ScanDir()
{
	# Byl předán platný vstupní adresář ? 
	if ! [[ -d $1 ]]; then 
		# Předáný parametr není platný adresář!
		return 8;
	fi;
	# Byl předán platný výstoní adresář ? 
	if ! [[ -d $2 ]]; then 
		# Předáný parametr není platný výstupnoí adresář!
		return 9;
	fi;
	# Seznam souborů
	# ls -l ${1}*.avi 
	# Můžu začít kódovat
	for i in ${1}*.avi; do 
		# Jméno -avi souboru který chci přepočítat
		INPUTFILE=$i
		# Pokouším se zakódovat video 
		#echo "Encoding file:$INPUTFILE"
		echo "Encoding file"
		time EncVideo $INPUTFILE
		echo 
		TestError $?
		# Pokusím se encodovat audio file
		EncAudio $INPUTFILE
		TestError $?
		# Mám audio i video, takže vše multiplexuji do jednoho MPEG containeru
		MplexVideo ${2}
		LASTERR=$?
		# Pokud došlo k chybě přetečení multiplexu (nr.7) při použití kóderu ffmpeg, 
		# tak to skusím překódovat ještě jednou ale za pomoci mpeg2enc
		if [[ "${USEFFMPEG}x" == "1x" ]] && [[ "${LASTERR}x" == "7x" ]]; then 
			# Spustím znovu video kodování,ale s mpeg2enc
			echo "Restarting video encoding with mpeg2enc.."
			USEFFMPEG=0					
			time EncVideo $INPUTFILE
			TestError $?	
			# Musím to vrátit zpátky na ffmpeg
			USEFFMPEG=1 
			# A skusíme MPLEX
			MplexVideo ${2}
			LASTERR=$?
		fi; 
		# Otestuji chybový výstup. Jestli se to nepodaří zakódovat ani s mpeg2enc, tak děj se vůle páně, ale bez ručního zásahu to nepůjde..
		TestError $LASTERR
		# Inkrementuji počítadlo přepočítaných souborů (budu generovat VTS_01_X kde X je 1 až ...)
		let FILESFOUND=$FILESFOUND+1
		# Kopíruji si vytvořené soubory do koncového videostreamu
		POM=`basename $INPUTFILE .avi`
		mv ${TMPFILE}.mpg ${2}${POM}.mpg
	done;
}

# ----------------------------------------------------------------------------------
# Funkce ohlásí chybu v zadaných parametrech a 
InputError()
{
	echo "ERROR - Vstupní parametry jsou neplatné!"
	echo "Use: mkdvd srcaddr/ dstaddr/"
	echo 
	echo "srcaddr = Source folder for avi files"
	echo "dstaddr = Destination for mpeg files"
}

# *************************************************
# 	Main program 
# *************************************************
# Testuji počet předaných parametrů
if (( ${#} != 2 )); then 
	InputError;	
	exit 1
fi;
# Testuji zda se v obou případech jedná o adresáře
if  ! [[ -d $1 ]] || ! [[ -d $2 ]]; then 
	InputError;
	exit 2	
fi;
# Vstupní a výstupní adresář nemůžou být stejné 
if [[ "${1}x" == "${2}x" ]]; then 
	echo "Vstupní a výstupní adresář nemohou být stejné!"
	echo "InAddr: $1, OutAddr: $2"
	echo 
	InputError;
	exit 3
fi; 
# --- Vlastní encodování --- 
#
# Teď už můžu projet vstupní adresář a přepočítat v něm uložené AVI soubory
# Výsledné soubory jsou uloženy pod původním názvem s příponou mpg do cilového adresáře 
ScanDir $1 $2 	 
TestError $?
# 
# A jsem hotov
echo "Finished files: $FILESFOUND"
