понедельник, 11 августа 2008 г.

Конвертируем FLAC в MP3 под Debian

Неоднократно от разных аудиофилов с хорошей аудиоаппаратурой слышал, что mp3 сжатие сильно ухудшает качество звука.

Однажды я решил попробовать скачать музыку в современном свободном формате со сжатием без потерь, чтобы попробовать оценить разницу между mp3 и flac на моей аппаратуре и моим слухом.

Накачал для примера несколько компакт-дисков, сжатых в этом формате. На слух разницы не услышал. Скачал ещё один компакт-диск, чтобы сравнить с альбомом в формате mp3 с битрейтом 192 килобита, который у меня уже был. Можно было поступить проще - просто пересжать один из компакт-дисков в mp3 и сравнить.

В итоге я опять не услышал никакой разницы. В мою голову закрались смутные сомнения:
  1. возможно скачанный диск был получен из треков mp3,
  2. у меня плохая аудиосистема,
  3. у меня плохая звуковая карта,
  4. у меня плохой слух.
Так или иначе, но если я не заметил разницы, смысла в хранении альбомов размером с пол-гигабайта я не увидел, а потому решил пересжать flac в mp3.

Из подручных средств под виндой у меня не оказалось перекодировщика, который бы умел декодировать flac (проигрыватель foobar2000 не в счёт). Кроме того, на домашнем компьютере почти не было места для пересжатия, потому я решил пересжать треки прямо на домашнем сервачке под Debian.

Для этого я использовал пакеты flac, lame и немножко shell-скриптинга.

Для начала установим пакет flac:
# aptitude install flac
Теперь нужно установить пакет lame. Этот пакет не включен в основную поставку Debian по лицензионным соображениям, поэтому воспользуемся сторонним сервером.

Для начала добавим новые источники в файл /etc/apt/sources.list:
# deb http://ftp.debian-unofficial.org/debian etch main contrib non-free restricted
# deb-src http://ftp.debian-unofficial.org/debian etch main contrib non-free restricted
Теперь добавим GPG-ключи:
# wget http://ftp-master.debian-unofficial.org/other/openpgp/archive-key-2006.asc -O - | apt-key add -
wget http://ftp-master.debian-unofficial.org/other/openpgp/archive-key-2007.asc -O - | apt-key add -
Теперь обновим список пакетов:
# aptitude update
И установим пакет lame:
# aptitude install lame
Для потоковой обработки всех файлов с расширением .flac в текущем каталоге я наваял следующий shell-скрипт mlame.sh:
#!/bin/sh

for flac in *.flac;
do
  mpeg=`echo $flac | cut -f1 -d.`.mp3
  flac -d -c "$flac" | lame --cbr -b 192 - "$mpeg"
done
Этот скрипт находит в текущем каталоге файлы с расширением flac. В цикле для каждого такого файла создаёт имя целевого файла mp3, затем настраивает команды flac и lame для совместной работы в конвейере.

Сжатие осуществляется в mp3-файл с постоянным битрейтом 192 килобита.

Если есть предложения по оптимизации скрипта, буду рад выслушать. К сожалению мне не удалось обойтись без cat, поскольку в именах файлов были пробелы, поэтому скрипты воспринимали имя файла как несколько не связанных между собой аргументов.

Ссылки по теме:
Установка lame на Debian

