1

My video plays just fine but I need to have some elements appear in front of it.

I’m using 'PApplet' inside Eclipse (A college assignment requires that we use Processing IDE but I need some of Java functions to make it work the way I envision it) and everytime a video starts playing (through javafx) it takes over the whole program screen.

Even though I call a rectangle, for exemple, after I call the video to start, it still takes over the entire screen and I can’t see this rectangle.

public class UsingProcessing extends PApplet {

   String Dir = System.getProperty("C:\\Users\\Matheus\\eclipse-workspace\\Narraint");
   Stage stage;

   ZonedDateTime now = ZonedDateTime.now();
   LocalDateTime startOfDay = now.toLocalDate().atStartOfDay();
   java.time.Duration d = java.time.Duration.between(startOfDay,now);
   javafx.util.Duration duration = new javafx.util.Duration( d.toMillis());


   public static void main(String[] args) {

      PApplet.main("UsingProcessing");
   }

   public void settings() {

      size(1100, 618,FX2D);
   }

   public void setup() {

      try {

          Field field = PSurfaceFX.class.getDeclaredField("stage");
          field.setAccessible(true);
          stage = (Stage)field.get(surface);

          File f = new File(Dir, "narrativas.mp4");

          Media media = new Media(f.toURI().toURL().toString());
          javafx.scene.media.MediaPlayer player = new javafx.scene.media.MediaPlayer(media);
          MediaView viewer = new MediaView(player);

          DoubleProperty width = viewer.fitWidthProperty();
          DoubleProperty height = viewer.fitHeightProperty();
          width.bind(Bindings.selectDouble(viewer.sceneProperty(), "width"));
          height.bind(Bindings.selectDouble(viewer.sceneProperty(), "height"));
          viewer.setPreserveRatio(true);

          StackPane root = new StackPane();
          root.getChildren().add(viewer);

          Scene scenes = new Scene(root, 1100, 618, Color.TRANSPARENT);
          stage.setScene(scenes);
          stage.setTitle("OBSV.CamFeed.6°07'08.3\"S 12°23'51.5\"E");
          stage.setFullScreen(false);
          stage.show();
          player.setStartTime(duration); 
          player.setCycleCount(MediaPlayer.INDEFINITE);
          player.play();
      } 

      catch(Exception e) {

          e.printStackTrace();
      }
   }

