linuxで音楽CDをflacにしてからさらにmp3にした時のメモ

注意

以下のコマンドを使っているので無ければできません
cdrdao, cueconvert, sox, flac, metaflac, shnsplit, lame, eyeD3

シェルスクリプトにまとめたもの

※新規のディレクトリに移動してから実行してください
※エラーが起きた場合の処理は書いてないです。気が向いたら書いてどこかで公開しておきます

音楽CDからflacにするシェルスクリプト
#!/bin/sh
cddb_server='freedbtest.dyndns.org:80:/~cddb/cddbutf8.cgi'

sudo cdrdao read-cd --device /dev/cdrom --with-cddb --cddb-servers "${cddb_server}" --datafile CDImage.bin CDImage.toc

cueconvert -i toc -o cue CDImage.toc CDImage.cue
printf "`cat CDImage.cue`\n"|sed 's/CDImage\.bin/CDImage\.wav/g' > CDImage.cue.tmp
mv CDImage.cue.tmp CDImage.cue
sox -t cdda CDImage.bin CDImage.wav
flac CDImage.wav
metaflac --set-tag-from-file="CUESHEET=CDImage.cue" CDImage.flac

引数はいりません

追記:2013/01/05 19時頃

もしfreedbからとってきた曲情報が気に入らない場合などでcueを編集したい場合はまずは.cueをいじってから

    % metaflac --remove-tag="CUESHEET" CDImage.flac
    % metaflac --set-tag-from-file="CUESHEET=CDImage.cue" CDImage.flac

こうします。最初にremove-tagをしておかないと前のcuesheetの後ろに追記されることになるので消してから行いましょう

flacから曲ごとにmp3を生成するシェルスクリプト
#!/bin/sh
if [ "${#}" != '1' ];then
    echo "引数にflacファイルを指定してください"
    exit 1
fi
cue='CDImage.cue'

metaflac --show-tag="CUESHEET" "${1}"|sed -e '1s/^CUESHEET=//' > "${cue}"
shnsplit "${1}" -f "${cue}" -o 'cust ext=mp3 lame --add-id3v2 -b 320 --quiet - %f' -t '%n. %t'

information=`cat "${cue}"|sed -n "1,/FILE/p"`
album=`echo "${information}"|grep '^TITLE'|sed -e 's/^TITLE[^"]*"//' -e 's/"$//'`
year=`echo "${information}"|grep '^MESSAGE'|grep -o '[0-9]*'`

track_total=`cat "${cue}"|grep '^TRACK'|wc -l`

