Conversion par lots H.265 mkv en H.264 avec ffmpeg pour rendre les fichiers compatibles pour le ré-encodage

31

J'ai des fichiers encodés H.265 qui sont tellement gourmands en ressources qu'ils ne fonctionnent pas bien et mon logiciel de conversion (mencoder) ne prend pas (actuellement) en charge le format H.265. Puis-je les convertir en H.264 dans un fichier de commandes en ligne de commande pour convertir rapidement les fichiers à recompresser à l'aide de Devede / OGMrip? Lors de la recherche sur ce site, je ne l'ai pas trouvé discuté, donc je posterai ce que je pense être une question utile et une réponse à la question.

TheMegolith
la source

Réponses:

37

Oui, en utilisant ffmpeg.

Ouvrez un terminal et dirigez-le vers le répertoire contenant les fichiers encodés H.265, en supposant que vous avez ffmpeginstallé les bibliothèques appropriées et en supposant qu'elles sont au format MKV, copiez et collez ce qui suit dans la fenêtre du terminal.

INPUT="$1"
for i in *.mkv ; do
    ffmpeg -i "$i" -bsf:v h264_mp4toannexb -sn -map 0:0 -map 0:1 -vcodec libx264 "$i.ts"
    mv "$i.ts" "$i.mpg"
    sleep 3
done

Voilà. Cela se convertira en h.264 dans un conteneur MPG dans le même répertoire.

Explication des commutateurs de commande:

  • for i in *.mkv ; do ... done

    Cela configure tous les fichiers .mkv dans un répertoire à inclure dans le processus par lots. Cela peut être modifié pour s'adapter à l'extension du conteneur des fichiers que vous souhaitez traiter.

  • ffmpeg -i "$i" Exécute le programme ffmpeg et appelle le traitement des fichiers.

    • -bsf:v active le filtre de flux vidéo à utiliser.

    • h264_mp4toannexb - Est le filtre de flux binaire qui est activé.

      Convertir un flux binaire H.264 du mode préfixé de longueur en mode de préfixe de code de démarrage (tel que défini dans l'Annexe B de la spécification UIT-T H.264).

      Ceci est requis par certains formats de streaming, généralement le format de flux de transport MPEG-2 ( mpegts) traitant MKV h.264 (actuellement) l'exige, s'il n'est pas inclus, vous obtiendrez une erreur dans la fenêtre du terminal vous demandant de l'utiliser.

    • -sn arrête la diffusion des flux de sous-titres (pour ceux qui ne veulent pas de sous-titres dans leur vidéo). Ceci est facultatif et peut être supprimé.

    • -map 0:0 -map 0:1Indique à ffmpeg de ne traiter que les deux premiers flux du fichier ( 0:0c'est le flux vidéo, 0:1c'est le premier flux audio du fichier). Cela fait deux choses, supprime les flux audio en excès, généralement le premier flux audio est en anglais mais pas toujours. D'autres flux tels que les sous-titres intégrés sont supprimés, ce qui réduit la taille du fichier. Il s'agit également d'une chaîne facultative. Vous pouvez utiliser ffprobepour afficher les flux disponibles dans le fichier. -mapest facultatif et peut être supprimé de la commande.

    • -vcodec libx264 Cela indique à ffmpeg de coder la sortie en H.264

    • "$i.ts" Enregistre la sortie au format .ts, ceci est utile pour ne pas écraser vos fichiers source.

  • mv "$i.ts" "$i.mpg"Convertit l'extension de fichier en MPG dans le même répertoire. Cela peut être configuré pour l'envoyer à n'importe quel répertoire que vous aimez.

  • sleep 3 - permet au processus de se reposer en donnant à ffmpeg le temps de mettre en file d'attente le fichier suivant

TheMegolith
la source
3
Excellent! Nous pouvons maintenant supprimer les commentaires sous la question. Je dirais que le sleep 3n'est pas nécessaire (mais peut être utile pour terminer la boucle) et INPUT=$1n'a aucun sens puisque vous l'exécutez directement dans un shell interactif.
muru
11
Envisagez de copier le flux audio avec -c:a copyau lieu de ré-encoder. En outre, 0:0ne fait pas toujours référence à la vidéo et 0:1ne fait pas toujours référence à l'audio. Vous pouvez utiliser un spécificateur de flux pour éviter les problèmes potentiels: -map 0:v -map 0:asi vous voulez que tous les flux vidéo et audio de l'entrée 0, ou -map 0:v:0 -map 0:a:0si vous ne voulez que les premiers flux vidéo et audio de l'entrée 0. Si vous ne voulez que le flux audio anglais: -map 0:m:language:eng(en supposant qu'il est étiqueté).
llogan
1
@LordNeckbeard Je voterai pour que vous écriviez une réponse complète.
Fran Marzoa
1
@Fran N'a pas remarqué qu'il y avait autant de votes positifs sur ce commentaire. J'ai ajouté une réponse en utilisant des méthodes plus simples, moins sujettes aux erreurs et plus efficaces.
llogan
1
J'irais totalement avec simplement ffmpeg -i $INPUT -vcodec h264 -acodec copy $OUTPUT. Quelque chose que j'utilise tous les jours et que je peux mémoriser par opposition à ce barrage de drapeaux sans signification pour lequel chaque réponse ffmpeg est si tristement célèbre.
Ben Sinclair
20

