jueves, 23 de abril de 2009

Convertir vídeo AVCHD a hd-mov para cinelerra.




Este tutorial describe como codificar vídeo en formato AVCHD (.mts, m2ts, etc.) a QuickTimeLinux de alta definición.

El tutorial está publicado en el wiki de www.aulir.com aquí

Aunque he realizado algunas modificaciones que simplifican el script y lo hacen más legible.

Aquí teneis el script.
Espero que os sirva...

#!/bin/sh

# Extraemos el nombre del script ejecutable
NOMBRE=$0

# Buscamos el ejecutable de ffmpeg
#FFMPEG=ffmpeg
FFMPEG=`which ffmpeg`

# Elegimos la extensión de salida
format=mov

# Ratio de entrada y salida
irate=25000/1001 # input
orate=25000/1001 # output

# Cámara que se ha utilizado
CAMARA=CANON

# Preset elegido por defecto
PRESET=edit # as below

while :
do
case "$1" in
-d)
set -x
;;

-c)
shift
CAMARA=$1
shift
;;

-p)
shift
PRESET=$1
shift
;;

-i)
shift
isize=$1
shift
;;

-x)
shift
PUT_HERE=true
;;

-f)
shift
format=$1
shift
;;

*)
break
;;
esac
done

# Archivo de entrada
input=$1

######################################
# Tipos de tamaño de vídeo, auido, etc.
MACRO_SIZE_HUGE=1920x1080
MACRO_SIZE_LARGE=1366x768
MACRO_SIZE_MEDIUM=1280x720
MACRO_SIZE_SMALL=640x360
MACRO_SIZE_THUMB=320x180

#MACRO_VIDEO_MJPEG="-vcodec mjpeg -sameq -shortest -f $format"
#MACRO_VIDEO_MPEG4="-vcodec mpeg4 -sameq -shortest -f $format"
MACRO_VIDEO_MJPEG="-vcodec mjpeg -sameq -f $format"
MACRO_VIDEO_MPEG4="-vcodec mpeg4 -sameq -f $format"
MACRO_VIDEO_VC3="-vcodec dnxhd -b 90Mb -f $format -an"

MACRO_AUDIO_AAC="-acodec libfaac -ac 2 -ab 128k -ar 44100"
MACRO_AUDIO_AAC_HD="-acodec libfaac -ac 2 -ab 448k -ar 48000"
MACRO_AUDIO_THUMB="-acodec libfaac -ac 1 -ab 64k -ar 22050"

MACRO_AUDIO_RAW="-acodec pcm_s16le -ac 2 -ar 48000"
MACRO_AUDIO_COPY="-acodec copy"
######################################

# Corrector de sincronía entre audio y video en función del fabricante de la cámara
if [ "$CAMARA" = CANON ]; then
#correccion=2.5004190476 # CANON
#correccion=2.497591614 # CANON EN EL PORTATIL ASUS
correccion=2.498284520 # CANON EN EL ASUS 2
fi

if [ "$CAMARA" = SONY ]; then
correccion=2.083334442 # SONY
fi
irate2=`echo "$irate * $correccion" | bc`

# Si solo se introduce el nombre del ejecutable, se muestra una ayuda
if [ "x$1" = x ]
then
#------------------------------------------------------------------
cat 1>&2 <$NOMBRE luismanolo@gmail.com

Uso: $NOMBRE [opciones] archivo.mts ...

Opciones:
-d # activa el depurado
-p PRESET # establece el preset
-i SIZE # especifica el tamaño (default is 1920x1080)
-f FORMAT # especifica el formato de salida (default is mov)
-c CAMARA # fabricante de la cámara (SONY/CANON)

Presets:
vc3 # Codec equivalente al Apple ProRes
thumb # $MACRO_SIZE_THUMB mpeg4 + aac audio (primeros 20 segundos de video)
small # $MACRO_SIZE_SMALL mpeg4 + aac audio
medium # $MACRO_SIZE_MEDIUM mpeg4 + aac audio
large # $MACRO_SIZE_LARGE mpeg4 + aac audio
huge # $MACRO_SIZE_HUGE mpeg4 + aac audio
edit-mp4 # $MACRO_SIZE_MEDIUM mpeg4 keyframes + raw audio
edit-mj # $MACRO_SIZE_MEDIUM mjpeg + raw audio
edit # shorthand for 'edit-mj'

Ejemplos:

Convertir archivos AVCHD a 720p para editar con Cinelerra
$NOMBRE -p edit *.mts

Crear un video corto para previsualizar
$NOMBRE -p thumb *.mts

EOF
exit 1
fi
##################################################################

case $PRESET in

# am assuming editing is done at MEDIUM/720p
# with raw audio and best quality video

vc3)
osize=$MACRO_SIZE_HUGE
oaudio_in="$MACRO_AUDIO_RAW"
#oaudio_out="$MACRO_AUDIO_COPY"
oaudio_out="$MACRO_AUDIO_COPY_HD"
ovideo="$MACRO_VIDEO_VC3"
osuffix=vc3.$format
;;

edit|edit-mj)
osize=$MACRO_SIZE_MEDIUM
oaudio_in="$MACRO_AUDIO_RAW"
#oaudio_out="$MACRO_AUDIO_COPY"
oaudio_out="$MACRO_AUDIO_COPY_HD"
ovideo="$MACRO_VIDEO_MJPEG"
osuffix=edit-mj.$format # this one needed disambiguation
;;

