Drafting JNI for mpv API. Refactoring & code cleanup.
This commit is contained in:
parent
bd45f72b5a
commit
e89cad31ef
23 changed files with 500 additions and 131 deletions
37
mpv_library/Makefile
Normal file
37
mpv_library/Makefile
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# 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
|
21
mpv_library/mplayer4anime_mpv_MpvSlave.h
Normal file
21
mpv_library/mplayer4anime_mpv_MpvSlave.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* 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
|
6
mpv_library/mpvjni.c
Normal file
6
mpv_library/mpvjni.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include <mpv/client.h>
|
||||||
|
#include "mplayer4anime_mpv_MpvSlave.h"
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_mplayer4anime_mpv_MpvSlave_play(JNIEnv * jnienv, jobject jobject){
|
||||||
|
|
||||||
|
};
|
|
@ -122,4 +122,7 @@ public class AppPreferences {
|
||||||
|
|
||||||
public double getSceneHeight(){ return preferences.getDouble("window_height", 800.0); }
|
public double getSceneHeight(){ return preferences.getDouble("window_height", 800.0); }
|
||||||
public void setSceneHeight(double value){ preferences.putDouble("window_height", value); }
|
public void setSceneHeight(double value){ preferences.putDouble("window_height", value); }
|
||||||
|
|
||||||
|
public int getBackendEngineIndexId(){ return preferences.getInt("backend_player", 0); }
|
||||||
|
public void setBackendEngineIndexId(int value){ preferences.putInt("backend_player", value); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ import mplayer4anime.Playlists.Playlists;
|
||||||
import mplayer4anime.Settings.SettingsWindow;
|
import mplayer4anime.Settings.SettingsWindow;
|
||||||
import mplayer4anime.appPanes.ControllerPane;
|
import mplayer4anime.appPanes.ControllerPane;
|
||||||
import mplayer4anime.appPanes.ControllerSUB;
|
import mplayer4anime.appPanes.ControllerSUB;
|
||||||
|
import mplayer4anime.mplayer.MplayerSlave;
|
||||||
|
import mplayer4anime.mpv.MpvSlave;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -56,12 +58,10 @@ public class Controller implements Initializable {
|
||||||
private final AppPreferences appPreferences = AppPreferences.getINSTANCE();
|
private final AppPreferences appPreferences = AppPreferences.getINSTANCE();
|
||||||
|
|
||||||
private ResourceBundle resourceBundle;
|
private ResourceBundle resourceBundle;
|
||||||
// Get host services for opening URLs etc.
|
|
||||||
private HostServices hostServices;
|
private HostServices hostServices;
|
||||||
|
|
||||||
private String currentPlaylistLocation;
|
private String currentPlaylistLocation;
|
||||||
|
private String backend;
|
||||||
private MplayerSlave mplayer;
|
private ISlaveModeAppOrchestration player;
|
||||||
|
|
||||||
// If application started with playlist passed as an argument, then we'll try to load it (if it's valid).
|
// If application started with playlist passed as an argument, then we'll try to load it (if it's valid).
|
||||||
public void setPlaylistAsArgument(String playlist) {
|
public void setPlaylistAsArgument(String playlist) {
|
||||||
|
@ -96,8 +96,14 @@ public class Controller implements Initializable {
|
||||||
continue;
|
continue;
|
||||||
addRecentlyOpened(recentPlaylists[i]);
|
addRecentlyOpened(recentPlaylists[i]);
|
||||||
}
|
}
|
||||||
|
if (appPreferences.getBackendEngineIndexId() == 0) {
|
||||||
mplayer = new MplayerSlave(resourceBundle);
|
backend = "mplayer";
|
||||||
|
player = new MplayerSlave(resourceBundle);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
backend = "mpv";
|
||||||
|
player = new MpvSlave(resourceBundle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setHostServices(HostServices hostServices) {
|
void setHostServices(HostServices hostServices) {
|
||||||
|
@ -126,11 +132,15 @@ public class Controller implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void infoBtn(){ new AboutWindow(this.hostServices); } // TODO: fix this shit with hostSerivces that doesn't work @ linux
|
private void infoBtn(){
|
||||||
|
new AboutWindow(this.hostServices);
|
||||||
|
} // TODO: fix this shit with hostSerivces that doesn't work @ linux
|
||||||
|
|
||||||
/** SETTINGS HANDLE */
|
/** SETTINGS HANDLE */
|
||||||
@FXML
|
@FXML
|
||||||
private void settingsBtn(){ new SettingsWindow(); }
|
private void settingsBtn(){
|
||||||
|
new SettingsWindow();
|
||||||
|
}
|
||||||
// Get event that notify application in case some settings has been changed
|
// Get event that notify application in case some settings has been changed
|
||||||
// This function called from MediatorControl after mediator receives request form SettingsController indicating that user updated some required fields.
|
// This function called from MediatorControl after mediator receives request form SettingsController indicating that user updated some required fields.
|
||||||
void updateAfterSettingsChanged(){
|
void updateAfterSettingsChanged(){
|
||||||
|
@ -138,6 +148,18 @@ public class Controller implements Initializable {
|
||||||
subPaneController.setEncoding(appPreferences.getSubsEncodingList(), null);
|
subPaneController.setEncoding(appPreferences.getSubsEncodingList(), null);
|
||||||
// In case of application failure should be better to save this immediately
|
// In case of application failure should be better to save this immediately
|
||||||
appPreferences.setLastTimeUsedSubsEncoding(subPaneController.getSelectedEncoding());
|
appPreferences.setLastTimeUsedSubsEncoding(subPaneController.getSelectedEncoding());
|
||||||
|
switchBackend(appPreferences.getBackendEngineIndexId());
|
||||||
|
}
|
||||||
|
private void switchBackend(int newBackEndId){
|
||||||
|
if (newBackEndId == 0 && backend.equals("mpv")){
|
||||||
|
backend = "mplayer";
|
||||||
|
player = new MplayerSlave(resourceBundle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (newBackEndId == 1 && backend.equals("mplayer")){
|
||||||
|
backend = "mpv";
|
||||||
|
player = new MpvSlave(resourceBundle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -147,46 +169,53 @@ public class Controller implements Initializable {
|
||||||
}
|
}
|
||||||
private void setAllLists(JsonStorage jsonStorage){
|
private void setAllLists(JsonStorage jsonStorage){
|
||||||
if (jsonStorage != null) {
|
if (jsonStorage != null) {
|
||||||
mkvPaneController.cleanList();
|
|
||||||
mkaPaneController.cleanList();
|
|
||||||
subPaneController.cleanList();
|
|
||||||
mkvPaneController.setFilesFromList(jsonStorage.getVideo());
|
mkvPaneController.setFilesFromList(jsonStorage.getVideo());
|
||||||
mkaPaneController.setFilesFromList(jsonStorage.getAudio());
|
mkaPaneController.setFilesFromList(jsonStorage.getAudio());
|
||||||
subPaneController.setFilesFromList(jsonStorage.getSubs());
|
subPaneController.setFilesFromList(jsonStorage.getSubs());
|
||||||
subPaneController.selectEncodingValue(jsonStorage.getSubEncoding(), appPreferences);
|
subPaneController.selectEncodingValue(jsonStorage.getSubEncoding(), appPreferences);
|
||||||
|
|
||||||
currentPlaylistLocation = Playlists.getPlaylistLocation(); // TODO: Implement listener? mmm...
|
currentPlaylistLocation = Playlists.getPlaylistLocation(); // TODO: Implement listener? mmm...
|
||||||
//System.out.println(currentPlaylistLocation);
|
|
||||||
statusLbl.setText(currentPlaylistLocation);
|
statusLbl.setText(currentPlaylistLocation);
|
||||||
addRecentlyOpened(currentPlaylistLocation);
|
addRecentlyOpened(currentPlaylistLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void saveBtn() {
|
private void saveBtn() {
|
||||||
if (mkvPaneController.getElementsCount() == 0)
|
if (mkvPaneController.getElementsCount() == 0) {
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToSaveEmptyPlaylist"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
else {
|
resourceBundle.getString("ErrorUnableToSaveEmptyPlaylist"));
|
||||||
JsonStorage jsonStorage = new JsonStorage(mkvPaneController.getElementsAll(), mkaPaneController.getElementsAll(), subPaneController.getElementsAll(), subPaneController.getSelectedEncoding());
|
return;
|
||||||
|
}
|
||||||
|
JsonStorage jsonStorage = new JsonStorage(
|
||||||
|
mkvPaneController.getElementsAll(),
|
||||||
|
mkaPaneController.getElementsAll(),
|
||||||
|
subPaneController.getElementsAll(),
|
||||||
|
subPaneController.getSelectedEncoding());
|
||||||
if (Playlists.SaveCurrent(resourceBundle, jsonStorage)) {
|
if (Playlists.SaveCurrent(resourceBundle, jsonStorage)) {
|
||||||
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
||||||
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
||||||
addRecentlyOpened(currentPlaylistLocation);
|
addRecentlyOpened(currentPlaylistLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@FXML
|
@FXML
|
||||||
private void saveAsBtn() {
|
private void saveAsBtn() {
|
||||||
if (mkvPaneController.getElementsCount() == 0)
|
if (mkvPaneController.getElementsCount() == 0) {
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToSaveEmptyPlaylist"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
else {
|
resourceBundle.getString("ErrorUnableToSaveEmptyPlaylist"));
|
||||||
JsonStorage jsonStorage = new JsonStorage(mkvPaneController.getElementsAll(), mkaPaneController.getElementsAll(), subPaneController.getElementsAll(), subPaneController.getSelectedEncoding());
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonStorage jsonStorage = new JsonStorage(
|
||||||
|
mkvPaneController.getElementsAll(),
|
||||||
|
mkaPaneController.getElementsAll(),
|
||||||
|
subPaneController.getElementsAll(),
|
||||||
|
subPaneController.getSelectedEncoding());
|
||||||
if (Playlists.SaveAs(resourceBundle, jsonStorage)) {
|
if (Playlists.SaveAs(resourceBundle, jsonStorage)) {
|
||||||
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
||||||
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
||||||
addRecentlyOpened(currentPlaylistLocation);
|
addRecentlyOpened(currentPlaylistLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@FXML
|
@FXML
|
||||||
private void cleanAllRecentlyOpened(){
|
private void cleanAllRecentlyOpened(){
|
||||||
recentlyOpenedMenu.getItems().remove(0,recentlyOpenedMenu.getItems().size() - 2);
|
recentlyOpenedMenu.getItems().remove(0,recentlyOpenedMenu.getItems().size() - 2);
|
||||||
|
@ -223,15 +252,15 @@ public class Controller implements Initializable {
|
||||||
/* PLAYER */
|
/* PLAYER */
|
||||||
@FXML
|
@FXML
|
||||||
private void subsTriggerBtn(){
|
private void subsTriggerBtn(){
|
||||||
mplayer.subtitlesSwitch();
|
player.subtitlesSwitch();
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void fullscreenBtn(){
|
private void fullscreenBtn(){
|
||||||
mplayer.fullscreenSwitch();
|
player.fullscreenSwitch();
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void muteBtn(){
|
private void muteBtn(){
|
||||||
mplayer.mute();
|
player.mute();
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void playPrevTrackBtn(){
|
private void playPrevTrackBtn(){
|
||||||
|
@ -240,7 +269,7 @@ public class Controller implements Initializable {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mkvPaneController.setElementSelectedByIndex(index-1);
|
mkvPaneController.setElementSelectedByIndex(index-1);
|
||||||
mplayer.forcePlay(appPreferences.getPath(),
|
player.forcePlay(appPreferences.getPath(),
|
||||||
mkvPaneController.getElementSelected(),
|
mkvPaneController.getElementSelected(),
|
||||||
mkaPaneController.getElementSelected(),
|
mkaPaneController.getElementSelected(),
|
||||||
subPaneController.getElementSelected(),
|
subPaneController.getElementSelected(),
|
||||||
|
@ -265,7 +294,7 @@ public class Controller implements Initializable {
|
||||||
subPaneController.setElementSelectedByIndex(index + 1);
|
subPaneController.setElementSelectedByIndex(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
mplayer.forcePlay(appPreferences.getPath(),
|
player.forcePlay(appPreferences.getPath(),
|
||||||
mkvPaneController.getElementSelected(),
|
mkvPaneController.getElementSelected(),
|
||||||
mkaPaneController.getElementSelected(),
|
mkaPaneController.getElementSelected(),
|
||||||
subPaneController.getElementSelected(),
|
subPaneController.getElementSelected(),
|
||||||
|
@ -279,7 +308,7 @@ public class Controller implements Initializable {
|
||||||
if (mkvPaneController.getElementSelected() == null)
|
if (mkvPaneController.getElementSelected() == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mplayer.playPause(appPreferences.getPath(),
|
player.playPause(appPreferences.getPath(),
|
||||||
mkvPaneController.getElementSelected(),
|
mkvPaneController.getElementSelected(),
|
||||||
mkaPaneController.getElementSelected(),
|
mkaPaneController.getElementSelected(),
|
||||||
subPaneController.getElementSelected(),
|
subPaneController.getElementSelected(),
|
||||||
|
@ -290,15 +319,15 @@ public class Controller implements Initializable {
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void stopBtn(){
|
private void stopBtn(){
|
||||||
mplayer.stop();
|
player.stop();
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void volumeUpBtn(){
|
private void volumeUpBtn(){
|
||||||
mplayer.volumeUp();
|
player.volumeUp();
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void volumeDownBtn(){
|
private void volumeDownBtn(){
|
||||||
mplayer.volumeDown();
|
player.volumeDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
package mplayer4anime;
|
|
||||||
|
|
||||||
public interface IMediatorContol {
|
|
||||||
void registerMainController(mplayer4anime.Controller mc);
|
|
||||||
void sentUpdates();
|
|
||||||
}
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
/*
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
package mplayer4anime.IPC;
|
package mplayer4anime.IPC;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
@ -11,8 +29,8 @@ import java.net.Socket;
|
||||||
|
|
||||||
class ServerSocketProvider implements Runnable{
|
class ServerSocketProvider implements Runnable{
|
||||||
|
|
||||||
private ServerSocket serverSocket;
|
private final ServerSocket serverSocket;
|
||||||
private Controller controller;
|
private final Controller controller;
|
||||||
|
|
||||||
ServerSocketProvider(Controller mainCntrl, ServerSocket srvSock){
|
ServerSocketProvider(Controller mainCntrl, ServerSocket srvSock){
|
||||||
this.serverSocket = srvSock;
|
this.serverSocket = srvSock;
|
||||||
|
@ -42,6 +60,7 @@ class ServerSocketProvider implements Runnable{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex){
|
catch (IOException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
System.out.println("Socket has been closed.");
|
System.out.println("Socket has been closed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.net.InetAddress;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
|
// TODO: Rewrite and remove. Or just remove.
|
||||||
public class SingleInstanceHandler implements Runnable{
|
public class SingleInstanceHandler implements Runnable{
|
||||||
|
|
||||||
private ServerSocket servSock;
|
private ServerSocket servSock;
|
||||||
|
@ -41,15 +42,9 @@ public class SingleInstanceHandler implements Runnable{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (! Thread.currentThread().isInterrupted());
|
||||||
if ( Thread.currentThread().isInterrupted() ){
|
|
||||||
try {
|
try {
|
||||||
servSock.close();
|
servSock.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException ignore) {}
|
||||||
System.out.println("Internal issue: unable to create client socket.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,5 +19,25 @@
|
||||||
package mplayer4anime;
|
package mplayer4anime;
|
||||||
|
|
||||||
public interface ISlaveModeAppOrchestration {
|
public interface ISlaveModeAppOrchestration {
|
||||||
// TODO: implement unified interface for mplayer and mpv
|
void subtitlesSwitch();
|
||||||
|
void fullscreenSwitch();
|
||||||
|
void mute();
|
||||||
|
void forcePlay(String mplayerPath,
|
||||||
|
String VideoFile,
|
||||||
|
String AudioFile,
|
||||||
|
String SubtitlesFile,
|
||||||
|
String subtitlesEncoding,
|
||||||
|
boolean subtitlesHidden,
|
||||||
|
boolean isFullscreen);
|
||||||
|
boolean pause();
|
||||||
|
void playPause(String mplayerPath,
|
||||||
|
String VideoFile,
|
||||||
|
String AudioFile,
|
||||||
|
String SubtitlesFile,
|
||||||
|
String subtitlesEncoding,
|
||||||
|
boolean subtitlesHidden,
|
||||||
|
boolean isFullscreen);
|
||||||
|
void stop();
|
||||||
|
void volumeUp();
|
||||||
|
void volumeDown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package mplayer4anime;
|
package mplayer4anime;
|
||||||
|
|
||||||
public class MediatorControl implements IMediatorContol{
|
public class MediatorControl{
|
||||||
private Controller mainController;
|
private Controller mainController;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerMainController(Controller mc) {
|
public void registerMainController(Controller mc) {
|
||||||
mainController = mc;
|
mainController = mc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sentUpdates() {
|
public void sentUpdates() {
|
||||||
mainController.updateAfterSettingsChanged();
|
mainController.updateAfterSettingsChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
/*
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
package mplayer4anime.Playlists;
|
package mplayer4anime.Playlists;
|
||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
|
@ -9,12 +27,10 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class Playlists {
|
public class Playlists {
|
||||||
|
|
||||||
private static String playlistLocation;
|
private static String playlistLocation;
|
||||||
|
|
||||||
//TODO: Show popUp if unable to write! Or nothing to write! Or overwrite!
|
//TODO: Show popUp if unable to write! Or nothing to write! Or overwrite!
|
||||||
/**
|
//TODO: Disable 'Save' button if no files added
|
||||||
* Interface for Save As functionality
|
|
||||||
* */
|
|
||||||
public static boolean SaveAs(ResourceBundle resourceBundle, JsonStorage jStorage){
|
public static boolean SaveAs(ResourceBundle resourceBundle, JsonStorage jStorage){
|
||||||
File playlistFile;
|
File playlistFile;
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
|
@ -27,49 +43,51 @@ public class Playlists {
|
||||||
|
|
||||||
return writeFile(resourceBundle, playlistFile, jStorage);
|
return writeFile(resourceBundle, playlistFile, jStorage);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Interface for Save functionality
|
|
||||||
* */
|
|
||||||
public static boolean SaveCurrent(ResourceBundle resourceBundle, JsonStorage jStorage) {
|
public static boolean SaveCurrent(ResourceBundle resourceBundle, JsonStorage jStorage) {
|
||||||
if (playlistLocation == null || playlistLocation.equals("")){
|
if (playlistLocation == null || playlistLocation.equals("")){
|
||||||
return Playlists.SaveAs(resourceBundle, jStorage);
|
return Playlists.SaveAs(resourceBundle, jStorage);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return writeFile(resourceBundle, new File(playlistLocation), jStorage);
|
return writeFile(resourceBundle, new File(playlistLocation), jStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true for success, false for failure
|
||||||
|
* */
|
||||||
|
private static boolean writeFile(ResourceBundle resourceBundle, File playlistFile, JsonStorage jStorage){
|
||||||
|
if (playlistFile == null) {
|
||||||
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
"Unable to save: File not selected");// TODO: translate
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Working with file itself
|
|
||||||
private static boolean writeFile(ResourceBundle resourceBundle, File playlistFile, JsonStorage jStorage){
|
|
||||||
// TODO: Add 'Override pop-up notification!'
|
|
||||||
if (playlistFile != null) {
|
|
||||||
if (!playlistFile.getAbsolutePath().endsWith(".alpr")) {
|
if (!playlistFile.getAbsolutePath().endsWith(".alpr")) {
|
||||||
playlistFile = new File(playlistFile.getAbsolutePath() + ".alpr");
|
playlistFile = new File(playlistFile.getAbsolutePath() + ".alpr");
|
||||||
}
|
}
|
||||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(playlistFile.getAbsolutePath()), StandardCharsets.UTF_8))
|
|
||||||
|
try (Writer writer = new OutputStreamWriter(
|
||||||
|
new FileOutputStream(playlistFile.getAbsolutePath()), StandardCharsets.UTF_8))
|
||||||
{
|
{
|
||||||
Gson jsonObject = new GsonBuilder().setPrettyPrinting().create();
|
Gson jsonObject = new GsonBuilder().setPrettyPrinting().create();
|
||||||
jsonObject.toJson(jStorage, writer);
|
jsonObject.toJson(jStorage, writer);
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
||||||
playlistLocation = playlistFile.getAbsolutePath();
|
playlistLocation = playlistFile.getAbsolutePath();
|
||||||
// Return success notification
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (java.io.FileNotFoundException e){
|
} catch (java.io.FileNotFoundException e){
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorFileNotFound"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
resourceBundle.getString("ErrorFileNotFound"));
|
||||||
} catch (java.io.UnsupportedEncodingException e){
|
} catch (java.io.UnsupportedEncodingException e){
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnSaveIncorrectEncoding"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
resourceBundle.getString("ErrorOnSaveIncorrectEncoding"));
|
||||||
} catch (java.io.IOException e){
|
} catch (java.io.IOException e){
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnSaveIOProblem"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
resourceBundle.getString("ErrorOnSaveIOProblem"));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
System.out.println("Unable to save: File not selected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Interface for Opening playlists via FileChooser
|
* Interface for Opening playlists via FileChooser
|
||||||
* */
|
* */
|
||||||
|
@ -89,30 +107,30 @@ public class Playlists {
|
||||||
* Interface for Opening playlists using file itself
|
* Interface for Opening playlists using file itself
|
||||||
* */
|
* */
|
||||||
public static JsonStorage ReadByPath(ResourceBundle resourceBundle, File playlistFile){
|
public static JsonStorage ReadByPath(ResourceBundle resourceBundle, File playlistFile){
|
||||||
if (playlistFile != null) {
|
if (playlistFile == null) {
|
||||||
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
"Playlist file not selected");// TODO: translate
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try (Reader reader = new InputStreamReader(new FileInputStream(playlistFile))) {
|
try (Reader reader = new InputStreamReader(new FileInputStream(playlistFile))) {
|
||||||
JsonStorage jStorage = new Gson().fromJson(reader, JsonStorage.class);
|
JsonStorage jStorage = new Gson().fromJson(reader, JsonStorage.class);
|
||||||
if (jStorage != null){
|
if (jStorage != null){
|
||||||
playlistLocation = playlistFile.getAbsolutePath();
|
playlistLocation = playlistFile.getAbsolutePath();
|
||||||
//System.out.println("FILE:|"+playlistLocation+"|");
|
|
||||||
return jStorage;
|
return jStorage;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return null;
|
|
||||||
} catch (java.io.FileNotFoundException e){
|
} catch (java.io.FileNotFoundException e){
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorFileNotFound"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
resourceBundle.getString("ErrorFileNotFound"));
|
||||||
} catch (com.google.gson.JsonSyntaxException e){
|
} catch (com.google.gson.JsonSyntaxException e){
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnOpenIncorrectFormatOfFile"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
resourceBundle.getString("ErrorOnOpenIncorrectFormatOfFile"));
|
||||||
} catch (java.io.IOException e){
|
} catch (java.io.IOException e){
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnOpenIOProblem"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
|
resourceBundle.getString("ErrorOnOpenIOProblem"));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
System.out.println("Playlist file not selected");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return path to file opened */
|
/** Return path to file opened */
|
||||||
public static String getPlaylistLocation(){
|
public static String getPlaylistLocation(){
|
||||||
|
|
|
@ -20,6 +20,7 @@ package mplayer4anime;
|
||||||
|
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates window with notification
|
* Creates window with notification
|
||||||
|
@ -30,7 +31,13 @@ public class ServiceWindow {
|
||||||
alertBox.setTitle(title);
|
alertBox.setTitle(title);
|
||||||
alertBox.setHeaderText(null);
|
alertBox.setHeaderText(null);
|
||||||
alertBox.setContentText(body);
|
alertBox.setContentText(body);
|
||||||
alertBox.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); // Java bug workaround for linux
|
alertBox.getDialogPane().setMinWidth(Region.USE_PREF_SIZE);
|
||||||
|
alertBox.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||||
|
alertBox.setResizable(true);
|
||||||
alertBox.show();
|
alertBox.show();
|
||||||
|
|
||||||
|
Stage dialogStage = (Stage) alertBox.getDialogPane().getScene().getWindow();
|
||||||
|
dialogStage.setAlwaysOnTop(true);
|
||||||
|
dialogStage.toFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ public class SettingsController implements Initializable {
|
||||||
private Label pathToMplayerLbl;
|
private Label pathToMplayerLbl;
|
||||||
@FXML
|
@FXML
|
||||||
private CheckBox subtitlesFirstCheckBox;
|
private CheckBox subtitlesFirstCheckBox;
|
||||||
|
@FXML
|
||||||
|
private ChoiceBox<String> backEndEngineChoiceBox;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle resBundle) {
|
public void initialize(URL url, ResourceBundle resBundle) {
|
||||||
|
@ -55,6 +57,8 @@ public class SettingsController implements Initializable {
|
||||||
subEncodingListController.setList(appPreferences.getSubsEncodingList(), false);
|
subEncodingListController.setList(appPreferences.getSubsEncodingList(), false);
|
||||||
videoExtensionListController.setList(appPreferences.getVideoExtensionsList(), true);
|
videoExtensionListController.setList(appPreferences.getVideoExtensionsList(), true);
|
||||||
audioExtensionListController.setList(appPreferences.getAudioExtensionsList(), true);
|
audioExtensionListController.setList(appPreferences.getAudioExtensionsList(), true);
|
||||||
|
backEndEngineChoiceBox.getItems().addAll("mplayer", "mpv");
|
||||||
|
backEndEngineChoiceBox.getSelectionModel().select(appPreferences.getBackendEngineIndexId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -103,6 +107,7 @@ public class SettingsController implements Initializable {
|
||||||
appPreferences.setSubsEncodingList(subEncodingListController.getList());
|
appPreferences.setSubsEncodingList(subEncodingListController.getList());
|
||||||
appPreferences.setVideoExtensionsList(videoExtensionListController.getList());
|
appPreferences.setVideoExtensionsList(videoExtensionListController.getList());
|
||||||
appPreferences.setAudioExtensionsList(audioExtensionListController.getList());
|
appPreferences.setAudioExtensionsList(audioExtensionListController.getList());
|
||||||
|
appPreferences.setBackendEngineIndexId(backEndEngineChoiceBox.getSelectionModel().getSelectedIndex());
|
||||||
|
|
||||||
MediatorControl.getInstance().sentUpdates(); // TODO: implement list to track what should be updated
|
MediatorControl.getInstance().sentUpdates(); // TODO: implement list to track what should be updated
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,6 +238,7 @@ public class ControllerPane implements Initializable {
|
||||||
* Set files using lists. Used if playlist loaded
|
* Set files using lists. Used if playlist loaded
|
||||||
* */
|
* */
|
||||||
public void setFilesFromList(String[] fileLocations){
|
public void setFilesFromList(String[] fileLocations){
|
||||||
|
cleanList();
|
||||||
if (fileLocations != null && fileLocations.length != 0) {
|
if (fileLocations != null && fileLocations.length != 0) {
|
||||||
File[] files = new File[fileLocations.length];
|
File[] files = new File[fileLocations.length];
|
||||||
for (int i=0; i < fileLocations.length; i++)
|
for (int i=0; i < fileLocations.length; i++)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package mplayer4anime;
|
package mplayer4anime.mplayer;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package mplayer4anime;
|
package mplayer4anime.mplayer;
|
||||||
|
|
||||||
|
import mplayer4anime.ISlaveModeAppOrchestration;
|
||||||
|
import mplayer4anime.ServiceWindow;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
@ -42,7 +45,7 @@ public class MplayerSlave implements ISlaveModeAppOrchestration {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void subtitlesSwitch(){
|
public void subtitlesSwitch(){
|
||||||
if (! playerSingleCommand("get_sub_visibility"))
|
if (! playerSingleCommand("get_sub_visibility"))
|
||||||
return;
|
return;
|
||||||
|
@ -66,15 +69,15 @@ public class MplayerSlave implements ISlaveModeAppOrchestration {
|
||||||
System.out.println("Can't determine whether subtitles enabled or disabled");
|
System.out.println("Can't determine whether subtitles enabled or disabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void fullscreenSwitch(){
|
public void fullscreenSwitch(){
|
||||||
playerSingleCommand("vo_fullscreen");
|
playerSingleCommand("vo_fullscreen");
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void mute(){
|
public void mute(){
|
||||||
playerSingleCommand("mute");
|
playerSingleCommand("mute");
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void forcePlay(String mplayerPath,
|
public void forcePlay(String mplayerPath,
|
||||||
String VideoFile,
|
String VideoFile,
|
||||||
String AudioFile,
|
String AudioFile,
|
||||||
|
@ -94,7 +97,7 @@ public class MplayerSlave implements ISlaveModeAppOrchestration {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public boolean pause(){
|
public boolean pause(){
|
||||||
if (player == null || !player.isAlive())
|
if (player == null || !player.isAlive())
|
||||||
return false;
|
return false;
|
||||||
|
@ -103,7 +106,7 @@ public class MplayerSlave implements ISlaveModeAppOrchestration {
|
||||||
playerIn.flush();
|
playerIn.flush();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void playPause(String mplayerPath,
|
public void playPause(String mplayerPath,
|
||||||
String VideoFile,
|
String VideoFile,
|
||||||
String AudioFile,
|
String AudioFile,
|
||||||
|
@ -155,15 +158,15 @@ public class MplayerSlave implements ISlaveModeAppOrchestration {
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToStartMplayer"));
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToStartMplayer"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void stop(){
|
public void stop(){
|
||||||
playerSingleCommand("stop");
|
playerSingleCommand("stop");
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void volumeUp(){
|
public void volumeUp(){
|
||||||
playerSingleCommand("volume +1 0");
|
playerSingleCommand("volume +1 0");
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void volumeDown(){
|
public void volumeDown(){
|
||||||
playerSingleCommand("volume -1 0");
|
playerSingleCommand("volume -1 0");
|
||||||
}
|
}
|
108
src/main/java/mplayer4anime/mpv/MpvJniLibraryLoader.java
Normal file
108
src/main/java/mplayer4anime/mpv/MpvJniLibraryLoader.java
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
96
src/main/java/mplayer4anime/mpv/MpvSlave.java
Normal file
96
src/main/java/mplayer4anime/mpv/MpvSlave.java
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void subtitlesSwitch() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fullscreenSwitch() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mute() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forcePlay(String mplayerPath,
|
||||||
|
String VideoFile,
|
||||||
|
String AudioFile,
|
||||||
|
String SubtitlesFile,
|
||||||
|
String subtitlesEncoding,
|
||||||
|
boolean subtitlesHidden,
|
||||||
|
boolean isFullscreen) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean pause() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void playPause(String mplayerPath,
|
||||||
|
String VideoFile,
|
||||||
|
String AudioFile,
|
||||||
|
String SubtitlesFile,
|
||||||
|
String subtitlesEncoding,
|
||||||
|
boolean subtitlesHidden,
|
||||||
|
boolean isFullscreen) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void volumeUp() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void volumeDown() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.CheckBox?>
|
<?import javafx.scene.control.CheckBox?>
|
||||||
|
<?import javafx.scene.control.ChoiceBox?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.Tab?>
|
<?import javafx.scene.control.Tab?>
|
||||||
<?import javafx.scene.control.TabPane?>
|
<?import javafx.scene.control.TabPane?>
|
||||||
|
@ -42,6 +43,12 @@
|
||||||
<Font name="System Italic" size="12.0" />
|
<Font name="System Italic" size="12.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<Label text="%settings_backendSelect" />
|
||||||
|
<ChoiceBox fx:id="backEndEngineChoiceBox" prefWidth="150.0" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
<HBox alignment="CENTER_LEFT" VBox.vgrow="NEVER">
|
<HBox alignment="CENTER_LEFT" VBox.vgrow="NEVER">
|
||||||
<children>
|
<children>
|
||||||
<CheckBox fx:id="subtitlesFirstCheckBox" mnemonicParsing="false" text="%settings_SubtitlesTabFirst" />
|
<CheckBox fx:id="subtitlesFirstCheckBox" mnemonicParsing="false" text="%settings_SubtitlesTabFirst" />
|
||||||
|
|
|
@ -53,6 +53,7 @@ settings_Tab_Subtitles=Subtitles
|
||||||
settings_videoExtensionList=Avaliable video files extensions:
|
settings_videoExtensionList=Avaliable video files extensions:
|
||||||
settings_audioExtensionList=Avaliable audio layer extensions:
|
settings_audioExtensionList=Avaliable audio layer extensions:
|
||||||
ApplyBtn=Apply
|
ApplyBtn=Apply
|
||||||
|
settings_backendSelect=Backend engine:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,4 +53,5 @@ settings_Tab_Video=\u0412\u0438\u0434\u0435\u043E
|
||||||
settings_videoExtensionList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u0434\u043B\u044F \u0444\u0430\u0439\u043B\u043E\u0432 \u0432\u0438\u0434\u0435\u043E:
|
settings_videoExtensionList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u0434\u043B\u044F \u0444\u0430\u0439\u043B\u043E\u0432 \u0432\u0438\u0434\u0435\u043E:
|
||||||
settings_audioExtensionList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u0434\u043B\u044F \u0430\u0443\u0434\u0438\u043E\u0434\u043E\u0440\u043E\u0436\u0435\u043A:
|
settings_audioExtensionList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u0434\u043B\u044F \u0430\u0443\u0434\u0438\u043E\u0434\u043E\u0440\u043E\u0436\u0435\u043A:
|
||||||
ApplyBtn=\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C
|
ApplyBtn=\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C
|
||||||
|
settings_backendSelect=\u0414\u0432\u0438\u0436\u043E\u043A \u0432\u043E\u0441\u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0434\u0435\u043D\u0438\u044F:
|
||||||
|
|
||||||
|
|
BIN
src/main/resources/native/linux/amd64/mpvjni.so
Executable file
BIN
src/main/resources/native/linux/amd64/mpvjni.so
Executable file
Binary file not shown.
BIN
src/main/resources/native/linux/x86/mpvjni.so
Executable file
BIN
src/main/resources/native/linux/x86/mpvjni.so
Executable file
Binary file not shown.
Loading…
Reference in a new issue