minor bugfixes and clean up

* fixed a bug that prevented posters from showing at the first start
* added the ability to start a series from the last watched episode
This commit is contained in:
Jannik 2019-06-22 21:04:43 +02:00
parent 9af3ad26bd
commit 5488bece2d
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
10 changed files with 161 additions and 269 deletions

View File

@ -23,10 +23,8 @@
package kellerkinder.HomeFlix.application; package kellerkinder.HomeFlix.application;
import java.awt.Desktop; import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -217,53 +215,12 @@ public class FilmDetailView {
MainWindowController.getInstance().disableBlur(); // disable blur MainWindowController.getInstance().disableBlur(); // disable blur
} }
// TODO rework
private void playFilm() { private void playFilm() {
if(new File(currentStreamURL).isDirectory()) { if(new File(currentStreamURL).isDirectory()) {
return; return;
} }
if (Player.isSupportedFormat(currentStreamURL)) { new Player(currentStreamURL);
new Player(currentStreamURL);
} else {
LOGGER.error("using fallback player!");
if (System.getProperty("os.name").contains("Linux")) {
String line;
String output = "";
Process p;
try {
p = Runtime.getRuntime().exec("which vlc");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output = line;
}
LOGGER.info("which vlc: " + output);
input.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if (output.contains("which: no vlc") || output == "") {
// JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info",
// XMLController.getLocalBundle().getString("vlcNotInstalled"), btnStyle, primaryStage);
// vlcInfoAlert.showAndWait();
} else {
try {
new ProcessBuilder("vlc", currentStreamURL).start();
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
}
}
} else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) {
try {
Desktop.getDesktop().open(new File(currentStreamURL));
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
}
} else {
LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! ");
}
}
} }
} }

View File