   public void draw() {

      rect(30, 20, 80, 50); //Just for testing, if anything can show up in
                           //front of the video then my problem is solved!
   }
}
94matheus
  • 55
  • 4
  • 1
    You are trying to show a 'rect' in front of the video, but you need to do it using the processing lib? Or the 'rect' can be done other way? – vladwoguer May 12 '19 at 18:19
  • Yes! I need to use processing lib functions like rect, eclipse, text but for some reason the video (which i'm calling through javafx) is taking priority over everything else and it is the only thing appearing on screen. – 94matheus May 12 '19 at 20:19
  • 1
    The reason you can't see the rectangle is that you are replacing the processing scene(that it uses to render the 'rect') with yours that contains the video. I would try a different approach take a look at this solution: https://stackoverflow.com/questions/52709779/java-processing-3-paplet-in-javafx-scene-as-fxnode With access to the canvas produced by the processing you can use a `StackPane` to place the canvas in front of the video(Take a look on this: https://stackoverflow.com/questions/30068651/is-it-possible-to-put-imageview-on-canvas-in-javafx) – vladwoguer May 13 '19 at 02:10
  • 1
    I added a answer that worked for me with a simpler approach. – vladwoguer May 13 '19 at 02:59

1 Answers1

2

The reason you can't see the rectangle is that you are replacing the processing scene(that it uses to render the 'rect') with your scene that contains the video.

With access to the canvas produced by the processing (That you can get with the stage variable) you can use the StackPane to place the canvas in front of the video:

public void settings() {
    size(300, 300, FX2D);
}

...

StackPane root = new StackPane();
root.getChildren().add(viewer);
Node processingCanvas = stage.getScene().getRoot().getChildrenUnmodifiable().get(0);
root.getChildren().add(processingCanvas);
Scene scenes = new Scene(root, 1100, 618, Color.TRANSPARENT);
stage.setScene(scenes);

UPDATE

Complete example as requested:

import java.io.File;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;

import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
import processing.core.PApplet;
import processing.javafx.PSurfaceFX;

public class UsingProcessing extends PApplet {

    private static final String VIDEO_FILE_NAME = "teste.mp4";
    private static final String DIRECTORY = "/home/vladwoguer/Downloads/";
    Stage stage;

    ZonedDateTime now = ZonedDateTime.now();
    LocalDateTime startOfDay = now.toLocalDate().atStartOfDay();
    javafx.util.Duration duration = Duration.ZERO;

    public static void main(String[] args) {

        PApplet.main("UsingProcessing");
    }

    public void settings() {
        size(300, 300, FX2D);
    }

    public void setup() {

        try {

            Field field = PSurfaceFX.class.getDeclaredField("stage");
            field.setAccessible(true);
            stage = (Stage) field.get(surface);

            File f = new File(DIRECTORY, VIDEO_FILE_NAME);

            Media media = new Media(f.toURI().toURL().toString());
            javafx.scene.media.MediaPlayer player = new javafx.scene.media.MediaPlayer(media);
            MediaView viewer = new MediaView(player);

            DoubleProperty width = viewer.fitWidthProperty();
            DoubleProperty height = viewer.fitHeightProperty();
            width.bind(Bindings.selectDouble(viewer.sceneProperty(), "width"));
            height.bind(Bindings.selectDouble(viewer.sceneProperty(), "height"));
            viewer.setPreserveRatio(true);

            StackPane root = new StackPane();
            root.getChildren().add(viewer);
            Node processingCanvas = stage.getScene().getRoot().getChildrenUnmodifiable().get(0);

            root.getChildren().add(processingCanvas);
            Scene scenes = new Scene(root, 1100, 618, Color.TRANSPARENT);
            stage.setScene(scenes);
            stage.setTitle("OBSV.CamFeed.6°07'08.3\"S 12°23'51.5\"E");
            stage.setFullScreen(false);
            stage.show();
            player.setStartTime(duration);
            player.setCycleCount(MediaPlayer.INDEFINITE);
            player.play();

        }

        catch (Exception e) {

            e.printStackTrace();
        }
    }

    public void draw() {
        rect(30, 20, 80, 50); // Just for testing, if anything can show up in
    }
}

* UPDATE * Transparent background

Using:

public void draw() {

    PImage img;
    img = loadImage(DIRECTORY + "background_1.png");
    background(img);

    rect(50, 50, 150, 150); // Just for testing, if anything can show up in
}

background_1.png must be a transparent png image the same size as the Scene.

Result:

Result

Complete Code:

import java.io.File;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;

import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
import processing.core.PApplet;
import processing.core.PImage;
import processing.javafx.PSurfaceFX;

public class UsingProcessing extends PApplet {

    private static final String VIDEO_FILE_NAME = "teste.mp4";
    private static final String DIRECTORY = "/home/vladwoguer/Downloads/";
    Stage stage;

    ZonedDateTime now = ZonedDateTime.now();
    LocalDateTime startOfDay = now.toLocalDate().atStartOfDay();
    javafx.util.Duration duration = Duration.ZERO;

    public static void main(String[] args) {

        PApplet.main("UsingProcessing");
    }

    public void settings() {
        size(300, 300, FX2D);
    }

    public void setup() {

        try {

            Field field = PSurfaceFX.class.getDeclaredField("stage");
            field.setAccessible(true);
            stage = (Stage) field.get(surface);

            File f = new File(DIRECTORY, VIDEO_FILE_NAME);

            Media media = new Media(f.toURI().toURL().toString());
            javafx.scene.media.MediaPlayer player = new javafx.scene.media.MediaPlayer(media);
            MediaView viewer = new MediaView(player);

            DoubleProperty width = viewer.fitWidthProperty();
            DoubleProperty height = viewer.fitHeightProperty();
            width.bind(Bindings.selectDouble(viewer.sceneProperty(), "width"));
            height.bind(Bindings.selectDouble(viewer.sceneProperty(), "height"));
            viewer.setPreserveRatio(true);

            StackPane root = new StackPane();
            root.getChildren().add(viewer);
            Node processingCanvas = stage.getScene().getRoot().getChildrenUnmodifiable().get(0);

            root.getChildren().add(processingCanvas);
            Scene scenes = new Scene(root, 300, 300, Color.TRANSPARENT);
            stage.setScene(scenes);
            stage.setTitle("OBSV.CamFeed.6°07'08.3\"S 12°23'51.5\"E");
            stage.setFullScreen(false);
            stage.show();
            player.setStartTime(duration);
            player.setCycleCount(MediaPlayer.INDEFINITE);
            player.play();

        }

        catch (Exception e) {

            e.printStackTrace();
        }
    }

    public void draw() {
        PImage img;
        img = loadImage(DIRECTORY + "background_1.png");
        background(img);
        rect(50, 50, 150, 150); // Just for testing, if anything can show up in
    }
}
vladwoguer
  • 951
  • 1
  • 14
  • 28
  • 1
    You are welcome. Here the video played fine, the only thing I changed in the code besides the solution was changing the video path to one in my machine. But if you want I can paste the complete example in my answer. – vladwoguer May 13 '19 at 12:26
  • 1
    Yes, if you can paste the whole thing here, it would help me even more! I don't know what am I doing wrong and I bet it's something dumb. Hey, thanks again! – 94matheus May 13 '19 at 13:10
  • Okay, now I think I discovered what's going wrong over here. If I have 'size(300, 300, FX2D)' and 'new Scene(root, 1100, 618, Color.TRANSPARENT)' my program crashes as soon as I execute it. It only works if both screen sizes are the same, but i think that's what makes it so one screen covers another and I can only see one at a time... Even as I try other videos, it still crashes if the sizes are not equal. I'll keep fiddling with it until I find a solution but if you have any ideia why this is happening, i'l be very happy to know it! – 94matheus May 14 '19 at 03:32
  • Hey, sorry for bothering you again, but this is what is happening over here. https://imgur.com/gallery/lpjGn6i if 'root.getChildren().add(processingCanvas);' is below or https://imgur.com/gallery/oM6dRW2 if 'root.getChildren().add(viewer);' is below on the code. Now what i really need is this :https://forum.processing.org/two/uploads/imageupload/958/OHSZ2PW05U3H.png. Is the latter what you are getting over there? – 94matheus May 15 '19 at 15:47
  • 1
    Hi. This happens because of the background it has to be transparent to achieve what you want. – vladwoguer May 15 '19 at 23:58
  • 1
    I'm trying to set the background to transparent using the alpha, but it only allows rgb colors, so I'm gonna check if I can achieve this using `PGraphics`. If you already achieve to set the background transparent please let me know. – vladwoguer May 16 '19 at 14:11
  • Yeah, i'm still stuck haha I actually found a hack to make the background transparent (as you said it only allows rgb colors) but it requires the use of P2D render so i'm trying to find a similar solution using javafx (FX2D) – 94matheus May 16 '19 at 15:18
  • 1
    I tried several ways to achieve the transparent background. The nearest result possible is: https://imgur.com/kzzB9ia just a small canvas not background transparent. Tried to manipulate canvas and Processing `alpha` attributes, no result. https://github.com/processing/processing/issues/5293 – vladwoguer May 17 '19 at 02:08
  • I see! No problem! You helped me tremendously already. Thanks for your time again! I'll keep looking into this but maybe i'll need to think of a workaround in the end. – 94matheus May 17 '19 at 02:18
  • 1
    @94matheus last second solution Use a image transparent, I will update my answer – vladwoguer May 17 '19 at 02:27