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:
		| @ -23,10 +23,8 @@ | ||||
| package kellerkinder.HomeFlix.application; | ||||
|  | ||||
| import java.awt.Desktop; | ||||
| import java.io.BufferedReader; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStreamReader; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| @ -217,53 +215,12 @@ public class FilmDetailView { | ||||
| 		MainWindowController.getInstance().disableBlur(); // disable blur | ||||
| 	} | ||||
| 	 | ||||
| 	// TODO rework | ||||
| 	private void playFilm() { | ||||
| 		if(new File(currentStreamURL).isDirectory()) { | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		if (Player.isSupportedFormat(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! "); | ||||
| 			} | ||||
| 		} | ||||
| 		new Player(currentStreamURL); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -43,8 +43,8 @@ public class Main extends Application { | ||||
| 	private MainWindowController mainWindowController; | ||||
| 	private static XMLController xmlController; | ||||
| 	private static Logger LOGGER; | ||||
| 	public static final String version = "0.7.90"; | ||||
| 	public static final String buildNumber = "171"; | ||||
| 	public static final String version = "0.7.91"; | ||||
| 	public static final String buildNumber = "173"; | ||||
| 	public static final String versionName = "toothless dragon"; | ||||
|  | ||||
| 	@Override | ||||
| @ -100,11 +100,11 @@ public class Main extends Application { | ||||
| 		 | ||||
| 		xmlController = new XMLController(); | ||||
| 		 | ||||
| 		if (XMLController.getConfigFile().exists()) { | ||||
| 			xmlController.loadSettings(); | ||||
| 		} else { | ||||
| 			xmlController.saveSettings(); | ||||
| 		if (!XMLController.getConfigFile().exists()) { | ||||
| 			xmlController.saveSettings(); // save the settings file with default values if it doesn't exist | ||||
| 		} | ||||
| 		 | ||||
| 		xmlController.loadSettings(); | ||||
|  | ||||
| 		if (!XMLController.getPosterCache().exists()) { | ||||
| 			XMLController.getPosterCache().mkdir(); | ||||
|  | ||||
| @ -22,16 +22,12 @@ | ||||
|  | ||||
| package kellerkinder.HomeFlix.application; | ||||
|  | ||||
| import java.awt.Desktop; | ||||
| import java.io.BufferedReader; | ||||
| import java.io.File; | ||||
| import java.io.FileReader; | ||||
| import java.io.FileWriter; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStreamReader; | ||||
| import java.io.Writer; | ||||
| import java.math.BigInteger; | ||||
| import java.net.URLConnection; | ||||
| import java.time.LocalDate; | ||||
| import java.util.Locale; | ||||
| import java.util.ResourceBundle; | ||||
| @ -73,7 +69,6 @@ import kellerkinder.HomeFlix.controller.UpdateController; | ||||
| import kellerkinder.HomeFlix.controller.XMLController; | ||||
| import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; | ||||
| import kellerkinder.HomeFlix.datatypes.PosterModeElement; | ||||
| import kellerkinder.HomeFlix.player.Player; | ||||
|  | ||||
| public class MainWindowController {	 | ||||
| 	 | ||||
| @ -109,8 +104,6 @@ public class MainWindowController { | ||||
|  | ||||
| 	private String btnStyle; | ||||
|  | ||||
| 	private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, null); | ||||
|  | ||||
| 	private ObservableList<PosterModeElement> posterEmenents = FXCollections.observableArrayList(); | ||||
| 	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); | ||||
| 	} | ||||
|  | ||||
| 	// 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 | ||||
| 	@FXML | ||||
| 	private void aboutBtnAction() { | ||||
| @ -272,6 +212,7 @@ public class MainWindowController { | ||||
| 			if (selectedFolder != null && selectedFolder.exists()) { | ||||
| 				selectFirstSource.getAlert().close(); | ||||
| 				writeSource(selectedFolder.getPath(), "local"); | ||||
| 				settingsViewController.loadInitSources(); | ||||
| 			} else { | ||||
| 				LOGGER.error("The selected folder dosen't exist!"); | ||||
| 				System.exit(1); | ||||
| @ -286,6 +227,7 @@ public class MainWindowController { | ||||
| 			if (selectedFile != null && selectedFile.exists()) { | ||||
| 				selectFirstSource.getAlert().close(); | ||||
| 				writeSource(selectedFile.getPath(), "stream"); | ||||
| 				settingsViewController.loadInitSources(); | ||||
| 			} else { | ||||
| 				LOGGER.error("The selected file dosen't exist!"); | ||||
| 				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() { | ||||
| @ -437,13 +368,15 @@ 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); | ||||
|  | ||||
| 		for (FilmTabelDataType entry : dbController.getAllNotCachedEntries()) { | ||||
| 			System.out.println(entry.getStreamUrl() + " is NOT cached!"); | ||||
|  | ||||
| 			Runnable OMDbAPIWorker = new OMDbAPIController(entry, XMLController.getOmdbAPIKey()); | ||||
| 			Runnable OMDbAPIWorker = new OMDbAPIController(entry); | ||||
| 			executor.execute(OMDbAPIWorker); | ||||
| 		} | ||||
| 		executor.shutdown(); | ||||
| @ -456,9 +389,7 @@ public class MainWindowController { | ||||
| 		} catch (InterruptedException 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"); | ||||
| 	} | ||||
| 	 | ||||
| @ -502,7 +433,7 @@ public class MainWindowController { | ||||
| 		for(FilmTabelDataType entry : dbController.getStreamsList()) { | ||||
| 			if (dbController.getCacheDate(entry.getStreamUrl()).isBefore(lastValidCache)) { | ||||
| 				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); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @ -48,6 +48,7 @@ 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 { | ||||
| 	 | ||||
| @ -121,7 +122,7 @@ public class SeriesDetailView { | ||||
| 	 | ||||
| 	@FXML | ||||
| 	private void btnPlayAction() { | ||||
| //		playFilm(); // TODO | ||||
| 		new Player(dbController.getLastWatchedEpisode(currentStreamURL)); | ||||
| 	} | ||||
| 	 | ||||
| 	@FXML | ||||
|  | ||||
| @ -243,18 +243,20 @@ public class SettingsView { | ||||
| 	} | ||||
|      | ||||
|     // add a all elements of sourcesList to the sources table on the settings pane | ||||
|  	private void loadInitSources() { | ||||
|  		try { | ||||
| 			// create a JsonArray, containing all sources, add each source to the mwc, get all films from it | ||||
| 			JsonArray sources = Json.parse(new FileReader(XMLController.getDirHomeFlix() + "/sources.json")).asArray(); | ||||
| 			for (JsonValue source : sources) { | ||||
| 				String path = source.asObject().getString("path", ""); | ||||
| 				String mode = source.asObject().getString("mode", ""); | ||||
| 				sourcesList.add(new SourceDataType(path, mode)); | ||||
| 			} | ||||
| 		} catch (Exception e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
|  	void loadInitSources() { | ||||
|  		if(new File(XMLController.getDirHomeFlix() + "/sources.json").exists()) { | ||||
|  			try { | ||||
|  				// create a JsonArray, containing all sources, add each source to the mwc, get all films from it | ||||
|  				JsonArray sources = Json.parse(new FileReader(XMLController.getDirHomeFlix() + "/sources.json")).asArray(); | ||||
|  				for (JsonValue source : sources) { | ||||
|  					String path = source.asObject().getString("path", ""); | ||||
|  					String mode = source.asObject().getString("mode", ""); | ||||
|  					sourcesList.add(new SourceDataType(path, mode)); | ||||
|  				} | ||||
|  			} catch (Exception e) { | ||||
|  				e.printStackTrace(); | ||||
|  			} | ||||
|  		} | ||||
|  	} | ||||
|      | ||||
|     public void updateColor(String btnStyle) { | ||||
|  | ||||
| @ -42,7 +42,6 @@ import org.apache.logging.log4j.Logger; | ||||
| import javafx.collections.FXCollections; | ||||
| import javafx.collections.ObservableList; | ||||
| import javafx.scene.image.Image; | ||||
| import javafx.scene.image.ImageView; | ||||
| import kellerkinder.HomeFlix.datatypes.DatabaseDataType; | ||||
| import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; | ||||
| import kellerkinder.HomeFlix.datatypes.OMDbAPIResponseDataType; | ||||
| @ -52,8 +51,6 @@ public class DBController { | ||||
| 	 | ||||
| 	private static DBController instance = null; | ||||
| 	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> sourceStreams = new ArrayList<DatabaseDataType>(); // contains all films from the sources | ||||
| 	private Connection connection = null; | ||||
| @ -161,10 +158,8 @@ public class DBController { | ||||
| 			ResultSet rs = stmt.executeQuery("SELECT * FROM films ORDER BY title"); | ||||
| 			 | ||||
| 			while (rs.next()) {			 | ||||
| 				ImageView imageView = rs.getBoolean("favorite") ? new ImageView(favorite_black) : new ImageView(favorite_border_black); | ||||
| 				filmsList.add(new FilmTabelDataType(rs.getString("streamUrl"), | ||||
| 						rs.getString("title"), rs.getString("season"), rs.getString("episode") ,rs.getBoolean("favorite"), | ||||
| 						imageView)); | ||||
| 						rs.getString("title"), rs.getString("season"), rs.getString("episode"))); | ||||
| 			} | ||||
| 			stmt.close(); | ||||
| 			rs.close();		 | ||||
| @ -189,10 +184,8 @@ public class DBController { | ||||
| 			ResultSet rs = ps.executeQuery(); | ||||
| 			 | ||||
| 			while (rs.next()) { | ||||
| 				ImageView imageView = rs.getBoolean("favorite") ? new ImageView(favorite_black) : new ImageView(favorite_border_black); | ||||
| 				film = new FilmTabelDataType(rs.getString("streamUrl"), | ||||
| 						rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), | ||||
| 						imageView); | ||||
| 						rs.getString("title"), rs.getString("season"), rs.getString("episode")); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 			ps.close(); | ||||
| @ -597,8 +590,7 @@ public class DBController { | ||||
| 			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"), rs.getBoolean("favorite"), | ||||
| 						new ImageView(favorite_border_black))); | ||||
| 						rs.getString("title"), rs.getString("season"), rs.getString("episode"))); | ||||
| 			} | ||||
| 			stmt.close(); | ||||
| 			rs.close(); | ||||
| @ -682,7 +674,8 @@ public class DBController { | ||||
| 	/** | ||||
| 	 * get the next episode of a series | ||||
| 	 * @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 | ||||
| 	 */ | ||||
| 	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 | ||||
| 			nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"), | ||||
| 					rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"), | ||||
| 					new ImageView()); | ||||
| 					rs.getString("season"), rs.getString("episode")); | ||||
| 			 | ||||
| 			rs.close(); | ||||
| 			ps.close(); | ||||
| @ -723,33 +715,31 @@ public class DBController { | ||||
| 	 | ||||
| 	/** TODO rework, we should save the next episode in the root entry | ||||
| 	 * get the last watched episode | ||||
| 	 * @param title the title of the series | ||||
| 	 * @return the last watched episode as {@link FilmTabelDataType} object | ||||
| 	 * @param streamURL URL of the stream | ||||
| 	 * @return the last watched episodes URL | ||||
| 	 */ | ||||
| 	public FilmTabelDataType getLastWatchedEpisode(String title) { | ||||
| 		LOGGER.info("last watched episode of: " + title); | ||||
| 		FilmTabelDataType nextFilm = null; | ||||
| 	public String getLastWatchedEpisode(String streamURL) { | ||||
| 		LOGGER.info("last watched episode in: " + streamURL); | ||||
| 		String lastEp = null; | ||||
| 		double lastCurrentTime = 0; | ||||
| 		 | ||||
| 		try { | ||||
| 			Statement stmt = connection.createStatement(); | ||||
| 			ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\";"); | ||||
| 			PreparedStatement ps = connection.prepareStatement("SELECT * FROM films WHERE streamUrl LIKE ?"); | ||||
| 			ps.setString(1, streamURL + "/%"); | ||||
| 			ResultSet rs = ps.executeQuery(); | ||||
| 			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 | ||||
| 				if (rs.getDouble("currentTime") > lastCurrentTime) { | ||||
| 					break; | ||||
| 				if (rs.getDouble("currentTime") > lastCurrentTime || lastEp == null) { | ||||
| 					lastEp = rs.getString("streamUrl"); | ||||
| 				} | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 			stmt.close(); | ||||
| 			ps.close(); | ||||
| 		} catch (Exception e) { | ||||
| 			LOGGER.error("Ups! error while getting the last watched episode!", e); | ||||
| 		}  | ||||
|  | ||||
| 		return nextFilm; | ||||
| 		return lastEp; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
|  | ||||
| @ -55,9 +55,9 @@ public class OMDbAPIController implements Runnable { | ||||
| 	 * @param currentTableFilm		the current film object | ||||
| 	 * @param omdbAPIKey			the omdbAPI key | ||||
| 	 */ | ||||
| 	public OMDbAPIController(FilmTabelDataType currentTableFilm, String omdbAPIKey) { | ||||
| 	public OMDbAPIController(FilmTabelDataType currentTableFilm) { | ||||
| 		this.currentTableFilm = currentTableFilm; | ||||
| 		this.omdbAPIKey = omdbAPIKey; | ||||
| 		omdbAPIKey = XMLController.getOmdbAPIKey(); | ||||
| 		dbController = DBController.getInstance(); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -20,20 +20,11 @@ | ||||
|  */ | ||||
| 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 { | ||||
| 	private final StringProperty streamUrl = new SimpleStringProperty(); | ||||
| 	private final StringProperty title = new SimpleStringProperty(); | ||||
| 	private final StringProperty season = new SimpleStringProperty(); | ||||
| 	private final StringProperty episode = new SimpleStringProperty(); | ||||
| 	private final BooleanProperty favorite = new SimpleBooleanProperty(); | ||||
| 	private final SimpleObjectProperty<ImageView> image = new SimpleObjectProperty<>(); | ||||
| 	private String streamUrl; | ||||
| 	private String title; | ||||
| 	private String season; | ||||
| 	private String episode; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * tableData is the data-type of tree-table-view | ||||
| @ -41,93 +32,44 @@ public class FilmTabelDataType { | ||||
| 	 * @param title title of the film | ||||
| 	 * @param season season 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, | ||||
| 			final boolean favorite, final ImageView image) { | ||||
| 		this.streamUrl.set(streamUrl); | ||||
| 		this.title.set(title); | ||||
| 		this.season.set(season); | ||||
| 		this.episode.set(episode); | ||||
| 		this.favorite.set(favorite); | ||||
| 		this.image.set(image); | ||||
| 	public FilmTabelDataType(String streamUrl, String title, String season, String episode) { | ||||
| 		this.streamUrl = streamUrl; | ||||
| 		this.title = title; | ||||
| 		this.season = season; | ||||
| 		this.episode = episode; | ||||
| 	} | ||||
| 	 | ||||
| 	public StringProperty streamUrlProperty(){ | ||||
| 	public String getStreamUrl() { | ||||
| 		return streamUrl; | ||||
| 	} | ||||
| 	 | ||||
| 	public StringProperty titleProperty(){ | ||||
| 	public String getTitle() { | ||||
| 		return title; | ||||
| 	} | ||||
| 	 | ||||
| 	public StringProperty seasonProperty(){ | ||||
|  | ||||
| 	public String getSeason() { | ||||
| 		return season; | ||||
| 	} | ||||
| 	 | ||||
| 	public StringProperty episodeProperty(){ | ||||
| 	public String getEpisode() { | ||||
| 		return episode; | ||||
| 	} | ||||
| 	 | ||||
| 	public BooleanProperty favoriteProperty(){ | ||||
| 		return favorite; | ||||
| 	} | ||||
| 	 | ||||
| 	public SimpleObjectProperty<ImageView> imageProperty(){ | ||||
| 		return image; | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| 	public final String getStreamUrl() { | ||||
| 		return streamUrlProperty().get(); | ||||
| 	} | ||||
| 	 | ||||
| 	public final String getTitle() { | ||||
| 		return titleProperty().get(); | ||||
| 	public void setStreamUrl(String streamUrl) { | ||||
| 		this.streamUrl = streamUrl; | ||||
| 	} | ||||
|  | ||||
| 	public final String getSeason() { | ||||
| 		return seasonProperty().get(); | ||||
| 	} | ||||
| 	 | ||||
| 	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 void setTitle(String title) { | ||||
| 		this.title = title; | ||||
| 	} | ||||
|  | ||||
| 	public final void setTitle(String title) { | ||||
| 		titleProperty().set(title); | ||||
| 	} | ||||
|  | ||||
| 	public final void setSeason(String season) { | ||||
| 		seasonProperty().set(season); | ||||
| 	public void setSeason(String season) { | ||||
| 		this.season = season; | ||||
| 	} | ||||
| 	 | ||||
| 	public final void setEpisode(String season) { | ||||
| 		episodeProperty().set(season); | ||||
| 	public void setEpisode(String episode) { | ||||
| 		this.episode = episode; | ||||
| 	} | ||||
| 	 | ||||
| 	public final void setFavorite(boolean favorite) { | ||||
| 		favoriteProperty().set(favorite); | ||||
| 	} | ||||
| 	 | ||||
| 	public final void setImage(ImageView image) { | ||||
| 		imageProperty().set(image); | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -22,8 +22,16 @@ | ||||
|  | ||||
| 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 org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
|  | ||||
| import javafx.fxml.FXMLLoader; | ||||
| import javafx.scene.Scene; | ||||
| import javafx.scene.image.Image; | ||||
| @ -31,13 +39,13 @@ import javafx.scene.layout.AnchorPane; | ||||
| import javafx.stage.Stage; | ||||
| import kellerkinder.HomeFlix.application.Main; | ||||
| import kellerkinder.HomeFlix.controller.DBController; | ||||
|  | ||||
| public class Player { | ||||
| 	 | ||||
| 	private PlayerController playerController; | ||||
| 	private Stage stage; | ||||
| 	private AnchorPane pane; | ||||
| 	private Scene scene; | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(Player.class.getName()); | ||||
| 	 | ||||
| 	// TODO move the players choose logic to a separate static class | ||||
| 	 | ||||
| @ -46,6 +54,20 @@ public class Player { | ||||
| 	 * @param currentTableFilm	the currently selected film | ||||
| 	 */ | ||||
| 	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); | ||||
| 		 | ||||
| 		try { | ||||
| @ -72,6 +94,61 @@ public class Player { | ||||
| 			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() { | ||||
| 		return stage; | ||||
| @ -81,16 +158,4 @@ public class Player { | ||||
| 		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")); | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
|  | ||||
| @ -90,7 +90,7 @@ public class JFX2BtnCancelAlert { | ||||
| 		JFXButton cancelBtn = new JFXButton(); | ||||
| 		cancelBtn.setText(cancelText); | ||||
| 		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.setPrefHeight(32); | ||||
| 		cancelBtn.setStyle(btnStyle); | ||||
| @ -100,11 +100,15 @@ public class JFX2BtnCancelAlert { | ||||
| 		content.setHeading(new Text(headingText)); | ||||
| 		content.setBody(new Text(bodyText)); | ||||
| 		 | ||||
| 		// TODO only on first start | ||||
| 		Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); | ||||
| 		stage.setMinWidth(416); | ||||
| 		stage.setMinHeight(162); | ||||
| 		stage.setOnCloseRequest(event -> System.exit(0)); | ||||
| 		// only on first start | ||||
| 		if (stage == null) { | ||||
| 			cancelBtn.addEventHandler(ActionEvent.ACTION, (e)-> System.exit(0)); | ||||
| 			Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); | ||||
| 			stage.setMinWidth(416); | ||||
| 			stage.setMinHeight(162); | ||||
| 			stage.setOnCloseRequest(event -> System.exit(0)); | ||||
| 		} | ||||
|  | ||||
| 		 | ||||
| 		alert.setContent(content); | ||||
| 		alert.showAndWait(); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user