comment puis-je extraire l'audio par lots des fichiers mp4 avec ffmpeg sans décompression (détection automatique du codec audio)?

19

J'ai 228 fichiers mp4 (2,6 Go) et je voudrais en extraire l'audio (mp3 ou ogg). Je veux les extraire par lots - de préférence avec bash. Je ne sais pas si tous les fichiers utilisent le même codec audio qu'ils ont été enregistrés au cours d'années différentes, allant de 2006 à 2012.

Je veux les parcourir tous, choisir le nom du fichier, détecter le codec audio et utiliser ffmpeg pour extraire l'audio.

C'est possible?

wryrych
la source
Il s'agit d'une question de script et en tant que telle n'a rien à voir avec Ubuntu. Ce n'est pas hors sujet ici, mais SO ou unix.SE pourrait être un meilleur endroit pour demander.
Mahesh
Merci. La prochaine fois, j'essaierai de poser une telle question à un endroit plus approprié.
Wryrych

Réponses:

29

Vous dites que vous voulez "en extraire l'audio (mp3 ou ogg)". Mais que faire si l'audio du fichier mp4 n'en fait pas partie? il faudrait quand même transcoder. Alors pourquoi ne pas laisser la détection du format audio à ffmpeg?

Pour convertir un fichier:

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

Pour convertir de nombreux fichiers:

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

Vous pouvez bien sûr sélectionner tous les paramètres ffmpeg pour l'encodage audio que vous aimez, pour définir des choses comme le débit binaire, etc.

Utilisez -acodec libmp3lameet modifiez l'extension de .oggà .mp3pour l'encodage mp3.

Si vous voulez vraiment extraire l'audio, vous pouvez simplement "copier" la piste audio dans un fichier en utilisant -acodec copy. Bien sûr, la principale différence est que le transcodage est lent et gourmand en CPU, tandis que la copie est très rapide car vous ne faites que déplacer des octets d'un fichier à un autre. Voici comment copier uniquement la piste audio (en supposant qu'elle soit au format mp3):

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

Notez que dans ce cas, le format du fichier audio doit être cohérent avec ce que contient le conteneur (c'est-à-dire si l'audio est au format AAC, vous devez le dire audiofile.aac). Vous pouvez utiliser la ffprobecommande pour voir quel codec vous avez, cela peut fournir des informations:

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

Une façon possible d'analyser automatiquement le codec audio et de nommer le fichier audio en conséquence serait:

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

Remarques: les fichiers de sortie sont créés dans le sous-répertoire outputqu'il crée au début (si nécessaire). Pour les autres codecs que mp3 et vorbis, il convertit l'audio en ogg. Ubuntu 14.04 n'a pas ffmpeg dans les référentiels standard, mais vous pouvez ajouter le référentiel ppa: mc3man / trusty-media et installer le package ffmpeg pour obtenir le logiciel nécessaire. Voir ici pour plus de détails.

roadmr
la source
Je me trompe. Je voulais avoir du mp3 ou de l'ogg mais comme vous l'avez remarqué, le codec audio était différent - aac dans cet exemple. Je dois donc les transcoder de toute façon. Merci beaucoup pour votre aide!
wryrych
Votre exemple automagique rompt avec les noms de fichiers qui contiennent des espaces parce que vous n'avez pas cité $ file dans la sous-instruction ffprobe. Le changer en: pour le fichier dans * mp4 * avi; faire ffmpeg -i "$ file" -vn -acodec copier "$ file". ffprobe "$file" 2>&1 |sed -rn 's/.*Audio: (...), .*/\1/p'; done Corrige cela.
Andrew Beals
+1 mais il semble que cette réponse pourrait utiliser une mise à jour:This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Nicolas Raoul
ffmpegou ffprobene sont pas disponibles pour Ubuntu 14.04 ou version ultérieure.
jarno
1
@jarno Le réel ffmpeg est revenu sur Ubuntu en 15.04 , et il ressemble à la balle Libav avconvet avprobea été supprimé en 15.10 .
llogan
1

Comme Nicolas Raoul l'a déclaré, cela doit être mis à jour. Voici la même ligne que roadmr a donnée mais en utilisant avconv à la place:

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

Scooby-2
la source
C'est maintenant dépassé. FFmpeg est de retour et Libav est parti.
llogan
Absolument correct. Si quelqu'un pensait que ffmpeg allait mourir, lisez ceci: en.wikipedia.org/wiki/Libav#Confusion
Scooby-2