FFMPEG - Cas pratique d'utilisation

FFMPEG - Cas pratique d'utilisation

Ph.Leroy

2018-1108

FFMPEG

Fffmpeg est un merveilleux outil pour manipuler des vidéos, que ce soit à partir de fichier ou a partir de flux viéo (caméra,...); ce document n'est qu'un pense bête me permettant de retrouver ce que j'ai déjà eu le besoin de faire dans le passé.

L'essentiel

ATTENTION à ne plus employer
pile@vps337721:/var/www/raphia$ ffmpeg -ss 00:00:01 -i /var/www/raphia/video/Compilation Leroy 1950-1970.webmsd.webm -vf scale=200:-1 -vframes 1 /var/www/raphia/thumb/19/03/910958259.jpg
ffmpeg version 0.8.21-6:0.8.21-0+deb7u1, Copyright (c) 2000-2014 the Libav developers
  built on Oct 16 2017 15:36:54 with gcc 4.7.2
The ffmpeg program is only provided for script compatibility and will be removed
in a future release. It has been deprecated in the Libav project to allow for
incompatible command line syntax improvements in its replacement called avconv
(see Changelog for details). Please use avconv instead.
/var/www/raphia/video/Compilation: No such file or directory

Ffmpeg est en ligne de commande il attend des sources en entrée (option -i) et produit un fichier en sortie (sans option) dans la logique d'Unix.

$ffmpeg -i SOURCE -i SOURCE2 PUIT

Les sources multiples sont identifiées par leur indice d'entrée (SOURCE2 -> 1), d'une manière générale les options s'appliquent à l'entrée ou sortie suivantesuivante afin d'éviter tout mélange.

Par exemple:

  • Pour préciser le débit de sortie (video bitrate)
    $ ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi
    
  • Pour forcer le nombre d'images par seconde (frame rate) à 24 ips:
    ffmpeg -i input.avi -r 24 output.avi
    
  • pour forcer le nombre d'images par seconde de l'entrée (applicable aux seuls formats bruts) à une image par seconde et le nombre d'images par seconde de la sortie à 24 ips:
    ffmpeg -r 1 -i input.m2v -r 24 output.avi
    

    ==Extraction d'une partie temporelle== Si vous devez extraire une partie de la video commencant à [start] pour une durée de [duration]:

    ffmpeg -ss [start] -i in.mp4 -t [duration] -c copy out.mp4
    

    Les options signifient:

  • ss définit la datation de départ, par exemple 00:01:23.000 ou 83 (en secondes)

  • t définit la durée de la séquence (même format que ci-dessus), des versions récentes de ffmpeg disposent de l'option -to pour définir la datation de fin.

  • c copy copient le premier flux video, audio et sous-titre de la source vers le puit sans les réencoder; cela permet de ne pas perdre en qualité et d’exécuter la commande très rapidement.

    Par exemple extraction a partir de la 2° seconde pour une durée de 3,5 secondes:
    ffmpeg -ss 2 -t 3.5 -i IMG_2862.mp4 -c copy out.mp4
    

Extraction d'une partie de la vue

$ ffmpeg -i source.mp4 -filter:v "crop=in_w/2:in_h/2:in_w/4:in_h/4" -c:a copy puit.mp4

Le fichier source est source.mp4, le fichier produit est puit.mp4 et on utilise le filtre "crop". Ce filtre attend en paramètre la largeur, la hauteur, l'abscisse et l'ordonnée de la zone que l'on veut extraire; ici on utilise les dimensions de la source (in_w et in_h).

Génération des calques

Pour générer les calques c'est à dire toutes les images contenues dans la vidéo, afin de pouvoir faire un gif par exemple, il suffit de:

$ ffmpeg -i source.mp4 -r 15 image-%3d.png

Comment faire un aller-retour

Si vous avez l'intention de faire un gif animé qui boucle en permanenece, pour éviter les sauts on peut dupliquer les calques générés en ordre inverse pour un aller et retour.

Un petit shell est bien pratique.

 #!/bin/sh
 # On a 55 calques generes par ffmpeg frame-001.png a frame-055.png
 for i in `seq 1 55`
 do 
         j=$((56-$i)); 
         src=$(printf "Clip_premiere-%03d.png" $j);
         k=$((55+55-$j+1));
         puit=$( printf "Clip_premiere-%03d.png" $k);
         #echo $src vers $puit;
         cp $src $puit;
 done

