como posso extrair em lote o áudio de arquivos mp4 com ffmpeg sem descompressão (detecção automática de codec de áudio)?

19

Tenho 228 arquivos mp4 (2,6 GB) e gostaria de extrair áudio deles (mp3 ou ogg). Quero extraí-los em lote - de preferência com o bash. Não tenho certeza se todos os arquivos usam o mesmo codec de áudio gravado em anos diferentes, variando de 2006 a 2012.

Eu quero percorrer todos eles, escolher o nome do arquivo, detectar o codec de áudio e usar ffmpeg para extrair o áudio.

É possível?

wryrych
fonte
Esta é uma pergunta sobre scripts e, como tal, não tem nada a ver com o Ubuntu. Não está fora de tópico aqui, mas SO ou unix.SE pode ser um lugar melhor para perguntar.
Mahesh
Obrigado. Da próxima vez, tentarei fazer essa pergunta em um local mais apropriado.
wryrych

Respostas:

28

Você diz que deseja "extrair áudio deles (mp3 ou ogg)". Mas e se o áudio no arquivo mp4 não for um desses? você teria que transcodificar de qualquer maneira. Então, por que não deixar a detecção do formato de áudio em ffmpeg?

Para converter um arquivo:

ffmpeg -i videofile.mp4 -vn -acodec libvorbis audiofile.ogg

Para converter muitos arquivos:

for vid in *.mp4; do ffmpeg -i "$vid" -vn -acodec libvorbis "${vid%.mp4}.ogg"; done

Obviamente, você pode selecionar qualquer parâmetro ffmpeg para a codificação de áudio que desejar, para definir coisas como taxa de bits e assim por diante.

Use -acodec libmp3lamee altere a extensão de .oggpara .mp3para codificação mp3.

Se o que você deseja é realmente extrair o áudio, você pode simplesmente "copiar" a faixa de áudio para um arquivo usando -acodec copy. Obviamente, a principal diferença é que a transcodificação é lenta e exige muita CPU, enquanto a cópia é realmente rápida, pois você está apenas movendo bytes de um arquivo para outro. Veja como copiar apenas a faixa de áudio (supondo que esteja no formato mp3):

ffmpeg -i videofile.mp4 -vn -acodec copy audiofile.mp3

Observe que, nesse caso, o formato do audiofile deve ser consistente com o que o contêiner possui (por exemplo, se o áudio for no formato AAC, é preciso dizer audiofile.aac). Você pode usar o ffprobecomando para ver qual codec você possui, isso pode fornecer algumas informações:

ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "videofile.mp4"

Uma maneira possível de analisar automaticamente o codec de áudio e nomear o arquivo de áudio adequadamente seria:

mkdir -p output
# current directory has to contain at least one .mp4 file 
for vid in *.mp4; do
   codec="$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "$vid")"
   case "$codec" in
    mp3    ) filetype=mp3 ;;
    vorbis ) filetype=ogg ;;
    *      ) filetype= ;;
   esac

   if [ "$filetype" ]; then 
    ffmpeg -i "$vid" -vn -acodec copy output/"${vid%.*}"."$filetype"
   else
    ffmpeg -i "$vid" -vn -acodec libvorbis output/"${vid%.*}".ogg
done

Notas: os arquivos de saída são criados no subdiretório criado no outputinício (se necessário). Para outros codecs que não o mp3 e o vorbis, ele converte o áudio em ogg. O Ubuntu 14.04 não possui ffmpeg nos repositórios padrão, mas você pode adicionar o repositório ppa: mc3man / trusty-media e instalar o pacote ffmpeg para obter o software necessário. Veja aqui para detalhes.

roadmr
fonte
Eu coloquei errado. Eu queria ter mp3 ou ogg, mas como você notou, o codec de áudio era diferente - aac neste exemplo. Então eu tenho que transcodificá-los de qualquer maneira. Muito obrigado pela sua ajuda!
wryrych
Seu exemplo de automagia quebra com nomes de arquivos que possuem espaços, porque você não citou $ file na sub-instrução ffprobe. Alterando para: para arquivo em * mp4 * avi; faça ffmpeg -i "$ file" -vn -acodec copie "$ file". ffprobe "$file" 2>&1 |sed -rn 's/.*Audio: (...), .*/\1/p'; done Corrige isso.
precisa
+1, mas parece que esta resposta poderia usar uma atualização:This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Nicolas Raoul
ffmpegou ffprobenão está disponível para o Ubuntu 14.04 ou posterior.
Jarno
1
@jarno O real ffmpeg retornou ao Ubuntu em 15.04 , e parece com o joio do Libav avconve avprobefoi removido em 15.10 .
Llogan 18/03/16
1

Como Nicolas Raoul afirmou, isso precisa ser atualizado. Aqui está a mesma linha que roadmr deu, mas usando avconv:

for vid in *.mp4; do avconv -i "$vid" "${vid%.mp4}.mp3"; done

Scooby-2
fonte
Agora está desatualizado. O FFmpeg está de volta e o Libav se foi.
Llogan 18/03/16
Absolutamente correto. Se alguém pensou ffmpeg ia morrer, leia isto: en.wikipedia.org/wiki/Libav#Confusion
Scooby-2