16 комментариев:

  1. спасибо! не пришлось ничего выдумывать. только 192 на 320 исправил.

    ОтветитьУдалить
  2. а тэги? не осилил? а ведь есть же foobar2000, который "не в счет", потому что оффтопик:)

    ОтветитьУдалить
  3. >а тэги? не осилил? а ведь есть же foobar2000, который "не в счет", потому что оффтопик:)

    Я храню музыку в виде artist/date-album/tracknumber-title. Это все теги, которые мне были нужны, поэтому потом я воспользовался ExFalso или TagRenamer, сейчас уже не помню.

    Вообще задача была - только конвертировать звук, но если бы нужно было перенести ещё и теги, то я бы воспользовался mp3v2 из пакета python-mutagen и написал бы соответствующий скрипт.

    Анонимус знает только фубар и молится на него?

    ОтветитьУдалить
  4. Раз уж приветствуется доработка скрипта... есть предложение исправить до примерно такого вида:

    Скрипт следует положить в каталог, в котором лежат подлежащие конвертации flac-файлы. и запустить...

    #!/bin/sh
    # Для всех .flac-файлов в данном каталоге:
    for flac in *.flac;

    do

    # Новое имя файла -замена расширения с '.flac' на '.mp3'
    newname=`echo $flac | sed s/\.flac$/\.mp3/`

    # Собственно конвертирование
    flac -d -c --totally-silent "$flac" | lame -S --cbr -b 192 - "$newname"

    # Раскомментировать, если нужно удалять оригинальные .flac-файлы

    #rm "$flac"

    done

    ОтветитьУдалить
  5. Ну и ещё одно маленькое улучшение. Вызывать программы в bash принято так: newname=$(echo $flac | sed s/\.flac$/\.mp3/)

    Кстати, помещать скрипт в папку с файлами совсем не обязательно.

    ОтветитьУдалить
  6. >Ну и ещё одно маленькое улучшение. Вызывать программы в bash принято так: newname=$(echo $flac | sed s/\.flac$/\.mp3/)

    Во-первых, это не bash-скрипт, а shell-скрипт. А во-вторых то, что вы предложили - не улучшение, а ухудшение, поскольку не будет работать в стандартном shell.

    Только не нужно мне говорить о том, что bash - стандарт де-факто. Его в Debian из всех системных скриптов выпилили, заменив на более компактный и удовлетворяющий стандартам dash.

    ОтветитьУдалить
  7. >Кстати, помещать скрипт в папку с файлами совсем не обязательно.

    Я нигде вроде и не писал, что его нужно поместить непременно в текущий каталог. Его нужно запускать так, чтобы в текущем каталоге были flac-файле.

    ОтветитьУдалить
  8. Спасибо, мил человек. То, что искал!

    ОтветитьУдалить
  9. Супер! Отличта! Поиски удовлетворяют результаты!

    Предлагаю умным объединиться и налячкать хотя бы для bash подборку скриптов и создать некий multi-media-converter под Debian/Ubuntu (текстовый) а глядиш он и в графике появицо. У меня такого рода скриптов чуть-чуть и маленькая жменька, это следующий в коллекции! Хотелось бы и самому, но в написании такого рода программ мешает недостаток опыта. :( Может чего подскажете?

    ОтветитьУдалить
  10. >Хотелось бы и самому, но в написании такого рода программ мешает недостаток опыта. :( Может чего подскажете?

    Изучить shell-скриптинг. Бумажных книг и электронной документации в интернете на русском языке предостаточно.

    ОтветитьУдалить
  11. Вот скрипт который кодирует и переносит теги. На Ubuntu работает
    #!/bin/bash
    OUT_DIR="./mp3"
    [ ! -d ${OUT_DIR} ] && mkdir -p ${OUT_DIR}
    # modify the lame options to your
    # preference
    lame_opts=" --vbr-new -V 2 -B 256 "
    for FLAC in *.flac;
    do
    MP3=`basename "${FLAC%.flac}.mp3"`
    [ -r "$FLAC" ] || { echo can not read file \"$FLAC\" >&1 ; exit 1 ; } ;
    metaflac --export-tags-to=- "$FLAC" | sed 's/=\(.*\)/="\1"/' > tmp.tmp
    . ./tmp.tmp
    rm tmp.tmp
    [ -z $TITLE ] && TITLE="$Title"
    [ -z $TRACKNUMBER ] && TRACKNUMBER="$Tracknumber"
    [ -z $GENRE ] && GENRE="$Genre"
    [ -z $DATE ] && DATE="$Date"
    [ -z $COMMENT ] && COMMENT="$Comment"
    [ -z $ARTIST ] && ARTIST="$Artist"
    [ -z $ALBUM ] && ALBUM="$Album"

    echo "Converting ${FLAC} to MP3 format"
    flac -c -d "$FLAC" | lame ${lame_opts} \
    --tt "$TITLE" \
    --tn "$TRACKNUMBER" \
    --tg "$GENRE" \
    --ty "$DATE" \
    --tc "$COMMENT" \
    --ta "$ARTIST" \
    --tl "$ALBUM" \
    --add-id3v2 \
    - ${OUT_DIR}/"$MP3"
    done

    ОтветитьУдалить
  12. Не получилось у меня в sh его запустить, да и нет у меня ни bash'а ни sh'а стандартного, всякие dash'ы и tcsh'ы.
    Не стал разбираться, сделал так:
    $ python
    import os
    for f in os.listdir("."): os.system('cat "%s" | flac -d -c - | lame -h - "%s"' % (f, f.replace(".flac", ".mp3")))

    ОтветитьУдалить
  13. Не получилось у меня в sh его запустить, да и нет у меня ни bash'а ни sh'а стандартного, всякие dash'ы и tcsh'ы.

    dash - это и есть стандартный sh, реализованный командой Debian.

    >Не стал разбираться, сделал так:

    У кого в системе нет стандартного shell, а у кого-то может и не быть python.

    Логическое продолжение статьи с разбивкой FLAC по CUE-трекам здесь:
    http://vladimir-stupin.blogspot.com/2010/08/flac-cue-mp3.html

    ОтветитьУдалить
  14. Есть ещё такая замечательная штука cue2tracks http://www.ylsoftware.com/storage/files/14

    ОтветитьУдалить
  15. Просто супер ... спасибо!

    ОтветитьУдалить