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

5

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

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

    
por OMGtechy 21.04.2013 / 21:16

3 respostas

5

Aqui está um verso simples que você pode digitar em um terminal:

find . -name "*.wav" -print0 | while read -d $'
find . -name "*.wav" -print0 | while read -d $'
while <something is true>; do
    <run some commands>
done
' file; do ffmpeg -i "$file" -c:a libfdk_aac -vbr 3 output.m4a "${file%wav}m4a"; done
' file; do neroAacEnc -2pass -q 1 -if "$file" -of "${file%wav}m4a"; done

Você também pode usar o ffmpeg, como sugere o @slm,

find . -name "*.wav" -print0 | while read -d $'
find . -name "*.wav" -print0 | while read -d $'
while <something is true>; do
    <run some commands>
done
' file; do ffmpeg -i "$file" -c:a libfdk_aac -vbr 3 output.m4a "${file%wav}m4a"; done
' file; do neroAacEnc -2pass -q 1 -if "$file" -of "${file%wav}m4a"; done

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

Explicação

find é um programa que retorna caminhos para arquivos que correspondem a uma determinada propriedade de arquivo, neste caso, o nome do arquivo. Se tudo o que você queria saber era quais arquivos .wav estão em subdiretórios do caminho atual, você faria find . -name "*.wav" . Normalmente isso gera cada arquivo em uma nova linha. O -print0 separa 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 caractere | é conhecido como um pipe. Ele diz ao shell para obter a saída do comando à esquerda e passá-lo como entrada para o comando à direita, neste caso, o comando read dentro do loop while .

O comando read é usado para obter a saída de find e atribuí-la a uma variável, "file". Normalmente, isso designaria valores para "file" a cada palavra por vez, mas o -d $'find'$ faz com que as atribuições sejam delimitadas pelo caractere nulo (correspondendo como delimitamos os arquivos em -print0 usando o read flag).

Os loops while fazem com que do atribua iterativamente valores a "file" para cada nome de arquivo correspondente. Os done e ffmpeg fazem parte da sintaxe bash padrão para um loop while:

%pre%

Nesse caso, nosso "executar algum comando" é neroAacEnc ou $file . Em cada um dos casos, o arquivo de entrada (ou seja, read ) é especificado com a variável "file" que atribuímos com ${file%wav}w4a , e o arquivo de saída (ie, $file ) é uma manipulação dessa variável nos permite especificar um nome diferente para a saída. Normalmente, ${file} ou % avaliaria o nome do arquivo, digamos algum song.wav . O % diz para cortar da direita da variável qualquer sequência que coincida com os caracteres [1] para a direita do ${file%wav} (ou seja, "wav"). Então, % iria avaliar alguma música. , e então o "m4a" estaria lá para ser o novo final do nome do arquivo: alguma música.m4a .

[1] Eu digo "personagens" aqui por simplicidade. A sequência à direita do ${file%w*v} pode ser uma expressão regular. Por exemplo, se disséssemos %code% e a variável fosse algum song.w1234v , também seria avaliada para alguma música. .

    
por 21.04.2013 / 21:51
2

Não tenho certeza sobre a linha de comando muda para o 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ê pode 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 ./myscript.bash e pronto.

Referências

- Guia de codificação do FFmpeg e AAC

NOTA: Existem "receitas" adicionais para converter .wav para .aac e obter diferentes qualidades, características, etc.

    
por 21.04.2013 / 21:31
2

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 o bash 4.0 ou superior e shopt -s globstar ou zsh. Você pode mostrar informações sobre os arquivos de resultados com ffmpeg -i .

De acordo com o link , o codificador nativo (que foi usado se eu não especificasse -c: a ) é de qualidade inferior à libfaac, que é de qualidade inferior à libfdk_aac. --enable-libfdk_aac --enable-nonfree (ou brew install ffmpeg --with-fdk-aac ) inclui suporte para libfdk_aac.

Se você tem 4 CPUs, isso gera até 4 processos 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.

    
por 22.04.2013 / 01:11