
У меня есть коллекция музыки в формате .wav, и я хотел бы конвертировать ее в .aac/.mp4 с помощью neroAacEnc.
Как это сделать? Я использую Arch Linux x86_64 и Xterm.
решение1
Вот короткая однострочная команда, которую можно ввести в терминале:
find . -name "*.wav" -print0 | while read -d $'\0' file; do neroAacEnc -2pass -q 1 -if "$file" -of "${file%wav}m4a"; done
Вы также можете использовать ffmpeg, как предлагает @slm,
find . -name "*.wav" -print0 | while read -d $'\0' file; do ffmpeg -i "$file" -c:a libfdk_aac -vbr 3 output.m4a "${file%wav}m4a"; done
Я не уверен, насколько neroAacEnc сопоставим с ffmpeg, но я знаю, что ffmpeg — это продвинутая программа, довольно популярная среди многих пользователей Linux.
Объяснение
find
— это программа, которая возвращает пути к файлам, которые соответствуют определенному свойству файла, в данном случае имени файла. Если бы вы хотели узнать только, какие файлы .wav находятся в подкаталогах вашего текущего пути, вы бы сделали find . -name "*.wav"
. Обычно это выводит каждый файл на новой строке. -print0
Вместо этого он разделяет соответствия нулевым символом. Это позволяет правильно обрабатывать имена файлов с пробелами, когда мы передаем вывод следующим командам.
Символ |
называется каналом. Он сообщает оболочке, что нужно взять вывод команды слева и передать его в качестве ввода команде справа, в данном случае команде read
внутри while
цикла.
Команда read
используется для получения выходных данных find
и присвоения их переменной "file". Обычно это присваивает значения "file" каждому слову за раз, но приводит к тому, что -d $'\0'$
назначения разделяются нулевым символом (соответствуя тому, как мы разделяли файлы find
с помощью -print0
флага).
Циклы while вызывают read
итеративное назначение значений "file" для каждого соответствующего имени файла. do
И done
являются частью стандартного синтаксиса bash для цикла while:
while <something is true>; do
<run some commands>
done
В этом случае наше "запустить некоторую команду" - это либо , ffmpeg
либо neroAacEnc
. В каждом из случаев входной файл (т. е. $file
) указывается с помощью переменной "file", которую мы назначили с помощью read
, а выходной файл (т. е. ${file%wav}w4a
) является манипуляцией этой переменной, которая позволяет нам указать другое имя для выходных данных. Обычно $file
или ${file}
оценивается как имя файла, скажемкакая-то песня.wav. %
Говорит обрезать справа от переменной любую последовательность, соответствующую символам[1] справа от %
(т.е. "wav"). Так что ${file%wav}
будет оценено каккакая-то песня., а затем «m4a» будет новым окончанием имени файла:какая-то песня.m4a.
[1] Я говорю "символы" здесь для простоты. Последовательность справа от %
может быть регулярным выражением. Например, если мы сказали, ${file%w*v}
и переменная былакакая-то песня.w1234v, он также будет оцениваться каккакая-то песня..
решение2
Не уверен насчет ключей командной строки для neroAacEnc, но что-то вроде этого:
% cd <dir where .wav files are>
% find . -type f -name '*.wav' -exec sh -c '
orgfile="$0"
newfile="$(echo "$0" | sed 's/.wav/.aac/')"
neroAacEnc $orgfile $newfile
' {} \;
Или вы можете использовать ffmpeg для выполнения преобразования (не проверено):
% cd <dir where .wav files are>
% find . -type f -name '*.wav' -exec sh -c '
orgfile="$0"
newfile="$(echo "$0" | sed 's/.wav/.aac/')"
ffmpeg -i $orgfile -ab 256 $newfile
' {} \;
Как скрипт (поместите нижеприведенное в файл)
#!/bin/bash
# myscript.bash
cd <dir where .wav files are>
find . -type f -name '*.wav' -exec sh -c '
orgfile="$0"
newfile="$(echo "$0" | sed 's/.wav/.aac/')"
neroAacEnc -2pass -q 1 -if $orgfile -of $newfile
' {} \;
После создания файла (myscript.bash) сделайте его исполняемым chmod +x myscript.bash
, запустите его ./myscript.bash
, и все готово.
Рекомендации
-Руководство по кодированию FFmpeg и AAC
ПРИМЕЧАНИЕ:Существуют дополнительные «рецепты» для конвертации .wav в .aac и получения различных качеств, характеристик и т. д.
решение3
Я бы также использовал ffmpeg. Если вы используете libfaac, он поддерживает только -aq, но не -vbr или -ab:
for f in **/*.wav; do ffmpeg -i "$f" -c:a libfaac -aq 150 "${f%wav}m4a"; done
**
требуется bash 4.0 или выше и shopt -s globstar
/или zsh. Вы можете показать информацию о файлах результатов с помощью ffmpeg -i
.
В соответствии сhttp://ffmpeg.org/trac/ffmpeg/wiki/AACEncodingGuide, собственный кодировщик (который использовался, если бы я не указал -c:a) имеет более низкое качество, чем libfaac, который, в свою очередь, имеет более низкое качество, чем libfdk_aac. --enable-libfdk_aac --enable-nonfree
(или brew install ffmpeg --with-fdk-aac
) включает поддержку libfdk_aac.
Если у вас 4 процессора, параллельно будет выполняться до 4 процессов:
find . -name \*.wav | parallel ffmpeg -i {} -c:a libfdk_aac -vbr 4.5 {.}.m4a
-vbr 0 — самый низкий, -vbr 5 — самый высокий.