databrary / datavyu-ffmpegplugin

A Java Media Player based on FFmpeg and SDL2
GNU General Public License v3.0
13 stars 4 forks source link

JavaFX support like VLCJ #225

Open vahid64 opened 4 years ago

vahid64 commented 4 years ago

Hello sir

We need to develop a java player based on ffmpeg with JavaFX components, so show video frames on a part of window such as button or etc (like vlcJ).

Can i use your plugin for support that ? any solution ?

TheoWolf commented 4 years ago

Hello @vahid64, You are encouraged to use our Java Player in your JavaFX application, our player will create a new window that you can control via a JavaFX application. Here is how to start with JavaFX, all that you will have to do is implement your video controller (Swing example here) in JavaFX in order to control the Media Player. EDIT: Updated the code to work on both Windows and Mac OSX

import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.datavyu.plugins.MediaPlayer;
import org.datavyu.plugins.ffmpeg.FfmpegSdlMediaPlayer;

import java.io.File;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimpleJavaFXMediaPlayer extends Application {
  private static Logger logger = LogManager.getLogger(SimpleJavaFXMediaPlayer.class);
  private JMediaPlayerControlFrame controller;
  private MediaPlayer mediaPlayer;
  private URI mediaPath;

  @Override
  public void start(Stage primaryStage) {
    mediaPath = new File("counter.mp4").toURI();

    MediaPlayerTask mediaPlayerTask = new MediaPlayerTask(mediaPath);

    mediaPlayerTask.setOnSucceeded(
        event -> {
          mediaPlayer = mediaPlayerTask.getValue();

          mediaPlayer.addMediaErrorListener(
              // Handle error thrown by The Media Player
              (source, errorCode, message) -> logger.error(errorCode + ": " + message));

          // Handle Window Key events triggered from SDL window
          mediaPlayer.addSdlKeyEventListener(
              (source, nativeMediaRef, javaKeyCode) ->
                   controller.handleKeyEvents(javaKeyCode));
          // Open a simple JFrame to control the media player through key commands
          // Be creative and create your own controller in JavaFX
          Platform.runLater(
              () -> {
                controller = new JMediaPlayerControlFrame(mediaPlayer);
              });
        });

    mediaPlayerTask.setOnFailed(event -> Platform.exit());

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.execute(mediaPlayerTask);
    executorService.shutdown();
  }

  public static void main(String[] args) {
    Application.launch(args);
  }
}

class MediaPlayerTask extends Task<MediaPlayer> {
  private URI mediaPath;

  MediaPlayerTask(URI mediaPath) {
    this.mediaPath = mediaPath;
  }

  @Override
  protected MediaPlayer call() throws Exception {
    MediaPlayer mediaPlayer = new FfmpegSdlMediaPlayer(mediaPath);
    mediaPlayer.init();
    return mediaPlayer;
  }
}

Hope this will help

vahid64 commented 4 years ago

So your java player could not display the video image in the desired components. is that right?

Thank you for your response @TheoWolf

TheoWolf commented 4 years ago

@vahid64 We do have two players, one that we can call "Master" which uses its own Native Window (from SDL2 framework) and a "Slave" player which can display streams in a Java Component, However, the latter is not fully operational yet, we are facing some UDP issues; the display is laggy, it will eventually be fixed in future releases (I'm working on it). Here is a sample if you would like to try it out.

import org.datavyu.plugins.MediaPlayer;
import org.datavyu.plugins.ffmpeg.FfmpegJavaMediaPlayer;

import java.io.File;
import java.net.URI;

public class SimpleJavaMediaPlayer {
  private static Logger logger = LogManager.getLogger(SimpleJavaMediaPlayer.class);

  public static void main(String[] args) {
    // Define the media file
    URI mediaPath = new File("FILE_PATH").toURI();

    // Create the media player using the constructor with File
    MediaPlayer mediaPlayer = new FfmpegJavaMediaPlayer(mediaPath, new JFrame());

    // Handle Media Player errors
    mediaPlayer.addMediaErrorListener(
        (source, errorCode, message) -> logger.error(errorCode + ": " + message));

    mediaPlayer.init();

    JMediaPlayerControlFrame controller = new JMediaPlayerControlFrame(mediaPlayer);
  }
}
vahid64 commented 4 years ago

@TheoWolf

We need to develop a java player based on ffmpeg with JavaFX components

but FfmpegJavaMediaPlayer need AWT container! can i send a javafx component instead of awt container?

TheoWolf commented 4 years ago

Yes, we are using only AWT Container but implementing a JavaFX Image canvas is a straight forward process (Implementing a JavaFX equivalent of this class ) As soon as the UDP bug will be fixed, I will add classes to handle JavaFX Node display, it is already on my TODO list

vahid64 commented 4 years ago

Thanks! We are waiting for it.

moliyadi commented 4 years ago

waiting for it +1 Thanks!

TheoWolf commented 4 years ago

@moliyadi @vahid64 Sorry for the delayed answer, I got pulled onto different projects. I will try to work on this ticket as soon as possible