From 9d8ab59361825e01463b8047523b97a3dcf875ee Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Tue, 14 Sep 2021 05:34:30 +0300 Subject: [PATCH] Remove JNI, add JNA. Proof of concept. --- mpv_library/Makefile | 37 ------ mpv_library/mplayer4anime_mpv_MpvSlave.h | 21 ---- mpv_library/mpvjni.c | 6 - pom.xml | 5 + src/main/java/mplayer4anime/mpv/LibC.java | 30 +++++ src/main/java/mplayer4anime/mpv/LibMpv.java | 37 ++++++ .../mpv/MpvJniLibraryLoader.java | 108 ------------------ .../java/mplayer4anime/mpv/MpvProcess.java | 104 +++++++++++++++++ src/main/java/mplayer4anime/mpv/MpvSlave.java | 13 +-- .../java/mplayer4anime/mpv/mpv_event.java | 33 ++++++ src/main/resources/appPanes/genericPane.fxml | 8 +- src/main/resources/appPanes/subPane.fxml | 8 +- .../resources/native/linux/amd64/mpvjni.so | Bin 14760 -> 0 bytes src/main/resources/native/linux/x86/mpvjni.so | Bin 14092 -> 0 bytes 14 files changed, 220 insertions(+), 190 deletions(-) delete mode 100644 mpv_library/Makefile delete mode 100644 mpv_library/mplayer4anime_mpv_MpvSlave.h delete mode 100644 mpv_library/mpvjni.c create mode 100644 src/main/java/mplayer4anime/mpv/LibC.java create mode 100644 src/main/java/mplayer4anime/mpv/LibMpv.java delete mode 100644 src/main/java/mplayer4anime/mpv/MpvJniLibraryLoader.java create mode 100644 src/main/java/mplayer4anime/mpv/MpvProcess.java create mode 100644 src/main/java/mplayer4anime/mpv/mpv_event.java delete mode 100755 src/main/resources/native/linux/amd64/mpvjni.so delete mode 100755 src/main/resources/native/linux/x86/mpvjni.so diff --git a/mpv_library/Makefile b/mpv_library/Makefile deleted file mode 100644 index 2dccfb8..0000000 --- a/mpv_library/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# Compiler -CC=gcc -# Flags -CFLAGS=-O2 -MKDIR_P = mkdir -p -APP_NAME = mpvjni - -all: x86 amd64 - -x86: - $(MKDIR_P) ./x86 - $(CC) ${CFLAGS} -m32 -c -fPIC -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" ${APP_NAME}.c -o ${APP_NAME}_x86.o - $(CC) ${CFLAGS} -m32 -shared -fPIC -o ./x86/${APP_NAME}.so ${APP_NAME}_x86.o -lc - -amd64: - $(MKDIR_P) ./amd64 - $(CC) ${CFLAGS} -m64 -c -fPIC -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" ${APP_NAME}.c -o ${APP_NAME}_amd64.o - $(CC) ${CFLAGS} -m64 -shared -fPIC -o ./amd64/${APP_NAME}.so ${APP_NAME}_amd64.o -lc - -clean: - rm -rf \ - ${APP_NAME}_amd64.o \ - ${APP_NAME}_x86.o \ - ./x86 \ - ./amd64 - -headers: - cd /src/main/java - javac mplayer4anime/mpv/MpvJni.java -h ../../../mpv_library/ - -install: x86 amd64 - install ./x86/${APP_NAME}.so ../src/main/resources/native/linux/x86/ - install ./amd64/${APP_NAME}.so ../src/main/resources/native/linux/amd64/ - -uninstall: - rm ../src/main/resources/native/linux/x86/${APP_NAME}.so - rm ../src/main/resources/native/linux/amd64/${APP_NAME}.so diff --git a/mpv_library/mplayer4anime_mpv_MpvSlave.h b/mpv_library/mplayer4anime_mpv_MpvSlave.h deleted file mode 100644 index 9c9fbbe..0000000 --- a/mpv_library/mplayer4anime_mpv_MpvSlave.h +++ /dev/null @@ -1,21 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class mplayer4anime_mpv_MpvSlave */ - -#ifndef _Included_mplayer4anime_mpv_MpvSlave -#define _Included_mplayer4anime_mpv_MpvSlave -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: mplayer4anime_mpv_MpvSlave - * Method: play - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_mplayer4anime_mpv_MpvSlave_play - (JNIEnv *, jobject); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/mpv_library/mpvjni.c b/mpv_library/mpvjni.c deleted file mode 100644 index f3e3b1c..0000000 --- a/mpv_library/mpvjni.c +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include "mplayer4anime_mpv_MpvSlave.h" - -JNIEXPORT void JNICALL Java_mplayer4anime_mpv_MpvSlave_play(JNIEnv * jnienv, jobject jobject){ - -}; \ No newline at end of file diff --git a/pom.xml b/pom.xml index ad1a7ed..bb4d038 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,11 @@ + + net.java.dev.jna + jna-platform + 5.6.0 + com.google.code.gson gson diff --git a/src/main/java/mplayer4anime/mpv/LibC.java b/src/main/java/mplayer4anime/mpv/LibC.java new file mode 100644 index 0000000..d099104 --- /dev/null +++ b/src/main/java/mplayer4anime/mpv/LibC.java @@ -0,0 +1,30 @@ +/* + Copyright 2018-2021 Dmitry Isaenko + + This file is part of mplayer4anime. + + mplayer4anime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + mplayer4anime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with mplayer4anime. If not, see . + */ +package mplayer4anime.mpv; + +import com.sun.jna.Library; +import com.sun.jna.Native; + +public interface LibC extends Library { + LibC INSTANCE = Native.load("c", LibC.class); + + int LC_NUMERIC = 1; + + String setlocale(int localeType, String name); +} diff --git a/src/main/java/mplayer4anime/mpv/LibMpv.java b/src/main/java/mplayer4anime/mpv/LibMpv.java new file mode 100644 index 0000000..0655285 --- /dev/null +++ b/src/main/java/mplayer4anime/mpv/LibMpv.java @@ -0,0 +1,37 @@ +/* + Copyright 2018-2021 Dmitry Isaenko + + This file is part of mplayer4anime. + + mplayer4anime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + mplayer4anime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with mplayer4anime. If not, see . + */ +package mplayer4anime.mpv; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.ptr.IntByReference; + +public interface LibMpv extends Library { + LibMpv INSTANCE = Native.load("libmpv", LibMpv.class); + + long mpv_create(); + int mpv_set_option_string(long ctx, String name, String data); + int mpv_set_option(long ctx, String name, int format, IntByReference data); + int mpv_initialize(long ctx); + int mpv_command(long ctx, String[] args); + + + mpv_event mpv_wait_event(long ctx, double timeout); + void mpv_terminate_destroy(long ctx); +} diff --git a/src/main/java/mplayer4anime/mpv/MpvJniLibraryLoader.java b/src/main/java/mplayer4anime/mpv/MpvJniLibraryLoader.java deleted file mode 100644 index 48bd958..0000000 --- a/src/main/java/mplayer4anime/mpv/MpvJniLibraryLoader.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright 2018-2021 Dmitry Isaenko - - This file is part of mplayer4anime. - - mplayer4anime is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - mplayer4anime is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with mplayer4anime. If not, see . - */ -package mplayer4anime.mpv; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.net.URL; - -public final class MpvJniLibraryLoader { - private MpvJniLibraryLoader(){} - public static boolean load(){ - String osName = System.getProperty("os.name").toLowerCase().replace(" ", ""); - String osArch = System.getProperty("os.arch").toLowerCase().replace(" ", ""); - String libPostfix = "so"; - - if (osName.equals("linux")){ - switch (osArch){ - case "i386": - case "i586": - case "i686": - osArch = "x86"; - break; - case "x86_64": - case "amd64": - osArch = "amd64"; - break; -// case "arm": -// osArch = "arm"; -// break; - default: - return false; - } - } - else - return false; - - final URL url_ = MpvJniLibraryLoader.class.getResource("/native/"+osName+"/"+osArch+"/mpvjni."+libPostfix); - if (url_ == null) - return false; - - String proto = url_.getProtocol(); - - File libraryFile; - if (proto.equals("file")){ - // We can pick file from disk as is. - try { - libraryFile = new File(url_.toURI()); - } - catch (URISyntaxException e){ - e.printStackTrace(); - return false; - } - } - else if (proto.equals("jar")){ - // We have to export file to temp dir. - InputStream inStream = MpvJniLibraryLoader.class.getResourceAsStream("/native/"+osName+"/"+osArch+"/mpvjni."+libPostfix); - if (inStream == null) - return false; - // Create temp folder - try{ - File tmpDirFile = File.createTempFile("jni", null); - if (! tmpDirFile.delete()) - return false; - if (! tmpDirFile.mkdirs()) - return false; - libraryFile = new File(tmpDirFile, "mpvjni."+libPostfix); - byte[] ioBuffer = new byte[8192]; - FileOutputStream foStream = new FileOutputStream(libraryFile); - while (inStream.read(ioBuffer) != -1) - foStream.write(ioBuffer); - foStream.close(); - inStream.close(); - libraryFile.deleteOnExit(); - tmpDirFile.deleteOnExit(); - } - catch (IOException ioe){ - ioe.printStackTrace(); - return false; - } - } - else - return false; - - //System.out.println("LIB LOCATION: "+libraryFile); - System.load(libraryFile.getAbsolutePath()); - //System.out.println("LIB LOADED"); - return true; - } -} diff --git a/src/main/java/mplayer4anime/mpv/MpvProcess.java b/src/main/java/mplayer4anime/mpv/MpvProcess.java new file mode 100644 index 0000000..2a43e6b --- /dev/null +++ b/src/main/java/mplayer4anime/mpv/MpvProcess.java @@ -0,0 +1,104 @@ +/* + Copyright 2018-2021 Dmitry Isaenko + + This file is part of mplayer4anime. + + mplayer4anime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + mplayer4anime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with mplayer4anime. If not, see . + */ +package mplayer4anime.mpv; + +import com.sun.jna.ptr.IntByReference; +import mplayer4anime.ServiceWindow; + +public class MpvProcess implements Runnable{ + private String videoFilename; + private final LibC libC = LibC.INSTANCE; + private final LibMpv libMpv = LibMpv.INSTANCE; + + /** MPV_FORMAT*/ + private final int MPV_FORMAT_NONE = 0; + private final int MPV_FORMAT_STRING = 1; + private final int MPV_FORMAT_OSD_STRING = 2; + private final int MPV_FORMAT_FLAG = 3; + private final int MPV_FORMAT_INT64 = 4; + private final int MPV_FORMAT_DOUBLE = 5; + private final int MPV_FORMAT_NODE = 6; + private final int MPV_FORMAT_NODE_ARRAY = 7; + private final int MPV_FORMAT_NODE_MAP = 8; + private final int MPV_FORMAT_BYTE_ARRAY = 9; + + /** mpv_event_id */ + private final int MPV_EVENT_NONE = 0; + private final int MPV_EVENT_SHUTDOWN = 1; + private final int MPV_EVENT_LOG_MESSAGE = 2; + private final int MPV_EVENT_GET_PROPERTY_REPLY = 3; + private final int MPV_EVENT_SET_PROPERTY_REPLY = 4; + private final int MPV_EVENT_COMMAND_REPLY = 5; + private final int MPV_EVENT_START_FILE = 6; + private final int MPV_EVENT_END_FILE = 7; + private final int MPV_EVENT_FILE_LOADED = 8; + private final int MPV_EVENT_TRACKS_CHANGED = 9;//DEPRECATED + private final int MPV_EVENT_TRACK_SWITCHED = 10;//DEPRECATED + private final int MPV_EVENT_IDLE = 11;//DEPRECATED + private final int MPV_EVENT_PAUSE = 12;//DEPRECATED + private final int MPV_EVENT_UNPAUSE = 13;//DEPRECATED + private final int MPV_EVENT_TICK = 14;//DEPRECATED + private final int MPV_EVENT_SCRIPT_INPUT_DISPATCH = 15;//DEPRECATED + private final int MPV_EVENT_CLIENT_MESSAGE = 16; + private final int MPV_EVENT_VIDEO_RECONFIG = 17; + private final int MPV_EVENT_AUDIO_RECONFIG = 18; + private final int MPV_EVENT_METADATA_UPDATE = 19;//DEPRECATED + private final int MPV_EVENT_SEEK = 20; + private final int MPV_EVENT_PLAYBACK_RESTART = 21; + private final int MPV_EVENT_PROPERTY_CHANGE = 22; + private final int MPV_EVENT_CHAPTER_CHANGE = 23;//DEPRECATED + private final int MPV_EVENT_QUEUE_OVERFLOW = 24; + private final int MPV_EVENT_HOOK = 25; + + MpvProcess(String filename){ + this.videoFilename = filename; + libC.setlocale(LibC.LC_NUMERIC, "C"); //Somehow it's important + } + + @Override + public void run() { + if (nonSupportedOs()) { + return; + } + + long ctx = libMpv.mpv_create(); + libMpv.mpv_set_option_string(ctx, "input-default-bindings", "yes"); + libMpv.mpv_set_option_string(ctx, "input-vo-keyboard", "yes"); + IntByReference value = new IntByReference(1); + libMpv.mpv_set_option(ctx, "osc", MPV_FORMAT_FLAG, value); + libMpv.mpv_initialize(ctx); + libMpv.mpv_command(ctx, new String[]{"loadfile", videoFilename, null}); + while (true){ + mpv_event event = libMpv.mpv_wait_event(ctx, 10000); + if (event.event_id == MPV_EVENT_SHUTDOWN) + break; + System.out.println(event.event_id); + } + libMpv.mpv_terminate_destroy(ctx); + } + + private boolean nonSupportedOs(){ + if (! System.getProperty("os.name").toLowerCase().contains("linux")) { + ServiceWindow.getErrorNotification("Error", + "Non-Linux OS are not supported. Yet. Please yse mplayer backend for now."); + return true; + } + return false; + } +} diff --git a/src/main/java/mplayer4anime/mpv/MpvSlave.java b/src/main/java/mplayer4anime/mpv/MpvSlave.java index 3a5a068..a514ee7 100644 --- a/src/main/java/mplayer4anime/mpv/MpvSlave.java +++ b/src/main/java/mplayer4anime/mpv/MpvSlave.java @@ -19,19 +19,10 @@ package mplayer4anime.mpv; import mplayer4anime.ISlaveModeAppOrchestration; -import mplayer4anime.ServiceWindow; import java.util.ResourceBundle; public class MpvSlave implements ISlaveModeAppOrchestration { - static { - if (! MpvJniLibraryLoader.load()){ - ServiceWindow.getErrorNotification("Error", - "Unable to load mpv back end library. Please use mplayer instead"); // TODO: use bundle & translate - } - } - - native void play(); public MpvSlave(ResourceBundle resourceBundle){ @@ -76,7 +67,9 @@ public class MpvSlave implements ISlaveModeAppOrchestration { String subtitlesEncoding, boolean subtitlesHidden, boolean isFullscreen) { - + //TODO: fix + Thread thread = new Thread(new MpvProcess(VideoFile)); + thread.start(); } @Override diff --git a/src/main/java/mplayer4anime/mpv/mpv_event.java b/src/main/java/mplayer4anime/mpv/mpv_event.java new file mode 100644 index 0000000..105d892 --- /dev/null +++ b/src/main/java/mplayer4anime/mpv/mpv_event.java @@ -0,0 +1,33 @@ +/* + Copyright 2018-2021 Dmitry Isaenko + + This file is part of mplayer4anime. + + mplayer4anime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + mplayer4anime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with mplayer4anime. If not, see . + */ +package mplayer4anime.mpv; + +import com.sun.jna.Structure; +import com.sun.jna.Structure.FieldOrder; +import com.sun.jna.ptr.IntByReference; + +@FieldOrder({"event_id","error","reply_userdata","data"}) +public class mpv_event extends Structure { + public mpv_event(){} + + public int event_id; + public int error; + public long reply_userdata; // long replaced originally uint64_t + public IntByReference data; +} diff --git a/src/main/resources/appPanes/genericPane.fxml b/src/main/resources/appPanes/genericPane.fxml index d8c2db1..cf120f1 100644 --- a/src/main/resources/appPanes/genericPane.fxml +++ b/src/main/resources/appPanes/genericPane.fxml @@ -18,12 +18,12 @@ @@ -39,12 +39,12 @@