Problem with video portrait

For my actual project I have to display on a screen in Portrait mode videos and pictures which are also in portrait mode. The videos and pictures got exactly the same size (they have done by a smartphone).

I get no problem with the pictures which perfectly size the screen, but when i play the videos, they are constructed in landscape mode: processing add black border to the video !!

I have tried to resize the video as its height is the same of the picture, and center the video to get it normaly sized correctly, but for a reason i don’t understand, the video is not really center (a difference about 35 pixels on the left)

Any idea to how solve this?

PS: I also forgot the instruction which permit to get the window active: I mean i have to click on the output window with the mouse before any controls with keyboard works, and i know there was an instructio to get it active but don’t remember which one

1 Like

Please show us your code, so we can take a look at what might be wrong. :wink:

import processing.video.*;


// initialisation
// définition des constantes
  PImage citrouille_img; // objet image citrouille

  int t_animation_max = 30 * 60 * 30 ; // 30 min * 30 fps  
  int t_animation; // compteur pour la durée de l'animation avant une nouvelle
  int t_disapear; // compteur permettant l'animation citrouille
  int t_lr = 5 * 30 ; // durée max de l'animation gauche ou droite ici 5s
  int t_fear = 10 * 30; // durée max de l'animation peur ici 10s
  int t_laught = 6 * 30; // durée max de l'animation rire ici 6s
  int t_angry = 12 * 30; // durée max de l'animation méchant ici 12s
  int t_between = 15 * 30; // durée max entre deux animations ici 15s
  
  String[] name_sketch = {"man","femme","girl"};
  String[] style_sketch = {"center","left","right","fear","angry","laught","boredom"};
  int n_sketch; //  numéro de sketch actuel
  String sketch_name; // nom du sketch ??
  String sketch_style; // position du sketch ??
  String event_pos;
  
  Boolean paysage; // permettra de savoir l'orientation de l'Ă©cran principal (si multi-Ă©cran)
  
  Movie[][] collection_movie = new Movie [name_sketch.length][style_sketch.length-1];
    
  class Portrait {
   PImage center;
   PImage left;
   PImage right;
   PImage currentimg;
   Movie v_current; // video en cours pour l'animation
   int pic_height, pic_width; // servira Ă  calculer la taille de l'image pour obtenir un plein Ă©cran
   int mov_height, mov_width; // servira Ă  calculer la taille de la video pour obtenir un plein Ă©cran
   int mov_pos;
   int t_anim;
   String pos;
   
    // constructeur avec les noms et position
    Portrait (String name, String style) {
      center = loadImage(name+"_immobile.bmp");
      left = loadImage(name+"_left.bmp");
      right = loadImage(name+"_right.bmp");
      //v_current = new Movie(this.v_current,name+"_left.avi");// video left

      if (!paysage) { // on est en orientation portrait
        pic_width = width*(width/center.height);
        pic_height = height*(width/center.height);
      } else { // on est en orientation paysage
        pic_width = height*(height/center.height);
        pic_height = width*(height/center.height);
      }
      t_anim = 0;
      pos = style;
    }
    
    // methode pour charger la vidéo actuelle et en changer plus tard
    void change_video(Movie m) {
     actual_portrait.v_current = m;
     actual_portrait.v_current.play(); // chargement de la video pour qu'elle soit prĂȘte Ă  dĂ©marrer
     actual_portrait.v_current.jump(0); // positionnement au début de la vidéo
     actual_portrait.v_current.pause(); // et on met la video en pause
     while (actual_portrait.v_current.width == 0) delay(10);
     
     actual_portrait.v_current.loadPixels();
     
     for (int x=0;x<actual_portrait.v_current.width/2;x++) {
      for (int y=0; y<actual_portrait.v_current.height/2;y++) {
        color p_color = actual_portrait.v_current.pixels[x+y];
        if (p_color == -16579837) { // notre pixel n'est pas noir donc on a un début d'image
          actual_portrait.mov_width = actual_portrait.v_current.width-2*x;
          actual_portrait.mov_height = actual_portrait.v_current.height;
          mov_pos = actual_portrait.v_current.pixelWidth;
        }
      }
     }
    }
  }
  
  Portrait actual_portrait;
  Portrait [] tab_portrait = new Portrait[3];
  
void settings() {
  if (displayWidth<displayHeight) { //on est en orientation portrait ce qui est obligatoire pour le meilleur rendu
    paysage = false;
  } else {
    paysage = true;
  }
  fullScreen(1); // l'application sera joué sur l'écran principal
}
  
