¿Cómo puedo extraer audio por lotes de archivos mp4 con ffmpeg sin descompresión (detección automática de códec de audio)?

19

Tengo 228 archivos mp4 (2.6GB) y me gustaría extraer audio de ellos (mp3 u ogg). Quiero extraerlos por lotes, preferiblemente con bash. No estoy seguro de si todos los archivos usan el mismo códec de audio que se grabaron en diferentes años, desde 2006-2012.

Quiero recorrer todos ellos, elegir el nombre del archivo, detectar el códec de audio y usar ffmpeg para extraer el audio.

¿Es posible?

wryrych
fuente
Esta es una pregunta de secuencias de comandos y, como tal, no tiene nada que ver con Ubuntu. No está fuera de tema aquí, pero SO o unix.SE podría ser un mejor lugar para preguntar.
Mahesh
Gracias. La próxima vez intentaré hacer esa pregunta en el lugar más apropiado.
wryrych

Respuestas:

29

Dices que quieres "extraer audio de ellos (mp3 u ogg)". Pero, ¿qué pasa si el audio en el archivo mp4 no es uno de esos? tendrías que transcodificar de todos modos. Entonces, ¿por qué no dejar la detección del formato de audio en ffmpeg?

Para convertir un archivo:

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

Para convertir muchos archivos:

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

Por supuesto, puede seleccionar cualquier parámetro ffmpeg para la codificación de audio que desee, para establecer cosas como la tasa de bits, etc.

Use -acodec libmp3lamey cambie la extensión de .ogga .mp3para codificación de mp3.

Si lo que quiere es realmente extraer el audio, simplemente puede "copiar" la pista de audio a un archivo usando -acodec copy. Por supuesto, la principal diferencia es que la transcodificación es lenta e intensiva en CPU, mientras que la copia es realmente rápida, ya que solo está moviendo bytes de un archivo a otro. Aquí se explica cómo copiar solo la pista de audio (suponiendo que esté en formato mp3):

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

Nótese que en este caso, el formato de archivo de audio tiene que ser coherente con lo que dispone el recipiente (es decir, si el audio está en formato AAC, que tiene que decir audiofile.aac). Puede usar el ffprobecomando para ver qué códec tiene, esto puede proporcionar alguna información:

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

Una posible forma de analizar automáticamente el códec de audio y nombrar el archivo de audio en consecuencia sería:

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: los archivos de salida se crean en el subdirectorio outputque crea al principio (si es necesario). Para otros códecs que no sean mp3 y vorbis, convierte el audio a ogg. Ubuntu 14.04 no tiene ffmpeg en los repositorios estándar, pero puede agregar el repositorio ppa: mc3man / trusty-media e instalar el paquete ffmpeg para obtener el software necesario. Ver aquí para más detalles.

roadmr
fuente
Lo puse mal. Quería tener mp3 u ogg, pero como notaron, el códec de audio era diferente: aac en este ejemplo. Así que tengo que transcodificarlos de todos modos. ¡Muchas gracias por su ayuda!
wryrych
Su ejemplo automágico se rompe con nombres de archivo que tienen espacios en ellos porque no citó $ file en la subdeclaración ffprobe. Cambiándolo a: para archivo en * mp4 * avi; do ffmpeg -i "$ archivo" -vn -acodec copia "$ archivo". ffprobe "$file" 2>&1 |sed -rn 's/.*Audio: (...), .*/\1/p'; hecho Corrige eso.
Andrew Beals
+1 pero parece que esta respuesta podría usar una actualización:This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Nicolas Raoul
ffmpego ffprobeno están disponibles para Ubuntu 14.04 o posterior.
jarno
1
@jarno El real ffmpeg regresó a Ubuntu en 15.04 , y se parece a la paja de Libav avconvy avprobese ha eliminado en 15.10 .
llogan
1

Como dijo Nicolas Raoul, esto necesita una actualización. Aquí está la misma línea que dio roadmr pero usando avconv en su lugar:

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

Scooby-2
fuente
Esto ahora está desactualizado. FFmpeg está de vuelta y Libav se ha ido.
llogan
Absolutamente correcto. Si alguien pensó que ffmpeg iba a morir, lea esto: en.wikipedia.org/wiki/Libav#Confusion
Scooby-2