Skript AllToRiver

K Vánocům 2005 jsem dostal MP3 přehrávač IRiver IFP-880, který podporuje také formát Ogg Vorbis. No a protože má jenom 128 MB paměti a můj MP3 archiv má průměr bitrate kolem 200 kbps, moc by se mi tam toho nevešlo.

Proto si písničky předělávám do nízkobitrateového Vorbisu. Jenže Iriver je na Vorbis dost vybíravý a potřebuje, aby byl se vzorkovací frekvencí 44100 Hz a s průměrným bitrate mezi 96 a 320 kbps. Zejména ta spodní hranice je jednak dost zarážející, jednak dost diskutabilní. Nicméně ve firmwaru je to tak ošetřeno, že když ogg nemá průměrný bitrate alespoň 96 kbps, ani se ho to nepokusí přehrát.

No a pokud chci využít plně vlastnosti Vorbisu, je potřeba kódovat VBR algoritmem, který ale zase vůbec nezaručuje, jaký bude průměrný bitrate výsledku. Takže každá cca pátá písnička nehrála. Už mě to přestalo bavit a tak jsem napsal skript, který všechno udělá za mne:

#!/bin/bash
#Konverze souboru na prikazovem radku do Ogg Vorbis ABR >= 96kbps , 44100KHz
#Potrebuje libsndfile, mpg321, vorbis-tools (oggenc, oggdec),
# debianutils (mktemp)
#12.5.2006 pridana normalizace



trap int INT

int() {
echo "\nZachycen SIGINT, uklizim po sobe... "
rm -f ${TMPFILE}
rm -f ${RESFILE}
exit 1
}


while [ "$*" ];
do
FNAME="$1" #Vstupni soubor
EXT="${FNAME##*.}" #Pripona vst. souboru
OUTFNAME="${FNAME##*/}" #Odstraneni cesty z vystupu
TMPFILE=`mktemp /tmp/alltoriver.XXXXXX` # Docasny Wav - na konci se smaze
case "$EXT" in
[mM][pP]3)
OUTFNAME="${OUTFNAME%$EXT}ogg"
WAVFILE=$TMPFILE #Pracovni Wav - nemaze se
mpg321 -w $WAVFILE "$FNAME"
;;
[oO][gG][gG])
if [ "$OUTFNAME" == "$FNAME" ]; then
OUTFNAME="${OUTFNAME%.$EXT}-iriver.ogg"
fi
WAVFILE=$TMPFILE
oggdec -o $WAVFILE "$FNAME"
;;
[wW][aA][vV])
OUTFNAME="${OUTFNAME%$EXT}ogg"
WAVFILE="$FNAME"
;;
*)
echo "Soubor ${FNAME##*/} ma neznamou priponu, preskakuji... " 1>&2
shift
continue
;;
esac

#Prevzorkovani

FREQ=`file "$WAVFILE" | sed 's/.* \([0-9]\+\) Hz$/\1/'`
if [ $FREQ -ne 44100 ]; then
RESFILE=`mktemp /tmp/alltoriver_r.XXXXXX`
sndfile-resample -to 44100 "$WAVFILE" "$RESFILE"
rm $TMPFILE
TMPFILE=$RESFILE
WAVFILE=$RESFILE
fi

#Normalizace

if [ "$WAVFILE" != "$TMPFILE" ]; then
cp "$WAVFILE" "$TMPFILE"
WAVFILE=$TMPFILE
fi
normalize --peak "$WAVFILE"


#Enkodovani

BITRATE=110
AVGBITRATE=0
while [ $AVGBITRATE -lt 96 ];
do
oggenc -b $BITRATE -o "$OUTFNAME" "$WAVFILE"
#-t "$TIT" -a "$ART" -l "$ALB"
AVGBITRATE=`ogginfo "$OUTFNAME" | grep '^[^=]*Average bitrate' | sed 's/.*rate:
\([0-9]*\),.*/\1/'`
BITRATE=$(($BITRATE + 2))
done

rm "$TMPFILE"
shift
done

Skript můžete stáhnout zde, jeho kamaráda, co si poradí s celými adresáři zde.

Použití je jednoduché, stačí mu předhodit seznam souborů mp3, wav, nebo ogg a v aktuálním adresáři se vytvoří soubory s příponou ogg zakódované tak, aby jej Iriver přečetl. Když vyjde zakódovaný soubor s nižším bitratem než 96 kbps, zakóduje ho znova s vyšším nominálním a to tak dlouho, dokud se nedostane přes. Id3 tagy jsem původně řešil, ale zjistil jsem, že Iriver, když čte Ogg s tagy, tak za určitých okolností padá. Tak jsem to nakonec zrušil.