IFS=$'\n'
for i in `find . -type f -name '*.mp3'`;do
    filename=${i##*/}
    track=${filename%%.*}
    information=`cat "${cue}"|sed -n "/TRACK ${track}/,/INDEX/p"`
    title=`echo "${information}"|grep '^TITLE'|sed -e 's/^TITLE[^"]*"//' -e 's/"$//'`
    artist=`echo "${information}"|grep '^PERFORMER'|sed -e 's/^PERFORMER[^"]*"//' -e 's/"$//'`

    eyeD3 --to-v2.3 \
    --set-encoding=utf16-LE \
    --artist="${artist}" \
    --album="${album}" \
    --title="${title}" \
    --track="${track}" \
    --track-total="${track_total}" \
    --year="${year}" \
    "${i}"
done

引数にflacファイルを指定して実行します
flacに埋め込みcueがあることが前提に書かれていますが外部にあるcueを使いたい場合は

    metaflac --show-tag="CUESHEET" "${1}"|sed -e '1s/^CUESHEET=//' > "${cue}"

これをコメントアウトするなりしてcue変数に外部cueのパスを書けば多分動きます

以下、いちいちコマンドにしたもの

音楽CDからflacにする手順

まずは面倒なことを避けるために適当に作ったディレクトリに移動してから行なってください

cdからファイルを生成するのと同時にfreedbtestから曲名などの情報をとってくる

    # cdrdao read-cd --device /dev/cdrom --with-cddb --cddb-servers 'freedbtest.dyndns.org:80:/~cddb/cddbutf8.cgi' --datafile CDImage.bin CDImage.toc

.tocから.cueに変換

    % cueconvert -i toc -o cue CDImage.toc CDImage.cue

文字化け修正とファイル名の変更箇所をいじる

    % printf "`cat CDImage.cue`\n"|sed 's/CDImage\.bin/CDImage\.wav/g' > CDImage.cue.tmp
    % mv CDImage.cue.tmp CDImage.cue

バイナリから.wavを生成

    % sox -t cdda CDImage.bin CDImage.wav

.wavから.flacに変換

    % flac CDImage.wav

.flacに.cueを埋め込む

    % metaflac --set-tag-from-file="CUESHEET=CDImage.cue" CDImage.flac

これでcueが埋め込まれたflacの生成ができます
再生はdeadbeefという音楽プレイヤーで試しました

flacから曲ごとにmp3を生成する手順

次はshnsplitコマンドを使用するのですが
flacの埋め込みに使った元のcueファイルがなければ
必要なのでflacに埋め込まれているcueを取り出します

    % metaflac --show-tag="CUESHEET" CDImage.flac|sed -e '1s/^CUESHEET=//' > CDImage.cue

flacを分割してmp3にします。この時に出力されるファイル名は 「トラック番号. 曲名.mp3」 になります
それはオプションの-t "%n. %t"で定義されているらしい

    % shnsplit CDImage.flac -f CDImage.cue -o 'cust ext=mp3 lame --add-id3v2 -b 320 --quiet - %f' -t '%n. %t'

別にこのままでもいいのですがid3tagを使いたいので (使わない人は先程のオプションの--add-id3v2はいらない)
ファイル名の前につけたトラック番号を利用して
cueから色々と情報を抜き取るとしますがコマンドの1行や2行では済まないのでシェルスクリプトで書きます

#!/bin/sh
cue='CDImage.cue'

information=`cat "${cue}"|sed -n "1,/FILE/p"`
album=`echo "${information}"|grep '^TITLE'|sed -e 's/^TITLE[^"]*"//' -e 's/"$//'`
year=`echo "${information}"|grep '^MESSAGE'|grep -o '[0-9]*'`

track_total=`cat "${cue}"|grep '^TRACK'|wc -l`

IFS=$'\n'
for i in `find . -type f -name '*.mp3'`;do
    filename=${i##*/}
    track=${filename%%.*}
    information=`cat "${cue}"|sed -n "/TRACK ${track}/,/INDEX/p"`
    title=`echo "${information}"|grep '^TITLE'|sed -e 's/^TITLE[^"]*"//' -e 's/"$//'`
    artist=`echo "${information}"|grep '^PERFORMER'|sed -e 's/^PERFORMER[^"]*"//' -e 's/"$//'`

    eyeD3 --to-v2.3 \
    --set-encoding=utf16-LE \
    --artist="${artist}" \
    --album="${album}" \
    --title="${title}" \
    --track="${track}" \
    --track-total="${track_total}" \
    --year="${year}" \
    "${i}"
done

こんな感じのシェルスクリプトを実行すれば
アーティストとアルバム名と曲名とトラック番号と合計トラック数と年代が
id3tagとしてmp3に書き込まれます
ちなみにcueの仕様は確認したりしてないので変な挙動をするかもしれませんが、テストに使ったcueは

CATALOG 4580226569643
TITLE "不完全燃焼/スイッチが入ったら"
PERFORMER "石川智晶"
MESSAGE " YEAR: 2011"

FILE "CDImage.wav" WAVE
TRACK 01 AUDIO
TITLE "不完全燃焼"
PERFORMER "石川智晶"
MESSAGE ""
ISRC JPG751100248
INDEX 01 00:00:00

TRACK 02 AUDIO
TITLE "スイッチが入ったら"
PERFORMER "石川智晶"
MESSAGE ""
ISRC JPG751100248
INDEX 00 04:08:30
INDEX 01 04:08:34

TRACK 03 AUDIO
TITLE "不完全燃焼 (without vocal)"
PERFORMER "石川智晶"
MESSAGE ""
ISRC JPG751100249
INDEX 00 08:40:14
INDEX 01 08:40:32

TRACK 04 AUDIO
TITLE "スイッチが入ったら (without vocal)"
PERFORMER "石川智晶"
MESSAGE ""
ISRC JPG751100250
INDEX 00 12:48:21
INDEX 01 12:48:25

こんな感じになってます

後書き

id3tagにジャンルも指定したかったけどcueに書いてなかったので書いてません

それとアルバム名に/が混ざってる場合があるのでflacのファイル名をアルバム名に変える処理も書いていない
それをいってしまえば曲名もその可能性があるけどshnsplitが勝手に「/」を「-」に置換してくれるので無視することにしました
(どうやって対応しよう…エスケープするのが最終手段かなあ…)

mplayerでどうやって埋め込みcueを再生するんだ…もしかして対応していない?