Conversion par lots de H.265 en H.264

Ces exemples ont été écrits récemment ffmpeg. Épargnez-vous des ennuis et téléchargez une version récente. Ensuite, mettez le ffmpegbinaire dans ~/binou /usr/local/bin(vous devrez peut-être vous déconnecter puis vous connecter pour qu'il soit remarqué).

Sortie Matroska

mkdir h264vids
for f in *.mp4; do ffmpeg -i "$f" -map 0 -c copy -c:v libx264 -crf 23 -preset medium h264vids/"${f%.*}.mkv"; done
  • Cet exemple sortira dans un répertoire nommé h264vids.

  • Cet exemple suppose que vos entrées le sont .mp4. Sinon, changez l' .mp4instance de l'exemple en votre type de fichier d'entrée, ou utilisez simplement le gourmand *par lui-même.

  • Ajustez la -crfqualité et la -presetvitesse / efficacité d'encodage. Ou supprimez simplement ces options et utilisez les valeurs par défaut qui sont assez bonnes et devraient suffire pour la plupart (l'exemple utilise les valeurs par défaut pour ces options). Voir FFmpeg Wiki: H.264 pour plus d'informations sur ces options.

Sortie MP4

Celui-ci est un peu plus compliqué. Cela effectuera un codage conditionnel selon que l'audio d'entrée est AAC ou non. Si l'audio d'entrée est AAC, l'audio sera copié (re-multiplexé) tel quel et un ré-encodage inutile est évité. Si l'audio d'entrée n'est pas AAC, il sera recodé en AAC.

Voici un script simple montrant comment procéder à l'aide de ffprobeet ffmpeg. Copiez-le et enregistrez-le dans le répertoire contenant vos vidéos à convertir, donnez-lui l'autorisation d'exécution avec chmod +x yourscriptname, puis exécutez-le avec ./yourscriptname.

#!/bin/bash

mkdir h264vids

for f in *.mkv
do
  audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
  if [ "$audioformat" = "aac" ]; then
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a copy -movflags +faststart h264vids/"${f%.*}.mp4"
  else
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart h264vids/"${f%.*}.mp4"
  fi
done
  • Cet exemple sortira dans un répertoire nommé h264vids.

  • Cet exemple suppose que vos entrées le sont .mkv. Sinon, changez l' .mkvinstance de l'exemple en votre type de fichier d'entrée, ou utilisez simplement le gourmand *par lui-même.

  • Voir la note ci-dessus concernant -crfet -preset.

  • Vous pouvez suspendre l'encodage avec ctrl+ zet reprendre avec fg.

llogan
la source
1

Compte tenu des réponses précédentes, j'ai trouvé ce qui suit:

for file in *265.mkv; do nice -n19 ffmpeg -i $file -c copy -c:v libx264 ${file/%265.mkv/264.mkv}; done

Cela suppose que les fichiers ont toujours un nom se terminant par 265.mkv. Cette fin sera remplacée par 264.mkv.

Si le nom de votre fichier est différent, vous devez adapter la commande en conséquence.

kerner1000
la source
C'est une excellente réponse qui, je pense, devrait être votée plus haut en raison de son utilisation pertinente de la substitution de paramètres Bash.
Sysinfo.io Il y a