Нашел эту ветку при попытке сделать прямое кодирование 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варианты работы лучше; все метаданные записаны на месте, поэтому необходимо создать дубликат файла.