For an english version of this page, please go here
Dato l'arrivo in casa di un Creative Zen nuovo fiammante, mi sono dedicato a cercare i parametri giusti per convertire video da un qualsivoglia formato ad un formato compatibile con questo gingillino. Lo Zen ha la capacità di riprodurre filmati in formato XVID e Windows Media Video, con alcune (piccole) limitazioni.
Per i dettagli, vedere questo documento prodotto dalla stessa Creative.
In un primo momento ho condotto vari esperimenti di conversione usando ffmpeg (mi piace di più rispetto a mencoder), ma tutti i filmati che produceva avevano il problema di saltare gli ultimi 6/7 secondi di video una volta riprodotti sullo ZEN. Dopo varie indagini, sono giunto alla conclusione che questo sia dovuto al fatto che ffmpeg produce sempre filmati VBR (a bitrate variabile), mentre lo ZEN richiede una codifica CBR (a bitrate costante). Se qualcuno conoscesse un modo per produrre filmati in CBR tramite ffmpeg (non funziona impostare minrate e maxrate allo stesso valore) è pregato di farmi un fischio qui.
Visti i problemi con ffmpeg, mi sono appoggiato a mplayer/mencoder.
Nota bene: durante i miei ultimi esperimenti con gnomad2, ho accertato che la durata del filmato non viene trasferita insieme al filmato sullo Zen, rendendo impossibile fermare la riproduzione video ad un certo punto per riprendere la riproduzione dallo stesso punto in un momento successivo. La durata viene invece correttamente trasferita usando il software per Windows fornito insieme allo Zen.
Questo script permette di convertire uno o più filmati da un qualsiasi formato video ad un formato AVI compatibile con lo ZEN, ma non solo. Se opportunamente modificato, è possibile adattare il seguente script alle proprie esigenze di transcodifica. Per esempio, lo si può adattare per ricodificare una serie di filmati in modo che siano riproducibili sul lettore DIVX/XVID da salotto ecc.
La codifica avviene in 2 passaggi.
È possibile usare questo script insieme al mio script per mostrare il progresso di una conversione video effettuata tramite mencoder. È possibile reperirlo qui.
La versione corrente è la 1.02 del 02/10/2008.
All'interno di un'apposita sezione (Sezione Modificabile) nello script sono presenti alcuni parametri, già impostati sui valori corretti per la produzione di filmati funzionanti su un Creative Zen. Qualora le necessità fossero diverse dal produrre un filmato compatibile con lo Zen, basterà modificare queste variabili.
#!/bin/bash
#
# Script per convertire un filmato in un formato fruibile dal Creative Zen
# ma, se opportunamente modificato, anche per altro ;).
# Fabbricato per vossignori da 414N <414N chiocciolinainaina slacky PUNTO it>
# 02/10/2008
# Versione 1.02
# ~~~~~~~~~~~~~~~~~~~~~~~Sezione modificabile~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# La risoluzione del display.
# Verrà considerata solo la risoluzione X per il calcolo della
# riscalatura, dato che mencoder consente di ricavare in automatico
# la risoluzione Y in modo da mantenere il rapporto d'aspetto originale.
RESOLUTION="320x240"
# L'estensione del file
EXTENSION="avi"
# Il bitrate audio (in migliaia di bit/s)
ARATE="128"
# La directory di output. Verrà creata se inesistente
OUTDIR=${OUTDIR:-~/ZenOut}
if ! [ -d "$OUTDIR" ]
then
echo "Creating folder $OUTDIR ."
mkdir -p "$OUTDIR"
fi
# Il framerate massimo permesso
MAXFRAMERATE="30"
# Il FOURCC da forzare
FOURCC="XVID"
# Il codec video da usare.
VCODEC="mpeg4"
# Il bitrate video (in bit/s).
BITRATE="800000"
# File di log
LOGFILE=/tmp/mencoder-conversion.log
# Lo script per mostrare il progresso della conversione
# Per non usarlo, mettere "" oppure lanciare lo script impostando
# SHOW_PROGRESS=0
PROGRESS_SCRIPT="mencoderprogress.sh"
#~~~~~~~~~~~~~~~~~~~~~~~Fine Sezione Modificabile~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~~~~~~~~Inizio blocco funzioni~~~~~~~~~~~~~~~~~~~~~~~~~~
# Funzione delete_leftovers
# Cancella i file intermedi del processo di conversione.
# Parametri: N/A
function delete_leftovers ()
{
if [ -e divx2pass.log ]
then
rm divx2pass.log
fi
return 0
}
# Funzione print
# Stampa a video un messaggio, utilizzando dialog o echo.
# Parametri:
# $1 : messaggio da stampare
function print ()
{
if [ "$USE_DIALOG" = 0 ]
then
echo "$1"
else
dialog --msgbox "$1" 10 50
fi
}
# Funzione per l'annullamento del processo di codifica.
# Parametri:
# $1 : eventuale messaggio da mostrare
function abort ()
{
delete_leftovers
if [ "$FILENAME" ]
then
rm "$OUTDIR/$FILENAME.$EXTENSION" 2>/dev/null
print "Conversion Aborted\n$1\nHit Ok to exit."
fi
exit 1
}
#~~~~~~~~~~~~~~~~~~~~~~~~~Fine blocco funzioni~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~~~~~~~~~~Inizio script~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~~~~~~~~Inizio blocco controlli~~~~~~~~~~~~~~~~~~~~~~~~~
# Flag per indicare se usare dialog o un normale echo
if [ -z `which dialog 2>/dev/null` ]
then
USE_DIALOG=0
else
USE_DIALOG=${USE_DIALOG:-1}
fi
# Flag per indicare se usare mencoderprogress.sh
if [ -z `which "$PROGRESS_SCRIPT" 2>/dev/null` ]
then
SHOW_PROGRESS=0
else
SHOW_PROGRESS=${SHOW_PROGRESS:-1}
fi
# Controllo presenza nel path dei programmi richiesti
PROGRAMS="mplayer mencoder awk file grep egrep rev cut basename rm mkdir"
for PROGRAM in $PROGRAMS
do
if [ -z "`which "$PROGRAM" 2>/dev/null`" ]
then
print "Could not find $PROGRAM in your path."
exit 1
fi
done
# Controllo accesso in scrittura al file di log e sua
# inizializzazione.
if [ -w "$LOGFILE" -o ! -e "$LOGFILE" ]
then
echo -e "`date` \
\n Job started on files: \n$@" > "$LOGFILE"
else
print "You don't have write permission on $LOGFILE"
exit 1
fi
# Controllo argomenti passati allo script
if [ $# -eq 0 ]
then
print "You must specify at least one file."
exit 1
fi
# Controllo di esistenza dei files e se sono filmati.
MOVIES=""
for I in "$@"
do
if [ -f "$I" ]
then
if [ -z "`file -L "$I" | egrep -i '(video|movie|asf|matroska|mp4)'`" ]
then
echo "$I is not a movie file. It will not be processed." >> "$LOGFILE"
else
MOVIES+="$I"$'\t'
fi
fi
done
if [ "$MOVIES" = "" ]
then
print "No movies to convert."
exit 0
fi
#~~~~~~~~~~~~~~~~~~~~~~~~~~~Fine blocco controlli~~~~~~~~~~~~~~~~~~~~~~~~~
# Cattura del segnale CTRL+C
trap abort INT
# Suddividione della risoluzione.
RESX=`echo "$RESOLUTION" | cut -dx -f1`
RESY=`echo "$RESOLUTION" | cut -dx -f2`
( echo "$MOVIES" | while read -d $'\t' MOVIE
do
# Estrapolazione del solo nome del file (senza estensione)
FILENAME=`basename "$MOVIE" | rev | cut -d. -f2- | rev`
# Lettura della risoluzione originale del filmato.
INFO=`mplayer -msglevel all=0 -identify -nosound -vc dummy -vo null "$MOVIE"`
ORESX=`echo "$INFO" | grep VIDEO_WIDTH | cut -d'=' -f2`
ORESY=`echo "$INFO" | grep VIDEO_HEIGHT | cut -d'=' -f2`
DURATION=`echo "$INFO" | grep LENGTH | cut -d'=' -f2`
FRAMERATE=`echo "$INFO" | grep VIDEO_FPS | cut -d'=' -f2`
# Controllo sul framerate (deve essere <= MAXFRAMERATE)
if [ `echo "$FRAMERATE" | awk '{printf "%.0f", $1}'` -gt "$MAXFRAMERATE" ]
then
FRAMERATE="$MAXFRAMERATE"
fi
# Stampa dei valori scelti sul file di log
echo -e "Converting $MOVIE to $OUTDIR/$FILENAME.$EXTENSION \
\nOriginal resolution = $ORESX x $ORESY \
\nTarget maximum resolution = $RESX x $RESY \
\nFramerate = $FRAMERATE fps \
\nMovie length = $DURATION s\
\n========================================================" >> "$LOGFILE"
# Parametri usati per il primo passaggio
FIRST_PASS_PARAMS="-vf scale=$RESX:-10 \
-ovc lavc \
-lavcopts vcodec=$VCODEC:vhq:v4mv:trell:mbd=2:turbo=1:dc=10:vbitrate=$BITRATE:vpass=1 \
-nosound \
-ofps $FRAMERATE \
-o /dev/null"
# Parametri usati per il secondo passaggio
SECOND_PASS_PARAMS="-vf scale=$RESX:-10 \
-ovc lavc \
-lavcopts vcodec=$VCODEC:vhq:v4mv:trell:mbd=2:dc=10:vbitrate=$BITRATE:vpass=2 \
-oac mp3lame \
-lameopts cbr:mode=2:br=$ARATE -af resample=44100 -srate 44100 \
-ffourcc $FOURCC \
-ofps $FRAMERATE"
# Primo passaggio
if [ "$SHOW_PROGRESS" -eq 1 ]
then
mencoder "$MOVIE" $FIRST_PASS_PARAMS 2>>"$LOGFILE" | "$PROGRESS_SCRIPT" "$DURATION" "First pass on $MOVIE"
else
mencoder "$MOVIE" $FIRST_PASS_PARAMS 2>>"$LOGFILE"
fi
if [ $? -ne 0 ]
then
abort "First pass failed.\nLog file saved to $LOGFILE ."
else
echo "Fist pass successfully completed" >> "$LOGFILE"
fi
# Secondo passaggio
if [ "$SHOW_PROGRESS" -eq 1 ]
then
mencoder "$MOVIE" $SECOND_PASS_PARAMS -o "$OUTDIR/$FILENAME.$EXTENSION" 2>>"$LOGFILE" | "$PROGRESS_SCRIPT" "$DURATION" "Second pass on $MOVIE"
else
mencoder "$MOVIE" $SECOND_PASS_PARAMS -o "$OUTDIR/$FILENAME.$EXTENSION" 2>>"$LOGFILE"
fi
if [ $? -ne 0 ]
then
abort "Second pass failed.\nLog file saved to $LOGFILE ."
else
echo "Movie converted successfully\
\n========================================================" >> "$LOGFILE"
fi
done )
if [ $? -eq 0 ]
then
print "All files converted successfully."
else
abort "Conversion failed.\nLog saved to $LOGFILE"
fi
exit 0
È sufficiente inserire lo script all'interno del path e renderlo eseguibile. Consiglio di creare una cartella (ad esempio bin) all'interno della propria home e di inserirla nel PATH, andando a modificare/creare i file ~/.bashrc e ~/.bash_profile nel seguente modo:
export PATH+=":~/bin"
Se avete suggerimenti/segnalazioni, per favore fiondatevi a scrivere un post qui.