@ -43,8 +43,8 @@ public class Main extends Application {
private MainWindowController mainWindowController; private MainWindowController mainWindowController;
private static XMLController xmlController; private static XMLController xmlController;
private static Logger LOGGER; private static Logger LOGGER;
public static final String version = "0.7.90"; public static final String version = "0.7.91";
public static final String buildNumber = "171"; public static final String buildNumber = "173";
public static final String versionName = "toothless dragon"; public static final String versionName = "toothless dragon";
@Override @Override
@ -100,11 +100,11 @@ public class Main extends Application {
xmlController = new XMLController(); xmlController = new XMLController();
if (XMLController.getConfigFile().exists()) { if (!XMLController.getConfigFile().exists()) {
xmlController.loadSettings(); xmlController.saveSettings(); // save the settings file with default values if it doesn't exist
} else {
xmlController.saveSettings();
} }
xmlController.loadSettings();
if (!XMLController.getPosterCache().exists()) { if (!XMLController.getPosterCache().exists()) {
XMLController.getPosterCache().mkdir(); XMLController.getPosterCache().mkdir();

View File

@ -22,16 +22,12 @@
package kellerkinder.HomeFlix.application; package kellerkinder.HomeFlix.application;
import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer; import java.io.Writer;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URLConnection;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@ -73,7 +69,6 @@ import kellerkinder.HomeFlix.controller.UpdateController;
import kellerkinder.HomeFlix.controller.XMLController; import kellerkinder.HomeFlix.controller.XMLController;
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
import kellerkinder.HomeFlix.datatypes.PosterModeElement; import kellerkinder.HomeFlix.datatypes.PosterModeElement;
import kellerkinder.HomeFlix.player.Player;
public class MainWindowController { public class MainWindowController {
@ -109,8 +104,6 @@ public class MainWindowController {
private String btnStyle; private String btnStyle;
private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, null);
private ObservableList<PosterModeElement> posterEmenents = FXCollections.observableArrayList(); private ObservableList<PosterModeElement> posterEmenents = FXCollections.observableArrayList();
private 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
@ -184,59 +177,6 @@ public class MainWindowController {
primaryStage.setMinWidth(1130.00); primaryStage.setMinWidth(1130.00);
} }
// Table-Mode fxml actions
@FXML
private void playbtnclicked() {
if (currentTableFilm.getStreamUrl().length() > 0) {
if (currentTableFilm.getStreamUrl().contains("_rootNode")) {
LOGGER.info("rootNode found, getting last watched episode");
currentTableFilm = dbController.getLastWatchedEpisode(currentTableFilm.getTitle());
}
if (isSupportedFormat(currentTableFilm)) {
new Player(currentTableFilm.getStreamUrl());
} else {
LOGGER.error("using fallback player!");
if (System.getProperty("os.name").contains("Linux")) {
String line;
String output = "";
Process p;
try {
p = Runtime.getRuntime().exec("which vlc");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output = line;
}
LOGGER.info("which vlc: " + output);
input.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if (output.contains("which: no vlc") || output == "") {
JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info",
XMLController.getLocalBundle().getString("vlcNotInstalled"), btnStyle, primaryStage);
vlcInfoAlert.showAndWait();
} else {
try {
new ProcessBuilder("vlc", currentTableFilm.getStreamUrl()).start();
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
}
}
} else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) {
try {
Desktop.getDesktop().open(new File(currentTableFilm.getStreamUrl()));
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
}
} else {
LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! ");
}
}
}
}
// general fxml actions // general fxml actions
@FXML @FXML
private void aboutBtnAction() { private void aboutBtnAction() {
@ -272,6 +212,7 @@ public class MainWindowController {
if (selectedFolder != null && selectedFolder.exists()) { if (selectedFolder != null && selectedFolder.exists()) {
selectFirstSource.getAlert().close(); selectFirstSource.getAlert().close();
writeSource(selectedFolder.getPath(), "local"); writeSource(selectedFolder.getPath(), "local");
settingsViewController.loadInitSources();
} else { } else {
LOGGER.error("The selected folder dosen't exist!"); LOGGER.error("The selected folder dosen't exist!");
System.exit(1); System.exit(1);
@ -286,6 +227,7 @@ public class MainWindowController {
if (selectedFile != null && selectedFile.exists()) { if (selectedFile != null && selectedFile.exists()) {
selectFirstSource.getAlert().close(); selectFirstSource.getAlert().close();
writeSource(selectedFile.getPath(), "stream"); writeSource(selectedFile.getPath(), "stream");
settingsViewController.loadInitSources();
} else { } else {
LOGGER.error("The selected file dosen't exist!"); LOGGER.error("The selected file dosen't exist!");
System.exit(1); System.exit(1);
@ -411,20 +353,9 @@ public class MainWindowController {
} }
} }
/**
* check if a film is supported by the HomeFlixPlayer or not this is the case if
* the mime type is mp4
*
* @param entry the film you want to check
* @return true if so, false if not
*/
private boolean isSupportedFormat(FilmTabelDataType film) {
String mimeType = URLConnection.guessContentTypeFromName(film.getStreamUrl());
return mimeType != null && (mimeType.contains("mp4") || mimeType.contains("vp6"));
}
/** /**
* Poser Mode WIP * Poser Mode
*/ */
private void posterModeStartup() { private void posterModeStartup() {
@ -437,13 +368,15 @@ public class MainWindowController {
* check if all posters are cached, if not cache the missing ones * check if all posters are cached, if not cache the missing ones
*/ */
void checkAllPosters() { 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 // get all not cached entries, none of them should have a cached poster
ExecutorService executor = Executors.newFixedThreadPool(5); ExecutorService executor = Executors.newFixedThreadPool(5);
for (FilmTabelDataType entry : dbController.getAllNotCachedEntries()) { for (FilmTabelDataType entry : dbController.getAllNotCachedEntries()) {
System.out.println(entry.getStreamUrl() + " is NOT cached!"); System.out.println(entry.getStreamUrl() + " is NOT cached!");
Runnable OMDbAPIWorker = new OMDbAPIController(entry, XMLController.getOmdbAPIKey()); Runnable OMDbAPIWorker = new OMDbAPIController(entry);
executor.execute(OMDbAPIWorker); executor.execute(OMDbAPIWorker);
} }
executor.shutdown(); executor.shutdown();
@ -456,9 +389,7 @@ public class MainWindowController {
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.error(e); LOGGER.error(e);
} }
// update all elements from the database
dbController.refreshDataBase(); // refreshes the database after a source path was added
System.out.println("finished refresh"); System.out.println("finished refresh");
} }
@ -502,7 +433,7 @@ public class MainWindowController {
for(FilmTabelDataType entry : dbController.getStreamsList()) { for(FilmTabelDataType entry : dbController.getStreamsList()) {
if (dbController.getCacheDate(entry.getStreamUrl()).isBefore(lastValidCache)) { if (dbController.getCacheDate(entry.getStreamUrl()).isBefore(lastValidCache)) {
System.out.println(entry.getTitle() + " chached on: " + dbController.getCacheDate(entry.getStreamUrl())); System.out.println(entry.getTitle() + " chached on: " + dbController.getCacheDate(entry.getStreamUrl()));
Runnable OMDbAPIWorker = new OMDbAPIController(entry, XMLController.getOmdbAPIKey()); Runnable OMDbAPIWorker = new OMDbAPIController(entry);
executor.execute(OMDbAPIWorker); executor.execute(OMDbAPIWorker);
} }
} }

View File

@ -48,6 +48,7 @@ import javafx.util.Duration;
import kellerkinder.HomeFlix.controller.DBController; import kellerkinder.HomeFlix.controller.DBController;
import kellerkinder.HomeFlix.controller.XMLController; import kellerkinder.HomeFlix.controller.XMLController;
import kellerkinder.HomeFlix.datatypes.SeriresDVEpisode; import kellerkinder.HomeFlix.datatypes.SeriresDVEpisode;
import kellerkinder.HomeFlix.player.Player;
public class SeriesDetailView { public class SeriesDetailView {
@ -121,7 +122,7 @@ public class SeriesDetailView {
@FXML @FXML
private void btnPlayAction() { private void btnPlayAction() {
// playFilm(); // TODO new Player(dbController.getLastWatchedEpisode(currentStreamURL));
} }
@FXML @FXML

View File

@ -243,18 +243,20 @@ public class SettingsView {
} }
// add a all elements of sourcesList to the sources table on the settings pane // add a all elements of sourcesList to the sources table on the settings pane
private void loadInitSources() { void loadInitSources() {
try { if(new File(XMLController.getDirHomeFlix() + "/sources.json").exists()) {
// create a JsonArray, containing all sources, add each source to the mwc, get all films from it try {
JsonArray sources = Json.parse(new FileReader(XMLController.getDirHomeFlix() + "/sources.json")).asArray(); // create a JsonArray, containing all sources, add each source to the mwc, get all films from it
for (JsonValue source : sources) { JsonArray sources = Json.parse(new FileReader(XMLController.getDirHomeFlix() + "/sources.json")).asArray();
String path = source.asObject().getString("path", ""); for (JsonValue source : sources) {
String mode = source.asObject().getString("mode", ""); String path = source.asObject().getString("path", "");
sourcesList.add(new SourceDataType(path, mode)); String mode = source.asObject().getString("mode", "");
} sourcesList.add(new SourceDataType(path, mode));
} catch (Exception e) { }
e.printStackTrace(); } catch (Exception e) {
} e.printStackTrace();
}
}
} }
public void updateColor(String btnStyle) { public void updateColor(String btnStyle) {

View File

@ -42,7 +42,6 @@ import org.apache.logging.log4j.Logger;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import kellerkinder.HomeFlix.datatypes.DatabaseDataType; import kellerkinder.HomeFlix.datatypes.DatabaseDataType;
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
import kellerkinder.HomeFlix.datatypes.OMDbAPIResponseDataType; import kellerkinder.HomeFlix.datatypes.OMDbAPIResponseDataType;
@ -52,8 +51,6 @@ public class DBController {
private static DBController instance = null; private static DBController instance = null;
private String DB_PATH; private String DB_PATH;
private Image favorite_black = new Image("icons/baseline_favorite_black_48dp.png"); // TODO this should be removed
private Image favorite_border_black = new Image("icons/baseline_favorite_border_black_48dp.png"); // TODO this too
private List<DatabaseDataType> databaseStreams = new ArrayList<DatabaseDataType>(); // contains all films stored in the database private List<DatabaseDataType> databaseStreams = new ArrayList<DatabaseDataType>(); // contains all films stored in the database
private List<DatabaseDataType> sourceStreams = new ArrayList<DatabaseDataType>(); // contains all films from the sources private List<DatabaseDataType> sourceStreams = new ArrayList<DatabaseDataType>(); // contains all films from the sources
private Connection connection = null; private Connection connection = null;
@ -161,10 +158,8 @@ public class DBController {
ResultSet rs = stmt.executeQuery("SELECT * FROM films ORDER BY title"); ResultSet rs = stmt.executeQuery("SELECT * FROM films ORDER BY title");
while (rs.next()) { while (rs.next()) {
ImageView imageView = rs.getBoolean("favorite") ? new ImageView(favorite_black) : new ImageView(favorite_border_black);
filmsList.add(new FilmTabelDataType(rs.getString("streamUrl"), filmsList.add(new FilmTabelDataType(rs.getString("streamUrl"),
rs.getString("title"), rs.getString("season"), rs.getString("episode") ,rs.getBoolean("favorite"), rs.getString("title"), rs.getString("season"), rs.getString("episode")));
imageView));
} }
stmt.close(); stmt.close();
rs.close(); rs.close();
@ -189,10 +184,8 @@ public class DBController {
ResultSet rs = ps.executeQuery(); ResultSet rs = ps.executeQuery();
while (rs.next()) { while (rs.next()) {
ImageView imageView = rs.getBoolean("favorite") ? new ImageView(favorite_black) : new ImageView(favorite_border_black);
film = new FilmTabelDataType(rs.getString("streamUrl"), film = new FilmTabelDataType(rs.getString("streamUrl"),
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), rs.getString("title"), rs.getString("season"), rs.getString("episode"));
imageView);
} }
rs.close(); rs.close();
ps.close(); ps.close();
@ -597,8 +590,7 @@ public class DBController {
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE cached = 0"); ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE cached = 0");
while (rs.next()) { while (rs.next()) {
notCachedEntries.add(new FilmTabelDataType(rs.getString("streamUrl"), notCachedEntries.add(new FilmTabelDataType(rs.getString("streamUrl"),
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), rs.getString("title"), rs.getString("season"), rs.getString("episode")));
new ImageView(favorite_border_black)));
} }
stmt.close(); stmt.close();
rs.close(); rs.close();
@ -682,7 +674,8 @@ public class DBController {
/** /**
* get the next episode of a series * get the next episode of a series
* @param title title of the film * @param title title of the film
* @param episode episode currently played * @param episode current episode
* @param season season of the current episode
* @return {@link FilmTabelDataType} the next episode as object * @return {@link FilmTabelDataType} the next episode as object
*/ */
public FilmTabelDataType getNextEpisode(String title, int episode, int season) { public FilmTabelDataType getNextEpisode(String title, int episode, int season) {
@ -710,8 +703,7 @@ public class DBController {
// at this point we have found the correct episode // at this point we have found the correct episode
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"),
rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), rs.getString("season"), rs.getString("episode"));
new ImageView());
rs.close(); rs.close();
ps.close(); ps.close();
@ -723,33 +715,31 @@ public class DBController {
/** TODO rework, we should save the next episode in the root entry /** TODO rework, we should save the next episode in the root entry
* get the last watched episode * get the last watched episode
* @param title the title of the series * @param streamURL URL of the stream
* @return the last watched episode as {@link FilmTabelDataType} object * @return the last watched episodes URL
*/ */
public FilmTabelDataType getLastWatchedEpisode(String title) { public String getLastWatchedEpisode(String streamURL) {
LOGGER.info("last watched episode of: " + title); LOGGER.info("last watched episode in: " + streamURL);
FilmTabelDataType nextFilm = null; String lastEp = null;
double lastCurrentTime = 0; double lastCurrentTime = 0;
try { try {
Statement stmt = connection.createStatement(); PreparedStatement ps = connection.prepareStatement("SELECT * FROM films WHERE streamUrl LIKE ?");
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\";"); ps.setString(1, streamURL + "/%");
ResultSet rs = ps.executeQuery();
while (rs.next()) { while (rs.next()) {
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"),
rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
new ImageView());
// get the first episode where currentTime != 0 // get the first episode where currentTime != 0
if (rs.getDouble("currentTime") > lastCurrentTime) { if (rs.getDouble("currentTime") > lastCurrentTime || lastEp == null) {
break; lastEp = rs.getString("streamUrl");
} }
} }
rs.close(); rs.close();
stmt.close(); ps.close();
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("Ups! error while getting the last watched episode!", e); LOGGER.error("Ups! error while getting the last watched episode!", e);
} }
return nextFilm; return lastEp;
} }
/** /**

View File

@ -55,9 +55,9 @@ public class OMDbAPIController implements Runnable {
* @param currentTableFilm the current film object * @param currentTableFilm the current film object
* @param omdbAPIKey the omdbAPI key * @param omdbAPIKey the omdbAPI key
*/ */
public OMDbAPIController(FilmTabelDataType currentTableFilm, String omdbAPIKey) { public OMDbAPIController(FilmTabelDataType currentTableFilm) {
this.currentTableFilm = currentTableFilm; this.currentTableFilm = currentTableFilm;
this.omdbAPIKey = omdbAPIKey; omdbAPIKey = XMLController.getOmdbAPIKey();
dbController = DBController.getInstance(); dbController = DBController.getInstance();
} }

View File

@ -20,20 +20,11 @@
*/ */
package kellerkinder.HomeFlix.datatypes; package kellerkinder.HomeFlix.datatypes;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.ImageView;
public class FilmTabelDataType { public class FilmTabelDataType {
private final StringProperty streamUrl = new SimpleStringProperty(); private String streamUrl;
private final StringProperty title = new SimpleStringProperty(); private String title;
private final StringProperty season = new SimpleStringProperty(); private String season;
private final StringProperty episode = new SimpleStringProperty(); private String episode;
private final BooleanProperty favorite = new SimpleBooleanProperty();
private final SimpleObjectProperty<ImageView> image = new SimpleObjectProperty<>();
/** /**
* tableData is the data-type of tree-table-view * tableData is the data-type of tree-table-view
@ -41,93 +32,44 @@ public class FilmTabelDataType {
* @param title title of the film * @param title title of the film
* @param season season if it's a series * @param season season if it's a series
* @param episode episode if it's a series * @param episode episode if it's a series
* @param favorite indicator for favorites, used for sorting the items
* @param cached indicator for caching status
* @param image favorite icon
*/ */
public FilmTabelDataType(final String streamUrl, final String title, final String season, final String episode, public FilmTabelDataType(String streamUrl, String title, String season, String episode) {
final boolean favorite, final ImageView image) { this.streamUrl = streamUrl;
this.streamUrl.set(streamUrl); this.title = title;
this.title.set(title); this.season = season;
this.season.set(season); this.episode = episode;
this.episode.set(episode);
this.favorite.set(favorite);
this.image.set(image);
} }
public StringProperty streamUrlProperty(){ public String getStreamUrl() {
return streamUrl; return streamUrl;
} }
public StringProperty titleProperty(){ public String getTitle() {
return title; return title;
} }
public StringProperty seasonProperty(){ public String getSeason() {
return season; return season;
} }
public StringProperty episodeProperty(){ public String getEpisode() {
return episode; return episode;
} }
public BooleanProperty favoriteProperty(){ public void setStreamUrl(String streamUrl) {
return favorite; this.streamUrl = streamUrl;
}
public SimpleObjectProperty<ImageView> imageProperty(){
return image;
}
public final String getStreamUrl() {
return streamUrlProperty().get();
}
public final String getTitle() {
return titleProperty().get();
} }
public final String getSeason() { public void setTitle(String title) {
return seasonProperty().get(); this.title = title;
}
public final String getEpisode() {
return episodeProperty().get();
}
public final boolean getFavorite() {
return favoriteProperty().get();
}
public final ImageView getImage() {
return imageProperty().get();
}
public final void setStreamUrl(String streamUrl) {
streamUrlProperty().set(streamUrl);
} }
public final void setTitle(String title) { public void setSeason(String season) {
titleProperty().set(title); this.season = season;
}
public final void setSeason(String season) {
seasonProperty().set(season);
} }
public final void setEpisode(String season) { public void setEpisode(String episode) {
episodeProperty().set(season); this.episode = episode;
} }
public final void setFavorite(boolean favorite) {
favoriteProperty().set(favorite);
}
public final void setImage(ImageView image) {
imageProperty().set(image);
}
} }

View File

@ -22,8 +22,16 @@
package kellerkinder.HomeFlix.player; package kellerkinder.HomeFlix.player;
import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLConnection; import java.net.URLConnection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.image.Image; import javafx.scene.image.Image;
@ -31,13 +39,13 @@ import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage; import javafx.stage.Stage;
import kellerkinder.HomeFlix.application.Main; import kellerkinder.HomeFlix.application.Main;
import kellerkinder.HomeFlix.controller.DBController; import kellerkinder.HomeFlix.controller.DBController;
public class Player { public class Player {
private PlayerController playerController; private PlayerController playerController;
private Stage stage; private Stage stage;
private AnchorPane pane; private AnchorPane pane;
private Scene scene; private Scene scene;
private static final Logger LOGGER = LogManager.getLogger(Player.class.getName());
// TODO move the players choose logic to a separate static class // TODO move the players choose logic to a separate static class
@ -46,6 +54,20 @@ public class Player {
* @param currentTableFilm the currently selected film * @param currentTableFilm the currently selected film
*/ */
public Player(String streamURL) { public Player(String streamURL) {
if (isSupportedFormat(streamURL)) {
hfPlayer(streamURL);
} else {
legacyPlayer(streamURL);
}
}
/**
* start the integrated player
* @param streamURL
*/
private void hfPlayer(String streamURL) {
playerController = new PlayerController(this, streamURL); playerController = new PlayerController(this, streamURL);
try { try {
@ -72,6 +94,61 @@ public class Player {
e.printStackTrace(); e.printStackTrace();
} }
} }
/**
*
*/
private void legacyPlayer(String streamURL) {
LOGGER.warn("using fallback player!");
if (System.getProperty("os.name").contains("Linux")) {
String line;
String output = "";
Process p;
try {
p = Runtime.getRuntime().exec("which vlc");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output = line;
}
LOGGER.info("which vlc: " + output);
input.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if (output.contains("which: no vlc") || output == "") {
// JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info",
// XMLController.getLocalBundle().getString("vlcNotInstalled"), btnStyle, primaryStage);
// vlcInfoAlert.showAndWait();
} else {
try {
new ProcessBuilder("vlc", streamURL).start();
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
}
}
} else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) {
try {
Desktop.getDesktop().open(new File(streamURL));
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
}
} else {
LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! ");
}
}
/**
* check if a film is supported by the HomeFlixPlayer or not this is the case if
* the mime type is mp4
*
* @param streamURL URL of the stream you want to check
* @return true if so, false if not
*/
public static boolean isSupportedFormat(String streamURL) {
String mimeType = URLConnection.guessContentTypeFromName(streamURL);
return mimeType != null && (mimeType.contains("mp4") || mimeType.contains("vp6"));
}
public Stage getStage() { public Stage getStage() {
return stage; return stage;
@ -81,16 +158,4 @@ public class Player {
return scene; return scene;
} }
/**
* check if a film is supported by the HomeFlixPlayer or not this is the case if
* the mime type is mp4
*
* @param entry the film you want to check
* @return true if so, false if not
*/
public static boolean isSupportedFormat(String streamURL) {
String mimeType = URLConnection.guessContentTypeFromName(streamURL);
return mimeType != null && (mimeType.contains("mp4") || mimeType.contains("vp6"));
}
} }

View File

@ -90,7 +90,7 @@ public class JFX2BtnCancelAlert {
JFXButton cancelBtn = new JFXButton(); JFXButton cancelBtn = new JFXButton();
cancelBtn.setText(cancelText); cancelBtn.setText(cancelText);
cancelBtn.addEventHandler(ActionEvent.ACTION, (e)-> alert.close()); cancelBtn.addEventHandler(ActionEvent.ACTION, (e)-> alert.close());
cancelBtn.addEventHandler(ActionEvent.ACTION, (e)-> System.exit(0)); // TODO only on first start
cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
cancelBtn.setPrefHeight(32); cancelBtn.setPrefHeight(32);
cancelBtn.setStyle(btnStyle); cancelBtn.setStyle(btnStyle);
@ -100,11 +100,15 @@ public class JFX2BtnCancelAlert {
content.setHeading(new Text(headingText)); content.setHeading(new Text(headingText));
content.setBody(new Text(bodyText)); content.setBody(new Text(bodyText));
// TODO only on first start // only on first start
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); if (stage == null) {
stage.setMinWidth(416); cancelBtn.addEventHandler(ActionEvent.ACTION, (e)-> System.exit(0));
stage.setMinHeight(162); Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
stage.setOnCloseRequest(event -> System.exit(0)); stage.setMinWidth(416);
stage.setMinHeight(162);
stage.setOnCloseRequest(event -> System.exit(0));
}
alert.setContent(content); alert.setContent(content);
alert.showAndWait(); alert.showAndWait();