void setup () {
  if (millis() < 1000)
            ((java.awt.Canvas) surface.getNative()).requestFocus(); // permet que l'application ait le focus
  surface.setAlwaysOnTop(true); // place l'application sur le devant de l'Ă©cran
  surface.hideCursor(); // cache le curseur de la souris
  smooth();
  imageMode(CENTER); // le référentiel pour afficher n'est pas le coin haut gauche (0,0,) mais le centre de la zone de travail pour un contenu dynamique
  translate (width/2, height/2); // on se place justement au centre de l'Ă©cran pour ĂȘtre au point de rĂ©fĂ©rence
  n_sketch = 0;
  sketch_name = name_sketch[n_sketch]; // on initialise le nom du sketch au premier sketch
  sketch_style = style_sketch[0]; // on initialise la position au centre
  event_pos = "none"; // on initialise la détection d'évÚnement à aucun évÚnement
  t_animation = 0; // compteur pour la durée de l'animation avant une nouvelle
  t_disapear = 0; // compteur permettant l'animation citrouille
  
  citrouille_img = loadImage("citrouille2.png");
  
  // chargement de la collection de vidéos
  for (int i=0; i<name_sketch.length; i++) {
   tab_portrait[i] = new Portrait (name_sketch[i],"center"); // chargement des portraits
   for (int j=1; j<style_sketch.length; j++) {
    collection_movie [i][j-1] = new Movie(this,name_sketch[i]+"_"+style_sketch[j]+".mp4");
   }
  }
  actual_portrait = tab_portrait[n_sketch];
  actual_portrait.change_video(collection_movie [0][3]); //chargement de fear Ă  remplacer par ennui plus tard
  actual_portrait.currentimg = actual_portrait.center;
  if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
    rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
  image(actual_portrait.center,0,0,actual_portrait.pic_width,actual_portrait.pic_height); // affiche l'image center aux coordonnées 0,0 => !
  //                                                                                  v

}

// animation
void draw() {
  imageMode(CENTER); // le référentiel pour afficher n'est pas le coin haut gauche (0,0,) mais le centre de la zone de travail pour un contenu dynamique
  translate (width/2, height/2); // on se place justement au centre de l'Ă©cran pour ĂȘtre au point de rĂ©fĂ©rence
  if (millis() < 1000)
            ((java.awt.Canvas) surface.getNative()).requestFocus(); // permet que l'application ait le focus
  // ce taux a été défini car équivalent au fps des vidéos fournies
  frameRate(23.96); // vitesse d'animation 23.96 appels de draw() = 23.96 fps qui est la vitesse de nos animations
  // on recherche un événement
  detect_event();
  if (actual_portrait.t_anim == t_animation_max) {
    // marre de l'animation, on passe Ă  une autre !!
    if (t_disapear++ <= 5 * 23.96 ) {
      Citrouille(t_disapear); // affichage dans la console du nombre de fois que la fonction draw a été affichée
    } else {
      t_animation = 0;
      t_disapear = 0;
      actual_portrait.t_anim = 0;
    } 
    
  } else {
    // on continue l'animation en cours
    t_animation += 1;  
    // evenement arduino
    play_anim(actual_portrait, event_pos);// sequence video ou image
  }
}

// animation citrouille
// est lancée toutes les t_animation_max
// permet d'afficher des citrouilles au hasard dans l'Ă©cran pour tout le couvrir
// et permettre le changement de sketches vidéo
void Citrouille (int t) {
  if (t == 1) { // on ne change le sketch qu'une fois, juste Ă  la fin
    if (n_sketch<name_sketch.length-1) {
     n_sketch +=1;
    } else {
      n_sketch = 0;
    }
    actual_portrait = tab_portrait[n_sketch];
    actual_portrait.change_video(collection_movie [n_sketch][3]); //chargement de fear Ă  remplacer par ennui plus tard
    actual_portrait.currentimg = actual_portrait.center;
  }
  if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
    rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
  image(citrouille_img, random(width+2*citrouille_img.width)-citrouille_img.width,random(height+2*citrouille_img.height)-citrouille_img.height); 
}