Extraction d'une image pour en faire un poster

Lorsque on inclut une video dans une page html, la balise <video> permet de sélectionner un poster.

La commande suivante permet de générer une image a partir d'une vidéo, ici à la 15° seconde.

ffmpeg -ss 00:00:15 -i video.mp4 -vf scale=800:-1 -vframes 1 image.jpg

Obtention des informations d'un fichier

Pour obtenir les informations essentielles d'un fichier vidéo, on peut utiliser ffprobe qui est un exécutable du paquet avec la syntaxe suivante (attention il y a beaucoup d'informations).

$ ffprobe -v error -print_format json -select_streams v:0 -show_entries stream my_video.mp4
c/doc/19/04/lanXHWKQ.mp4'
{
    "programs": [

    ],
    "streams": [
        {
            "index": 0,
            "codec_name": "h264",
            "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
            "profile": "High",
            "codec_type": "video",
            "codec_time_base": "50/2997",
            "codec_tag_string": "avc1",
            "codec_tag": "0x31637661",
            "width": 240,
            "height": 180,
            "coded_width": 240,
            "coded_height": 180,
            "has_b_frames": 2,
            "sample_aspect_ratio": "0:1",
            "display_aspect_ratio": "0:1",
            "pix_fmt": "yuv420p",
            "level": 12,
            "chroma_location": "left",
            "refs": 1,
            "is_avc": "true",
            "nal_length_size": "4",
            "r_frame_rate": "2997/100",
            "avg_frame_rate": "2997/100",
            "time_base": "1/11988",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 42006,
            "duration": "3.504004",
            "bit_rate": "68404",
            "bits_per_raw_sample": "8",
            "nb_frames": "105",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "language": "und",
                "handler_name": "VideoHandler"
            }
        }
    ]
}

On peut choisir le format de production des données (-print_format ou -of: default, compact, flat, ini, json, xml cf.man), choisir le flux (-select streams v:0), et montrer que certaines entrées (-show_entries stream=codec_name); ci-dessus on a affiché l'ensemble des entrées disponibles sur les flux.

Nous ce qui nous intéresse est ceci:

$ ffprobe -v error -show_entries stream=width:stream=height -of flat myvideo.mp4
streams.stream.0.width=240
streams.stream.0.height=180

Ou sinon

$ ffprobe -v error -show_entries stream=width:stream=height -of default=noprint_wrappers=1 my_video.mp4
width=240
height=180

Génération du gif animé

Gimp peut servir a générer un gif animé "assez" simplement.

On a donc généré nos calques (on prend le terme utilisé par Gimp)

$ ffmpeg -i source.mp4 -r 15 calques/image-%3d.png

On ouvre Gimp en précisant "Fichier/Ouvrir en tant que calques..."

On convertit la palette en palette de couleurs indexées "Image / Mode / Couleurs indexées "

On choisit la palette la plus petite possible 63 par exemple (c'est là où on gagne sur la taille finale).

On fait attention à l'ordre des images que l'on peut changer avec " Calque / Pile / Inverser l'ordre des calques".

On peut utiliser l'optimisation pour réduire aux seules parties mouvantes des images "Filtres / Animation / Optimiser (pour Gif)".

Et enfin on exporte " Fichier / Exporter sous..." dans un fichier auquel on donne l'extension ".gif", dans la page qui s'ouvre on précise "En tant que animation", "Boucler indéfiniment" et on valorise le délai à 66 soit 1000/15 (nb d'ips choisi plus haut avec le -r 15).

Byzanz

Byzanz est un petit logiciel en ligne de commande qui permet de créer facilement des gifs animés à partir de capture d'écran.

Par exemple pour faire une capture d'écran:

byzanz-record --duration=20 --x=0 --y=0 --width=1024 --height=800 moo.gif

byzanz-record est bien entendu la commande base --duration=20 correspond à un enregistrement de 20 secondes x et y correspondent aux coordonnées du rectangle d’enregistrement --width et --height correspondent à la résolution d’écran souhaitée et enfin, moo.gif est bien entendu le nom du fichier de sortie