Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Jannik | 3805e6563d |
|
@ -1,5 +0,0 @@
|
|||
pipeline:
|
||||
package:
|
||||
image: maven
|
||||
commands:
|
||||
- mvn clean package
|
|
@ -1,6 +1,5 @@
|
|||
[![Build Status](https://ci.mosad.xyz/api/badges/Seil0/Project-HomeFlix/status.svg)](https://ci.mosad.xyz/Seil0/Project-HomeFlix) [![Latest](https://img.shields.io/badge/Download-latest-brightgreen.svg)](https://git.mosad.xyz/Seil0/Project-HomeFlix/releases)
|
||||
[![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://git.mosad.xyz/api/v1/repos/Seil0/Project-HomeFlix/releases&query=$[0].tag_name)](https://git.mosad.xyz/Seil0/Project-HomeFlix/releases)
|
||||
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[![Latest](https://img.shields.io/badge/Download-latest-brightgreen.svg?style=flat-square)](https://git.mosad.xyz/Seil0/Project-HomeFlix/releases)
|
||||
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg?style=flat-square)](https://www.gnu.org/licenses/gpl-3.0)
|
||||
|
||||
# Project-HomeFlix
|
||||
Project-HomeFlix is a Kellerkinder Project, that alowes you to sort all your local saved movies in clean UI. Project-HomeFlix is free and open-source software and uses other open-source projects to provied a nice user experience.
|
||||
|
@ -14,6 +13,6 @@ The dev branch is **only merged** into master when a **new release** is released
|
|||
[Libraries used in this Project](https://git.mosad.xyz/Seil0/Project-HomeFlix/wiki/Documentation#used-libraries-and-apis)
|
||||
|
||||
## Screenshots
|
||||
![Screenshot](https://raw.githubusercontent.com/Seil0/Seil0.github.io/master/images/Project-HomeFlix_MainWindow.webp)
|
||||
![Screenshot](https://raw.githubusercontent.com/Seil0/Seil0.github.io/master/images/Project-HomeFlix_MainWindow.png)
|
||||
|
||||
Project-HomeFlix © 2016-2019 mosad www.mosad.xyz, Project by [@Seil0](https://git.mosad.xyz/Seil0) and [@localhorst](https://git.mosad.xyz/localhorst)
|
||||
|
|
41
pom.xml
|
@ -3,17 +3,16 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.mosad</groupId>
|
||||
<groupId>org.kellerkinder</groupId>
|
||||
<artifactId>Project-HomeFlix</artifactId>
|
||||
<version>0.8.0</version>
|
||||
<version>0.7.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Project-HomeFlix</name>
|
||||
<url>https://www.mosad.xyz</url>
|
||||
<url>http://www.mosad.xyz</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<javafx.version>16</javafx.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -21,44 +20,38 @@
|
|||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<version>12.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<version>12.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>uk.co.caprica</groupId>
|
||||
<artifactId>vlcj</artifactId>
|
||||
<version>4.5.2</version>
|
||||
<version>12.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.11.0</version>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jfoenix</groupId>
|
||||
<artifactId>jfoenix</artifactId>
|
||||
<version>9.0.10</version>
|
||||
<version>9.0.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -70,19 +63,19 @@
|
|||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.36.0.3</version>
|
||||
<version>3.27.2.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.11.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.11.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -92,7 +85,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
|
@ -105,7 +98,7 @@
|
|||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>1.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
@ -114,21 +107,21 @@
|
|||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<mainClass>org.mosad.homeflix.application.Main</mainClass>
|
||||
<mainClass>kellerkinder.HomeFlix.application.Main</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.2.1</version>
|
||||
<configuration>
|
||||
<finalName>Project-HomeFlix</finalName>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.mosad.homeflix.application.JavaFX11Main</mainClass>
|
||||
<mainClass>kellerkinder.HomeFlix.application.JavaFX11Main</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.application.view;
|
||||
package kellerkinder.HomeFlix.application;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.File;
|
||||
|
@ -28,20 +28,24 @@ import java.io.IOException;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.controller.DBController;
|
||||
import org.mosad.homeflix.controller.XMLController;
|
||||
import org.mosad.homeflix.datatypes.OMDbAPIResponseDataType;
|
||||
import org.mosad.homeflix.player.Player;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.Duration;
|
||||
import kellerkinder.HomeFlix.controller.DBController;
|
||||
import kellerkinder.HomeFlix.controller.XMLController;
|
||||
import kellerkinder.HomeFlix.player.Player;
|
||||
|
||||
public class FilmDetailView extends DetailView {
|
||||
public class FilmDetailView {
|
||||
|
||||
@FXML private AnchorPane filmDVPane;
|
||||
|
||||
@FXML private Label lblTitle;
|
||||
@FXML private Label lblYear;
|
||||
|
@ -83,7 +87,7 @@ public class FilmDetailView extends DetailView {
|
|||
|
||||
public void initialize() {
|
||||
dbController = DBController.getInstance();
|
||||
rootPane.setStyle("-fx-background-color: rgba(89,89,89,0.9);");
|
||||
filmDVPane.setStyle("-fx-background-color: rgba(89,89,89,0.9);");
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
@ -110,7 +114,7 @@ public class FilmDetailView extends DetailView {
|
|||
|
||||
@FXML
|
||||
private void btnPlayAction() {
|
||||
new Player(currentStreamURL);
|
||||
playFilm();
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
@ -132,29 +136,29 @@ public class FilmDetailView extends DetailView {
|
|||
*/
|
||||
public void setFilm(String streamURL) {
|
||||
currentStreamURL = streamURL;
|
||||
OMDbAPIResponseDataType cacheInfo = dbController.readCache(streamURL); // get the cache data from the database
|
||||
String[] cacheInfo = dbController.readCache(streamURL); // get the cache data from the database
|
||||
|
||||
// add the cache data to the GUI
|
||||
lblTitle.setText(cacheInfo.getTitle());
|
||||
lblYear.setText("(" + cacheInfo.getYear() + ")");
|
||||
lblScore.setText(XMLController.getLocalBundle().getString("score") + ": " + cacheInfo.getMetascore() + "%");
|
||||
lblTitle.setText(cacheInfo[0]);
|
||||
lblYear.setText("(" + cacheInfo[1] + ")");
|
||||
lblScore.setText(XMLController.getLocalBundle().getString("score") + ": " + cacheInfo[15] + "%");
|
||||
|
||||
textPlot.setText(cacheInfo.getPlot());
|
||||
textPlot.setText(cacheInfo[11]);
|
||||
|
||||
lblDirectors.setText(cacheInfo.getDirector());
|
||||
lblWriters.setText(cacheInfo.getWriter());
|
||||
lblActors.setText(cacheInfo.getActors());
|
||||
lblDirectors.setText(cacheInfo[8]);
|
||||
lblWriters.setText(cacheInfo[9]);
|
||||
lblActors.setText(cacheInfo[10]);
|
||||
|
||||
lblRuntime.setText(cacheInfo.getRuntime());
|
||||
lblLanguage.setText(cacheInfo.getLanguage());
|
||||
lblRevenue.setText(cacheInfo.getBoxOffice());
|
||||
lblRating.setText(cacheInfo.getRated());
|
||||
lblRuntime.setText(cacheInfo[6]);
|
||||
lblLanguage.setText(cacheInfo[12]);
|
||||
lblRevenue.setText(cacheInfo[18]);
|
||||
lblRating.setText(cacheInfo[2]);
|
||||
|
||||
try {
|
||||
if (new File(cacheInfo.getPoster()).isFile()) {
|
||||
imgPoster.setImage(new Image(new File(cacheInfo.getPoster()).toURI().toString()));
|
||||
if (new File(cacheInfo[20]).isFile()) {
|
||||
imgPoster.setImage(new Image(new File(cacheInfo[20]).toURI().toString()));
|
||||
} else {
|
||||
imgPoster.setImage(new Image(cacheInfo.getPoster()));
|
||||
imgPoster.setImage(new Image(cacheInfo[20]));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
imgPoster.setImage(new Image("icons/Homeflix_Poster.png"));
|
||||
|
@ -173,7 +177,6 @@ public class FilmDetailView extends DetailView {
|
|||
/**
|
||||
* update the text of all static GUI elements of FilmDeatilView
|
||||
*/
|
||||
@Override
|
||||
public void updateGUILocal() {
|
||||
lblCrew.setText(XMLController.getLocalBundle().getString("crew"));
|
||||
lblDirectorsInfo.setText(XMLController.getLocalBundle().getString("directors"));
|
||||
|
@ -186,5 +189,38 @@ public class FilmDetailView extends DetailView {
|
|||
lblRevenueInfo.setText(XMLController.getLocalBundle().getString("boxOffice"));
|
||||
lblRatingInfo.setText(XMLController.getLocalBundle().getString("rated"));
|
||||
}
|
||||
|
||||
/**
|
||||
* show the FilmDVpane
|
||||
*/
|
||||
public void showPane() {
|
||||
filmDVPane.setVisible(true);
|
||||
FadeTransition fadeIn = new FadeTransition(Duration.millis(300), filmDVPane);
|
||||
fadeIn.setFromValue(0.3);
|
||||
fadeIn.setToValue(1.0);
|
||||
fadeIn.play();
|
||||
}
|
||||
|
||||
/**
|
||||
* hide the FilmDVpane
|
||||
*/
|
||||
private void hidePane() {
|
||||
FadeTransition fadeOut = new FadeTransition(Duration.millis(200), filmDVPane);
|
||||
fadeOut.setFromValue(1.0);
|
||||
fadeOut.setToValue(0.3);
|
||||
fadeOut.play();
|
||||
|
||||
filmDVPane.setVisible(false);
|
||||
|
||||
MainWindowController.getInstance().disableBlur(); // disable blur
|
||||
}
|
||||
|
||||
private void playFilm() {
|
||||
if(new File(currentStreamURL).isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
new Player(currentStreamURL);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.mosad.homeflix.application;
|
||||
package kellerkinder.HomeFlix.application;
|
||||
|
||||
public class JavaFX11Main {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,15 +20,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.application;
|
||||
package kellerkinder.HomeFlix.application;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.controller.DBController;
|
||||
import org.mosad.homeflix.controller.XMLController;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -36,6 +34,7 @@ import javafx.scene.Scene;
|
|||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.stage.Stage;
|
||||
import kellerkinder.HomeFlix.controller.XMLController;
|
||||
|
||||
public class Main extends Application {
|
||||
|
||||
|
@ -44,14 +43,12 @@ public class Main extends Application {
|
|||
private MainWindowController mainWindowController;
|
||||
private static XMLController xmlController;
|
||||
private static Logger LOGGER;
|
||||
public static final String version = "0.8.91";
|
||||
public static final String buildNumber = "177";
|
||||
public static final String versionName = "nimbly xlr8";
|
||||
|
||||
// TODO rename streamURL to mediaURL
|
||||
public static final String version = "0.8.0";
|
||||
public static final String buildNumber = "173";
|
||||
public static final String versionName = "toothless dragon";
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
|
||||
//initialize the mainWindowController and the primaryStage
|
||||
try {
|
||||
|
@ -63,10 +60,7 @@ public class Main extends Application {
|
|||
//primaryStage.setResizable(false);
|
||||
primaryStage.setTitle("Project HomeFlix");
|
||||
primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); //adds application icon
|
||||
primaryStage.setOnCloseRequest(event -> {
|
||||
DBController.getInstance().closeDBConnection();
|
||||
System.exit(0);
|
||||
});
|
||||
primaryStage.setOnCloseRequest(event -> System.exit(0));
|
||||
|
||||
// generate window
|
||||
scene = new Scene(pane); // create new scene, append pane to scene
|
||||
|
@ -104,9 +98,7 @@ public class Main extends Application {
|
|||
LOGGER.info("Java: " + XMLController.getJavaVend() + " " + XMLController.getJavaVers());
|
||||
LOGGER.info("User: " + XMLController.getUserName() + " " + XMLController.getUserHome());
|
||||
|
||||
xmlController = new XMLController(); // Initialize the XMLController
|
||||
|
||||
// TODO run Migrations
|
||||
xmlController = new XMLController();
|
||||
|
||||
if (!XMLController.getConfigFile().exists()) {
|
||||
xmlController.saveSettings(); // save the settings file with default values if it doesn't exist
|
||||
|
@ -118,7 +110,7 @@ public class Main extends Application {
|
|||
XMLController.getPosterCache().mkdir();
|
||||
}
|
||||
|
||||
launch();
|
||||
launch(args);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.application;
|
||||
package kellerkinder.HomeFlix.application;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
|
@ -39,14 +39,6 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import org.kellerkinder.Alerts.JFX2BtnCancelAlert;
|
||||
import org.kellerkinder.Alerts.JFXInfoAlert;
|
||||
import org.mosad.homeflix.application.view.FilmDetailView;
|
||||
import org.mosad.homeflix.application.view.SeriesDetailView;
|
||||
import org.mosad.homeflix.controller.DBController;
|
||||
import org.mosad.homeflix.controller.OMDbAPIController;
|
||||
import org.mosad.homeflix.controller.UpdateController;
|
||||
import org.mosad.homeflix.controller.XMLController;
|
||||
import org.mosad.homeflix.datatypes.FilmTabelDataType;
|
||||
import org.mosad.homeflix.datatypes.PosterModeElement;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonArray;
|
||||
|
@ -71,6 +63,12 @@ import javafx.stage.DirectoryChooser;
|
|||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
import kellerkinder.HomeFlix.controller.DBController;
|
||||
import kellerkinder.HomeFlix.controller.OMDbAPIController;
|
||||
import kellerkinder.HomeFlix.controller.UpdateController;
|
||||
import kellerkinder.HomeFlix.controller.XMLController;
|
||||
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
||||
import kellerkinder.HomeFlix.datatypes.PosterModeElement;
|
||||
|
||||
public class MainWindowController {
|
||||
|
||||
|
@ -106,7 +104,7 @@ public class MainWindowController {
|
|||
private String btnStyle;
|
||||
|
||||
private ObservableList<PosterModeElement> posterEmenents = FXCollections.observableArrayList();
|
||||
private final LocalDate lastValidCache = LocalDate.now().minusDays(30); // current date - 30 days is the last valid cache date
|
||||
private LocalDate lastValidCache = LocalDate.now().minusDays(30); // current date - 30 days is the last valid cache date
|
||||
|
||||
public MainWindowController() {
|
||||
// the constructor
|
||||
|
@ -149,7 +147,7 @@ public class MainWindowController {
|
|||
|
||||
// load data list in gui
|
||||
posterModeStartup();
|
||||
|
||||
|
||||
checkAutoUpdate(); // TODO async
|
||||
}
|
||||
|
||||
|
@ -158,7 +156,7 @@ public class MainWindowController {
|
|||
|
||||
// general actions
|
||||
HamburgerBackArrowBasicTransition burgerTask = new HamburgerBackArrowBasicTransition(menuHam);
|
||||
menuHam.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> {
|
||||
menuHam.addEventHandler(MouseEvent.MOUSE_PRESSED, (e) -> {
|
||||
|
||||
if (menuTrue) {
|
||||
sideMenuSlideOut();
|
||||
|
@ -360,27 +358,29 @@ public class MainWindowController {
|
|||
* check if all posters are cached, if not cache the missing ones
|
||||
*/
|
||||
void checkAllPosters() {
|
||||
dbController.refreshDataBase(); // refreshes the database after a source path was added
|
||||
|
||||
// get all not cached entries, none of them should have a cached poster
|
||||
ExecutorService executor = Executors.newFixedThreadPool(5);
|
||||
|
||||
dbController.refreshDataBase(); // refreshes the database after a source path was added
|
||||
|
||||
// get all not cached entries
|
||||
for (FilmTabelDataType entry : dbController.getAllNotCachedEntries()) {
|
||||
// System.out.println(entry.getStreamUrl() + " is NOT cached!");
|
||||
|
||||
Runnable OMDbAPIWorker = new OMDbAPIController(entry);
|
||||
executor.execute(OMDbAPIWorker);
|
||||
}
|
||||
executor.shutdown();
|
||||
|
||||
// TODO show loading screen
|
||||
|
||||
// wait for all OMDbAPI requests to finish
|
||||
|
||||
// we might need this as otherwise it would load before all tasks are finished
|
||||
try {
|
||||
executor.awaitTermination(1, TimeUnit.MINUTES);
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
LOGGER.info("finished refresh");
|
||||
|
||||
System.out.println("finished refresh");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,7 +393,7 @@ public class MainWindowController {
|
|||
|
||||
// add button onAction
|
||||
for (PosterModeElement element : posterEmenents) {
|
||||
element.getButton().addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
|
||||
element.getButton().addEventHandler(MouseEvent.MOUSE_CLICKED, (event) -> {
|
||||
enableBlur(); // blur the FlowPane
|
||||
|
||||
// if the selected element is a file it's a film, else a series
|
||||
|
@ -409,6 +409,8 @@ public class MainWindowController {
|
|||
|
||||
posterModeFlowPane.getChildren().clear(); // remove all GUIElements from the posterModeFlowPane
|
||||
posterModeFlowPane.getChildren().addAll(posterEmenents); // add all films/series as new GUIElements to the posterModeFlowPane
|
||||
|
||||
System.out.println("added gui elements");
|
||||
}
|
||||
|
||||
// TODO can this be done in dbController? with dbController.refreshDataBase();
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.application.view;
|
||||
package kellerkinder.HomeFlix.application;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.File;
|
||||
|
@ -28,14 +28,10 @@ import java.io.IOException;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.controller.DBController;
|
||||
import org.mosad.homeflix.controller.XMLController;
|
||||
import org.mosad.homeflix.datatypes.OMDbAPIResponseDataType;
|
||||
import org.mosad.homeflix.datatypes.SeriesDVEpisode;
|
||||
import org.mosad.homeflix.player.Player;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -45,11 +41,18 @@ import javafx.scene.control.ScrollPane;
|
|||
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.Duration;
|
||||
import kellerkinder.HomeFlix.controller.DBController;
|
||||
import kellerkinder.HomeFlix.controller.XMLController;
|
||||
import kellerkinder.HomeFlix.datatypes.SeriresDVEpisode;
|
||||
import kellerkinder.HomeFlix.player.Player;
|
||||
|
||||
public class SeriesDetailView extends DetailView {
|
||||
public class SeriesDetailView {
|
||||
|
||||
@FXML private AnchorPane seriesDVPane;
|
||||
@FXML private ScrollPane scrollPaneEpisodes;
|
||||
|
||||
@FXML private HBox hBoxEpisodes;
|
||||
|
@ -86,7 +89,7 @@ public class SeriesDetailView extends DetailView {
|
|||
|
||||
public void initialize() {
|
||||
dbController = DBController.getInstance();
|
||||
rootPane.setStyle("-fx-background-color: rgba(89,89,89,0.9);");
|
||||
seriesDVPane.setStyle("-fx-background-color: rgba(89,89,89,0.9);");
|
||||
scrollPaneEpisodes.setStyle("-fx-background-color: transparent;");
|
||||
scrollPaneEpisodes.setHbarPolicy(ScrollBarPolicy.ALWAYS);
|
||||
|
||||
|
@ -141,21 +144,21 @@ public class SeriesDetailView extends DetailView {
|
|||
*/
|
||||
public void setSeries(String streamURL) {
|
||||
currentStreamURL = streamURL;
|
||||
OMDbAPIResponseDataType cacheInfo = dbController.readCache(streamURL); // get the cache data from the database
|
||||
String[] cacheInfo = dbController.readCache(streamURL); // get the cache data from the database
|
||||
|
||||
// add the cache data to the GUI
|
||||
lblTitle.setText(cacheInfo.getTitle());
|
||||
lblYear.setText("(" + cacheInfo.getYear() + ")");
|
||||
lblScore.setText(XMLController.getLocalBundle().getString("score") + ": " + cacheInfo.getMetascore() + "%");
|
||||
lblTitle.setText(cacheInfo[0]);
|
||||
lblYear.setText("(" + cacheInfo[1] + ")");
|
||||
lblScore.setText(XMLController.getLocalBundle().getString("score") + ": " + cacheInfo[15] + "%");
|
||||
|
||||
textPlot.setText(cacheInfo.getPlot());
|
||||
textPlot.setText(cacheInfo[11]);
|
||||
|
||||
lblDirectors.setText(cacheInfo.getDirector());
|
||||
lblWriters.setText(cacheInfo.getWriter());
|
||||
lblActors.setText(cacheInfo.getActors());
|
||||
lblDirectors.setText(cacheInfo[8]);
|
||||
lblWriters.setText(cacheInfo[9]);
|
||||
lblActors.setText(cacheInfo[10]);
|
||||
|
||||
try {
|
||||
imgPoster.setImage(new Image(new File(cacheInfo.getPoster()).toURI().toString()));
|
||||
imgPoster.setImage(new Image(new File(cacheInfo[20]).toURI().toString()));
|
||||
} catch (Exception e) {
|
||||
imgPoster.setImage(new Image("icons/Homeflix_Poster.png"));
|
||||
LOGGER.error("No Poster found, useing default.");
|
||||
|
@ -184,7 +187,6 @@ public class SeriesDetailView extends DetailView {
|
|||
/**
|
||||
* update the text of all static GUI elements of FilmDeatilView
|
||||
*/
|
||||
@Override
|
||||
public void updateGUILocal() {
|
||||
lblCrew.setText(XMLController.getLocalBundle().getString("crew"));
|
||||
lblDirectorsInfo.setText(XMLController.getLocalBundle().getString("directors"));
|
||||
|
@ -192,6 +194,31 @@ public class SeriesDetailView extends DetailView {
|
|||
lblActorsInfo.setText(XMLController.getLocalBundle().getString("actors"));
|
||||
}
|
||||
|
||||
/**
|
||||
* show the FilmDVpane
|
||||
*/
|
||||
public void showPane() {
|
||||
seriesDVPane.setVisible(true);
|
||||
FadeTransition fadeIn = new FadeTransition(Duration.millis(300), seriesDVPane);
|
||||
fadeIn.setFromValue(0.3);
|
||||
fadeIn.setToValue(1.0);
|
||||
fadeIn.play();
|
||||
}
|
||||
|
||||
/**
|
||||
* hide the FilmDVpane
|
||||
*/
|
||||
private void hidePane() {
|
||||
FadeTransition fadeOut = new FadeTransition(Duration.millis(200), seriesDVPane);
|
||||
fadeOut.setFromValue(1.0);
|
||||
fadeOut.setToValue(0.3);
|
||||
fadeOut.play();
|
||||
|
||||
seriesDVPane.setVisible(false);
|
||||
|
||||
MainWindowController.getInstance().disableBlur(); // disable blur
|
||||
}
|
||||
|
||||
/**
|
||||
* add all episodes of one season to the ScrollPane
|
||||
* @param season the season to add
|
||||
|
@ -205,7 +232,7 @@ public class SeriesDetailView extends DetailView {
|
|||
} catch (Exception e) {
|
||||
poster = new Image("icons/Homeflix_Poster.png");
|
||||
}
|
||||
hBoxEpisodes.getChildren().add(new SeriesDVEpisode(episodePoster[0], episodePoster[1], poster));
|
||||
hBoxEpisodes.getChildren().add(new SeriresDVEpisode(episodePoster[0], episodePoster[1], poster));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.application;
|
||||
package kellerkinder.HomeFlix.application;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
|
@ -30,11 +30,6 @@ import java.io.Writer;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.application.view.FilmDetailView;
|
||||
import org.mosad.homeflix.controller.DBController;
|
||||
import org.mosad.homeflix.controller.UpdateController;
|
||||
import org.mosad.homeflix.controller.XMLController;
|
||||
import org.mosad.homeflix.datatypes.SourceDataType;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonArray;
|
||||
|
@ -59,6 +54,10 @@ import javafx.scene.layout.AnchorPane;
|
|||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import kellerkinder.HomeFlix.controller.DBController;
|
||||
import kellerkinder.HomeFlix.controller.UpdateController;
|
||||
import kellerkinder.HomeFlix.controller.XMLController;
|
||||
import kellerkinder.HomeFlix.datatypes.SourceDataType;
|
||||
|
||||
public class SettingsView {
|
||||
|
||||
|
@ -87,7 +86,6 @@ public class SettingsView {
|
|||
|
||||
@FXML private JFXToggleButton autoUpdateToggleBtn;
|
||||
@FXML private JFXToggleButton autoplayToggleBtn;
|
||||
@FXML private JFXToggleButton fullscreenToggleBtn;
|
||||
|
||||
@FXML private TableView<SourceDataType> sourcesTable;
|
||||
@FXML private TableColumn<SourceDataType, String> sourceColumn;
|
||||
|
@ -110,7 +108,6 @@ public class SettingsView {
|
|||
|
||||
autoUpdateToggleBtn.setSelected(XMLController.isAutoUpdate());
|
||||
autoplayToggleBtn.setSelected(XMLController.isAutoplay());
|
||||
fullscreenToggleBtn.setSelected(XMLController.isFullscreen());
|
||||
languageChoisBox.setItems(languages);
|
||||
branchChoisBox.setItems(branches);
|
||||
|
||||
|
@ -199,12 +196,6 @@ public class SettingsView {
|
|||
XMLController.setAutoplay(!XMLController.isAutoplay());
|
||||
xmlController.saveSettings();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void fullscreenToggleBtnAction(ActionEvent event) {
|
||||
XMLController.setFullscreen(!XMLController.isFullscreen());
|
||||
xmlController.saveSettings();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void colorPickerAction(ActionEvent event) {
|
||||
|
@ -215,12 +206,16 @@ public class SettingsView {
|
|||
|
||||
@FXML
|
||||
private void updateBtnAction(ActionEvent event) {
|
||||
|
||||
|
||||
new UpdateController();
|
||||
if (UpdateController.isUpdateAvailable()) {
|
||||
updateBtn.setText(XMLController.getLocalBundle().getString("updateBtnUpdateAvailable"));
|
||||
UpdateController.update();
|
||||
} else {
|
||||
updateBtn.setText(XMLController.getLocalBundle().getString("updateBtnNoUpdateAvailable"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** TODO can this be done async?
|
||||
|
@ -280,8 +275,6 @@ public class SettingsView {
|
|||
autoUpdateToggleBtn.setToggleLineColor(Color.valueOf(XMLController.getColor()));
|
||||
autoplayToggleBtn.setToggleColor(Color.valueOf(XMLController.getColor()));
|
||||
autoplayToggleBtn.setToggleLineColor(Color.valueOf(XMLController.getColor()));
|
||||
fullscreenToggleBtn.setToggleColor(Color.valueOf(XMLController.getColor()));
|
||||
fullscreenToggleBtn.setToggleLineColor(Color.valueOf(XMLController.getColor()));
|
||||
}
|
||||
|
||||
public void updateGUILocal() {
|
||||
|
@ -298,7 +291,6 @@ public class SettingsView {
|
|||
|
||||
autoUpdateToggleBtn.setText(XMLController.getLocalBundle().getString("autoUpdate"));
|
||||
autoplayToggleBtn.setText(XMLController.getLocalBundle().getString("autoplay"));
|
||||
fullscreenToggleBtn.setText(XMLController.getLocalBundle().getString("fullscreen"));
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,7 +19,7 @@
|
|||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.controller;
|
||||
package kellerkinder.HomeFlix.controller;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -38,14 +38,14 @@ import java.util.List;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.datatypes.DatabaseDataType;
|
||||
import org.mosad.homeflix.datatypes.FilmTabelDataType;
|
||||
import org.mosad.homeflix.datatypes.OMDbAPIResponseDataType;
|
||||
import org.mosad.homeflix.datatypes.PosterModeElement;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.image.Image;
|
||||
import kellerkinder.HomeFlix.datatypes.DatabaseDataType;
|
||||
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
||||
import kellerkinder.HomeFlix.datatypes.OMDbAPIResponseDataType;
|
||||
import kellerkinder.HomeFlix.datatypes.PosterModeElement;
|
||||
|
||||
public class DBController {
|
||||
|
||||
|
@ -103,13 +103,15 @@ public class DBController {
|
|||
* cache table: streamUrl is primary key
|
||||
*/
|
||||
private void createDatabase() {
|
||||
try (Statement stmt = connection.createStatement();) {
|
||||
try {
|
||||
Statement stmt = connection.createStatement();
|
||||
stmt.executeUpdate("create table if not exists films (streamUrl, title, season, episode, favorite, cached, currentTime)");
|
||||
stmt.executeUpdate("create table if not exists cache ("
|
||||
+ "streamUrl, Title, Year, Rated, Released, Season, Episode ,Runtime, Genre, Director, Writer,"
|
||||
+ " Actors, Plot, Language, Country, Awards, Poster, Metascore, imdbRating, imdbVotes,"
|
||||
+ " imdbID, Type, dvd, BoxOffice, Website, Response)");
|
||||
connection.commit();
|
||||
stmt.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
@ -120,16 +122,16 @@ public class DBController {
|
|||
*/
|
||||
private void loadDatabase() {
|
||||
// get all entries from the table
|
||||
try (Statement stmt = connection.createStatement();) {
|
||||
|
||||
try (ResultSet rs = stmt.executeQuery("SELECT * FROM films");) {
|
||||
while (rs.next()) {
|
||||
databaseStreams.add(new DatabaseDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode"),
|
||||
rs.getInt("favorite"), rs.getDouble("currentTime")));
|
||||
}
|
||||
try {
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT * FROM films");
|
||||
while (rs.next()) {
|
||||
databaseStreams.add(new DatabaseDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode"),
|
||||
rs.getInt("favorite"), rs.getDouble("currentTime")));
|
||||
}
|
||||
|
||||
stmt.close();
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
|
@ -143,18 +145,6 @@ public class DBController {
|
|||
sourceStreams = sourcesController.loadSources();
|
||||
}
|
||||
|
||||
/**
|
||||
* try to close the databse connection
|
||||
*/
|
||||
public void closeDBConnection( ) {
|
||||
try {
|
||||
connection.commit();
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Error while trying to close the databse connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load all streams from the database to a ObservableList, order entries by title
|
||||
* @return a ObservableList that contains all streams from the database
|
||||
|
@ -162,17 +152,17 @@ public class DBController {
|
|||
public ObservableList<FilmTabelDataType> getStreamsList() {
|
||||
ObservableList<FilmTabelDataType> filmsList = FXCollections.observableArrayList();
|
||||
LOGGER.info("loading data from database ...");
|
||||
|
||||
//load local Data
|
||||
try (Statement stmt = connection.createStatement(); ) {
|
||||
try {
|
||||
//load local Data
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT * FROM films ORDER BY title");
|
||||
|
||||
try (ResultSet rs = stmt.executeQuery("SELECT * FROM films ORDER BY title");) {
|
||||
while (rs.next()) {
|
||||
filmsList.add(new FilmTabelDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode")));
|
||||
}
|
||||
while (rs.next()) {
|
||||
filmsList.add(new FilmTabelDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode")));
|
||||
}
|
||||
|
||||
stmt.close();
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
|
@ -188,16 +178,17 @@ public class DBController {
|
|||
public FilmTabelDataType getStream(String streamUrl) {
|
||||
FilmTabelDataType film = null;
|
||||
LOGGER.info("refresh data for " + streamUrl);
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM films WHERE streamUrl = ?");) {
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT * FROM films WHERE streamUrl = ?");
|
||||
ps.setString(1, streamUrl);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
while (rs.next()) {
|
||||
film = new FilmTabelDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode"));
|
||||
}
|
||||
while (rs.next()) {
|
||||
film = new FilmTabelDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode"));
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Ups! error while refreshing mwc!", e);
|
||||
}
|
||||
|
@ -210,24 +201,25 @@ public class DBController {
|
|||
* @return a ObservableList of PosterModeElements
|
||||
*/
|
||||
public ObservableList<PosterModeElement> getPosterElementsList() {
|
||||
|
||||
ObservableList<PosterModeElement> posterElementsList = FXCollections.observableArrayList();
|
||||
LOGGER.info("loading data from database ...");
|
||||
|
||||
//load local Data
|
||||
try (Statement stmt = connection.createStatement();) {
|
||||
try {
|
||||
//load local Data
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE season = '' OR season = '0' ORDER BY title");
|
||||
|
||||
try (ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE season = '' OR season = '0' ORDER BY title");) {
|
||||
while (rs.next()) {
|
||||
String[] cacheData = readCacheLegacy(rs.getString("streamUrl")); // get from the cache table
|
||||
|
||||
if(cacheData[20] != null && cacheData[20].length() > 0) {
|
||||
posterElementsList.add(new PosterModeElement(rs.getString("streamUrl"), cacheData[0], new Image(new File(cacheData[20]).toURI().toString())));
|
||||
} else {
|
||||
posterElementsList.add(new PosterModeElement(rs.getString("streamUrl"), cacheData[0], new Image("icons/Homeflix_Poster.png")));
|
||||
}
|
||||
while (rs.next()) {
|
||||
String[] cacheData = readCache(rs.getString("streamUrl")); // get from the cache table
|
||||
|
||||
if(cacheData[20] != null && cacheData[20].length() > 0) {
|
||||
posterElementsList.add(new PosterModeElement(rs.getString("streamUrl"), cacheData[0], new Image(new File(cacheData[20]).toURI().toString())));
|
||||
} else {
|
||||
posterElementsList.add(new PosterModeElement(rs.getString("streamUrl"), cacheData[0], new Image("icons/Homeflix_Poster.png")));
|
||||
}
|
||||
}
|
||||
|
||||
stmt.close();
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("An error occured while getting all PosterElements!", e);
|
||||
}
|
||||
|
@ -264,71 +256,69 @@ public class DBController {
|
|||
* check if there are any entries that have been removed from the film-directory
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void checkRemoveEntry() {
|
||||
private void checkRemoveEntry() throws SQLException {
|
||||
PreparedStatement ps = connection.prepareStatement("DELETE FROM films WHERE streamUrl = ?");
|
||||
LOGGER.info("checking for entrys to remove to DB ...");
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("DELETE FROM films WHERE streamUrl = ?");) {
|
||||
for (DatabaseDataType dbStreamEntry : databaseStreams) {
|
||||
// if the directory doen't contain the entry form the database, remove it
|
||||
|
||||
// if sourceStreams has a item where StreamUrl equals dbStreamEntry.getStreamUrl() return it, else null
|
||||
DatabaseDataType result = sourceStreams.stream()
|
||||
.filter(x -> dbStreamEntry.getStreamUrl().equals(x.getStreamUrl()))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
// if the result is null, the file is missing, remove it from the database
|
||||
if (result == null) {
|
||||
ps.setString(1, dbStreamEntry.getStreamUrl());
|
||||
ps.addBatch();
|
||||
LOGGER.info("removed \"" + dbStreamEntry.getTitle() + "\" from database");
|
||||
}
|
||||
}
|
||||
for (DatabaseDataType dbStreamEntry : databaseStreams) {
|
||||
// if the directory doen't contain the entry form the database, remove it
|
||||
|
||||
ps.executeBatch();
|
||||
connection.commit();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("An error occured, while cheking for media to remove", e);
|
||||
// if sourceStreams has a item where StreamUrl equals dbStreamEntry.getStreamUrl() return it, else null
|
||||
DatabaseDataType result = sourceStreams.stream()
|
||||
.filter(x -> dbStreamEntry.getStreamUrl().equals(x.getStreamUrl()))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
// if the result is null, the file is missing, remove it from the database
|
||||
if (result == null) {
|
||||
ps.setString(1, dbStreamEntry.getStreamUrl());
|
||||
ps.addBatch();
|
||||
LOGGER.info("removed \"" + dbStreamEntry.getTitle() + "\" from database");
|
||||
}
|
||||
}
|
||||
|
||||
ps.executeBatch();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* check for new media in the source directories
|
||||
* check if there are new films in the film-directory
|
||||
* @throws SQLException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
private void checkAddEntry() throws FileNotFoundException, IOException {
|
||||
private void checkAddEntry() throws SQLException, FileNotFoundException, IOException {
|
||||
PreparedStatement ps = connection.prepareStatement("insert into films values (?, ?, ?, ?, ?, ?, ?)");
|
||||
LOGGER.info("checking for entrys to add to DB ...");
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("insert into films values (?, ?, ?, ?, ?, ?, ?)");) {
|
||||
for (DatabaseDataType sourceStreamEntry : sourceStreams) {
|
||||
|
||||
// if databaseStream has a item where StreamUrl equals sourceStreamEntry.getStreamUrl() return it, else null
|
||||
DatabaseDataType result = databaseStreams.stream()
|
||||
.filter(x -> sourceStreamEntry.getStreamUrl().equals(x.getStreamUrl()))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
// if the result is null, the entry is missing, add it to the database
|
||||
if (result == null) {
|
||||
ps.setString(1, sourceStreamEntry.getStreamUrl());
|
||||
ps.setString(2, sourceStreamEntry.getTitle());
|
||||
ps.setString(3, sourceStreamEntry.getSeason());
|
||||
ps.setString(4, sourceStreamEntry.getEpisode());
|
||||
ps.setInt(5, sourceStreamEntry.getFavorite());
|
||||
ps.setDate(6, new Date(0));
|
||||
ps.setDouble(7, sourceStreamEntry.getCurrentTime());
|
||||
ps.addBatch(); // adds the entry
|
||||
LOGGER.info("Added \"" + sourceStreamEntry.getTitle() + "\" to database");
|
||||
databaseStreams.add(sourceStreamEntry);
|
||||
}
|
||||
}
|
||||
// new
|
||||
for (DatabaseDataType sourceStreamEntry : sourceStreams) {
|
||||
|
||||
ps.executeBatch();
|
||||
connection.commit();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("An error occured, while cheking for new media", e);
|
||||
// if databaseStream has a item where StreamUrl equals sourceStreamEntry.getStreamUrl() return it, else null
|
||||
DatabaseDataType result = databaseStreams.stream()
|
||||
.filter(x -> sourceStreamEntry.getStreamUrl().equals(x.getStreamUrl()))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
// if the result is null, the entry is missing, add it to the database
|
||||
if (result == null) {
|
||||
ps.setString(1, sourceStreamEntry.getStreamUrl());
|
||||
ps.setString(2, sourceStreamEntry.getTitle());
|
||||
ps.setString(3, sourceStreamEntry.getSeason());
|
||||
ps.setString(4, sourceStreamEntry.getEpisode());
|
||||
ps.setInt(5, sourceStreamEntry.getFavorite());
|
||||
ps.setDate(6, new Date(0));
|
||||
ps.setDouble(7, sourceStreamEntry.getCurrentTime());
|
||||
ps.addBatch(); // adds the entry
|
||||
LOGGER.info("Added \"" + sourceStreamEntry.getTitle() + "\" to database");
|
||||
databaseStreams.add(sourceStreamEntry);
|
||||
}
|
||||
}
|
||||
|
||||
ps.executeBatch();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -337,42 +327,44 @@ public class DBController {
|
|||
*/
|
||||
public void printAllDBEntriesDEBUG() {
|
||||
System.out.println("Outputting all entries ... \n");
|
||||
try (Statement stmt = connection.createStatement();) {
|
||||
|
||||
try (ResultSet rs = stmt.executeQuery("SELECT * FROM films");) {
|
||||
while (rs.next()) {
|
||||
System.out.println(rs.getString("streamUrl"));
|
||||
System.out.println(rs.getString("title"));
|
||||
System.out.println(rs.getString("season"));
|
||||
System.out.println(rs.getString("episode"));
|
||||
System.out.println(rs.getString("rating"));
|
||||
System.out.println(rs.getString("cached"));
|
||||
System.out.println(rs.getString("currentTime") + "\n");
|
||||
}
|
||||
try {
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT * FROM films");
|
||||
while (rs.next()) {
|
||||
System.out.println(rs.getString("streamUrl"));
|
||||
System.out.println(rs.getString("title"));
|
||||
System.out.println(rs.getString("season"));
|
||||
System.out.println(rs.getString("episode"));
|
||||
System.out.println(rs.getString("rating"));
|
||||
System.out.println(rs.getString("cached"));
|
||||
System.out.println(rs.getString("currentTime") + "\n");
|
||||
}
|
||||
|
||||
rs.close();
|
||||
stmt.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("An error occured, while printing all entries", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the favorite status of a media entry
|
||||
* @param mediaURL URL of the media
|
||||
* return the favorite state for a stream
|
||||
* @param streamURL URL of the stream
|
||||
* @return 0 if it's not a favorite, else 1
|
||||
*/
|
||||
public int getFavoriteState(String mediaURL) {
|
||||
public int getFavoriteState(String streamURL) {
|
||||
int favoriteState = 0;
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT favorite FROM films WHERE streamUrl = ?");) {
|
||||
ps.setString(1, mediaURL);
|
||||
PreparedStatement ps;
|
||||
try {
|
||||
ps = connection.prepareStatement("SELECT favorite FROM films WHERE streamUrl = ?");
|
||||
ps.setString(1, streamURL);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
while (rs.next()) {
|
||||
favoriteState = rs.getInt("favorite");
|
||||
}
|
||||
while (rs.next()) {
|
||||
favoriteState = rs.getInt("favorite");
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
|
@ -381,13 +373,18 @@ public class DBController {
|
|||
}
|
||||
|
||||
public void toggleFavoriteState(String streamURL) {
|
||||
int fav = getFavoriteState(streamURL) == 0 ? 1 : 0;
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("UPDATE films SET favorite = ? WHERE streamUrl = ?");) {
|
||||
ps.setInt(1, fav);
|
||||
ps.setString(2, streamURL);
|
||||
PreparedStatement ps;
|
||||
try {
|
||||
if (getFavoriteState(streamURL) == 0) {
|
||||
ps = connection.prepareStatement("UPDATE films SET favorite = 1 WHERE streamUrl = ?");
|
||||
} else {
|
||||
ps = connection.prepareStatement("UPDATE films SET favorite = 0 WHERE streamUrl = ?");
|
||||
}
|
||||
|
||||
ps.setString(1, streamURL);
|
||||
ps.executeUpdate();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
|
@ -399,11 +396,12 @@ public class DBController {
|
|||
*/
|
||||
public void dislike(String streamUrl) {
|
||||
LOGGER.info("dislike " + streamUrl);
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("UPDATE films SET favorite = 0 WHERE streamUrl = ?");){
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("UPDATE films SET favorite = 0 WHERE streamUrl = ?");
|
||||
ps.setString(1, streamUrl);
|
||||
ps.executeUpdate();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
|
@ -415,13 +413,14 @@ public class DBController {
|
|||
*/
|
||||
public void like(String streamUrl) {
|
||||
LOGGER.info("like " + streamUrl);
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("UPDATE films SET favorite = 1 WHERE streamUrl = ?");) {
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("UPDATE films SET favorite = 1 WHERE streamUrl = ?");
|
||||
ps.setString(1, streamUrl);
|
||||
ps.executeUpdate();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! An error occured!", e);
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,13 +429,15 @@ public class DBController {
|
|||
* @param streamUrl URL of the film
|
||||
*/
|
||||
public void setCached(String streamUrl) {
|
||||
try (PreparedStatement ps = connection.prepareStatement("UPDATE films SET cached = ? WHERE streamUrl = ?");) {
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("UPDATE films SET cached = ? WHERE streamUrl = ?");
|
||||
ps.setDate(1, new Date(System.currentTimeMillis()));
|
||||
ps.setString(2, streamUrl);
|
||||
ps.executeUpdate();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! An error occured, while setting cached = DATE for {}.", streamUrl, e);
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,18 +447,19 @@ public class DBController {
|
|||
*/
|
||||
public LocalDate getCacheDate(String streamUrl) {
|
||||
LocalDate cacheDate = LocalDate.now().minusDays(31);
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT cached FROM films WHERE streamUrl = ?");){
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT cached FROM films WHERE streamUrl = ?");
|
||||
ps.setString(1, streamUrl);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
while (rs.next()) {
|
||||
cacheDate = rs.getDate("cached").toLocalDate();
|
||||
}
|
||||
while (rs.next()) {
|
||||
cacheDate = rs.getDate("cached").toLocalDate();
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! An error occured, while rerading the cached date for {}.", streamUrl, e);
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
|
||||
return cacheDate;
|
||||
|
@ -469,9 +471,10 @@ public class DBController {
|
|||
* @param omdbResponse the response data from omdbAPI
|
||||
*/
|
||||
public void addCache(String streamUrl, OMDbAPIResponseDataType omdbResponse) {
|
||||
LOGGER.info("adding cache for: " + streamUrl);
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("insert into cache values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");){
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("insert into cache values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
|
||||
|
||||
LOGGER.info("adding cache for: " + streamUrl);
|
||||
ps.setString(1,streamUrl);
|
||||
ps.setString(2,omdbResponse.getTitle());
|
||||
ps.setString(3,omdbResponse.getYear());
|
||||
|
@ -502,8 +505,9 @@ public class DBController {
|
|||
ps.addBatch();
|
||||
ps.executeBatch();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Ups! An error while adding cache data for {}.", streamUrl, e);
|
||||
LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,15 +518,15 @@ public class DBController {
|
|||
*/
|
||||
public boolean searchCacheByURL(String streamUrl) {
|
||||
boolean retValue = false;
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM cache WHERE streamUrl = ?");) {
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT * FROM cache WHERE streamUrl = ?");
|
||||
ps.setString(1, streamUrl);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
retValue = rs.next();
|
||||
}
|
||||
|
||||
ResultSet rs = ps.executeQuery();
|
||||
retValue = rs.next();
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Ups! An error while searching for {} in the cache.", streamUrl, e);
|
||||
LOGGER.error("Ups! error while getting the current time!", e);
|
||||
}
|
||||
|
||||
return retValue;
|
||||
|
@ -533,89 +537,47 @@ public class DBController {
|
|||
* @param streamUrl URL of the film
|
||||
* @return a String array (length = 21) with all cached data
|
||||
*/
|
||||
public String[] readCacheLegacy(String streamUrl) {
|
||||
public String[] readCache(String streamUrl) {
|
||||
String[] cacheData = new String[21];
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM cache WHERE streamUrl = ?");) {
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT * FROM cache WHERE streamUrl = ?");
|
||||
ps.setString(1, streamUrl);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
while (rs.next()) {
|
||||
cacheData[0] = rs.getString("Title");
|
||||
cacheData[1] = rs.getString("Year");
|
||||
cacheData[2] = rs.getString("Rated");
|
||||
cacheData[3] = rs.getString("Released");
|
||||
cacheData[4] = rs.getString("Season");
|
||||
cacheData[5] = rs.getString("Episode");
|
||||
cacheData[6] = rs.getString("Runtime");
|
||||
cacheData[7] = rs.getString("Genre");
|
||||
cacheData[8] = rs.getString("Director");
|
||||
cacheData[9] = rs.getString("Writer");
|
||||
cacheData[10] = rs.getString("Actors");
|
||||
cacheData[11] = rs.getString("Plot");
|
||||
cacheData[12] = rs.getString("Language");
|
||||
cacheData[13] = rs.getString("Country");
|
||||
cacheData[14] = rs.getString("Awards");
|
||||
cacheData[15] = rs.getString("metascore");
|
||||
cacheData[16] = rs.getString("imdbRating");
|
||||
cacheData[17] = rs.getString("Type");
|
||||
cacheData[18] = rs.getString("BoxOffice");
|
||||
cacheData[19] = rs.getString("Website");
|
||||
cacheData[20] = rs.getString("Poster");
|
||||
}
|
||||
while (rs.next()) {
|
||||
cacheData[0] = rs.getString("Title");
|
||||
cacheData[1] = rs.getString("Year");
|
||||
cacheData[2] = rs.getString("Rated");
|
||||
cacheData[3] = rs.getString("Released");
|
||||
cacheData[4] = rs.getString("Season");
|
||||
cacheData[5] = rs.getString("Episode");
|
||||
cacheData[6] = rs.getString("Runtime");
|
||||
cacheData[7] = rs.getString("Genre");
|
||||
cacheData[8] = rs.getString("Director");
|
||||
cacheData[9] = rs.getString("Writer");
|
||||
cacheData[10] = rs.getString("Actors");
|
||||
cacheData[11] = rs.getString("Plot");
|
||||
cacheData[12] = rs.getString("Language");
|
||||
cacheData[13] = rs.getString("Country");
|
||||
cacheData[14] = rs.getString("Awards");
|
||||
cacheData[15] = rs.getString("metascore");
|
||||
cacheData[16] = rs.getString("imdbRating");
|
||||
cacheData[17] = rs.getString("Type");
|
||||
cacheData[18] = rs.getString("BoxOffice");
|
||||
cacheData[19] = rs.getString("Website");
|
||||
cacheData[20] = rs.getString("Poster");
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! error while getting the current time for {}.", streamUrl, e);
|
||||
LOGGER.error("Ups! an error occured!", e);
|
||||
}
|
||||
|
||||
return cacheData;
|
||||
}
|
||||
|
||||
public OMDbAPIResponseDataType readCache(String streamUrl) {
|
||||
OMDbAPIResponseDataType omdbResponse = new OMDbAPIResponseDataType();
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM cache WHERE streamUrl = ?");) {
|
||||
ps.setString(1, streamUrl);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
while (rs.next()) {
|
||||
omdbResponse.setTitle(rs.getString("Title"));
|
||||
omdbResponse.setYear(rs.getString("Year"));
|
||||
omdbResponse.setRated(rs.getString("Rated"));
|
||||
omdbResponse.setReleased(rs.getString("Released"));
|
||||
omdbResponse.setSeason(rs.getString("Season"));
|
||||
omdbResponse.setEpisode(rs.getString("Episode"));
|
||||
omdbResponse.setRuntime(rs.getString("Runtime"));
|
||||
omdbResponse.setGenre(rs.getString("Genre"));
|
||||
omdbResponse.setDirector(rs.getString("Director"));
|
||||
omdbResponse.setWriter(rs.getString("Writer"));
|
||||
omdbResponse.setActors(rs.getString("Actors"));
|
||||
omdbResponse.setPlot(rs.getString("Plot"));
|
||||
omdbResponse.setLanguage(rs.getString("Language"));
|
||||
omdbResponse.setCountry(rs.getString("Country"));
|
||||
omdbResponse.setAwards(rs.getString("Awards"));
|
||||
omdbResponse.setMetascore(rs.getString("metascore"));
|
||||
omdbResponse.setImdbRating(rs.getString("imdbRating"));
|
||||
omdbResponse.setImdbVotes(rs.getString("imdbVotes"));
|
||||
omdbResponse.setImdbID(rs.getString("imdbID"));
|
||||
omdbResponse.setType(rs.getString("Type"));
|
||||
omdbResponse.setDvd(rs.getString("dvd"));
|
||||
omdbResponse.setBoxOffice(rs.getString("BoxOffice"));
|
||||
//omdbResponse.setProduction(object.getString("Production", ""));
|
||||
omdbResponse.setWebsite(rs.getString("Website"));
|
||||
omdbResponse.setResponse(rs.getString("Response"));
|
||||
omdbResponse.setPoster(rs.getString("Poster"));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! error while getting the current time for {}.", streamUrl, e);
|
||||
}
|
||||
|
||||
return omdbResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all NOT cached entries
|
||||
* @return a {@link ArrayList} of all NOT cached entries
|
||||
|
@ -623,15 +585,15 @@ public class DBController {
|
|||
public ArrayList<FilmTabelDataType> getAllNotCachedEntries() {
|
||||
ArrayList<FilmTabelDataType> notCachedEntries = new ArrayList<>();
|
||||
|
||||
try (Statement stmt = connection.createStatement();) {
|
||||
|
||||
try (ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE cached = 0");) {
|
||||
while (rs.next()) {
|
||||
notCachedEntries.add(new FilmTabelDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode")));
|
||||
}
|
||||
try {
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE cached = 0");
|
||||
while (rs.next()) {
|
||||
notCachedEntries.add(new FilmTabelDataType(rs.getString("streamUrl"),
|
||||
rs.getString("title"), rs.getString("season"), rs.getString("episode")));
|
||||
}
|
||||
|
||||
stmt.close();
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("An error occured, while getting all NOT cached entries", e);
|
||||
}
|
||||
|
@ -648,14 +610,13 @@ public class DBController {
|
|||
public double getCurrentTime(String streamUrl) {
|
||||
LOGGER.info("get currentTime for " + streamUrl);
|
||||
double currentTime = 0;
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM films WHERE streamUrl = ?");) {
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT * FROM films WHERE streamUrl = ?");
|
||||
ps.setString(1, streamUrl);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
currentTime = rs.getDouble("currentTime");
|
||||
}
|
||||
|
||||
ResultSet rs = ps.executeQuery();
|
||||
currentTime = rs.getDouble("currentTime");
|
||||
rs.close();
|
||||
ps.close();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Ups! error while getting the current time!", e);
|
||||
}
|
||||
|
@ -670,12 +631,13 @@ public class DBController {
|
|||
*/
|
||||
public void setCurrentTime(String streamUrl, double currentTime) {
|
||||
LOGGER.info("set currentTime = " + currentTime + " for " + streamUrl);
|
||||
|
||||
try (PreparedStatement ps = connection.prepareStatement("UPDATE films SET currentTime = ? WHERE streamUrl = ?");) {
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement("UPDATE films SET currentTime = ? WHERE streamUrl = ?");
|
||||
ps.setDouble(1, currentTime);
|
||||
ps.setString(2, streamUrl);
|
||||
ps.executeUpdate();
|
||||
connection.commit();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Ups! error while updateing the current time!", e);
|
||||
}
|
||||
|
@ -689,19 +651,18 @@ public class DBController {
|
|||
*/
|
||||
public ArrayList<String[]> getEpisodes(String title, int season) {
|
||||
ArrayList<String[]> episodePosters =new ArrayList<>();
|
||||
|
||||
// try to get a all episode of one season
|
||||
try (PreparedStatement ps = connection.prepareStatement("SELECT streamUrl, episode FROM films WHERE title = ? AND season = ?");) {
|
||||
try {
|
||||
// try to get a all episode of one season
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT streamUrl, episode FROM films WHERE title = ? AND season = ?");
|
||||
ps.setString(1, title);
|
||||
ps.setString(2, Integer.toString(season));
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
try (ResultSet rs = ps.executeQuery();) {
|
||||
// for each episode load cache data
|
||||
while (rs.next()) {
|
||||
String[] cacheData = readCacheLegacy(rs.getString("streamUrl"));
|
||||
String[] ret = {rs.getString("streamUrl"), rs.getString("episode"), cacheData[20]};
|
||||
episodePosters.add(ret);
|
||||
}
|
||||
// for each episode load cache data
|
||||
while (rs.next()) {
|
||||
String[] cacheData = readCache(rs.getString("streamUrl"));
|
||||
String[] ret = {rs.getString("streamUrl"), rs.getString("episode"), cacheData[20]};
|
||||
episodePosters.add(ret);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
LOGGER.error("Ups! error while getting episodes of a season!", e);
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.controller;
|
||||
package kellerkinder.HomeFlix.controller;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
|
@ -32,13 +32,14 @@ import javax.imageio.ImageIO;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.datatypes.FilmTabelDataType;
|
||||
import org.mosad.homeflix.datatypes.OMDbAPIResponseDataType;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.JsonValue;
|
||||
|
||||
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
||||
import kellerkinder.HomeFlix.datatypes.OMDbAPIResponseDataType;
|
||||
|
||||
public class OMDbAPIController implements Runnable {
|
||||
|
||||
private DBController dbController;
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.controller;
|
||||
package kellerkinder.HomeFlix.controller;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
|
@ -31,13 +31,14 @@ import java.util.List;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.datatypes.DatabaseDataType;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonArray;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.JsonValue;
|
||||
|
||||
import kellerkinder.HomeFlix.datatypes.DatabaseDataType;
|
||||
|
||||
public class SourcesController {
|
||||
|
||||
private List<DatabaseDataType> sourceStreams = new ArrayList<DatabaseDataType>();
|
||||
|
@ -84,10 +85,10 @@ public class SourcesController {
|
|||
for (File file : new File(path).listFiles()) {
|
||||
// if it's valid file add it to the sourceStreams
|
||||
if (isValidFile(file)) {
|
||||
sourceStreams.add(new DatabaseDataType(file.getPath(), cutOffEnd(file.getName().replace("_", " ")), "", "", 0, 0.0));
|
||||
sourceStreams.add(new DatabaseDataType(file.getPath(), cutOffEnd(file.getName()), "", "", 0, 0.0));
|
||||
} else if(isValidSeriesRoot(file)) {
|
||||
// get all directories (series), root and season must be directories
|
||||
sourceStreams.add(new DatabaseDataType(file.getPath(), file.getName().replace("_", " "), "0", "0", 0, 0.0)); // add the series root node
|
||||
sourceStreams.add(new DatabaseDataType(file.getPath(), file.getName(), "0", "0", 0, 0.0)); // add the series root node
|
||||
int sn = 1;
|
||||
for (File season : file.listFiles()) {
|
||||
if (season.isDirectory()) {
|
|
@ -19,7 +19,7 @@
|
|||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.controller;
|
||||
package kellerkinder.HomeFlix.controller;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
|
@ -34,13 +34,14 @@ import javax.swing.ProgressMonitorInputStream;
|
|||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.application.Main;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonArray;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.JsonValue;
|
||||
|
||||
import kellerkinder.HomeFlix.application.Main;
|
||||
|
||||
public class UpdateController {
|
||||
|
||||
private static int updateBuildNumber; // tag_name from gitea
|
||||
|
@ -56,6 +57,9 @@ public class UpdateController {
|
|||
/**
|
||||
* updater for Project HomeFlix based on cemu_UIs, checks for Updates and download it
|
||||
*/
|
||||
public UpdateController() {
|
||||
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
if (browserDownloadUrl != null) {
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.controller;
|
||||
package kellerkinder.HomeFlix.controller;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
|
@ -61,7 +61,6 @@ public class XMLController {
|
|||
private static boolean autoUpdate = false;
|
||||
private static boolean useBeta = false;
|
||||
private static boolean autoplay = false;
|
||||
private static boolean fullscreen = true;
|
||||
private static double fontSize = 17;
|
||||
private static ResourceBundle localBundle = ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US);
|
||||
|
||||
|
@ -277,14 +276,6 @@ public class XMLController {
|
|||
public static void setAutoplay(boolean autoplay) {
|
||||
XMLController.autoplay = autoplay;
|
||||
}
|
||||
|
||||
public static boolean isFullscreen() {
|
||||
return fullscreen;
|
||||
}
|
||||
|
||||
public static void setFullscreen(boolean fullscreen) {
|
||||
XMLController.fullscreen = fullscreen;
|
||||
}
|
||||
|
||||
public static double getFontSize() {
|
||||
return fontSize;
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.datatypes;
|
||||
package kellerkinder.HomeFlix.datatypes;
|
||||
|
||||
public class DatabaseDataType {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
package org.mosad.homeflix.datatypes;
|
||||
package kellerkinder.HomeFlix.datatypes;
|
||||
|
||||
public class FilmTabelDataType {
|
||||
private String streamUrl;
|
|
@ -20,36 +20,36 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.datatypes;
|
||||
package kellerkinder.HomeFlix.datatypes;
|
||||
|
||||
public class OMDbAPIResponseDataType {
|
||||
|
||||
private String title = "";
|
||||
private String year = "";
|
||||
private String rated = "";
|
||||
private String released = "";
|
||||
private String season = "";
|
||||
private String episode = "";
|
||||
private String runtime = "";
|
||||
private String genre = "";
|
||||
private String director = "";
|
||||
private String writer = "";
|
||||
private String actors = "";
|
||||
private String plot = "";
|
||||
private String language = "";
|
||||
private String country = "";
|
||||
private String awards = "";
|
||||
private String poster = "";
|
||||
private String metascore = "";
|
||||
private String imdbRating = "";
|
||||
private String imdbVotes = "";
|
||||
private String imdbID = "";
|
||||
private String type = "";
|
||||
private String dvd = "";
|
||||
private String boxOffice = "";
|
||||
private String production = "";
|
||||
private String website = "";
|
||||
private String response = "";
|
||||
private String title;
|
||||
private String year;
|
||||
private String rated;
|
||||
private String released;
|
||||
private String season;
|
||||
private String episode;
|
||||
private String runtime;
|
||||
private String genre;
|
||||
private String director;
|
||||
private String writer;
|
||||
private String actors;
|
||||
private String plot;
|
||||
private String language;
|
||||
private String country;
|
||||
private String awards;
|
||||
private String poster;
|
||||
private String metascore;
|
||||
private String imdbRating;
|
||||
private String imdbVotes;
|
||||
private String imdbID;
|
||||
private String type;
|
||||
private String dvd;
|
||||
private String boxOffice;
|
||||
private String production;
|
||||
private String website;
|
||||
private String response;
|
||||
|
||||
/**
|
||||
* OMDbAPIResponseDataType is the data-type for the omdbAPI response
|
||||
|
@ -71,7 +71,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setYear(String year) {
|
||||
this.year = year == null ? "N/A" : year;
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public String getRated() {
|
||||
|
@ -79,7 +79,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setRated(String rated) {
|
||||
this.rated = rated == null ? "N/A" : rated;
|
||||
this.rated = rated;
|
||||
}
|
||||
|
||||
public String getReleased() {
|
||||
|
@ -87,7 +87,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setReleased(String released) {
|
||||
this.released = released == null ? "N/A" : released;
|
||||
this.released = released;
|
||||
}
|
||||
|
||||
public String getSeason() {
|
||||
|
@ -127,7 +127,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setDirector(String director) {
|
||||
this.director = director == null ? "N/A" : director;
|
||||
this.director = director;
|
||||
}
|
||||
|
||||
public String getWriter() {
|
||||
|
@ -135,7 +135,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setWriter(String writer) {
|
||||
this.writer = writer == null ? "N/A" : writer;
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
public String getActors() {
|
||||
|
@ -143,7 +143,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setActors(String actors) {
|
||||
this.actors = actors == null ? "N/A" : actors;
|
||||
this.actors = actors;
|
||||
}
|
||||
|
||||
public String getPlot() {
|
||||
|
@ -151,7 +151,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setPlot(String plot) {
|
||||
this.plot = plot == null ? "N/A" : plot;
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
|
@ -159,7 +159,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language == null ? "N/A" : language;
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
|
@ -167,7 +167,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country == null ? "N/A" : country;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getAwards() {
|
||||
|
@ -175,7 +175,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setAwards(String awards) {
|
||||
this.awards = awards == null ? "N/A" : awards;
|
||||
this.awards = awards;
|
||||
}
|
||||
|
||||
public String getPoster() {
|
||||
|
@ -191,7 +191,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setMetascore(String metascore) {
|
||||
this.metascore = metascore == null ? "N/A" : metascore;
|
||||
this.metascore = metascore;
|
||||
}
|
||||
|
||||
public String getImdbRating() {
|
||||
|
@ -199,7 +199,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setImdbRating(String imdbRating) {
|
||||
this.imdbRating = imdbRating == null ? "N/A" : imdbRating;
|
||||
this.imdbRating = imdbRating;
|
||||
}
|
||||
|
||||
public String getImdbVotes() {
|
||||
|
@ -207,7 +207,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setImdbVotes(String imdbVotes) {
|
||||
this.imdbVotes = imdbVotes == null ? "N/A" : imdbVotes;
|
||||
this.imdbVotes = imdbVotes;
|
||||
}
|
||||
|
||||
public String getImdbID() {
|
||||
|
@ -231,7 +231,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setDvd(String dvd) {
|
||||
this.dvd = dvd == null ? "N/A" : dvd;
|
||||
this.dvd = dvd;
|
||||
}
|
||||
|
||||
public String getBoxOffice() {
|
||||
|
@ -239,7 +239,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setBoxOffice(String boxOffice) {
|
||||
this.boxOffice = boxOffice == null ? "N/A" : boxOffice;
|
||||
this.boxOffice = boxOffice;
|
||||
}
|
||||
|
||||
public String getProduction() {
|
||||
|
@ -247,7 +247,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setProduction(String production) {
|
||||
this.production = production == null ? "N/A" : production;
|
||||
this.production = production;
|
||||
}
|
||||
|
||||
public String getWebsite() {
|
||||
|
@ -255,7 +255,7 @@ public class OMDbAPIResponseDataType {
|
|||
}
|
||||
|
||||
public void setWebsite(String website) {
|
||||
this.website = website == null ? "N/A" : website;
|
||||
this.website = website;
|
||||
}
|
||||
|
||||
public String getResponse() {
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.datatypes;
|
||||
package kellerkinder.HomeFlix.datatypes;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
|
|
@ -1,20 +1,19 @@
|
|||
package org.mosad.homeflix.datatypes;
|
||||
|
||||
import org.mosad.homeflix.player.Player;
|
||||
package kellerkinder.HomeFlix.datatypes;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import kellerkinder.HomeFlix.player.Player;
|
||||
|
||||
public class SeriesDVEpisode extends AnchorPane {
|
||||
public class SeriresDVEpisode extends AnchorPane {
|
||||
|
||||
private String streamURL;
|
||||
private Label label = new Label();
|
||||
private ImageView imageView = new ImageView();
|
||||
|
||||
public SeriesDVEpisode() {
|
||||
public SeriresDVEpisode() {
|
||||
super.getChildren().addAll(imageView, label);
|
||||
super.prefWidth(200);
|
||||
super.prefHeight(112);
|
||||
|
@ -28,7 +27,7 @@ public class SeriesDVEpisode extends AnchorPane {
|
|||
super.setLeftAnchor(label, 7.0);
|
||||
}
|
||||
|
||||
public SeriesDVEpisode(String streamURL, String episode, Image poster) {
|
||||
public SeriresDVEpisode(String streamURL, String episode, Image poster) {
|
||||
this();
|
||||
|
||||
this.streamURL = streamURL;
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <@Seil0>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
package org.mosad.homeflix.datatypes;
|
||||
package kellerkinder.HomeFlix.datatypes;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <seil0@mosad.xyz>
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.player;
|
||||
package kellerkinder.HomeFlix.player;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.BufferedReader;
|
||||
|
@ -31,15 +31,14 @@ import java.net.URLConnection;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.mosad.homeflix.application.Main;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import kellerkinder.HomeFlix.application.Main;
|
||||
import kellerkinder.HomeFlix.controller.DBController;
|
||||
public class Player {
|
||||
|
||||
private PlayerController playerController;
|
||||
|
@ -55,20 +54,21 @@ public class Player {
|
|||
* @param currentTableFilm the currently selected film
|
||||
*/
|
||||
public Player(String streamURL) {
|
||||
try {
|
||||
defaultPlayer(streamURL);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error while playing media", e);
|
||||
|
||||
if (isSupportedFormat(streamURL)) {
|
||||
hfPlayer(streamURL);
|
||||
} else {
|
||||
legacyPlayer(streamURL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* start the integrated player
|
||||
* @param streamURL
|
||||
*/
|
||||
private void defaultPlayer(String mediaURL) {
|
||||
playerController = new PlayerController(this, mediaURL);
|
||||
private void hfPlayer(String streamURL) {
|
||||
playerController = new PlayerController(this, streamURL);
|
||||
|
||||
try {
|
||||
FXMLLoader fxmlLoader = new FXMLLoader();
|
||||
|
@ -77,19 +77,19 @@ public class Player {
|
|||
pane = (AnchorPane) fxmlLoader.load();
|
||||
stage = new Stage();
|
||||
scene = new Scene(pane);
|
||||
scene.getStylesheets().add(getClass().getResource("/css/Player.css").toExternalForm());
|
||||
stage.setScene(scene);
|
||||
stage.setTitle("HomeFlix");
|
||||
stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png")));
|
||||
stage.setOnCloseRequest(event -> {
|
||||
playerController.stop();
|
||||
DBController.getInstance().setCurrentTime(streamURL, playerController.getCurrentTime());
|
||||
playerController.getMediaPlayer().stop();
|
||||
stage.close();
|
||||
});
|
||||
//stage.setFullScreen(true);
|
||||
stage.show();
|
||||
|
||||
playerController.init();
|
||||
playerController.start();
|
||||
|
||||
stage.setFullScreen(true);
|
||||
stage.show();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -158,8 +158,4 @@ public class Player {
|
|||
return scene;
|
||||
}
|
||||
|
||||
public Pane getPane() {
|
||||
return pane;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,310 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2019 <@Seil0>
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
package kellerkinder.HomeFlix.player;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXSlider;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.media.Media;
|
||||
import javafx.scene.media.MediaPlayer;
|
||||
import javafx.scene.media.MediaPlayer.Status;
|
||||
import javafx.scene.media.MediaView;
|
||||
import javafx.util.Duration;
|
||||
import kellerkinder.HomeFlix.controller.DBController;
|
||||
import kellerkinder.HomeFlix.controller.XMLController;
|
||||
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
||||
|
||||
public class PlayerController {
|
||||
|
||||
@FXML private MediaView mediaView;
|
||||
|
||||
@FXML private VBox bottomVBox;
|
||||
|
||||
@FXML private HBox controlsHBox;
|
||||
|
||||
@FXML private JFXSlider timeSlider;
|
||||
|
||||
@FXML private JFXButton stopBtn;
|
||||
@FXML private JFXButton playBtn;
|
||||
@FXML private JFXButton fullscreenBtn;
|
||||
@FXML private JFXButton nextEpBtn;
|
||||
|
||||
@FXML private ImageView stopIcon;
|
||||
@FXML private ImageView playIcon;
|
||||
@FXML private ImageView fullscreenIcon;
|
||||
|
||||
private Player player;
|
||||
private Media media;
|
||||
private MediaPlayer mediaPlayer;
|
||||
|
||||
private FilmTabelDataType film;
|
||||
private double currentTime = 0;
|
||||
private double seekTime = 0;
|
||||
private double startTime = 0;
|
||||
private double duration = 0;
|
||||
private int season = 0;
|
||||
private int episode = 0;
|
||||
private int countdown = 0;
|
||||
private boolean mousePressed = false;
|
||||
private boolean showControls = true;
|
||||
private boolean autoplay;
|
||||
|
||||
private Image playArrow = new Image("icons/baseline_play_arrow_black_48dp.png");
|
||||
private Image pause = new Image("icons/baseline_pause_black_48dp.png");
|
||||
private Image fullscreen = new Image("icons/baseline_fullscreen_black_48dp.png");
|
||||
private Image fullscreenExit = new Image("icons/baseline_fullscreen_exit_black_48dp.png");
|
||||
|
||||
/**
|
||||
* create a new PlayerWindow object
|
||||
* @param mainWCon the MainWindowController TODO do we need this?
|
||||
* @param player the player object (needed for closing action)
|
||||
* @param film the film object
|
||||
*/
|
||||
public PlayerController(Player player, String streamURL) {
|
||||
this.player = player;
|
||||
this.film = DBController.getInstance().getStream(streamURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the PlayerWindow
|
||||
*/
|
||||
public void init() {
|
||||
initActions();
|
||||
|
||||
if (film.getStreamUrl().startsWith("http")) {
|
||||
media = new Media(film.getStreamUrl());
|
||||
} else {
|
||||
media = new Media(new File(film.getStreamUrl()).toURI().toString());
|
||||
}
|
||||
|
||||
// create the MediaPlayer object
|
||||
mediaPlayer = new MediaPlayer(media);
|
||||
mediaView.setPreserveRatio(true);
|
||||
mediaView.setMediaPlayer(mediaPlayer);
|
||||
|
||||
final DoubleProperty width = mediaView.fitWidthProperty();
|
||||
final DoubleProperty height = mediaView.fitHeightProperty();
|
||||
|
||||
width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width"));
|
||||
height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height"));
|
||||
|
||||
startTime = DBController.getInstance().getCurrentTime(film.getStreamUrl());
|
||||
autoplay = XMLController.isAutoplay();
|
||||
season = !film.getSeason().isEmpty() ? Integer.parseInt(film.getSeason()) : 0;
|
||||
episode = !film.getEpisode().isEmpty() ? Integer.parseInt(film.getEpisode()) : 0;
|
||||
|
||||
initMediaPlayer();
|
||||
|
||||
// set the control elements to the correct value
|
||||
playIcon.setImage(pause);
|
||||
fullscreenIcon.setImage(fullscreenExit);
|
||||
timeSlider.setValue(0);
|
||||
}
|
||||
|
||||
private void initMediaPlayer() {
|
||||
// start the media if the player is ready
|
||||
mediaPlayer.setOnReady(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
duration = media.getDuration().toMillis();
|
||||
timeSlider.setMax((duration / 1000) / 60);
|
||||
|
||||
mediaPlayer.play();
|
||||
mediaPlayer.seek(Duration.millis(startTime));
|
||||
}
|
||||
});
|
||||
|
||||
// every time the play time changes execute this
|
||||
mediaPlayer.currentTimeProperty().addListener(new ChangeListener<Duration>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
|
||||
currentTime = newValue.toMillis(); // set the current time
|
||||
double timeToEnd = (duration - currentTime);
|
||||
|
||||
if (timeToEnd < 20000 && episode != 0 && autoplay) {
|
||||
// show 20 seconds before the end a button (next episode in 10 seconds)
|
||||
if (!nextEpBtn.isVisible())
|
||||
nextEpBtn.setVisible(true);
|
||||
|
||||
if (countdown != (int) ((timeToEnd - 10000) / 1000)) {
|
||||
countdown = (int) ((timeToEnd - 10000) / 1000);
|
||||
nextEpBtn.setText("next episode in " + countdown + " seconds"); // TODO translate
|
||||
bottomVBox.setVisible(true);
|
||||
}
|
||||
|
||||
// if we are end time -10 seconds, do autoplay, if activated
|
||||
if (timeToEnd < 10000) {
|
||||
nextEpBtn.setVisible(false);
|
||||
autoPlayNewFilm();
|
||||
}
|
||||
} else if (timeToEnd < 120) {
|
||||
// if we are 120ms to the end stop the media
|
||||
mediaPlayer.stop();
|
||||
DBController.getInstance().setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
|
||||
playIcon.setImage(playArrow);
|
||||
} else {
|
||||
if (nextEpBtn.isVisible())
|
||||
nextEpBtn.setVisible(false);
|
||||
}
|
||||
|
||||
if (!mousePressed) {
|
||||
timeSlider.setValue((currentTime / 1000) / 60);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize some PlayerWindow GUI-Elements actions
|
||||
*/
|
||||
private void initActions() {
|
||||
|
||||
player.getScene().addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {
|
||||
// hide controls timer initialization
|
||||
final Timer timer = new Timer();
|
||||
TimerTask controlAnimationTask = null; // task to execute save operation
|
||||
final long delayTime = 3000; // hide the controls after 2 seconds
|
||||
|
||||
@Override
|
||||
public void handle(MouseEvent mouseEvent) {
|
||||
|
||||
// show controls
|
||||
if (!showControls) {
|
||||
player.getScene().setCursor(Cursor.DEFAULT);
|
||||
bottomVBox.setVisible(true);
|
||||
}
|
||||
|
||||
// hide controls
|
||||
if (controlAnimationTask != null)
|
||||
controlAnimationTask.cancel();
|
||||
|
||||
controlAnimationTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
bottomVBox.setVisible(false);
|
||||
player.getScene().setCursor(Cursor.NONE);
|
||||
showControls = false;
|
||||
}
|
||||
};
|
||||
timer.schedule(controlAnimationTask, delayTime);
|
||||
}
|
||||
});
|
||||
|
||||
// if the mouse on the timeSlider is released seek to the new position
|
||||
timeSlider.setOnMouseReleased(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent event) {
|
||||
mediaPlayer.seek(new Duration(seekTime));
|
||||
mousePressed = false;
|
||||
}
|
||||
});
|
||||
|
||||
timeSlider.setOnMousePressed(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent event) {
|
||||
mousePressed = true;
|
||||
}
|
||||
});
|
||||
|
||||
// get the new seek time
|
||||
timeSlider.valueProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
|
||||
seekTime = (double) new_val * 1000 * 60;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
void stopBtnAction(ActionEvent event) {
|
||||
DBController.getInstance().setCurrentTime(film.getStreamUrl(), currentTime);
|
||||
mediaPlayer.stop();
|
||||
player.getStage().close();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void fullscreenBtnAction(ActionEvent event) {
|
||||
if (player.getStage().isFullScreen()) {
|
||||
player.getStage().setFullScreen(false);
|
||||
fullscreenIcon.setImage(fullscreen);
|
||||
} else {
|
||||
player.getStage().setFullScreen(true);
|
||||
fullscreenIcon.setImage(fullscreenExit);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void playBtnAction(ActionEvent event) {
|
||||
if (mediaPlayer.getStatus().equals(Status.PLAYING)) {
|
||||
mediaPlayer.pause();
|
||||
playIcon.setImage(playArrow);
|
||||
} else {
|
||||
mediaPlayer.play();
|
||||
playIcon.setImage(pause);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void nextEpBtnAction(ActionEvent event) {
|
||||
autoPlayNewFilm();
|
||||
}
|
||||
|
||||
private void autoPlayNewFilm() {
|
||||
autoplay = false;
|
||||
DBController.getInstance().setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
|
||||
FilmTabelDataType nextFilm = DBController.getInstance().getNextEpisode(film.getTitle(), episode, season);
|
||||
if (nextFilm != null) {
|
||||
mediaPlayer.stop();
|
||||
film = nextFilm;
|
||||
init();
|
||||
autoplay = true;
|
||||
}
|
||||
}
|
||||
|
||||
public MediaPlayer getMediaPlayer() {
|
||||
return mediaPlayer;
|
||||
}
|
||||
|
||||
public double getCurrentTime() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package org.mosad.homeflix.application.view;
|
||||
|
||||
import org.mosad.homeflix.application.MainWindowController;
|
||||
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.util.Duration;
|
||||
|
||||
public class DetailView {
|
||||
|
||||
@FXML protected AnchorPane rootPane;
|
||||
|
||||
public void updateGUILocal() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* show the root pane
|
||||
*/
|
||||
public void showPane() {
|
||||
rootPane.setVisible(true);
|
||||
FadeTransition fadeIn = new FadeTransition(Duration.millis(300), rootPane);
|
||||
fadeIn.setFromValue(0.3);
|
||||
fadeIn.setToValue(1.0);
|
||||
fadeIn.play();
|
||||
}
|
||||
|
||||
/**
|
||||
* hide the root pane and disable the blur in MainWindowController
|
||||
*/
|
||||
protected void hidePane() {
|
||||
FadeTransition fadeOut = new FadeTransition(Duration.millis(200), rootPane);
|
||||
fadeOut.setFromValue(1.0);
|
||||
fadeOut.setToValue(0.3);
|
||||
fadeOut.play();
|
||||
|
||||
rootPane.setVisible(false);
|
||||
|
||||
MainWindowController.getInstance().disableBlur(); // disable blur
|
||||
}
|
||||
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <seil0@mosad.xyz>
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.player;
|
||||
|
||||
import uk.co.caprica.vlcj.media.MediaRef;
|
||||
import uk.co.caprica.vlcj.media.TrackType;
|
||||
import uk.co.caprica.vlcj.player.base.MediaPlayer;
|
||||
import uk.co.caprica.vlcj.player.base.MediaPlayerEventListener;
|
||||
|
||||
public class HFMediaPlayerEventListener implements MediaPlayerEventListener {
|
||||
|
||||
@Override
|
||||
public void mediaChanged(MediaPlayer mediaPlayer, MediaRef media) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void opening(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buffering(MediaPlayer mediaPlayer, float newCache) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playing(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paused(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopped(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forward(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void backward(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeChanged(MediaPlayer mediaPlayer, long newTime) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void positionChanged(MediaPlayer mediaPlayer, float newPosition) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seekableChanged(MediaPlayer mediaPlayer, int newSeekable) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pausableChanged(MediaPlayer mediaPlayer, int newPausable) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void titleChanged(MediaPlayer mediaPlayer, int newTitle) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snapshotTaken(MediaPlayer mediaPlayer, String filename) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lengthChanged(MediaPlayer mediaPlayer, long newLength) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void videoOutput(MediaPlayer mediaPlayer, int newCount) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrambledChanged(MediaPlayer mediaPlayer, int newScrambled) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elementaryStreamAdded(MediaPlayer mediaPlayer, TrackType type, int id) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elementaryStreamDeleted(MediaPlayer mediaPlayer, TrackType type, int id) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elementaryStreamSelected(MediaPlayer mediaPlayer, TrackType type, int id) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void corked(MediaPlayer mediaPlayer, boolean corked) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void muted(MediaPlayer mediaPlayer, boolean muted) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void volumeChanged(MediaPlayer mediaPlayer, float volume) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void audioDeviceChanged(MediaPlayer mediaPlayer, String audioDevice) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chapterChanged(MediaPlayer mediaPlayer, int newChapter) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mediaPlayerReady(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
}
|
|
@ -1,635 +0,0 @@
|
|||
/**
|
||||
* Project-HomeFlix
|
||||
*
|
||||
* Copyright 2016-2022 <seil0@mosad.xyz>
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.mosad.homeflix.player;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.mosad.homeflix.controller.DBController;
|
||||
import org.mosad.homeflix.controller.XMLController;
|
||||
import org.mosad.homeflix.datatypes.FilmTabelDataType;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXDialogLayout;
|
||||
import com.jfoenix.controls.JFXListCell;
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import com.jfoenix.controls.JFXPopup;
|
||||
import com.jfoenix.controls.JFXPopup.PopupHPosition;
|
||||
import com.jfoenix.controls.JFXPopup.PopupVPosition;
|
||||
import com.jfoenix.controls.JFXSlider;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.image.PixelBuffer;
|
||||
import javafx.scene.image.PixelFormat;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.FontWeight;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.StringConverter;
|
||||
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
|
||||
import uk.co.caprica.vlcj.media.Media;
|
||||
import uk.co.caprica.vlcj.media.MediaEventAdapter;
|
||||
import uk.co.caprica.vlcj.media.MediaParsedStatus;
|
||||
import uk.co.caprica.vlcj.player.base.MediaPlayer;
|
||||
import uk.co.caprica.vlcj.player.base.TrackDescription;
|
||||
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
|
||||
import uk.co.caprica.vlcj.player.embedded.videosurface.CallbackVideoSurface;
|
||||
import uk.co.caprica.vlcj.player.embedded.videosurface.VideoSurfaceAdapters;
|
||||
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormat;
|
||||
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormatCallback;
|
||||
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.RenderCallback;
|
||||
import uk.co.caprica.vlcj.player.embedded.videosurface.callback.format.RV32BufferFormat;
|
||||
|
||||
/**
|
||||
* The PlayerController class is the main component of the HomeFlix Player.
|
||||
* It uses vlcj to play videos and some modified jfoenix GUI components to
|
||||
* create a Netflix like GUI.
|
||||
*
|
||||
* @author seil0
|
||||
*
|
||||
* TODO this class needs heavy cleaning
|
||||
*/
|
||||
public class PlayerController {
|
||||
|
||||
@FXML private AnchorPane panePlayer;
|
||||
@FXML private ImageView videoImageView;
|
||||
|
||||
@FXML private HBox hBoxTop;
|
||||
@FXML private HBox controlsHBox;
|
||||
|
||||
@FXML private VBox bottomVBox;
|
||||
|
||||
@FXML private JFXSlider timeSlider;
|
||||
|
||||
@FXML private JFXButton btnBack;
|
||||
@FXML private JFXButton btnPlay;
|
||||
@FXML private JFXButton btnReplay;
|
||||
@FXML private JFXButton btnForward;
|
||||
@FXML private JFXButton btnAudio;
|
||||
@FXML private JFXButton btnFullscreen;
|
||||
@FXML private JFXButton btnNextEpisode;
|
||||
|
||||
@FXML private ImageView stopIcon;
|
||||
@FXML private ImageView playIcon;
|
||||
@FXML private ImageView fullscreenIcon;
|
||||
|
||||
@FXML private Label lblTitle;
|
||||
@FXML private Label lblEndTime;
|
||||
|
||||
private Player player;
|
||||
private MediaPlayerFactory mediaPlayerFactory;
|
||||
private EmbeddedMediaPlayer embeddedMediaPlayer;
|
||||
private WritableImage videoImage;
|
||||
private PixelBuffer<ByteBuffer> videoPixelBuffer;
|
||||
|
||||
private FilmTabelDataType media;
|
||||
private long startTime = 0;
|
||||
private long currentTime = 0;
|
||||
private long endTime = 0;
|
||||
private long skipTime = 0;
|
||||
private long duration = 0;
|
||||
private List<TrackDescription> audioTracks = new ArrayList<>();
|
||||
private List<TrackDescription> subtitleTracks = new ArrayList<>();
|
||||
private int currentAudioTrack = 0;
|
||||
private int currentSubtitleTrack = 0;
|
||||
|
||||
private int season = 0;
|
||||
private int episode = 0;
|
||||
|
||||
private boolean mousePressed = false;
|
||||
private boolean showControls = true;
|
||||
private boolean autoplay;
|
||||
|
||||
private Image playArrow = new Image("icons/baseline_play_arrow_white_48dp.png");
|
||||
private Image pause = new Image("icons/baseline_pause_white_48dp.png");
|
||||
private Image fullscreen = new Image("icons/baseline_fullscreen_white_48dp.png");
|
||||
private Image fullscreenExit = new Image("icons/baseline_fullscreen_exit_white_48dp.png");
|
||||
|
||||
private JFXPopup audioPopup;
|
||||
|
||||
// fix wrong buffer resolution
|
||||
private int videoWidth = 0;
|
||||
private int videoHeigth = 0;
|
||||
|
||||
/**
|
||||
* create a new PlayerWindow object
|
||||
* @param player the player object (needed for closing action)
|
||||
* @param film the film object
|
||||
*/
|
||||
public PlayerController(Player player, String mediaURL) {
|
||||
this.player = player;
|
||||
this.media = DBController.getInstance().getStream(mediaURL);
|
||||
|
||||
mediaPlayerFactory = new MediaPlayerFactory();
|
||||
embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();
|
||||
embeddedMediaPlayer.videoSurface().set(new FXCallbackVideoSurface());
|
||||
}
|
||||
|
||||
public void init() {
|
||||
// initialize the image view
|
||||
videoImageView.setPreserveRatio(true);
|
||||
videoImageView.fitWidthProperty().bind(player.getStage().widthProperty());
|
||||
videoImageView.fitHeightProperty().bind(player.getStage().heightProperty());
|
||||
|
||||
// set needed variables
|
||||
startTime = (long) DBController.getInstance().getCurrentTime(media.getStreamUrl());
|
||||
autoplay = XMLController.isAutoplay();
|
||||
season = !media.getSeason().isEmpty() ? Integer.parseInt(media.getSeason()) : 0;
|
||||
episode = !media.getEpisode().isEmpty() ? Integer.parseInt(media.getEpisode()) : 0;
|
||||
|
||||
if (episode > 0) {
|
||||
// if the media is a TV show, add season + episode to the title
|
||||
lblTitle.setText(media.getTitle() + " S" + season + ":E" + episode);
|
||||
} else {
|
||||
lblTitle.setText(media.getTitle());
|
||||
}
|
||||
|
||||
initPlayerWindow();
|
||||
initMediaPlayer();
|
||||
initTimeSlider();
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize some PlayerWindow GUI-Elements actions
|
||||
*/
|
||||
private void initPlayerWindow() {
|
||||
|
||||
player.getScene().addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {
|
||||
|
||||
// hide controls timer initialization
|
||||
final Timer timer = new Timer();
|
||||
TimerTask controlAnimationTask = null; // task to execute save operation
|
||||
final long delayTime = 3000; // hide the controls after 2 seconds
|
||||
|
||||
@Override
|
||||
public void handle(MouseEvent mouseEvent) {
|
||||
|
||||
// show controls
|
||||
if (!showControls) {
|
||||
showControls = true;
|
||||
updateControls(); // update controls before showing them
|
||||
player.getScene().setCursor(Cursor.DEFAULT);
|
||||
hBoxTop.setVisible(true);
|
||||
bottomVBox.setVisible(true);
|
||||
showControls = true;
|
||||
}
|
||||
|
||||
// hide controls
|
||||
if (controlAnimationTask != null)
|
||||
controlAnimationTask.cancel();
|
||||
|
||||
controlAnimationTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// TODO a animation would be nice
|
||||
hBoxTop.setVisible(false);
|
||||
bottomVBox.setVisible(false);
|
||||
player.getScene().setCursor(Cursor.NONE);
|
||||
showControls = false;
|
||||
}
|
||||
};
|
||||
timer.schedule(controlAnimationTask, delayTime);
|
||||
}
|
||||
});
|
||||
|
||||
if (XMLController.isFullscreen()) {
|
||||
player.getStage().setFullScreen(!player.getStage().isFullScreen());
|
||||
fullscreenIcon.setImage(player.getStage().isFullScreen() ? fullscreenExit : fullscreen);
|
||||
}
|
||||
|
||||
// fix focused button has rippler fill https://github.com/jfoenixadmin/JFoenix/issues/1051
|
||||
btnBack.setStyle("-jfx-rippler-fill: black;");
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the embedded media player
|
||||
*/
|
||||
private void initMediaPlayer() {
|
||||
embeddedMediaPlayer.events().addMediaPlayerEventListener( new HFMediaPlayerEventListener() {
|
||||
|
||||
@Override
|
||||
public void mediaPlayerReady(MediaPlayer mediaPlayer) {
|
||||
audioTracks = mediaPlayer.audio().trackDescriptions();
|
||||
subtitleTracks = mediaPlayer.subpictures().trackDescriptions();
|
||||
currentAudioTrack = mediaPlayer.audio().track();
|
||||
currentSubtitleTrack = mediaPlayer.subpictures().track();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeChanged(MediaPlayer mediaPlayer, long newTime) {
|
||||
currentTime = newTime;
|
||||
endTime = duration - newTime;
|
||||
|
||||
Platform.runLater(() -> {
|
||||
updateControls();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(MediaPlayer mediaPlayer) {
|
||||
// Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lengthChanged(MediaPlayer mediaPlayer, long newLength) {
|
||||
duration = newLength;
|
||||
timeSlider.setMax(duration / 1000);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
embeddedMediaPlayer.events().addMediaEventListener(new MediaEventAdapter() {
|
||||
@Override
|
||||
public void mediaParsedChanged(Media media, MediaParsedStatus newStatus) {
|
||||
super.mediaParsedChanged(media, newStatus);
|
||||
videoWidth = embeddedMediaPlayer.video().videoDimension().width;
|
||||
videoHeigth= embeddedMediaPlayer.video().videoDimension().height;
|
||||
|
||||
// start the video
|
||||
embeddedMediaPlayer.media().play(media.newMediaRef());
|
||||
embeddedMediaPlayer.controls().skipTime(startTime); // skip to the start time
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the time slider
|
||||
*/
|
||||
private void initTimeSlider() {
|
||||
// if the mouse on the timeSlider is released, skip to the new position
|
||||
timeSlider.setOnMouseReleased(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent event) {
|
||||
embeddedMediaPlayer.controls().skipTime(skipTime);
|
||||
|
||||
// update time-stamps if video is paused
|
||||
if (!embeddedMediaPlayer.status().isPlaying()) {
|
||||
Platform.runLater(() -> {
|
||||
lblEndTime.setText(String.format("%d:%02d:%02d",
|
||||
TimeUnit.MILLISECONDS.toHours(endTime - skipTime) % 24,
|
||||
TimeUnit.MILLISECONDS.toMinutes(endTime - skipTime) % 60,
|
||||
TimeUnit.MILLISECONDS.toSeconds(endTime - skipTime) % 60));
|
||||
});
|
||||
}
|
||||
|
||||
mousePressed = false;
|
||||
}
|
||||
});
|
||||
|
||||
timeSlider.setOnMousePressed(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent event) {
|
||||
mousePressed = true;
|
||||
}
|
||||
});
|
||||
|
||||
// on value change, get the new skip time
|
||||
timeSlider.valueProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
|
||||
skipTime = ((new_val.longValue() * 1000) - currentTime);
|
||||
//System.out.println(timeSlider.getChildrenUnmodifiable());
|
||||
}
|
||||
});
|
||||
|
||||
timeSlider.setOnMouseMoved(new EventHandler<MouseEvent>() {
|
||||
@Override
|
||||
public void handle(MouseEvent event) {
|
||||
//System.out.println("TEST");
|
||||
}
|
||||
});
|
||||
|
||||
// show h:mm:ss in the animated thumb
|
||||
StringConverter<Double> convert = new StringConverter<Double>() {
|
||||
@Override
|
||||
public String toString(Double object) {
|
||||
long time = object.longValue();
|
||||
|
||||
return String.format("%d:%02d:%02d", TimeUnit.SECONDS.toHours(time) % 24,
|
||||
TimeUnit.SECONDS.toMinutes(time) % 60, TimeUnit.SECONDS.toSeconds(time) % 60);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double fromString(String string) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
timeSlider.setLabelFormatter(convert);
|
||||
|
||||
// get the animated thumb as StackPane
|
||||
StackPane animatedThumb = (StackPane) timeSlider.lookup(".animated-thumb");
|
||||
// System.out.println(animatedThumb);
|
||||
// System.out.println(animatedThumb.getChildren());
|
||||
|
||||
// modify the animated thumb
|
||||
Text thumbText = (Text) animatedThumb.getChildren().get(0);
|
||||
thumbText.setStyle("-fx-font-size: 15px; -fx-fill: white;");
|
||||
|
||||
// TODO add a preview to the animated thumb, if that's possible
|
||||
// ImageView iv = new ImageView(fullscreenExit);
|
||||
// animatedThumb.getChildren().add(iv);
|
||||
}
|
||||
|
||||
// Start the parsing the media meta data
|
||||
public void start() {
|
||||
// parse meta data
|
||||
embeddedMediaPlayer.media().prepare(media.getStreamUrl());
|
||||
embeddedMediaPlayer.media().parsing().parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop and release the media player.
|
||||
* Always call this method to stop the media player.
|
||||
*/
|
||||
public void stop() {
|
||||
DBController.getInstance().setCurrentTime(media.getStreamUrl(), embeddedMediaPlayer.status().time());
|
||||
embeddedMediaPlayer.controls().stop();
|
||||
embeddedMediaPlayer.release();
|
||||
mediaPlayerFactory.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* call this every second to update all timers
|
||||
*/
|
||||
private void updateControls() {
|
||||
|
||||
// update control if they are visible
|
||||
if (showControls) {
|
||||
// update slider position, if the mouse does not press on the time
|
||||
if (!mousePressed) {
|
||||
timeSlider.setValue(currentTime / 1000);
|
||||
}
|
||||
|
||||
// update endTime label
|
||||
lblEndTime.setText(String.format("%d:%02d:%02d",
|
||||
TimeUnit.MILLISECONDS.toHours(endTime) % 24,
|
||||
TimeUnit.MILLISECONDS.toMinutes(endTime) % 60,
|
||||
TimeUnit.MILLISECONDS.toSeconds(endTime) % 60));
|
||||
}
|
||||
|
||||
// show the next episode button 30 seconds before the end of a episode
|
||||
if (endTime < 31000 && episode != 0 && autoplay) {
|
||||
int countdown = (int) ((endTime / 1000) - 20); // a 10 seconds countdown
|
||||
|
||||
if (!btnNextEpisode.isVisible()) {
|
||||
btnNextEpisode.setVisible(true);
|
||||
}
|
||||
|
||||
if (endTime > 20000) {
|
||||
btnNextEpisode.setText(XMLController.getLocalBundle().getString("nextEpisode")
|
||||
+ countdown + XMLController.getLocalBundle().getString("seconds"));
|
||||
bottomVBox.setVisible(true);
|
||||
} else {
|
||||
btnNextEpisode.setVisible(false);
|
||||
playNextMedia();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnBackAction(ActionEvent event) {
|
||||
stop();
|
||||
player.getStage().close();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnPlayAction(ActionEvent event) {
|
||||
if (embeddedMediaPlayer.status().isPlaying()) {
|
||||
embeddedMediaPlayer.controls().pause();
|
||||
playIcon.setImage(playArrow);
|
||||
} else {
|
||||
embeddedMediaPlayer.controls().play();
|
||||
playIcon.setImage(pause);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnReplayAction(ActionEvent event) {
|
||||
embeddedMediaPlayer.controls().skipTime(-10000);
|
||||
|
||||
// update currentTime, endTime and controls if play back is paused
|
||||
if (!embeddedMediaPlayer.status().isPlaying()) {
|
||||
currentTime = currentTime - 10000;
|
||||
endTime = endTime + 10000;
|
||||
|
||||
Platform.runLater(() -> {
|
||||
updateControls();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnForwardAction(ActionEvent event) {
|
||||
embeddedMediaPlayer.controls().skipTime(10000);
|
||||
|
||||
// update currentTime, endTime and controls if play back is paused
|
||||
if (!embeddedMediaPlayer.status().isPlaying()) {
|
||||
currentTime = currentTime + 10000;
|
||||
endTime = endTime - 10000;
|
||||
|
||||
Platform.runLater(() -> {
|
||||
updateControls();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnAudioAction(ActionEvent event) {
|
||||
if (audioPopup == null) {
|
||||
audioPopup = new JFXPopup();
|
||||
|
||||
// audio track
|
||||
JFXListView<TrackDescription> audioList = new JFXListView<>();
|
||||
audioList.setCellFactory(param -> new TrackDescriptionCellFactory());
|
||||
audioList.setOnMouseClicked(ev -> {
|
||||
setAudioTrack(audioList.getSelectionModel().getSelectedItem().id());
|
||||
audioPopup.hide();
|
||||
});
|
||||
|
||||
audioTracks.forEach(track -> {
|
||||
audioList.getItems().add(track);
|
||||
if (track.id() == currentAudioTrack) {
|
||||
audioList.getSelectionModel().select(track);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Text audioHeading = new Text("Audio");
|
||||
audioHeading.setFill(Color.WHITE);
|
||||
audioHeading.setFont(Font.font(null, FontWeight.BOLD, 16));
|
||||
|
||||
// subtitle track
|
||||
JFXListView<TrackDescription> subtitleList = new JFXListView<>();
|
||||
subtitleList.setCellFactory(param -> new TrackDescriptionCellFactory());
|
||||
subtitleList.setOnMouseClicked(ev -> {
|
||||
setSubtitleTrack(subtitleList.getSelectionModel().getSelectedItem().id());
|
||||
audioPopup.hide();
|
||||
});
|
||||
|
||||
subtitleTracks.forEach(track -> {
|
||||
subtitleList.getItems().add(track);
|
||||
if (track.id() == currentSubtitleTrack) {
|
||||
subtitleList.getSelectionModel().select(track);
|
||||
}
|
||||
});
|
||||
|
||||
Text subtitleHeading = new Text("Subtitles");
|
||||
subtitleHeading.setFill(Color.WHITE);
|
||||
subtitleHeading.setFont(Font.font(null, FontWeight.BOLD, 16));
|
||||
|
||||
|
||||
// build dialog layout
|
||||
VBox audioBox = new VBox(audioHeading, audioList);
|
||||
VBox subtileBox = new VBox(subtitleHeading, subtitleList);
|
||||
HBox hbox = new HBox(audioBox, subtileBox);
|
||||
|
||||
JFXDialogLayout content = new JFXDialogLayout();
|
||||
content.setBody(hbox);
|
||||
content.setPadding(new Insets(-20, -20, -20, -20)); // fix JFXDialogLayout padding
|
||||
content.setSpacing(-10); // fix JFXDialogLayout spacing
|
||||
|
||||
audioPopup.setPopupContent(content);
|
||||
}
|
||||
|
||||
if (!audioPopup.isShowing()) {
|
||||
// TODO this does not work properly
|
||||
audioPopup.show(btnAudio, PopupVPosition.BOTTOM, PopupHPosition.RIGHT,
|
||||
0, -1 * bottomVBox.getHeight());
|
||||
} else {
|
||||
audioPopup.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void btnFullscreenAction(ActionEvent event) {
|
||||
player.getStage().setFullScreen(!player.getStage().isFullScreen());
|
||||
fullscreenIcon.setImage(player.getStage().isFullScreen() ? fullscreenExit : fullscreen);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void btnNextEpisodeAction(ActionEvent event) {
|
||||
btnNextEpisode.setVisible(false);
|
||||
playNextMedia();
|
||||
}
|
||||
|
||||
/**
|
||||
* play the next media
|
||||
*/
|
||||
private void playNextMedia() {
|
||||
autoplay = false;
|
||||
DBController.getInstance().setCurrentTime(media.getStreamUrl(), 0); // reset old video start time
|
||||
FilmTabelDataType nextMedia = DBController.getInstance().getNextEpisode(media.getTitle(), episode, season);
|
||||
if (nextMedia != null) {
|
||||
embeddedMediaPlayer.media().play(nextMedia.getStreamUrl());
|
||||
media = nextMedia;
|
||||
autoplay = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change the audio track
|
||||
* @param track the index of the audio track
|
||||
*/
|
||||
private void setAudioTrack(int track) {
|
||||
embeddedMediaPlayer.audio().setTrack(track);
|
||||
currentAudioTrack = track;
|
||||
}
|
||||
|
||||
private void setSubtitleTrack(int track) {
|
||||
embeddedMediaPlayer.subpictures().setTrack(track);
|
||||
currentSubtitleTrack = track;
|
||||
}
|
||||
|
||||
public double getCurrentTime() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
private class FXCallbackVideoSurface extends CallbackVideoSurface {
|
||||
FXCallbackVideoSurface() {
|
||||
super(new FXBufferFormatCallback(), new FXRenderCallback(), true,
|
||||
VideoSurfaceAdapters.getVideoSurfaceAdapter());
|
||||
}
|
||||
}
|
||||
|
||||
private class FXBufferFormatCallback implements BufferFormatCallback {
|
||||
|
||||
@Override
|
||||
public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) {
|
||||
return new RV32BufferFormat(sourceWidth, sourceHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allocatedBuffers(ByteBuffer[] buffers) {
|
||||
PixelFormat<ByteBuffer> pixelFormat = PixelFormat.getByteBgraPreInstance();
|
||||
|
||||
// fixes buffer resolution, video resolution mismatch
|
||||
videoPixelBuffer = new PixelBuffer<>(videoWidth, videoHeigth, buffers[0], pixelFormat);
|
||||
//videoPixelBuffer = new PixelBuffer<>(sourceWidth, sourceHeight, buffers[0], pixelFormat);
|
||||
|
||||
videoImage = new WritableImage(videoPixelBuffer);
|
||||
videoImageView.setImage(videoImage);
|
||||
}
|
||||
}
|
||||
|
||||
private class FXRenderCallback implements RenderCallback {
|
||||
|
||||
@Override
|
||||
public void display(MediaPlayer mediaPlayer, ByteBuffer[] nativeBuffers, BufferFormat bufferFormat) {
|
||||
Platform.runLater(() -> videoPixelBuffer.updateBuffer(pb -> null));
|
||||
}
|
||||
}
|
||||
|
||||
private class TrackDescriptionCellFactory extends JFXListCell<TrackDescription> {
|
||||
|
||||
@Override
|
||||
protected void updateItem(TrackDescription item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (empty || item == null || item.description() == null) {
|
||||
setText(null);
|
||||
} else {
|
||||
setText(item.description());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -209,3 +209,4 @@
|
|||
.scroll-pane > .viewport {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
* {
|
||||
-theme-secondary-dark: #303030;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Slider *
|
||||
* *
|
||||
******************************************************************************/
|
||||
.jfx-slider .slider-value {
|
||||
-fx-rotate: 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
.jfx-slider > .track {
|
||||
-fx-background-color: yellow;
|
||||
}
|
||||
*/
|
||||
|
||||
.jfx-slider > .colored-track {
|
||||
-fx-background-color: #ee3523;
|
||||
}
|
||||
|
||||
.jfx-slider > .thumb {
|
||||
-fx-background-color: #ee3523;
|
||||
}
|
||||
|
||||
|
||||
.jfx-slider .animated-thumb {
|
||||
-fx-rotate: 0.0;
|
||||
-fx-pref-height: 30.0px;
|
||||
-fx-pref-width: 80.0px;
|
||||
-fx-background-color: -theme-secondary-dark;
|
||||
-fx-background-radius: 5.0px 5.0px 5.0px 5.0px;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* ListView *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.list-view {
|
||||
-fx-background-color: -theme-secondary-dark;
|
||||
-fx-padding: 1.0px;
|
||||
}
|
||||
|
||||
.list-view .list-cell:hover {
|
||||
-fx-background-color: #434343;
|
||||
}
|
||||
|
||||
.list-view .list-cell:selected {
|
||||
-fx-background-color: #434343;
|
||||
}
|
||||
|
||||
.list-view .list-cell {
|
||||
-fx-background-color: -theme-secondary-dark;
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.list-view .label {
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.jfx-rippler {
|
||||
-jfx-rippler-fill: #ee3523;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Popup *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.jfx-popup-container {
|
||||
-fx-background-color: -theme-secondary-dark;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Button *
|
||||
* *
|
||||
******************************************************************************/
|
||||
/* FIXME disabled since buggy */
|
||||
/*
|
||||
.jfx-button:hover {
|
||||
-fx-scale-x: 1.1;
|
||||
-fx-scale-y: 1.1;
|
||||
-fx-scale-z: 1.1;
|
||||
}
|
||||
*/
|
|
@ -12,7 +12,7 @@
|
|||
<?import javafx.scene.text.Text?>
|
||||
<?import javafx.scene.text.TextFlow?>
|
||||
|
||||
<AnchorPane fx:id="rootPane" prefHeight="568.0" prefWidth="1130.0" style="-fx-background-color: #595959;" visible="false" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.mosad.homeflix.application.view.FilmDetailView">
|
||||
<AnchorPane fx:id="filmDVPane" prefHeight="568.0" prefWidth="1130.0" style="-fx-background-color: #595959;" visible="false" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.application.FilmDetailView">
|
||||
<children>
|
||||
<HBox layoutX="22.0" layoutY="21.0" prefWidth="808.0" spacing="10.0" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="300.0" AnchorPane.topAnchor="22.0">
|
||||
<children>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<AnchorPane fx:id="mainAnchorPane" prefHeight="600.0" prefWidth="1130.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.mosad.homeflix.application.MainWindowController">
|
||||
<AnchorPane fx:id="mainAnchorPane" prefHeight="600.0" prefWidth="1130.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.application.MainWindowController">
|
||||
<children>
|
||||
<ScrollPane fx:id="posterModeScrollPane" fitToWidth="true" layoutX="10.0" layoutY="48.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="32.0">
|
||||
<content>
|
||||
|
|
|
@ -3,145 +3,73 @@
|
|||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXSlider?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.media.MediaView?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<AnchorPane fx:id="panePlayer" prefHeight="720.0" prefWidth="1280.0" style="-fx-background-color: black;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<HBox alignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<ImageView fx:id="videoImageView" pickOnBounds="true" preserveRatio="true" />
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox fx:id="hBoxTop" alignment="CENTER_LEFT" spacing="10.0" style="-fx-background-color: linear-gradient(to bottom, #000000aa, #00000000);" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<JFXButton fx:id="btnBack" contentDisplay="GRAPHIC_ONLY" onAction="#btnBackAction">
|
||||
<graphic>
|
||||
<ImageView fitHeight="32.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_keyboard_backspace_white_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<Label fx:id="lblTitle" text="Title" textFill="WHITE">
|
||||
<font>
|
||||
<Font size="22.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
<VBox fx:id="bottomVBox" alignment="CENTER" style="-fx-background-color: linear-gradient(to top, #000000dd, #00000000);" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
|
||||
<children>
|
||||
<HBox spacing="10.0">
|
||||
<children>
|
||||
<JFXSlider fx:id="timeSlider" HBox.hgrow="ALWAYS">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</JFXSlider>
|
||||
<Label fx:id="lblEndTime" text="0:00:00" textFill="WHITE">
|
||||
<font>
|
||||
<Font size="17.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets left="10.0" right="10.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
<HBox fx:id="controlsHBox" spacing="10.0">
|
||||
<children>
|
||||
<HBox spacing="10.0">
|
||||
<children>
|
||||
<JFXButton fx:id="btnPlay" contentDisplay="GRAPHIC_ONLY" onAction="#btnPlayAction">
|
||||
<graphic>
|
||||
<ImageView fx:id="playIcon" fitHeight="42.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_pause_white_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton fx:id="btnReplay" contentDisplay="GRAPHIC_ONLY" onAction="#btnReplayAction">
|
||||
<graphic>
|
||||
<ImageView fitHeight="42.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_replay_10_white_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton fx:id="btnForward" contentDisplay="GRAPHIC_ONLY" onAction="#btnForwardAction">
|
||||
<graphic>
|
||||
<ImageView fitHeight="42.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_forward_10_white_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
<HBox alignment="TOP_RIGHT" spacing="10.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<JFXButton fx:id="btnAudio" contentDisplay="GRAPHIC_ONLY" onAction="#btnAudioAction">
|
||||
<graphic>
|
||||
<ImageView fitHeight="42.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_subtitles_white_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton fx:id="btnFullscreen" contentDisplay="GRAPHIC_ONLY" onAction="#btnFullscreenAction" prefHeight="39.0">
|
||||
<graphic>
|
||||
<ImageView fx:id="fullscreenIcon" fitHeight="42.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_fullscreen_white_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
<JFXButton fx:id="btnNextEpisode" onAction="#btnNextEpisodeAction" style="-fx-background-color: ee3523;" text="next episode in 10 seconds" textFill="WHITE" visible="false" AnchorPane.bottomAnchor="100.0" AnchorPane.rightAnchor="20.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
<opaqueInsets>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
<padding>
|
||||
<Insets bottom="7.0" left="7.0" right="7.0" top="7.0" />
|
||||
</padding>
|
||||
</JFXButton>
|
||||
</children>
|
||||
<AnchorPane prefHeight="720.0" prefWidth="1280.0" style="-fx-background-color: black;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<HBox alignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<MediaView fx:id="mediaView" />
|
||||
</children>
|
||||
</HBox>
|
||||
<VBox fx:id="bottomVBox" alignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
|
||||
<children>
|
||||
<JFXSlider fx:id="timeSlider">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</JFXSlider>
|
||||
<HBox fx:id="controlsHBox" alignment="CENTER" spacing="10.0">
|
||||
<children>
|
||||
<JFXButton fx:id="stopBtn" buttonType="RAISED" contentDisplay="GRAPHIC_ONLY" onAction="#stopBtnAction" prefHeight="39.0" style="-fx-background-color: white;">
|
||||
<graphic>
|
||||
<ImageView fx:id="stopIcon" fitHeight="29.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_stop_black_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic></JFXButton>
|
||||
<JFXButton fx:id="playBtn" buttonType="RAISED" contentDisplay="GRAPHIC_ONLY" onAction="#playBtnAction" prefHeight="39.0" style="-fx-background-color: white;">
|
||||
<graphic>
|
||||
<ImageView fx:id="playIcon" fitHeight="29.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_play_arrow_black_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic></JFXButton>
|
||||
<JFXButton fx:id="fullscreenBtn" buttonType="RAISED" contentDisplay="GRAPHIC_ONLY" onAction="#fullscreenBtnAction" prefHeight="39.0" style="-fx-background-color: white;">
|
||||
<graphic>
|
||||
<ImageView fx:id="fullscreenIcon" fitHeight="29.0" pickOnBounds="true" preserveRatio="true">
|
||||
<image>
|
||||
<Image url="@../icons/baseline_fullscreen_black_48dp.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</graphic></JFXButton>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
<JFXButton fx:id="nextEpBtn" onAction="#nextEpBtnAction" style="-fx-background-color: ee3523;" text="next episode in 10 seconds" textFill="WHITE" visible="false" AnchorPane.bottomAnchor="80.0" AnchorPane.rightAnchor="20.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
<opaqueInsets>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
<padding>
|
||||
<Insets bottom="7.0" left="7.0" right="7.0" top="7.0" />
|
||||
</padding></JFXButton>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<?import javafx.scene.text.Text?>
|
||||
<?import javafx.scene.text.TextFlow?>
|
||||
|
||||
<AnchorPane fx:id="rootPane" prefHeight="568.0" prefWidth="1130.0" style="-fx-background-color: #595959;" visible="false" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.mosad.homeflix.application.view.SeriesDetailView">
|
||||
<AnchorPane fx:id="seriesDVPane" prefHeight="568.0" prefWidth="1130.0" style="-fx-background-color: #595959;" visible="false" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.application.SeriesDetailView">
|
||||
<children>
|
||||
<HBox layoutX="22.0" layoutY="21.0" prefWidth="808.0" spacing="10.0" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="310.0" AnchorPane.topAnchor="22.0">
|
||||
<children>
|
||||
|
@ -61,7 +61,7 @@
|
|||
</graphic></JFXButton>
|
||||
</children>
|
||||
</HBox>
|
||||
<TextFlow layoutX="22.0" layoutY="150.0" lineSpacing="1.0" maxHeight="-Infinity" prefHeight="130.0" prefWidth="808.0" AnchorPane.bottomAnchor="308.0" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="310.0" AnchorPane.topAnchor="130.0">
|
||||
<TextFlow layoutX="22.0" layoutY="150.0" lineSpacing="1.0" maxHeight="-Infinity" prefHeight="130.0" prefWidth="808.0" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="310.0" AnchorPane.topAnchor="130.0">
|
||||
<children>
|
||||
<Text fx:id="textPlot" fill="#ecebed" strokeType="OUTSIDE" strokeWidth="0.0" text="Avatar: Der Herr der Elemente ist eine amerikanische Zeichentrickserie. Die Serie wurde erstellt und produziert von Michael Dante DiMartion und Bryan Konietzko. Avatar spielt in einer, stark asiatisch beeinflussten Welt, in der einige in der Lage sind die Elemente zu beeinflussen. Die Fähigkeit die Elemente zu "bändigen", erfolgt in einer Mischung aus mentaler Beeinflussung und einer Variation von fernöstlicher Kampfkunst.Die Serie erzählt die Geschichte des zwölfjährigen Aangs und seinen Freunden, die versuchen das Gleichgewicht der Elemente wieder herzustellen, indem sie die Herrschaft des Feuerlords über die drei anderen Elemente beenden. Aang ist der letzte verbliebene Luftbändiger und gleichzeitig der Avatar, welcher 100 Jahre verschollen war.">
|
||||
<font>
|
||||
|
@ -70,11 +70,11 @@
|
|||
</Text>
|
||||
</children>
|
||||
</TextFlow>
|
||||
<Label fx:id="lblCrew" layoutX="31.0" layoutY="346.0" text="Haupt-Crew" textFill="#ecebed" AnchorPane.bottomAnchor="264.0" AnchorPane.leftAnchor="22.0">
|
||||
<Label fx:id="lblCrew" layoutX="31.0" layoutY="346.0" text="Haupt-Crew" textFill="#ecebed" AnchorPane.leftAnchor="22.0" AnchorPane.topAnchor="280.0">
|
||||
<font>
|
||||
<Font size="20.0" />
|
||||
</font></Label>
|
||||
<HBox layoutX="22.0" layoutY="372.0" spacing="30.0" AnchorPane.bottomAnchor="218.0" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="310.0">
|
||||
<HBox layoutX="22.0" layoutY="372.0" spacing="30.0" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="310.0" AnchorPane.topAnchor="310.0">
|
||||
<children>
|
||||
<VBox spacing="3.0">
|
||||
<children>
|
||||
|
@ -118,7 +118,7 @@
|
|||
</VBox>
|
||||
</children>
|
||||
</HBox>
|
||||
<ScrollPane fx:id="scrollPaneEpisodes" layoutX="22.0" layoutY="398.0" prefHeight="135.0" style="-fx-background-color: #595959;" AnchorPane.bottomAnchor="63.0" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="310.0">
|
||||
<ScrollPane fx:id="scrollPaneEpisodes" layoutX="22.0" layoutY="398.0" prefHeight="135.0" style="-fx-background-color: #595959;" AnchorPane.leftAnchor="22.0" AnchorPane.rightAnchor="310.0" AnchorPane.topAnchor="370.0">
|
||||
<content>
|
||||
<HBox fx:id="hBoxEpisodes" maxHeight="-Infinity" minHeight="-Infinity" prefHeight="117.0" spacing="10.0">
|
||||
<padding>
|
||||
|
@ -127,7 +127,7 @@
|
|||
</HBox>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<HBox style="-fx-background-color: #ffffff;" AnchorPane.bottomAnchor="28.0" AnchorPane.leftAnchor="22.0">
|
||||
<HBox style="-fx-background-color: #ffffff;" AnchorPane.leftAnchor="22.0" AnchorPane.topAnchor="515.0">
|
||||
<children>
|
||||
<ChoiceBox fx:id="cbSeason" prefHeight="25.0" prefWidth="168.0" />
|
||||
</children>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<ScrollPane fx:id="settingsScrollPane" fitToHeight="true" fitToWidth="true" prefHeight="568.0" prefWidth="980.0" style="-fx-background-color: #ffffff;" visible="false" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.mosad.homeflix.application.SettingsView">
|
||||
<ScrollPane fx:id="settingsScrollPane" fitToHeight="true" fitToWidth="true" prefHeight="568.0" prefWidth="980.0" style="-fx-background-color: #ffffff;" visible="false" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.application.SettingsView">
|
||||
<content>
|
||||
<AnchorPane fx:id="settingsAnchorPane" style="-fx-background-color: #ffffff;">
|
||||
<children>
|
||||
|
@ -113,11 +113,6 @@
|
|||
<Insets bottom="-5.0" top="-5.0" />
|
||||
</padding>
|
||||
</JFXToggleButton>
|
||||
<JFXToggleButton fx:id="fullscreenToggleBtn" onAction="#fullscreenToggleBtnAction" text="start in fullscreen">
|
||||
<padding>
|
||||
<Insets bottom="-5.0" top="-5.0" />
|
||||
</padding>
|
||||
</JFXToggleButton>
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox spacing="10.0">
|
||||
|
|
Before Width: | Height: | Size: 617 B |
After Width: | Height: | Size: 109 B |
After Width: | Height: | Size: 111 B |
Before Width: | Height: | Size: 101 B |
Before Width: | Height: | Size: 101 B |
Before Width: | Height: | Size: 159 B |
After Width: | Height: | Size: 107 B |
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 616 B |
After Width: | Height: | Size: 107 B |
Before Width: | Height: | Size: 200 B |
|
@ -1,32 +1,13 @@
|
|||
# Project-HomeFlix
|
||||
#
|
||||
# Copyright 2016-2020 <seil0@mosad.xyz>
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# This program 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 this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301, USA.
|
||||
#
|
||||
# HomeFlix-Local_de_DE.properties German Local
|
||||
#HomeFlix-Local_de_DE.properties German Local
|
||||
|
||||
# main window translations
|
||||
#main window translations
|
||||
info = Info
|
||||
settings = Einstellungen
|
||||
streamingSettings = Stream Einst.
|
||||
tfSearch = Suche...
|
||||
openFolder = Ordner \u00F6ffnen
|
||||
|
||||
# settings translations
|
||||
#settings translations
|
||||
homeflixSettingsLbl = HomeFlix Einstellungen
|
||||
filmDirTextField = Pfad...
|
||||
addDirectory = Ordner hinzuf\u00FCgen
|
||||
|
@ -39,23 +20,22 @@ updateBtnChecking = Es wird nach Updates gesucht...
|
|||
updateBtnUpdateAvailable = Update verf\u00FCgbar
|
||||
updateBtnNoUpdateAvailable = Kein Update verf\u00FCgbar
|
||||
autoUpdate = beim Start nach Updates suchen:
|
||||
autoplay = Autoplay
|
||||
fullscreen = starte im Vollbildmodus
|
||||
autoplay = autoplay
|
||||
branchLbl = Updatezweig
|
||||
sourcesLbl = Quellen
|
||||
|
||||
# column translations
|
||||
#column translations
|
||||
columnStreamUrl = Datei Name
|
||||
columnName = Name
|
||||
columnSeason = Staffel
|
||||
columnEpisode = Episode
|
||||
columnFavorite = Favorit
|
||||
|
||||
# error translations
|
||||
#error translations
|
||||
vlcNotInstalled = Um einen Film abspielen wird der VLC Media Player ben\u00F6tigt!
|
||||
infoText = \nAutoren: \n \u2022 seil0@mosad.xyz \n \u2022 localhorst@mosad.xyz \n(c) 2016-2020 mosad www.mosad.xyz
|
||||
infoText = \nAutoren: \n \u2022 seil0@mosad.xyz \n \u2022 localhorst@mosad.xyz \n(c) 2016-2019 mosad www.mosad.xyz
|
||||
|
||||
# textFlow translations
|
||||
#textFlow translations
|
||||
title = Titel
|
||||
year = Jahr
|
||||
rated = Einstufung
|
||||
|
@ -63,7 +43,7 @@ released = Ver\u00F6ffentlicht am
|
|||
season = Staffel
|
||||
episode = Episode
|
||||
runtime = Laufzeit
|
||||
genre = Genre
|
||||
genre = Gener
|
||||
directors = Regisseur
|
||||
writers = Autoren
|
||||
actors = Schauspieler
|
||||
|
@ -77,15 +57,11 @@ type = Type
|
|||
boxOffice = BoxOffice
|
||||
website = Webseite
|
||||
|
||||
# first start
|
||||
#first start
|
||||
addSourceHeader = Neue Quelle hinzuf\u00FCgen
|
||||
addSourceBody = HomeFlix konnte keine Quelle finden. \nF\u00FCge eine loakels Verzeichniss oder eine Sreaming Datei als neue Quelle hinzu.
|
||||
addSourceBody = HomeFlix konnte keine Quelle finden. \nFüge eine loakels Verzeichniss oder eine Sreaming Datei als neue Quelle hinzu.
|
||||
cancelBtnText = Abbrechen
|
||||
|
||||
# DetailView
|
||||
#DetailView
|
||||
crew = Haupt-Crew
|
||||
score = Benutzerbewertung
|
||||
|
||||
# player
|
||||
nextEpisode = Nächste Folge in\u0020
|
||||
seconds = \u0020Sekunden
|
||||
|
|
|
@ -1,32 +1,13 @@
|
|||
# Project-HomeFlix
|
||||
#
|
||||
# Copyright 2016-2020 <seil0@mosad.xyz>
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# This program 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 this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301, USA.
|
||||
#
|
||||
# HomeFlix-Local_en_US.properties US-English Local and default
|
||||
#HomeFlix-Local_en_US.properties US-English Local and default
|
||||
|
||||
# main window translations
|
||||
#main window translations
|
||||
info = Info
|
||||
settings = Settings
|
||||
streamingSettings = Stream Settings
|
||||
tfSearch = Search...
|
||||
openFolder = open Folder
|
||||
|
||||
# settings translations
|
||||
#settings translations
|
||||
homeflixSettingsLbl = HomeFlix Settings
|
||||
filmDirTextField = Path...
|
||||
addDirectory = add directory
|
||||
|
@ -39,23 +20,22 @@ updateBtnChecking = checking for updates...
|
|||
updateBtnUpdateAvailable = update available
|
||||
updateBtnNoUpdateAvailable = no update available
|
||||
autoUpdate = check at startup for updates:
|
||||
autoplay = Autoplay
|
||||
fullscreen = start in fullscreen
|
||||
autoplay = autoplay
|
||||
branchLbl = Branch
|
||||
sourcesLbl = Sources
|
||||
sourcesLbl = Quellen
|
||||
|
||||
# column translations
|
||||
#column translations
|
||||
columnStreamUrl = File Name
|
||||
columnName = Name
|
||||
columnSeason = Season
|
||||
columnEpisode = Episode
|
||||
columnFavorite = Favorite
|
||||
|
||||
# error translations
|
||||
#error translations
|
||||
vlcNotInstalled = VLC Media Player is required to play a movie!
|
||||
infoText = \nMaintainers: \n \u2022 seil0@mosad.xyz \n \u2022 localhorst@mosad.xyz \n(c) 2016-2020 mosad www.mosad.xyz
|
||||
infoText = \nMaintainers: \n \u2022 seil0@mosad.xyz \n \u2022 localhorst@mosad.xyz \n(c) 2016-2019 mosad www.mosad.xyz
|
||||
|
||||
# textFlow translations
|
||||
#textFlow translations
|
||||
title = Title
|
||||
year = Year
|
||||
rated = Rating
|
||||
|
@ -63,7 +43,7 @@ released = published on
|
|||
season = Season
|
||||
episode = Episode
|
||||
runtime = Runtime
|
||||
genre = Genre
|
||||
genre = Gener
|
||||
directors = Directors
|
||||
writers = Writers
|
||||
actors = Actors
|
||||
|
@ -77,15 +57,11 @@ type = Type
|
|||
boxOffice = BoxOffice
|
||||
website = Website
|
||||
|
||||
# first startnext episode in
|
||||
#first start
|
||||
addSourceHeader = add a new source
|
||||
addSourceBody = HomeFlix was not able to load a source. \nAdd a new local directory or a streaming file as new source.
|
||||
addSourceBody = HomeFlix was not able to load a source. \nAdd a new local directory oa a streaming file as new source.
|
||||
cancelBtnText = cancel
|
||||
|
||||
# DetailView
|
||||
#DetailView
|
||||
crew = Featured Crew
|
||||
score = User Score
|
||||
|
||||
# player
|
||||
nextEpisode = next episode in\u0020
|
||||
seconds = \u0020seconds
|
||||
|
|