edit-mp4)
osize=$MACRO_SIZE_MEDIUM
oaudio_in="$MACRO_AUDIO_RAW"
oaudio_out="$MACRO_AUDIO_COPY"
ovideo="$MACRO_VIDEO_MPEG4 -intra"
osuffix=$PRESET.$format
;;

# playback presets below

huge) # novelty, not meant for serious use
osize=$MACRO_SIZE_HUGE
oaudio_in="$MACRO_AUDIO_RAW"
oaudio_out="$MACRO_AUDIO_COPY"
ovideo="$MACRO_VIDEO_MPEG4"
osuffix=$PRESET.$format
;;

large)
osize=$MACRO_SIZE_LARGE
oaudio_in="$MACRO_AUDIO_RAW"
oaudio_out="$MACRO_AUDIO_AAC"
ovideo="$MACRO_VIDEO_MPEG4"
osuffix=$PRESET.$format
;;

medium)
osize=$MACRO_SIZE_MEDIUM
oaudio_in="$MACRO_AUDIO_RAW"
oaudio_out="$MACRO_AUDIO_AAC"
ovideo="$MACRO_VIDEO_MPEG4"
osuffix=$PRESET.$format
;;

small)
osize=$MACRO_SIZE_SMALL
oaudio_in="$MACRO_AUDIO_RAW"
oaudio_out="$MACRO_AUDIO_AAC"
ovideo="$MACRO_VIDEO_MPEG4"
osuffix=$PRESET.$format
;;

thumb)
osize=$MACRO_SIZE_THUMB
itruncate="-t 00:00:20" # only set here for thumbnails; 20s -> 10s
oaudio_in="$MACRO_AUDIO_RAW"
oaudio_out="$MACRO_AUDIO_THUMB"
ovideo="$MACRO_VIDEO_MPEG4"
osuffix=$PRESET.$format
;;

*)
echo $NAME: Preset desconocido $PRESET
exit 1
;;

esac #

##################################################################
# Filtramos los tipos de archivos permitidos
case $input in
*.MTS) ;;
*.mts) ;;
*.M2TS) ;;
*.m2ts) ;;
*) echo no se puede manejar el archivo $input ; continue ;;
esac

##################################################################

# salida
output=$input.$osuffix

# salida en el mismo directorio en el que se ejecuta el script
#output=`basename $output`

# Archivo de aviso
avisowav=.aviso.wav

# Set XAUDIO and XVIDEO filenames
XAUDIO=$input.wav # scratch file
XVIDEO=- # pipe

# detecta el tamaño
if [ -z $isize ]; then
isize=$($FFMPEG -i $input 2>&1 | sed -n "s/.* Video: h264, yuv420p, \([^ ]*\) .*/\1/p")
#ifps=$($FFMPEG -i $input 2>&1 | sed -n "s/.* Video: h264, yuv420p, \([^ ]*\) .*/\1/p")
fi

##################################################################
# Extraemos el audio
$FFMPEG -y $itruncate -i $input -vn $oaudio_in $XAUDIO

# Extraemos unos segundos de audio para avisar del final del codificado
$FFMPEG -y -t 00:00:07 -i $XAUDIO $avisowav

echo "------------------------------------------------------------------"

# Extraemos el video en crudo y lo mezclamos con el audio extraido
$FFMPEG -y $itruncate \
-i $input \
-an \
-pix_fmt yuv420p -f rawvideo $XVIDEO |
$FFMPEG -y \
-i $XAUDIO \
-r $irate2 -s $isize -pix_fmt yuv420p -f rawvideo -i $XVIDEO \
-r $orate -s $osize $ovideo \
$oaudio_out \
$output \
2>salida.txt

##################################################################
# Calculamos el desfase entre el audio y el vídeo
isize1=$($FFMPEG -i $output 2>&1 | sed -n "s/.* Duration: \([^ ]*\) .*/\1/p")
isize2=$($FFMPEG -i $XAUDIO 2>&1 | sed -n "s/.* Duration: \([^ ]*\) .*/\1/p")

horas1=$(echo $isize1 | cut -d ":" -f 1)
horas2=$(echo $isize2 | cut -d ":" -f 1)

minutos1=$(echo $isize1 | cut -d ":" -f 2)
minutos2=$(echo $isize2 | cut -d ":" -f 2)

segundos1=$(echo $isize1 | cut -d ":" -f 3 | cut -d "." -f 1)
segundos2=$(echo $isize2 | cut -d ":" -f 3 | cut -d "." -f 1)

decimas1=$(echo $isize1 | cut -d ":" -f 3 | cut -d "." -f 2 | cut -d "," -f 1)
decimas2=$(echo $isize2 | cut -d ":" -f 3 | cut -d "." -f 2 | cut -d "," -f 1)

totalsegundos1=`echo "( $horas1 * 3600 ) + ( $minutos1 * 60 ) + $segundos1" | bc`.$decimas1
totalsegundos2=`echo "( $horas2 * 3600 ) + ( $minutos2 * 60 ) + $segundos2" | bc`.$decimas2

relacion12=`echo "scale=9;$totalsegundos1 / $totalsegundos2" | bc`
recomendable=`echo "scale=9;0$relacion12 * $correccion" | bc`
echo "******************************************************"
echo "Corrección utilizada = "$correccion
echo " Tiempo de video "$totalsegundos1
echo " Tiempo de audio "$totalsegundos2
echo " Longitud video / Longitud audio = "$relacion12
echo "Corrección recomendable = "$recomendable
echo "******************************************************"

# avisamos del final del codificado
mplayer $avisowav

exit 0