Thomas 'Ingrid' Heuving schrieb am Sun, 11 Dec 2011 09:48:15 +0100:
> Hallo,
>
> kennt jemand ein Programm, mit dem man aus einer Liste von
> MP3-Dateien eine CDDB-Datei erzeugen kann?
So ein Programm habe ich nicht gefunden, so dass ich mir doch mein
eigenes Skript schreiben musste. Die erzeugte DISCID ist ziemlich
nah an der, die man erhält. wenn man die MP3 nach wav umwandelt und
daraus mit cdrecord eine CD-DA brennt. Außer den üblicherweisen
vorhandenen Programmen wird nur mediainfo benötigt.
#!/bin/bash
various=false
[ "$1" = "-v" ] && shift && various=true;
# Erzeugt auf stdout eine CDDB-Datei
# 150 ist der Anfangssektor, wenn man mit cdrecord brennt
gesframe=150;
# Erste zwei Stellen der Disc-Id
n=0;
# Mittlere 4 Stellen der Disc-Id
gesamt=0;
# Letzte zwei Stellen der Disc-Id
anz=0;
# Beginn der cddb-Datei
cat <<-END
# xmcd CD database file generated by cddbAusMp3
#
# Track frame offsets:
END
#Tracks abarbeiten
for file in *mp3; do
echo \# $gesframe;
# Laenge per mediainfo auslesen und dann in Minute, Sekunde und
# Millisekunde aufteilen. Problem: Fuehrende Nullen muessen
# entfernt werden, aber der String darf auch nicht leer sein
laenge=$(mediainfo --Inform="General;%Duration/String3%" $file |\
head -1);
min=$(echo $laenge | sed -e 's/\([^:]*:\)\([0-9][0-9]\)\(.*\)/\2/'|\
sed -e 's/[0]*//');
[ -z "$min" ] && min=0;
sekunde=$(echo $laenge |\
sed -e 's/\([^:]*:[^:]*:\)\([0-9][0-9]\)\(.*\)/\2/' |\
sed -e 's/[0]*//');
[ -z "$sekunde" ] && sekunde=0;
msek=$(echo $laenge | sed -e 's/\([^.]*.\)\([0-9]*\)\(.*\)/\2/'|\
sed -e 's/[0]*//');
[ -z "$msek" ] && msek=0;
# Aus den Millisekunden eine Framezahl berechnen. 75 Frames sind
# eine Sekunde.
frames=$(bc<<-END
define frames(sek){
auto erg1, erg2
scale=0
erg1=sek/13.33
erg2=sek%13.33
if (erg2 > 0)
erg1=erg1+1
return erg1
}
frames($msek)
END
)
# Erfahrungswert:
# Durchschnittliche Menge an Frames, die beim Brennen hinzugefuegt
# werden als Padding auf Sektorgroesse
frames=$(($frames+13));
# Fuer die Berechnung der mittleren vier Bytes der discid werden
# nur Minute und sekunde herangezogen, die Millisekunden werden
# vernachlaessigt. Also einfach durch 75 teilen, damit werden die
# Milisekunden abgeschnitten
# Algorithmus aus freedb.Howto.txt
gsek=$(($gesframe/75));
new=$(bc <<-END
scale=0;
define cddb_sum(n){
auto ret;
ret=0;
while (n>0)
{
ret = ret + (n % 10);
n = n / 10;
}
return (ret);
}
cddb_sum($gsek)
END
)
n=$(($n + $new))
anz=$(($anz+1));
# Neuen Startframe fuer naechsten Track berechnen
gesframe=$(($gesframe+(60*75*$min)+($sekunde*75)+$frames));
done
# Gesamtlaenge ist Ende des letzten Tracks minus Anfang des ersten
# Tracks. Teilen durch 75 gibt ganze Sekunden
gesamt=$(((($gesframe-150)/75)));
cat <<-END
#
# Disc length: $gesamt seconds
#
# Revision: 0
# Submitted via: cddbAusMp3 1.0
#
END
new=$(bc<<-END
scale=0
$n%255
END
)
# echo $n $new $gesamt $anz
printf DISCID=%2.2x%4.4x%2.2x $new $gesamt $anz
echo ''
# Albuminformationen werden aus der ersten MP3-Datei geholt
first=$(ls *.mp3 | head -1);
if [ $various = "true" ]
then
artist=("Various");
else
artist=($(mediainfo $first | grep Performer | head -1 |\
sed -e 's/.*: *//'))
fi
dtitle=($(mediainfo $first | grep Album | head -1 |\
sed -e 's/.*: *//'))
genre=($(mediainfo $first | grep Genre | head -1 |\
sed -e 's/.*: *//'))
year=$(mediainfo $first | grep -i "recorded date" |\
head -1 | sed -e 's/.*: *//')
original=$(mediainfo $first | grep "Original/Album" |\
head -1 | sed -e 's/.*: *//')
printf '%s%s%s%s\n' "DTITLE=" "$(echo ${artist[@]^})"\
" / " "$(echo ${dtitle[@]^})"
echo "DYEAR=$year"
echo "DGENRE=$(echo ${genre[@]^})"
# Titel schreiben
n=0;
for file in *mp3; do
titel=$(mediainfo $file | grep Track | head -1 |\
sed -e 's/.*: //');
artist=($(mediainfo $file | grep Performer |\
head -1 | sed -e 's/.*: *//'))
if [ $various = "true" ] && [ -n "$artist" ]
then
printf 'TTITLE%d=%s / %s' $n "$(echo ${artist[@]^})"\
"$(echo ${titel^})";
else
printf 'TTITLE%d=%s' $n "$(echo ${titel^})";
fi
echo '';
n=$(($n+1));
done
# Erweiterte Information fürs Album, derzeit Originalalbumnummer
# (wird von listentoyourears gesetzt)
echo "EXTD=$original"
n=0;
# Erweiterte Informationen pro Track (derzeit Genre)
for file in *mp3; do
ext=$(mediainfo $file | grep Genre |\
head -1 | sed -e 's/.*: *//')
printf 'EXTT%d=%s' $n "${ext^}";
echo '';
n=$(($n+1));
done
echo "PLAYORDER="
--
Thomas Heuving