// animation de tableau vivant
// 
void play_anim(Portrait n_portrait, String event_name) {
  println(event_name);
  println(n_portrait.pos);
  n_portrait.t_anim +=1;
  if (event_name == "none") { // il n'y a pas eu de nouvel Ă©vĂ©nement => on reste sur la mĂȘme animation
    switch (n_portrait.pos) {
      case "center" :
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image(n_portrait.center,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
        break; 
      case "left":
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image (n_portrait.left,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
        break;
      case "right" :
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image (n_portrait.right,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
        break;
      case "fear" :
        println("f");
        n_portrait.v_current.play();
        PImage mS = n_portrait.v_current.get();
        int vh = height/mS.height; 
        int x = 40;  // problĂšme de convertion de la taille de la video du Ă  cet ajout de bande noire dont j'ignore la provenance
        mS.resize(mS.width*vh+x,mS.height*vh+x);
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image(mS,0,0);
        break;
      case "angry" :
        break;
      case "laught" :
        break;
      case "boredom" :
        break;
    }
  } else {
    n_portrait.pos = event_name;
    switch (n_portrait.pos) {
      case "center" :
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image (n_portrait.center,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
        break; 
      case "left":
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image (n_portrait.left,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
        break;
      case "right" :
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image (n_portrait.right,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
        break;
      case "fear" :
        // n_portrait.v_current.jump(n_portrait.t_anim/25);
        println("a");
        //n_portrait.v_current.read();
        n_portrait.v_current.play();
        if (paysage)  // si on est en orientation paysage, il faut faire pivoter l'image
           rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
        image (n_portrait.v_current,0,0,actual_portrait.mov_width,actual_portrait.mov_height);
        //n_portrait.currentimg = img;
        break;
      case "angry" :
        break;
      case "laught" :
        break;
      case "boredom" :
        break;
    }
  }
}

void detect_event() {
 if (keyPressed == true) {
   if (key == CODED) {
    if (keyCode == LEFT) event_pos = "left";
    if (keyCode == RIGHT) event_pos = "right";
    if (keyCode == UP) event_pos = "fear";
    if (keyCode == DOWN) event_pos = "angry";
    if (keyCode == CONTROL) event_pos = "laught";
   } else {
     switch (key) { // on a demandé à quitter le programme
      case ESC :
        println ("good bye");
        exit();
        break;
     }
   }
 } else event_pos = "none";
}

// fonction pour lecture de l'image suivante dans la video
void movieEvent(Movie m) {
  m.read();
}
1 Like

Sorry, I should have been more specific. Please try to only post as much as we, the forum, need to see in order to reproduce the problem. It’s not easy to debug such larges portions of code, especially if you did not write them yourself.
So please, try to only post as much code as needed. :slight_smile:

1 Like

as you can see in this example “Frames” from video librairy, i just changed the size of the screen (to be like a portrait mode) and use my own video (i have already try .mov, .avi and this one this .mp4) which is in portrait mode
the video should be display in 0,0 (line 36) but i got a large black border, picture and then an other black border

/**
 * Frames 
 * by Andres Colubri. 
 * 
 * Moves through the video one frame at the time by using the
 * arrow keys. It estimates the frame counts using the framerate
 * of the movie file, so it might not be exact in some cases.
 */
 
import processing.video.*;

Movie mov;
int newFrame = 0;

void setup() {
  size(600,800);
  background(0);
  // Load and set the video to play. Setting the video 
  // in play mode is needed so at least one frame is read
  // and we can get duration, size and other information from
  // the video stream. 
  mov = new Movie(this, "man_angry.mp4");  
  
  // Pausing the video at the first frame. 
  mov.play();
  mov.jump(0);
  mov.pause();
}

void movieEvent(Movie m) {
  m.read();
}

void draw() {
  background(0);
  image(mov, 0, 0, width, height);
  fill(255);
  text(getFrame() + " / " + (getLength() - 1), 10, 30);
}

void keyPressed() {
  if (key == CODED) {
    if (keyCode == LEFT) {
      if (0 < newFrame) newFrame--; 
    } else if (keyCode == RIGHT) {
      if (newFrame < getLength() - 1) newFrame++;
    }
  } 
  setFrame(newFrame);  
}
  
int getFrame() {    
  return ceil(mov.time() * 30) - 1;
}

void setFrame(int n) {
  mov.play();
    
  // The duration of a single frame:
  float frameDuration = 1.0 / mov.frameRate;
    
  // We move to the middle of the frame by adding 0.5:
  float where = (n + 0.5) * frameDuration; 
    
  // Taking into account border effects:
  float diff = mov.duration() - where;
  if (diff < 0) {
    where += diff - 0.25 * frameDuration;
  }
    
  mov.jump(where);
  mov.pause();  
}  

int getLength() {
  return int(mov.duration() * mov.frameRate);
}

Thanks, but did you test this code? When I run it with just a random vertical video filmed on my phone, it displays the frames stretched and rotated to fit the window horizontally. Still probably now what you want, but I can’t reproduce the error you seem to be having.

yes i have test this code as you can see on the capture i have done on my last message