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?


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.


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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.