Как преобразовать все файлы .wav в подкаталогах в .aac с помощью neroAacEnc?

Как преобразовать все файлы .wav в подкаталогах в .aac с помощью neroAacEnc?

У меня есть коллекция музыки в формате .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 — самый высокий.

Связанный контент