From b8b71201636430ecc375149d58164ed1987e30d5 Mon Sep 17 00:00:00 2001 From: John Hendrikx Date: Fri, 21 Jun 2019 00:45:25 +0200 Subject: Add Java example using JavaFX and JNA --- libmpv/java/README.txt | 11 ++++ libmpv/java/pom.xml | 41 +++++++++++++++ libmpv/java/src/main/java/MPV.java | 44 ++++++++++++++++ libmpv/java/src/main/java/SampleMPVPlayer.java | 70 ++++++++++++++++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 libmpv/java/README.txt create mode 100644 libmpv/java/pom.xml create mode 100644 libmpv/java/src/main/java/MPV.java create mode 100644 libmpv/java/src/main/java/SampleMPVPlayer.java diff --git a/libmpv/java/README.txt b/libmpv/java/README.txt new file mode 100644 index 0000000..5075223 --- /dev/null +++ b/libmpv/java/README.txt @@ -0,0 +1,11 @@ +This example uses JNA to access the functions in libmpv, and places the +video on a JavaFX Stage. It also uses the user32 library (Windows) to get +the Window ID of the Stage in order to direct the video to this window. +This is platform specific, but similar functions exist on other platforms. + +To run this example, import as a Maven project. Create a folder "Lib" and +place the "mpv-1.dll" in it. + +It is also possible to put the dll in the "src/main/resources/win32-x86-64/lib" +folder. This allows you to package multiple libraries into a target JAR and +have JNA load the correct platform specific library automatically. diff --git a/libmpv/java/pom.xml b/libmpv/java/pom.xml new file mode 100644 index 0000000..fd991d2 --- /dev/null +++ b/libmpv/java/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + + com.example.mpvtest + mpvtest + 1.0.0-SNAPSHOT + + + + net.java.dev.jna + jna-platform + 5.3.1 + + + + org.openjfx + javafx-controls + 11.0.2 + + + + + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 11 + 11 + + + + + \ No newline at end of file diff --git a/libmpv/java/src/main/java/MPV.java b/libmpv/java/src/main/java/MPV.java new file mode 100644 index 0000000..5097e74 --- /dev/null +++ b/libmpv/java/src/main/java/MPV.java @@ -0,0 +1,44 @@ +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.win32.StdCallLibrary; + +import java.util.List; + +public interface MPV extends StdCallLibrary { + MPV INSTANCE = Native.load("lib/mpv-1.dll", MPV.class); + + /* + * Event ID's + */ + int MPV_EVENT_END_FILE = 7; + int MPV_EVENT_FILE_LOADED = 8; + int MPV_EVENT_IDLE = 11; + int MPV_EVENT_TICK = 14; + + long mpv_client_api_version(); + long mpv_create(); + int mpv_initialize(long handle); + int mpv_command(long handle, String[] args); + int mpv_command_string(long handle, String args); + Pointer mpv_get_property_string(long handle, String name); + int mpv_set_property_string(long handle, String name, String data); + int mpv_set_option_string(long handle, String name, String data); + void mpv_free(Pointer data); + int mpv_set_option(long handle, String name, int format, Pointer data); + + mpv_event mpv_wait_event(long handle, double timeOut); + int mpv_request_event(long handle, int event_id, int enable); + + class mpv_event extends Structure { + public int event_id; + public int error; + public long reply_userdata; + public Pointer data; + + @Override + protected List getFieldOrder() { + return List.of("event_id", "error", "reply_userdata", "data"); + } + } +} \ No newline at end of file diff --git a/libmpv/java/src/main/java/SampleMPVPlayer.java b/libmpv/java/src/main/java/SampleMPVPlayer.java new file mode 100644 index 0000000..429cd90 --- /dev/null +++ b/libmpv/java/src/main/java/SampleMPVPlayer.java @@ -0,0 +1,70 @@ +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.User32; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.ptr.LongByReference; + +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.paint.Color; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; + +public class SampleMPVPlayer extends Application { + private static final String STAGE_TITLE = "MPV video demo"; + + public static void main(String[] args) { + Application.launch(args); + } + + @Override + public void start(Stage stage) throws Exception { + stage.setTitle(STAGE_TITLE); + stage.show(); + + Stage childStage = new Stage(StageStyle.TRANSPARENT); + Button button = new Button("Hello World"); + Scene scene = new Scene(button); + + button.setStyle("-fx-font-size: 50px"); + button.setOpacity(0.5); + + scene.setFill(Color.TRANSPARENT); + + childStage.initModality(Modality.APPLICATION_MODAL); + childStage.initOwner(stage); + childStage.setScene(scene); + childStage.show(); + + play("https://www.youtube.com/watch?v=sFXGrTng0gQ"); + } + + private void play(String url) { + // Get interface to MPV DLL + MPV mpv = MPV.INSTANCE; + + // Create MPV player instance + long handle = mpv.mpv_create(); + + // Get the native window id by looking up a window by title: + WinDef.HWND hwnd = User32.INSTANCE.FindWindow(null, STAGE_TITLE); + + // Tell MPV on which window video should be displayed: + LongByReference longByReference = + new LongByReference(Pointer.nativeValue(hwnd.getPointer())); + mpv.mpv_set_option(handle, "wid", 4, longByReference.getPointer()); + + int error; + + // Initialize MPV after setting basic options: + if((error = mpv.mpv_initialize(handle)) != 0) { + throw new IllegalStateException("Initialization failed with error: " + error); + } + + // Load and play a video: + if((error = mpv.mpv_command(handle, new String[] {"loadfile", url})) != 0) { + throw new IllegalStateException("Playback failed with error: " + error); + } + } +} -- cgit v1.2.3