L'Amour au pas de courses

Ce wiki a été archivé en 2018.

Le nouveau wiki se trouve à: ressources.labomedia.org

Les fonctionnalités sont désactivées: vous pouvez faire une recherche sur Google site:https://wiki.labomedia.org et découvrir La Labomedia.

De Centre de Ressources Numériques - Labomedia
Aller à : navigation, rechercher
L'Amour au pas de courses
L amour au pas de course.png


Pour modifier la page utiliser l'onglet Modifier avec formulaire.

Résumé Clip musical
Auteur(s) 01ivier / Double GUI
Licence CC-BY-SA 3
Date de création 20 décembre 2014


Intentions / Contexte

Chanson interprétée par 01ivier lors du SummerLab de PiNG, à Nantes, au mois de juillet 2014 et mise en images à l'occasion des réjouissantes fêtes de fin année.

Principe de fonctionnement

Il faut faire sortir des sons de sa voix en suivant une mélodie. Ici, les sons sont volontairement intelligibles.

Des logos de grandes surfaces sont ensuite placées aléatoirement sur un fond noir en leur donnant la couleur du pixel qu'ils remplacent dans une vidéo réalisée lors de l'interprétation.

Le rendu est donc exclusivement composé de logos qui se chevauchent.

Besoins / Compétences

Savoir très bien chanter. Processing.

Documentation

Rendu

La version HD est visible sur Vimeo ici.

Work flow

J'ai utilisé VLC et sa fonction "conversion" pour réduire la vidéo originale shootée en FullHD et pour la passer en MPEG-4 de manière à ce que processing puisse la décoder sans crouter au bout de 30 secondes.

Habituellement, je me satisfais de la ligne de commande suivante...

ffmpeg -f x11grab -r 30 -s 960x540 -i :0.0+0,0 -b 2048000 love.avi

... pour obtenir un film à partir d'une animation générée par Processing.

Mais les deux processus simultanés étaient trop gourmands. J'ai donc exporté chacune des images en .png, numérotées en commençant par 0000.png (cette nomenclature est importante sinon 100.png passe avant 2.png), puis je les ai importées dans le logiciel libre de montage Kdenlive en utilisant la fonction "Ajouter un clip diaporama" qui va charger toutes les images dans l'ordre en offrant la possibilité de régler leur temps d'affichage.

J'ai ensuite importé la vidéo originale dont je n'ai gardé que la piste son.

Puis export en H.264 pour faire plaisir à viméo.

Les Logos

Voici les logos que j'ai utilisé. Pour pouvoir être sensibles à la fonction tint(), ils doivent être blancs, mais si je ne les avais pas passé en noir, vous n'auriez rien vu sur le Wiki... :-p

Auchan.png Carrefour.png Leclerc.png Inter.png Lidle.png Casino.png Leader.png Ed.png Dia.png


Code

Je pense qu'il y a un bug dans la lib processing.video sous Linux.

En effet, si cela marche très bien avec un flux provenant de la webcam, je n'ai pas réussi à utiliser la méthode .pixels avec une vidéo chragée. Idem pour des appels basiques tels que .width ou .height.

J'ai donc rusé en affichant la vidéo en dessous du rendu et en récupérant les couleurs des pixels affichés sur la scène plutôt que ceux de la vidéo. C'est totalement absurde, mais ça fait le job. Bien entendu, je n'exporte que la partie supérieure de la scène. D'où le get().

L'archive complète (sans la vidéo) avec les .png en blanc : Fichier:Lamouraupasdecourses.zip

 
import processing.video.*;  

Movie movie;

PImage[] tampons;
int nbLogo = 0;
int compteur = 0;
int largeur, hauteur, nbPix;

int xLogo, yLogo;
color couleur;

void setup() {

  movie = new Movie(this, "video.mp4");
  movie.play();

  largeur = 960;
  hauteur = 540;
  nbPix= largeur*hauteur;  

  tampons = new PImage[8];
  for (int i=0; i<tampons.length; i++) {
    tampons[i] = loadImage(str(i)+"c.png");
  }
  size(largeur, hauteur*2);
  frameRate(25);

  background(0);
}

void draw() {

  if (movie.available() == true) {
    // pour être sûr de lire toutes les frames
    movie.jump((frameCount+35+ 0.5)*0.04);
    // lit la frame
    movie.read();
  }

  tint(255);
  image(movie, 0, hauteur);
  loadPixels();

  for (int i=0; i<nbLogo; i++) {
    dessine();
  }
  
  // augmente le nb de logo affichés par frame
  if (frameCount%15 == 0 && nbLogo<1000) nbLogo += 5;

  // shoote la moitié supérieur de la scène et l'enregistre en png 
  get(0, 0, 960, 540).save("pix/"+num(frameCount)+".png");
}

// dessine les logos à la place des pixels
void dessine() {

  // choisi les coordonnées d'un pixel 
  // dans la partie inférieure de la scène 
  xLogo = int(random(width-1));
  yLogo = int(random(height/2-1));

  // récupère la couleur de ce pixel
  couleur = pixels[nbPix+xLogo+yLogo*width];

  // applique cette couleur au logo et le dessine
  
  tint(couleur);
  image(tampons[compteur%8], xLogo-15, yLogo-15);
  
  compteur++;
}

// Pour avoir des fichiers numérotés à 4 chiffres
String num(int valeur) {

  if (valeur < 10 ) return "000"+str(valeur);
  if (valeur >= 10 && valeur < 100) return "00"+str(valeur);
  if (valeur >= 100 && valeur < 1000) return "0"+str(valeur);
  else return str(valeur);
}