Нашел эту ветку при попытке сделать прямое кодирование MP3 из исходных файлов FLAC. Ответ Boehj обеспечивает хороший сценарий, но я лично предпочитаю использовать FFmpeg, так что это сценарий Bash, который я придумал для выполнения этой задачи. Протестировано и прекрасно работает в macOS Sierra (10.12.2).
Преимущества: Вы должны иметь ffmpeg
и lame
уже установлены на вашем Mac. Самый простой способ сделать это через Homebrew. Сначала убедитесь, что Homebrew установлен следующим образом:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Затем запустите эту команду для установки ffmpeg
и lame
:
brew install ffmpeg lame
Как только это будет сделано, вы готовы запустить этот скрипт. Этот сценарий будет искать файлы FLAC в каталоге, path/to/FLAC/files
но это можно изменить, просто .
указав, что файлы FLAC находятся в том же каталоге, в котором вы запускаете этот сценарий. При запуске он создаст mp3/
подкаталог, в котором будут находиться все файлы MP3. размещены.
find -E "path/to/FLAC/files" -type f -iregex ".*\.(FLAC)$" |\
while read full_audio_filepath
do
# Break up the full audio filepath stuff into different directory and filename components.
audio_dirname=$(dirname "${full_audio_filepath}");
audio_basename=$(basename "${full_audio_filepath}");
audio_filename="${audio_basename%.*}";
# audio_extension="${audio_basename##*.}";
# Set the MP3
mp3_dirpath="${audio_dirname}/mp3";
mp3_filepath="${mp3_dirpath}/${audio_filename}.mp3";
# Create the child MP3 directory.
mkdir -p "${mp3_dirpath}";
# Get the track metadata.
mp3_title=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TITLE= | cut -d '=' -f 2- );
mp3_artist=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:ARTIST= | cut -d '=' -f 2- );
mp3_album=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:ALBUM= | cut -d '=' -f 2- );
mp3_year=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:YEAR= | cut -d '=' -f 2- );
mp3_track=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TRACK= | cut -d '=' -f 2- | sed 's/^0*//' );
mp3_tracktotal=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TRACKTOTAL= | cut -d '=' -f 2- | sed 's/^0*//' );
mp3_genre=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:GENRE= | cut -d '=' -f 2- );
# Where the magic happens.
ffmpeg -y -v quiet -nostdin -i "${full_audio_filepath}" -ar 44100 -sample_fmt s16 -ac 2 -f s16le -acodec pcm_s16le - | \
lame --quiet --add-id3v2 --pad-id3v2 --tt "${mp3_title}" --ta "${mp3_artist}" --tl "${mp3_album}" --tn "${mp3_track}"/"${mp3_tracktotal}" --tg "${mp3_genre}" -r -m s --lowpass 19.7 -V 3 --vbr-new -q 0 -b 96 --scale 0.99 --athaa-sensitivity 1 - "${mp3_filepath}";
done
Некоторые заметки о том, что я выучил «The Hard Way ™», чтобы другие могли извлечь выгоду из того, что я сделал по-другому в этом сценарии, по сравнению с другими в Интернете.
- Эти
grep
команды для тега синтаксического анализа ( с использованием FFprobe , который установлен с FFmpeg) нечувствительны к регистру , используя -i
опцию , чтобы сделать это grep -i
.
- Следующая
cut
команда теперь ограничена разделением вывода только на основе первого =
в имени тега с -f 2-
опцией, которая делает команду cut -d '=' -f 2-
. Например, у Pavement есть песня под названием «5-4 = Unity», и если бы только второй фрагмент был выбран посредством вырезания, этот заголовок был бы обрезан до «5-4».
- Для отслеживания и общее количество дорожек-номеров я добавил дополнительную трубу ,
sed
которая избавляется от ведущих нулей: sed 's/^0*//'
.
- В подобных сценариях по всему Интернету вывод FFmpeg является чем-то похожим,
-f wav
и это фактически сжимает вывод FFmpeg, что не имеет смысла в настройке канала, где LAME собирается перекодировать его. Вместо этого здесь устанавливается выход, -f s16le -acodec pcm_s16le
который в основном является выходом RAW; идеально подходит для передачи звука в другой процесс, как этот.
- Чтобы иметь дело с выводом RAW на стороне трубы LAME, мне пришлось добавить
-r
опцию.
- Также обратите внимание на
--tt
, --ta
, --tl
, --tn
и --tg
варианты тегов ID3v2 для LAME. Когда аудио передается / передается из одного процесса в LAME, метаданные из исходного файла теряются. Один из предложенных вариантов, чтобы получить FFmpeg сохранить метаданные в текстовый файл, установив параметр с , -f ffmetadata "[metadata filename here]"
а затем снова запустить FFmpeg с чем - то вроде этого: -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1
. Это работает, но обратите внимание на требование к файлу назначения. Похоже, FFmpeg импортирует метаданные только тогда, когда он может скопировать файл, что кажется очень расточительным процессом. Использование FFprobe для получения значений , а затем устанавливать их в LAME с --tt
, --ta
, --tl
, --tn
и --tg
варианты работы лучше; все метаданные записаны на месте, поэтому необходимо создать дубликат файла.