Hi everyone,
Surely you'll be glad to know that now you can convert your audiobooks in Linux, thanks to the bash script that I whipped up and posted yesterday here:
http://ubuntuforums.org/showth
(using my nick in ubuntuforums, fezouro)
Enjoy!
Hi everyone,
Surely you'll be glad to know that now you can convert your audiobooks in Linux, thanks to the bash script that I whipped up and posted yesterday here:
http://ubuntuforums.org/showth
(using my nick in ubuntuforums, fezouro)
Enjoy!
#!/bin/bash
# Hack to avoid using the Nokia Audiobooks application
# No hassle with Windoze plus conversion is faster too
# The script just takes one single compulsory parameter: "book_title"
# Execute it in a directory contaning the mp3s plus a single cover jpg
# Any file names are fine
# Output files are in the folder ./book_title
# This folder can be moved as-is to the Audiobooks directory in the phone
# Change the parameters to amrwb-encoder if you want more compression, etc
# Change the chapter values by hand in the index file if you're a perfectionist
# Note: some sections are optional in theory (chapters, content_info),
# but removing some of them breaks the program
# Required packages (Debian): mpg321, resample, amrwb, mplayer
# Courtesy of Fezouro (Ubuntu forums)
# Version 0.2
if [ $# -lt 1 ]; then
echo "Book title parameter required"; exit;
fi
jpegs=`find . -maxdepth 1 -iname "*jpg"| wc -l`
if [ $jpegs -ne 1 ]; then
echo "Only one single cover JPG image can be present"; exit;
fi
echo "Converting: $1"
index="/tmp/index.inx"
tmp="/tmp/tmp.wav"
tmp2="/tmp/tmp2.wav"
rm -f $tmp $tmp2 $index
rm -rf "$1"
mkdir "$1";
echo "#BOOK" > $index
echo "$1;" >> $index
echo "#PIC" >> $index
echo "$1.jpg;" >> $index
echo "#TRACKS" >> $index
# number of files to process
count=`find . -maxdepth 1 -iname "*mp3"| wc -l`
start=`date +%s`
current=1
find . -maxdepth 1 -iname "*mp3" | sort | while read i; do
time_s=`date +%s`
j=`basename "$i" .mp3`
base=`basename "$j" .MP3`
out="$base.awb"
tput el1
echo -n -e "\r[$current/$count] $out"
# convert mp3 to wav
mpg321 -q -w $tmp "$i" > /dev/null
# resample to awb rate
resample -to 16000 -terse $tmp $tmp2 > /dev/null
# file length in seconds
lengthd=`mplayer -vo null -ao null -frames 0 -identify $tmp2 2>/dev/null | grep ID_LENGTH | awk -F= '{print $2}'`
# remove decimals
length=`echo "scale=0;$lengthd/1" | bc`
# convert wav to awb
amrwb-encoder -dtx 7 $tmp2 "$1/$out" > /dev/null 2>&1
# update index file
echo "$out:$length;" >> $index
current=$(($current+1))
rm -f $tmp $tmp2
done
echo "#CHAPTERS" >> $index
chapter=1;
find . -maxdepth 1 -iname "*mp3" | sort | while read i; do
j=`basename "$i" .mp3`
base=`basename "$j" .MP3`
out="$base.awb"
echo "$out:0s:$chapter:$base;" >> $index
chapter=$(($chapter+1))
done
echo "#VERSION" >> $index
echo "0.7;" >> $index
echo "#CONTENT_INFO" >> $index
echo "NokiaAudiobookManagerVersion=Hack by Fezouro;" >> $index
echo "CodecMode=7;" >> $index
echo "CodecBitRate=23050;" >> $index
echo "DTX=1;" >> $index
echo "SBRA=0;" >> $index
echo "SBRA_Rate=900;" >> $index
echo "InputFormat=2;" >> $index
# index must be in little endian UTF-16 unicode format
iconv -t UTF-16 $index > "$1/$1.inx"
# copy book cover with right name
cover=`find . -maxdepth 1 -iname \*.jpg`
cp "$cover" "$1/$1.jpg"
rm -f $tmp $tmp2 $index
elapsed=$(( `date +%s` - $start))
tput el1
echo -e "\rDone in $elapsed seconds"
Why wmrwb-encoder?
For me the sox works perfectly (must be compiled with amr support)
A piece from my script (mbrola based text2nokia, input is raw data piped from mbrola):
sox -s -c 1 -r 16000 -t raw -2 - -t amr-wb -C $level "$outdir"/"$outdir"_${nr}.awb vol 1.2 contrast
With sox you shuld not play with resampling - simply pass the parameters to sox.
Also, cover image bash function:
function makepic()
{
if which convert 2>/dev/null >/dev/null ; then
convert "$picture" -geometry 240x320 \
-gravity center \
-background '#4444aa' \
-extent 240x320 \
"$outdir"/"$outdir".jpg > /dev/null || \
cp "$picture" "$outdir/$outdir".jpg
else
cp "$picture" "$outdir/$outdir".jpg
fi
}
Thanks, I didn't know that you could do that with sox and awb! That's why the hassle with resampling and the rest.
Could you please post your full script?
Hi
My script is probably not very interesting (it converts text to audiobooks using experimental Polish synthesizer), but I suggest some improvements:
---- cut here ----
# convert mp3 directly to amr-wb
# The "contrast" effect requirex sox version >= 14.1
# amr-wb format requires sox compiled with amr format support
length=`sox "$i" -t amr-wb -c 1 -C 7 "$1/$out" rate -m 16000 contrast | \
awk -F: '/^Length/ {print int($2+0.5)}'`
# alternatively - convert mp3 to amr-wb with normalization instead of contrast
length=`sox "$i" -t amr-wb -c 1 -C 7 "$1/$out" \
vol $(sox "$i" -n stat -v 2>&1) rate -m 16000 stat 2>&1 | \
awk -F: '/^Length/ {print int($2+0.5)}'`
# alternatively - use sox and amrwb-encoder (no compilation required,
# on plain Ubuntu instalations requires sox-fmt-all and amrwb)
length=`sox "$i" -t wav -c 1 "$tmp2" \
vol $(sox "$i" -n stat -v 2>&1) rate -m 16000 stat 2>&1 | \
awk -F: '/^Length/ {print int($2+0.5)}'`
# convert wav to awb
amrwb-encoder -dtx 7 $tmp2 "$1/$out" > /dev/null 2>&1
# copy the cover image with correct name and aspect ratio
# requires ImageMagick
# put this code in proper place!
jpegs=`find . -maxdepth 1 -iname "*jpg"| wc -l`
if let "$jpegs>1" ; then
echo "Too many JPG images"
exit 1
fi
if [ "$jpegs" = "1" ] ; then
echo "#PIC" >> $index
echo "$1.jpg;" >> $index
cover=`find . -maxdepth 1 -iname \*.jpg`
convert "$cover"-geometry 240x320 \
-gravity center \
-background '#4444aa' \
-extent 240x320 \
"$1"/"$1".jpg
fi
--- cut here ---
I hope this would be helpful?
Thanks, that's very much appreciated. Yours is a great script!
On top of that, my method to get the length using mplayer was not too accurate sometimes, compared to the way you give using sox.
To sum up, you've blown my sox off :)