La meilleure façon de faire pivoter par lots 3000+ vidéos h.264?

8

J'ai environ 3000 courts clips vidéo, chacun d'environ 3 secondes. J'ai besoin de faire pivoter chacun d'eux de 90 degrés. Quelle est la meilleure façon de procéder? J'ai un abonnement Adobe Creative Cloud, ainsi qu'un accès aux machines Windows et Mac. Vous cherchez la solution la plus simple pour automatiser / traiter par lots la rotation de tant de vidéos.

Si vous vous posiez la question - les vidéos font partie d'un cours en ligne sur le bois d'oeuvre. L'apprenant regarde chaque vidéo sélectionnée au hasard, qui n'est qu'un court extrait d'un morceau de bois en rotation. Les vidéos ont été tournées de façon à ce que le bois (2x4, etc.) soit horizontal. Mais maintenant, le client veut que le bois soit vertical dans les clips.

user172586
la source
Seule rotation? Par exemple de 1280x720 à 720x1280 non?
p2 ou
Juste une rotation de 90 degrés dans le sens horaire (ou contre cw - peu importe pour ce projet).
user172586
Le conteneur de vos fichiers vidéo comprend-il une métadonnée «d'orientation»?
audionuma

Réponses:

9

Utilisez ffmpeget le filtre "transposer" comme suggéré "pauvre" . Par exemple, si vos fichiers sont mp4 et se trouvent dans le répertoire courant:

mkdir -p rotated
for f in *.mp4; do ffmpeg -i "$f" -vf transpose=2 -c:a copy -metadata:s:v rotate="" rotated/"$f"; done
  • La valeur de transposition peut être "1" ou "horloge" pour une rotation dans le sens horaire, "2" ou "cclock" pour une rotation dans le sens antihoraire. Il existe d'autres valeurs qui appliqueront également un flip.

  • Le son sera copié en flux pour éviter un ré-encodage inutile.

  • Les métadonnées de rotation du flux vidéo sont effacées dans cet exemple. Sinon, il ffmpegsera copié de l'entrée vers la sortie, ce qui entraînera une rotation incorrecte pour les joueurs qui prêtent attention à ces métadonnées (certains le font et d'autres pas).

Un autre exemple, plus détaillé et plus flexible, et qui conserve le fichier pivoté dans le même répertoire avec un nouveau nom:

ext=mp4
for f in /some/dir/*.$ext; do
    new=${f/%.$ext/-rotated.$ext};
    ffmpeg -i "$f" -vf transpose=2 -c:a copy -metadata:s:v rotate="" "$new"
done
mivk
la source
Oui! Je devrais en savoir plus sur les scripts bash :)
p2or
1

Vous avez spécifié que vous êtes intéressé à travailler sur un grand nombre de vidéos, si vous avez une machine multicœur et que vous utiliserez une forboucle normale fournie par votre shell, l'un de vos cœurs fonctionnera à chaud, tandis que d'autres ne feront absolument rien . Ce n'est pas l' idéal.

Ce que vous devriez faire pour un tel travail, c'est d'utiliser parallelun outil qui vous permet de démarrer plusieurs travaux à la fois, et il peut faire tout ce qu'une boucle for peut faire, mais mieux.

Je n'écrirai pas sur toutes les fonctionnalités de cet outil, mais je me concentrerai sur votre tâche spécifique.

Une façon de démarrer tous ces emplois serait:

parallel avconv -i "{}" -vf transpose=2 "{.}[rotated].mp4" ::: *.mp4

Ici {}remplace chaque nom de fichier et {.}remplace le nom de fichier sans extension.

Je proposerai que vous commenciez autant de travaux que vous avez de noyaux, enlevez-en un. La raison en est que votre système d'exploitation restera toujours utilisable, et cela vous évitera également si vous utilisez le chiffrement du disque dur (qui utilisera la puissance de traitement pour lire / écrire des données). Pour ce faire, ajoutez simplement --jobs -1à votre ligne de commande et vous limiterez le nombre de travaux.

parallel --jobs -1 avconv -i "{}" -vf transpose=2 "{.}[rotated].mp4" ::: *.mp4

Veuillez garder à l'esprit qu'aucune sortie ne sera donnée avant la fin de chaque encodage. Vous ne verrez donc pas à quel point chacune de vos vidéos est réalisée.

v010dya
la source
1

Sur la base de cette réponse, vous pouvez utiliser ffmpeg avec les commandes suivantes pour faire pivoter une vidéo:

ffmpeg -i input -vf transpose=2 output

Pour traiter par lots un dossier de films, vous pouvez utiliser un langage de programmation de votre choix et parcourir les fichiers. J'ai utilisé linux avec python 2.7+ ici. Il vous suffit de modifier le folder_movieschemin path_to_ffmpeget de définir votre film extension:

import os # import os module
import subprocess # import subprocess module

# set the path to your video folder
folder_movies = '/home/user/Desktop/test/'

# set ffmpeg path
path_to_ffmpeg = "/opt/ffmpeg/ffmpeg"

# set file extension
ext = ".mp4"

# collect all videos in folder_movies
movie_files = [f for f in os.listdir(folder_movies) if f.endswith(ext)] 

# iterate through the files
for i in movie_files:

    # setup correct filepath for mov's
    file_path = os.path.join(folder_movies,i)

    # generate new file path
    new_path = os.path.splitext(file_path)[0] + '_rotated_90' + ext

    # call ffmpeg with the correct arguments
    # command: ffmpeg -i input -vf transpose=2 output
    subprocess.call([path_to_ffmpeg, "-i",  file_path, "-vf", "transpose=2", "-c:a", "copy", new_path])

Ensuite, votre dossier de film devrait ressembler à:

entrez la description de l'image ici

L'avantage d'utiliser python est que le code s'exécute sur plusieurs plateformes . La seule chose que vous devez considérer sont les chemins vers le répertoire et l'exécutable ffmpeg. Pour exécuter cela sur une machine Windows, il vous suffit de remplacer les chemins d'accès par quelque chose comme:

# folder_movies = '/home/user/Desktop/test/' # linux or osx
folder_movies = r'c:\some\directory\test'    # windows, the r is important
folder_movies = 'c:/some/directory\test'     # windows (alternative)

# path_to_ffmpeg = '/opt/ffmpeg/ffmpeg'            # linux or osx
path_to_ffmpeg = r'c:\Program Files\ffmpeg\ffmpeg' # windows, the r is important
path_to_ffmpeg = 'c:/Program Files/ffmpeg\ffmpeg'  # windows (alternative)

Remarque: je ne suis pas un expert de ffmpeg, il existe peut-être un moyen de traiter par lots directement avec lui.

p2or
la source
1
Vous n'avez pas vraiment besoin d'un script complet pour cela. Cela peut être fait directement sur la ligne de commande Mac ou Linux avec quelque chose comme: mkdir -p rotated; for f in *.mp4; do ffmpeg -i "$f" -vf transpose=2 rotated/"$f"; done(en supposant que vos fichiers vidéo sont .mp4 dans cet exemple).
mivk
@mivk nice, pourquoi ne pas convertir cela en réponse?
p2 ou
@mivk Puisque vous utilisez une boucle for, c'est presque la même chose. Pour ceux qui n'utilisent pas linux ou osx, il est logique d'utiliser python ou un autre langage de script.
p2 ou
@poor: eh bien, pour les utilisateurs qui ne sont ni sur linux ni sur mac, la traduction dans PowerShell est "laissée comme exercice pour le lecteur" ... :-)
mivk
@mivk hehe, oui, mais personne ne veut l'utiliser;)
p2or