Lire une vidéo, image par image

Processing peut lire des vidéos ! Plutôt que la lire simplement, il peut la parcourir et en extraire des images. Quelques démos de code cool pour voir ça.

Précédent | 13/15 | Suivant

Quels fichiers vidéo lire ?

Processing peut lire les conteneurs mov et mp4 mais aussi anarchiquement d’autres fichiers, les avi ou les mkv par exemple, mais certains fichiers ne passent pas, c’est une question de conteneur et de codec, parfois c’est un mystère. Un copier/coller d’un bout d’article écrit ailleurs sur ce site :

Codecs

Un codec est un dispositif de compression/décompression, c’est àdire une suite d’opération permettant, àpartir d’un fichier numérique, d’en faire une version compressée, c’est àdire plus légère, c’est àdire stockée sur moins d’espace mémoire. le MPG2 par exemple, est employé pour faire circuler les images vidéos par satellite.
A partir de ce fichier compressé, le codec permet, àtravers d’algorithmes de décompression, de retrouver la version originale du fichier.
Il existe des codecs sans perte (un fichier zippé puis dézippé sera identique àl’original) ou avec perte (une image compressé en jpeg ou en mp3 on perdu dans l’opération une partie de la qualité du fichier original). On dit dans le deuxième cas que la compression est destructive.

Un rappel sur la différence entre conteneur et codec

Il faut bien rappeler que les formats AVI, MKV, MOV et MP4 ne sont pas des "formats video" mais des conteneurs. A l’intérieur, on va trouver différentes codecs et même d’autres choses. Dans un MKV par exemple on trouvera plusieurs fichiers audio et des fichiers de sous-titres. Ceci permet de choisir sa langue et ses sous-titres sans devoir changer de fichier, via le menu du lecteur.
On regardera donc quels sont les codecs employés pour compresser les flux vidéo et audio. Voici les codecs plus relevants actuellement :
 H.264 est un format sous licence, on le trouve dans le format mp4, mv4 ou Flv.
 Theora est un format libre, que l’on retrouve dans le format ogg.
 VP8, acheté par google puis versé dans le domaine public. On le trouve dans le format webm.

En son, on trouvera le MP3, le AAC et Vorbis.

l’industrie se met rarement d’accord sur un standard, car les ingénieurs n’aiment pas partager leur trouvailles avec leurs concurrents ni se sentir tenus de respecter des règles de productions partagées pendant leurs recherches. Les firmes qui les commercialisent veulent aussi, la plupart du temps, les intégrer dans un ecosystème d’applications dont ils ont par ailleurs la licence (comme le format AAC de Apple, inclus dans le conteneur MP4, utilisé par Itunes). Enfin, les solutions propriétaires obligent les clients (nous) àacquérir licences, matériels et logiciels : plus de supports, plus d’outils, plus de contenus. Ce ne sont pas les lecteurs Bétamax et V2000 qui me contrediront.

Un exemple de base

La librairie vidéo de Processing ne doit pas être téléchargée : elle est présente dans la version de base de Processing. Elle est accompagnée de quelques exemples, vous pourrez voir qu’elle peut aussi récupérer des images d’une webcam, et vous trouverez des exemples dans le module Processing sur ce site.

Dans les exemples officiels de Processing, celui-ci :
https://processing.org/reference/libraries/video/Movie_available_.html

import processing.video.*;
Movie myMovie;

void setup() {
  size(200, 200);
  frameRate(30);
  myMovie = new Movie(this, "totoro.mov");
  myMovie.loop();
}

void draw() {
  if (myMovie.available()) {
    myMovie.read();
  }
  image(myMovie, 0, 0);
}

Ce code suppose qu’une vidéo du nom de totoro.mov (de type mov, hein, il ne faut surtout pas renommer l’extension d’un fichier avi en mov par exemple, ça ne marche pas !).
Ce fichier doit être placé dans le dossier "data" du script. Pour faire ça, il suffit de jeter le fichier sur la fenêtre du script et il sera copié dans le bon dossier.

La première chose qui est faite par ce script est de charger la librairie vidéo et déclarer un objet :

import processing.video.*;
Movie myMovie;

La première ligne charge un gros paquet de code qui permet la suite du script, c’est le code de la classe video. C’est donc évidemment important de ne pas l’oublier.

Ensuite on crée un objet de type vidéo en lui donnant un nom, comme pour n’importe quelle variable, ici "myMovie".

Puis, dans le setup(), on va faire "démarrer" l’objet :

myMovie = new Movie(this, "totoro.mov");
myMovie.loop();

Remarquez que c’est àcet endroit que l’on donne àl’objet l’adresse du fichier vidéo, ici "totoro.mov". La ligne suivant est facultative, elle met en lecture en boucle la vidéo.

Dans le draw(), on va trouver le code suivant :

if (myMovie.available()) {
    myMovie.read();
  }
  image(myMovie, 0, 0);
}

mymovie.read() est une fonction qui comme son nom l’indique, lit une image de la vidéo en temps réel. Pour éviter des erreurs de calcul, ce code est mis dans un "if" qui vérifie qu’une image est disponible àla lecture, ce qui évite que la fonction read() ne renvoie une image noire parce que le code est occupé àcharger et que l’image n’est pas encore disponible entre deux frames.

Ce code n’est qu’une des manière d’avoir accès àune vidéo, il en existe des variantes qui n’utilise pas avalaible().

Remplir une grille d’images vidéo

Pour donner un exemple, voici un code qui remplit une surface d’images vidéo en temps réel :

import processing.video.*;
Movie myMovie;

int marges=50;
int x=marges;
int y=marges;

// la vidéo a une taille de 720 X 405 pixels
// je vais afficher des vignettes 10 X plus petites
int taille_x=72;
int taille_y=40;

void setup() {
  size(1000,800);
  background(255);
  frameRate(10); // 10 images secondes au max
  myMovie = new Movie(this, "zephetach_niki_paris.mp4");
  myMovie.loop();
}

void draw() {
  if (myMovie.available()) {
    myMovie.read();
    image(myMovie, x, y, taille_x, taille_y);
    x+=taille_x;
    // si on dépasse à droite, aller à la ligne suivante
    if(x+taille_x > width-marges){ 
      y+=taille_y;
      x=marges;
      if(y+taille_y > height-marges){
        saveFrame();
        // effacer et commencer une nouvelle image
        background(255);
        x=marges;
        y=marges;
      }
    }
  }
}

Ce qui donne ceci :

D’autres scripts vidéo sur ce site

Allez voir la partie "Traitement vidéo" de ce site.