English | Русский

Блог о Linux и велосипедах

Зеркалирование FLAC в Ogg Vorbis и не только

Зачем?

Лично я предпочитаю хранить музыку во FLAC, когда есть такая возможность. Но на портативном плеере с ограниченным объёмом памяти хранить музыку в формате без потерь не очень рационально. Поэтому появилась необходимость конвертировать FLAC в формат с потерями.

Во что будем конвертировать?

Среди аудиоформатов с потерями одним из наилучших соотношений битрейт/качество обладает Ogg Vorbis. Также в Ogg есть официальная поддержка gapless playback (нужна поддержка ещё и со стороны плеера). Ещё одним важным преимуществом для меня является то, что Vorbis и FLAC используют один и тот формат метаданных. Это означает, что такие теги, как originaldate или albumartist, при конвертации не потеряются.

Какие требования?

Конвертировать можно на лету (по запросу) или же асинхронно (периодически). Очевидно, в первом случае экономится дисковое пространство, а во втором — время. Готовых решений первого варианта мне известно немного: mp3fs (только MP3 CBR и в 1 поток), gstfs (проект живой?). Быть может для синхронной конвертации можно задействовать UPnP/DLNA-сервер? Я не пробовал...

Меня второй вариант больше устраивает, так как он проще и гибче. Если каталог A с FLAC-файлами зеркалируется в каталог B с Ogg-файлами, то этот процесс я представляю так:

  • из A конвертируются файлы, которых нет в B, или которые уже изменились;
  • из B файлы удаляются, если они были удалены из A;
  • на файлы ogg, mp3, aac и другие форматы с потерями создаются жёсткие ссылки из A в B для экономии пространства (перекодирование файлов с потерями крайне нежелательно);
  • картинки и прочие полезные файлы тоже копируются или линкуются;
  • иерархия файлов в A и B должна быть идентична.

И при этом крайне желательно, чтобы конвертация происходила в несколько потоков.

Реализация

Начал я с поиска готовых решений, и через некоторое время наткнулся на bash-скрипт FLAC-Convert. Он изначально создавался несколько для других нужд, но в нём уже была реализована конвертация в Ogg, MP3 и AAC, многопоточность, поддержка нескольких назначений одновременно (то есть кроме каталога B, ещё C, D и т.д.). Я добавил поддержку профилей, жёстких и символических ссылок и зеркалирование. Эти изменения затем были приняты в проект.

Зависимости

FLAC-Convert использует flac для декодирования FLAC-файлов. oggenc из vorbis-tools, lame и faac (или neroAacEnc) используются для кодирования в Ogg Vorbis, MP3 и AAC соответственно. mktorrent может использоваться для создания торрентов. Все зависимости опциональны.

Использование

Для задания конфигурации используются профили. По сути профиль представляет из себя bash-скрипт, в котором устанавливаются переменные, а затем он исполняется из основного скрипта. Для своей задачи я создал файл oggmirror.prof и запускаю скрипт так:

flacconvert.sh oggmirror.prof

Файл oggmirror.prof ищется сначала в текущем каталоге, а затем в каталоге со скриптом. Можно задать и полный путь к профилю.

Содержимое файла oggmirror.prof следующее:

run_level=0

Данная опция говорит, что нужно только конвертировать файлы (FLAC-Convert ещё может создавать торрент-файлы).

basefolder=$HOME/

Относительно этого каталога будут задаваться некоторые другие пути. Следует заметить, что каталоги в скрипте везде заканчиваются слешем.

flacfolder=${basefolder}Music/

Это каталог-источник A.

hard_link_exts=( mp3 ogg wma m4a jpg jpeg png bmp txt )

На все файлы с этими расширениями в каталоге B будут создаваться жёсткие ссылки.

copy_exts=( )
sym_link_exts=( )

Списки расширений файлов для копирования и создания символических ссылок. Если вся адуио-библиотека в формате с потерями умещается на портативном плеере, то имеет смысл сразу копировать все файлы на устройство и все необходимые расширения задавать в copy_exts.

mirror=1

Данная опция говорит про необходимость удалять файлы в каталоге B, если в A их уже нет.

conv_arr[1]="OGG"
dest_arr[1]="LossyMusic/"
ext_arr[1]="ogg"
opt_arr[1]="-q 5"

В нашем случае conv_arr, кроме как в сообщениях скрипта, использоваться нигде не будет. dest_arr задаёт путь каталога B относительно basefolder. Ещё раз обращаю внимание на слеш в конце пути. ext_arr определяет неявно кодировщик и расширение конвертируемых файлов. opt_arr служит для указания опций к кодировщику. -q5 примерно соответствует битрейту 160 кбит/с. Аудио с таким битрейтом многие находят прозрачным. Чтобы задать ещё одну цель, необходимо ещё раз установить эти четыре параметра, но с другим индексом.

conv_create=0

Если установить эту переменную в 1, то в конец каждого каталога, лежащего непосредственно в B, будет добавляться [OGG] (значение из conv_arr).

coreaddition=0

FLAC-Convert запускает столько потоков, сколько ядер не загружено в данный момент. Если вдруг система загружена полностью, то FLAC-Convert по идее будет ждать, пока хотя бы одно ядро освободится. Задав coreaddition=1, скрипт всегда будет выполнять хотя бы один процесс конвертации, если даже все ядра загружены.

verbose=2

Скрипт будет выводить предупреждения, стадию выполнения и все операции с файлами. Иногда бывает полезно знать, какие файлы в данный момент удаляются :)

Остальные опции и их описание можно найти в файле default.prof, который распространяется вместе с FLAC-Convert.

Напоследок, я советую перед использованием, протестировать свою конфигурацию на тестовых файлах, прогнать скрипт несколько раз и убедиться, что всё работает так, как задумано.

Комментарии

RSS
Здесь можно Markdown