Points clés à retenir
- Passez un tableau d’arguments plutôt que d’interpoler les données saisies par l’utilisateur dans une commande shell.
- Inspectez les fichiers d’entrée avant de sélectionner des flux ou de présumer leurs dimensions, leur durée et leurs codecs.
- Capturez le statut de sortie et stderr, et fixez une limite de temps explicite pour chaque processus.
Python pilote généralement FFmpeg comme processus enfant ou par l’intermédiaire d’une surcouche ; FFmpeg effectue toujours le traitement des médias. Les décisions techniques importantes concernent la sécurité des arguments, les limites de ressources, la progression, l’annulation, les fichiers temporaires et la reproductibilité.
L’essentiel
- Écrivez les fichiers de sortie de manière atomique et supprimez les fichiers temporaires en cas de réussite, d’échec ou d’annulation.
- Tenez compte du processeur, de la mémoire, du disque et des encodages simultanés dans la planification de la capacité.
Comprendre la séparation entre Python et FFmpeg
FFmpeg est le moteur de traitement des médias. Python le lance normalement comme processus enfant, lui fournit des arguments, surveille son exécution et valide les résultats. Une surcouche peut faciliter la construction des commandes, mais elle ne dispense pas de comprendre les flux, les codecs, les conteneurs, les filtres, le statut de sortie, la consommation de ressources et le comportement de la version de FFmpeg.
Commencez avec une seule commande fixe et un petit fichier de test dont la durée, les dimensions et les flux attendus sont connus. Pendant sa mise au point, exécutez cette même commande directement dans un terminal, puis reproduisez-la avec Python. Figez ou consignez la compilation de FFmpeg utilisée, car les encodeurs, les filtres, les valeurs par défaut et la prise en charge du matériel peuvent varier d’une machine à l’autre.
Utiliser subprocess pour la transparence
Une liste d’arguments correspond directement à la commande exécutée et facilite le débogage à l’aide de la documentation de FFmpeg.
Utiliser une surcouche de manière sélective
Une surcouche peut aider à composer des graphes, mais elle ajoute une API et une couche de gestion des versions que les équipes de production doivent également tester.
Exécuter des commandes sans shell
Passez les arguments sous forme de séquence à subprocess plutôt que d’interpoler une chaîne de commande et d’activer un shell. Chaque nom de fichier contenant des espaces reste alors un seul argument, et les métacaractères du shell ne deviennent pas de la syntaxe exécutable. Gardez le chemin de l’exécutable et les options prises en charge sous le contrôle de l’application.
N’acceptez jamais de codecs, de filtres, de chemins de sortie ou d’arguments supplémentaires arbitraires provenant d’un appelant non fiable. Validez les opérations demandées à l’aide d’une liste d’autorisation restreinte et traduisez-les en séquences d’arguments connues. Résolvez les chemins d’entrée et de sortie dans des répertoires contrôlés, rejetez les tentatives de traversée de répertoires et évitez de placer des secrets dans les arguments de commande susceptibles d’apparaître dans les listes de processus ou les journaux.
from pathlib import Path
import subprocess
import tempfile
def make_preview(source: Path, destination: Path) -> None:
destination.parent.mkdir(parents=True, exist_ok=True)
with tempfile.NamedTemporaryFile(
dir=destination.parent,
prefix=f".{destination.name}.",
suffix=".mp4",
delete=False,
) as temporary:
workfile = Path(temporary.name)
try:
subprocess.run(
[
"ffmpeg", "-nostdin", "-hide_banner", "-v", "error",
"-i", str(source),
"-map", "0:v:0", "-map", "0:a:0?",
"-c:v", "libx264", "-crf", "23",
"-c:a", "aac", "-b:a", "128k",
"-movflags", "+faststart",
"-f", "mp4",
"-y", str(workfile),
],
check=True,
timeout=300,
)
workfile.replace(destination)
finally:
workfile.unlink(missing_ok=True)Capturer les informations de diagnostic
Enregistrez le statut de sortie et un volume limité de la sortie stderr avec un identifiant de tâche, tout en masquant les chemins privés et les données utilisateur.
Éviter shell=True
Un shell élargit la surface d’attaque et n’est pas nécessaire pour une exécution ordinaire de FFmpeg.
Inspecter les fichiers d’entrée avant le traitement
Utilisez ffprobe pour obtenir les informations sur le conteneur et les flux au format JSON exploitable par machine. Validez la structure issue de l’analyse, car la durée, la fréquence d’images, les balises de langue, la rotation et même les flux attendus peuvent être absents ou incohérents. Sélectionnez explicitement les flux plutôt que de supposer que le premier flux vidéo ou audio correspond au contenu souhaité.
L’inspection aide à prendre de meilleures décisions, mais ne rend pas un fichier sûr. Appliquez des limites indépendantes à la taille des téléversements, à la durée, au nombre de pixels, au nombre de flux et aux formats acceptés. Tenez compte du coût de la décompression et du décodage, pas seulement du nombre d’octets compressés. Un petit fichier malformé ou inhabituellement complexe peut tout de même consommer beaucoup de ressources processeur, de mémoire ou d’espace disque temporaire.
import json
import subprocess
result = subprocess.run(
[
"ffprobe", "-v", "error", "-show_streams", "-show_format",
"-of", "json", "input.mov",
],
check=True,
capture_output=True,
text=True,
timeout=30,
)
metadata = json.loads(result.stdout)Valider les hypothèses
Rejetez ou orientez vers un autre traitement les fichiers dépourvus des flux vidéo ou audio requis, plutôt que de laisser une commande ultérieure échouer de manière ambiguë.
Inspecter aussi les résultats
Un code de sortie égal à zéro ne prouve pas que le fichier de sortie possède les flux, les dimensions, la durée ou le comportement de lecture requis.
Construire explicitement les opérations courantes sur les médias
L’extraction audio place le flux audio sélectionné dans un nouveau conteneur, en le copiant ou en le réencodant. La conversion de format peut se limiter à un remultiplexage lorsque les codecs conviennent déjà, ou nécessiter un transcodage complet dans le cas contraire. La compression exige de choisir le codec, la qualité cible, la résolution, la fréquence d’images, les paramètres audio et le temps d’encodage acceptable.
La découpe temporelle peut utiliser des arguments d’horodatage, mais sa précision et sa vitesse dépendent de la copie ou du réencodage des flux au voisinage des images clés. La fusion nécessite des fichiers d’entrée compatibles ou une passe de normalisation délibérée. L’extraction de vignettes et d’images nécessite de limiter leur nombre et leurs dimensions, car l’écriture de chaque image d’une longue vidéo peut créer des milliers de fichiers et épuiser l’espace disque.
Nommer les sorties selon leur usage
Utilisez des types de résultats explicites tels que lecture, audio, affiche, aperçu ou archive plutôt que des noms de fichiers convertis ambigus.
Garder les commandes déterministes
Précisez les correspondances et les options d’encodage importantes plutôt que de dépendre de valeurs par défaut susceptibles de changer d’une compilation à l’autre.
Signaler la progression, les échéances et l’annulation
FFmpeg écrit des diagnostics utiles sur stderr, mais ses informations d’état destinées à la lecture humaine constituent une interface fragile pour un programme. Pour obtenir une progression structurée, utilisez le protocole de progression de FFmpeg via un tube ou un descripteur de fichier et analysez les mises à jour documentées sous forme de paires clé-valeur. Comparez la durée traitée à une durée d’entrée validée et indiquez que le résultat est une estimation lorsque la durée manque ou que le traitement n’est pas linéaire.
Fixez une échéance explicite pour chaque tâche. En cas de dépassement du délai ou d’annulation par l’utilisateur, envoyez un signal au processus, envoyez un signal de terminaison plus fort s’il ne s’arrête pas, attendez sa terminaison, fermez les tubes et supprimez les fichiers partiels. La gestion de l’arborescence des processus est importante lorsque des couches d’encapsulation ou des utilitaires matériels créent des processus descendants. Le code appelant doit pouvoir distinguer l’annulation, le dépassement de l’échéance, une entrée invalide, un échec lié à la capacité et un échec de l’encodeur.
Éviter les tubes bloqués
Lisez en continu les flux stdout et stderr configurés ou redirigez-les de manière sûre afin qu’un tube plein ne puisse pas bloquer FFmpeg.
Limiter la fréquence des mises à jour
N’écrivez pas chaque ligne de progression dans une base de données ou un navigateur ; émettez les changements à un intervalle utile et borné.
Gérer les fichiers temporaires et la publication des sorties
Créez un répertoire de travail unique pour chaque tâche, avec des permissions restrictives. Séparez les noms de fichiers fournis par le code appelant des chemins du serveur, imposez des quotas de stockage et nettoyez les fichiers après une réussite, un échec, un dépassement de délai ou une annulation. Si le traitement passe par des tubes, tenez compte de la contre-pression et veillez à ce que les deux extrémités se ferment correctement.
Écrivez dans une sortie temporaire et publiez-la de manière atomique uniquement après que FFmpeg s’est terminé avec succès et que le résultat a passé la validation. Ne laissez jamais les consommateurs accéder à un fichier multimédia partiellement écrit. Stockez les objets finaux sous des noms contrôlés, joignez des métadonnées vérifiées et maintenez des règles de conservation pour les originaux, les fichiers intermédiaires, les journaux et les entrées dont le traitement a échoué.
Protéger les métadonnées
Supprimez les métadonnées inutiles ou validez les champs avant de les exposer, car les titres, les commentaires, les chemins et les données de localisation peuvent être sensibles.
Effectuer une analyse de sécurité lorsque nécessaire
L’analyse syntaxique des médias fait partie de la surface d’attaque ; maintenez donc FFmpeg à jour avec les correctifs et utilisez une isolation adaptée à la charge de travail.
Maîtriser la concurrence, le matériel et les coûts
L’encodage est généralement limité par la capacité globale plutôt que par la vitesse d’une commande. Limitez les tâches simultanées par catégorie de charge de travail et surveillez le CPU, la mémoire, l’espace disque temporaire, les descripteurs de fichiers et le temps d’attente dans la file. Plusieurs encodages en haute résolution peuvent épuiser les ressources d’un hôte, même si chacun réussit seul. Appliquez une contre-pression plutôt que de lancer un nombre illimité de processus enfants.
L’accélération matérielle peut améliorer le débit de traitement pour les codecs pris en charge, mais elle dépend des pilotes, de la disponibilité des périphériques, des options de compilation de FFmpeg, de la compatibilité des filtres et des exigences de qualité. Mesurez le coût total de la charge de travail, y compris les transferts et la mise en file d’attente. L’encodage sur CPU peut être plus simple et plus constant pour de petits volumes, tandis qu’un matériel dédié peut justifier sa complexité d’exploitation lorsque les volumes restent élevés.
Estimer avant l’admission
Utilisez la durée et la résolution obtenues par inspection ainsi que le type d’opération pour rejeter, différer ou acheminer les tâches particulièrement coûteuses.
Suivre les coûts unitaires
Mesurez le temps de calcul, le stockage temporaire, le nombre d’octets finaux, les nouvelles tentatives après échec et l’effort de l’opérateur par catégorie de sortie.
Choisir le traitement local ou géré en connaissance de cause
Conservez FFmpeg en local lorsque l’expérimentation à l’échelle de l’image, les graphes de filtres inhabituels, l’exécution hors ligne, les compilations personnalisées ou les options non prises en charge sont au cœur du produit. Le traitement local offre un contrôle direct, mais rend l’équipe applicative responsable des binaires, des mises à jour de sécurité, de la capacité, des files d’attente, de l’isolation, de la progression, du nettoyage du stockage et de la reprise après échec.
Pour les flux de travail courants de téléversement asynchrone, un Template Transloadit peut définir des Steps tels que /video/encode, /video/thumbs et le stockage sans installer de codecs sur les serveurs applicatifs. Le SDK Python peut créer une Assembly, ajouter des fichiers ou des Steps, attendre un état lorsque cela convient et renvoyer des données structurées de l’Assembly. Il s’agit d’une alternative gérée, et non d’une liaison logicielle directement substituable pour chaque option de FFmpeg.
Protéger les flux de travail dans le navigateur
Conservez les recettes de traitement et les informations d’identification côté serveur, désactivez la redéfinition des Steps du Template lorsque les clients ne doivent pas modifier le comportement et signez les requêtes non fiables.
Séparer l’état du téléversement de celui du traitement
Un téléversement terminé ne signifie pas que l’encodage et le stockage sont terminés.
Éviter de bloquer les requêtes
Pour les traitements longs, enregistrez durablement l’identifiant de la tâche ou de l’Assembly et terminez le flux de travail du produit de manière asynchrone.
Tester les échecs et exploiter le service
Créez des données de test couvrant une vidéo valide, une entrée uniquement audio, des flux manquants, une fréquence d’images variable, des métadonnées de rotation, des conteneurs endommagés, une longue durée, de grandes dimensions, des noms de fichiers Unicode et des codecs non pris en charge. Vérifiez par des assertions le comportement du produit via l’interface publique des tâches. Contrôlez les flux finaux et la durée, pas seulement la terminaison du processus, et effectuez des tests de lecture dans les clients cibles.
Surveillez l’ancienneté des tâches en file d’attente, les percentiles des durées d’exécution, la latence d’annulation, le taux de dépassement de délai, les codes de sortie, la pression sur le disque, les échecs de validation des sorties et le volume de nouvelles tentatives. Ne relancez que les traitements dont les échecs sont probablement transitoires, selon une politique bornée qui évite de traiter à répétition des entrées corrompues. Déployez les modifications de FFmpeg ou de Template sur un échantillon, comparez les sorties et conservez une version au bon fonctionnement avéré pour pouvoir revenir en arrière.
Expurger les erreurs présentées aux utilisateurs
Renvoyez une catégorie claire et un identifiant de tâche plutôt que le contenu brut de stderr, des traces de pile, des réponses du service de stockage ou des chemins internes.
Conserver les éléments de diagnostic en toute sécurité
Conservez les diagnostics expurgés assez longtemps pour examiner les échecs récurrents, dans le respect des exigences de confidentialité et de conservation.
Détails techniques à connaître
- Le module subprocess de Python peut transmettre une liste d’arguments directement à FFmpeg sans interpréteur de commandes, empêchant ainsi les espaces et les métacaractères des noms de fichiers d’être interprétés comme de la syntaxe de commande.
- ffprobe peut produire du JSON pour les flux, les paquets, les chapitres et les métadonnées du conteneur. Les résultats de l’inspection doivent être validés, car la durée, la fréquence d’images et les balises des flux peuvent être absentes ou incohérentes.
- Pour suivre la progression dans un format exploitable par une machine, FFmpeg prend en charge le protocole de progression sur un descripteur de fichier ou un tube. L’analyse de la sortie stderr habituelle est plus fragile, car son format destiné à la lecture humaine peut changer.
- Le code de sortie zéro de FFmpeg indique que la commande est terminée, sans garantir que le résultat répond aux attentes du produit ; inspectez les flux, la durée et les dimensions du résultat avant de le publier.
- Un dépassement du délai devrait entraîner l’arrêt de l’arborescence des processus et l’attente de la libération des ressources, car les encodeurs, les tubes et les processus d’encapsulation peuvent sinon subsister après l’abandon du processus appelant Python.
- Les limites de concurrence sont généralement plus importantes que la vitesse de chaque processus : plusieurs encodages peuvent épuiser simultanément les ressources CPU, la mémoire, l’espace disque temporaire ou les descripteurs de fichiers.
Une approche pratique
- 1
Commencez avec une seule commande fixe et un fichier de test dont les flux et la durée attendus sont connus.
- 2
Validez chaque option contrôlée par l’appelant à l’aide d’une liste d’autorisation avant de construire les arguments.
- 3
Ajoutez l’analyse de la progression, la gestion des dépassements de délai et le nettoyage avant d’accepter des fichiers clients.
- 4
Comparez la charge d’exploitation à celle d’un processus géré reposant sur des Assemblies avant d’augmenter le nombre de traitements simultanés.
Quand Transloadit est utile
Pour les téléversements en production, un Template peut exprimer des Steps courants de /video/encode, de /video/thumbs et de /video/adaptive sans installer de codecs sur les serveurs applicatifs. Le SDK Python crée des Assemblies et reçoit un état structuré au lieu d’extraire ces informations de la sortie du processus.
Périmètre architectural
Transloadit est une solution gérée pour les charges de traitement asynchrone de fichiers, pas une interface Python directement substituable pour chaque option de FFmpeg. Conservez FFmpeg en local lorsque votre besoin principal est l’expérimentation à l’image près, l’exécution hors ligne ou l’utilisation de filtres non pris en charge.
Questions fréquentes
FFmpeg utilise-t-il le CPU ou le GPU ?
Il peut utiliser l’un ou l’autre. Les encodeurs logiciels et de nombreux filtres utilisent les ressources du CPU, tandis que l’accélération matérielle prise en charge peut utiliser un GPU ou un moteur multimédia dédié. La disponibilité et le comportement dépendent de la compilation de FFmpeg, des pilotes, du codec, des filtres et des options de la commande.
Faut-il utiliser une bibliothèque d’encapsulation de FFmpeg ou subprocess en Python ?
Utilisez subprocess lorsque le contrôle direct et la correspondance explicite avec les commandes sont prioritaires. Une bibliothèque d’encapsulation peut faciliter la construction de graphes complexes, mais elle ne remplace ni la connaissance de FFmpeg, ni la validation, ni les limites de ressources, ni les tests des résultats.
Comment une application doit-elle calculer la progression de FFmpeg ?
Utilisez le protocole de progression et comparez la durée de média traitée à une durée validée. Considérez le pourcentage comme une estimation, limitez la fréquence des mises à jour et passez à un état indéterminé lorsque la durée ou le comportement de la charge de travail rend toute estimation fiable impossible.
Un code de sortie FFmpeg égal à zéro suffit-il pour publier le fichier de sortie ?
Non. Inspectez le fichier de sortie et vérifiez les flux requis, la durée, les dimensions, les codecs, la taille du fichier et les exigences de lecture propres au produit avant de le publier de manière atomique.
Quand dois-je utiliser Transloadit plutôt que FFmpeg en local ?
Utilisez Transloadit lorsque les opérations courantes sur les médias doivent s’intégrer à une chaîne de téléversement asynchrone gérée et que vous souhaitez obtenir un état structuré des Assemblies sans exploiter d’infrastructure de codecs. Gardez FFmpeg en local pour le travail hors ligne, les filtres non pris en charge, les compilations personnalisées ou les expérimentations image par image qui nécessitent un contrôle direct.