Como converter todos os arquivos .wav em subdiretórios para .aac usando o neroAacEnc?

Como converter todos os arquivos .wav em subdiretórios para .aac usando o neroAacEnc?

Tenho uma coleção de músicas no formato .wav e gostaria de convertê-las para .aac/.mp4 usando o neroAacEnc.

Como eu faço isso? Estou usando Arch Linux x86_64 e Xterm.

Responder1

Aqui está uma linha rápida que você pode digitar em um terminal:

find . -name "*.wav" -print0 | while read -d $'\0' file; do neroAacEnc -2pass -q 1 -if "$file" -of "${file%wav}m4a"; done

Você também pode usar ffmpeg, como sugere @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

Não tenho certeza de como o neroAacEnc se compara ao ffmpeg, mas sei que o ffmpeg é avançado e bastante popular entre muitos usuários do Linux.


Explicação

findé um programa que retorna caminhos para arquivos que correspondem a uma determinada propriedade do arquivo, neste caso o nome do arquivo. Se tudo que você quisesse saber fosse quais arquivos .wav estão nos subdiretórios do seu caminho atual, você faria find . -name "*.wav". Normalmente isso gera cada arquivo em uma nova linha. Isso -print0separa as correspondências com um caractere nulo. Isso permite o tratamento adequado de nomes de arquivos com espaços quando passamos a saída para os próximos comandos.

O |personagem é conhecido como cachimbo. Ele diz ao shell para pegar a saída do comando à esquerda e passá-la como entrada para o comando à direita, neste caso, o readcomando dentro do whileloop.

O readcomando é usado para obter a saída finde atribuí-la a uma variável, "arquivo". Normalmente, isso atribuiria valores para "arquivar" cada palavra por vez, mas -d $'\0'$faz com que as atribuições sejam delimitadas pelo caractere nulo (correspondendo à forma como delimitamos os arquivos findusando o -print0sinalizador).

Os loops while fazem com readque atribuam valores iterativamente ao "arquivo" para cada nome de arquivo correspondente. Os doe donefazem parte da sintaxe bash padrão para um loop while:

while <something is true>; do
    <run some commands>
done

Nesse caso, nosso "executar algum comando" é ffmpegou neroAacEnc. Em cada um dos casos, o arquivo de entrada (ou seja, $file) é especificado com a variável "file" que atribuímos com read, e o arquivo de saída (ou seja, ${file%wav}w4a) é uma manipulação desta variável que nos permite especificar um nome diferente para o saída. Normalmente $fileou ${file}seria avaliado como o nome do arquivo, digamosalguma música.wav. O %diz para cortar da direita da variável qualquer sequência que corresponda aos caracteres[1] à direita de %(ou seja, "wav"). Então ${file%wav}avaliaria paraalguma música., e então o "m4a" será o novo final do nome do arquivo:alguma música.m4a.


[1] Digo "personagens" aqui para simplificar. A sequência à direita de %poderia ser uma expressão regular. Por exemplo, se disséssemos ${file%w*v}e a variável fossealguma música.w1234v, também avaliariaalguma música..

Responder2

Não tenho certeza sobre a linha de comando mudar para neroAacEnc, mas algo assim:

% 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
' {} \;

Ou você poderia usar o ffmpeg para fazer a conversão (não testado):

% 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
' {} \;

Como um script (coloque o abaixo em um arquivo)

#!/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
' {} \;

Depois de criar o arquivo (myscript.bash), torne-o executável chmod +x myscript.bash, execute-o ./myscript.bashe pronto.

Referências

-Guia de codificação FFmpeg e AAC

OBSERVAÇÃO:Existem "receitas" adicionais para converter .wav em .aac e obter diferentes qualidades, características, etc.

Responder3

Eu também usaria o ffmpeg. Se você usa libfaac, ele suporta apenas -aq e não -vbr ou -ab:

for f in **/*.wav; do ffmpeg -i "$f" -c:a libfaac -aq 150 "${f%wav}m4a"; done

**requer bash 4.0 ou superior e shopt -s globstar/ou zsh. Você pode mostrar informações sobre os arquivos de resultados com a extensão ffmpeg -i.

De acordo comhttp://ffmpeg.org/trac/ffmpeg/wiki/AACEncodingGuide, o codificador nativo (que foi usado se eu não especifiquei -c:a) é de qualidade inferior ao libfaac, que é de qualidade inferior ao libfdk_aac. --enable-libfdk_aac --enable-nonfree(ou brew install ffmpeg --with-fdk-aac) inclui suporte para libfdk_aac.

Se você tiver 4 CPUs, até 4 processos serão executados em paralelo:

find . -name \*.wav | parallel ffmpeg -i {} -c:a libfdk_aac -vbr 4.5 {.}.m4a

-vbr 0 é o mais baixo, -vbr 5 é o mais alto.

informação relacionada