fixed time slider and autoplay

* fixed a bug that made it impossible to go further back than the start time
* fixed autoplay
* fixed wrong icon on playBtn at the start of the player
* fixed slider position at start of the player
This commit is contained in:
Jannik 2018-04-03 18:03:43 +02:00
parent 5e4373d70d
commit 0379de6179
5 changed files with 95 additions and 60 deletions

View File

@ -40,6 +40,7 @@ import javafx.scene.layout.AnchorPane;
import javafx.stage.DirectoryChooser; import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class Main extends Application { public class Main extends Application {
@ -90,6 +91,12 @@ public class Main extends Application {
primaryStage.setResizable(false); primaryStage.setResizable(false);
primaryStage.setTitle("Project HomeFlix"); primaryStage.setTitle("Project HomeFlix");
primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); //adds application icon primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); //adds application icon
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
System.exit(1);
}
});
mainWindowController = loader.getController(); //Link of FXMLController and controller class mainWindowController = loader.getController(); //Link of FXMLController and controller class
mainWindowController.setMain(this); //call setMain mainWindowController.setMain(this); //call setMain

View File

@ -231,14 +231,13 @@ public class MainWindowController {
private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName());
private int hashA = -647380320; private int hashA = -647380320;
private String version = "0.6.1"; private String version = "0.6.99";
private String buildNumber = "145"; private String buildNumber = "147";
private String versionName = "glowing vampire"; private String versionName = "glowing vampire";
private String dialogBtnStyle; private String dialogBtnStyle;
private String color; private String color;
private String title; private String title;
private String streamUrl; private String streamUrl;
private String currentEp;
private String ratingSortType; private String ratingSortType;
private String local; private String local;
private String omdbAPIKey; private String omdbAPIKey;
@ -256,7 +255,8 @@ public class MainWindowController {
private int indexList; private int indexList;
private int next; private int next;
private ResourceBundle bundle; private ResourceBundle bundle;
private FilmTabelDataType currentFilm;
private ObservableList<String> languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)"); private ObservableList<String> languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)");
private ObservableList<String> branches = FXCollections.observableArrayList("stable", "beta"); private ObservableList<String> branches = FXCollections.observableArrayList("stable", "beta");
private ObservableList<FilmTabelDataType> filterData = FXCollections.observableArrayList(); private ObservableList<FilmTabelDataType> filterData = FXCollections.observableArrayList();
@ -499,7 +499,6 @@ public class MainWindowController {
next = indexTable + 1; next = indexTable + 1;
title = columnTitle.getCellData(indexTable); // get name of selected item title = columnTitle.getCellData(indexTable); // get name of selected item
streamUrl = columnStreamUrl.getCellData(indexTable); // get file path of selected item streamUrl = columnStreamUrl.getCellData(indexTable); // get file path of selected item
currentEp = columnEpisode.getCellData(indexTable); // get the current episode of a series
for (FilmTabelDataType helpData : filmsList) { for (FilmTabelDataType helpData : filmsList) {
if (helpData.getStreamUrl().equals(streamUrl)) { if (helpData.getStreamUrl().equals(streamUrl)) {
@ -507,6 +506,8 @@ public class MainWindowController {
} }
} }
currentFilm = filmsList.get(indexList);
if (filmsList.get(indexList).getCached()) { if (filmsList.get(indexList).getCached()) {
LOGGER.info("loading from cache: " + title); LOGGER.info("loading from cache: " + title);
dbController.readCache(streamUrl); dbController.readCache(streamUrl);
@ -545,14 +546,11 @@ public class MainWindowController {
} }
@FXML @FXML
private void playbtnclicked() { private void playbtnclicked() {
// TODO rework when #19 is coming if (isSupportedFormat(currentFilm)) {
new Player(currentFilm, dbController);
try { } else {
System.out.println(); LOGGER.error("using fallback player!");
new Player(streamUrl, currentEp, dbController);
} catch (Exception e) {
LOGGER.error("using fallback player!", e); // FIXME doesn't work!
if (System.getProperty("os.name").contains("Linux")) { if (System.getProperty("os.name").contains("Linux")) {
String line; String line;
@ -574,7 +572,7 @@ public class MainWindowController {
vlcInfoAlert.showAndWait(); vlcInfoAlert.showAndWait();
} else { } else {
try { try {
Runtime.getRuntime().exec(new String[] { "vlc", streamUrl }); // TODO switch to ProcessBuilder new ProcessBuilder("vlc", streamUrl).start();
} catch (IOException e1) { } catch (IOException e1) {
showErrorMsg(errorPlay, e1); showErrorMsg(errorPlay, e1);
} }
@ -589,7 +587,20 @@ public class MainWindowController {
} else { } else {
LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! "); LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! ");
} }
} }
}
/** TODO improve function
* check if a film is supported by the HomeFlixPlayer or not
* @param entry the film you want to check
* @return true if so, false if not
*/
private boolean isSupportedFormat(FilmTabelDataType film) {
if (film.getStreamUrl().endsWith(".mp4")) {
return true;
} else {
return false;
}
} }
@FXML @FXML
@ -868,7 +879,7 @@ public class MainWindowController {
vlcNotInstalled = getBundle().getString("vlcNotInstalled"); vlcNotInstalled = getBundle().getString("vlcNotInstalled");
} }
// TODO remove after #19 has landed // TODO rework after #19 has landed
public void showErrorMsg(String msg, Exception exception) { public void showErrorMsg(String msg, Exception exception) {
Alert alert = new Alert(AlertType.ERROR); Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error"); alert.setTitle("Error");

View File

@ -651,21 +651,30 @@ public class DBController {
* get the next episode of a * get the next episode of a
* @param title URL of the film * @param title URL of the film
* @param nextEp number of the next episode * @param nextEp number of the next episode
* @return {@link String} the streamUrl of the next episode * @return {@link FilmTabelDataType} the next episode as object
*/ */
public String getNextEpisode(String title, int nextEp) { public FilmTabelDataType getNextEpisode(String title, int nextEp) {
String nextStreamUrl = ""; FilmTabelDataType nextFilm = null;
try { try {
Statement stmt = connection.createStatement(); Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery( ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\" AND episode = \"" + nextEp + "\";");
"SELECT * FROM films WHERE title = \"" + title + "\" AND episode = " + nextEp + ";"); while (rs.next()) {
nextStreamUrl = rs.getString("streamUrl"); if (rs.getBoolean("favorite") == true) {
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"),
rs.getString("title"), rs.getString("season"), rs.getString("episode") ,rs.getBoolean("favorite"),
rs.getBoolean("cached"), new ImageView(favorite_black));
} else {
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"),
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
rs.getBoolean("cached"), new ImageView(favorite_border_black));
}
}
rs.close(); rs.close();
stmt.close(); stmt.close();
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("Ups! error while refreshing mwc!", e); LOGGER.error("Ups! error while getting next episode!", e);
} }
return nextStreamUrl; return nextFilm;
} }
// removes the ending // removes the ending

View File

@ -31,21 +31,23 @@ import javafx.stage.Stage;
import javafx.stage.WindowEvent; import javafx.stage.WindowEvent;
import kellerkinder.HomeFlix.application.Main; import kellerkinder.HomeFlix.application.Main;
import kellerkinder.HomeFlix.controller.DBController; import kellerkinder.HomeFlix.controller.DBController;
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
public class Player { public class Player {
private PlayerController playerController; private PlayerController playerController;
private DBController dbController;
private Stage stage; private Stage stage;
private AnchorPane pane; private AnchorPane pane;
private Scene scene; private Scene scene;
/** /**
* generate a new PlayerWindow * generate a new PlayerWindow
* @param file the file you want to play * @param entry the film object
* @param currentEp the current episode (needed for autoplay)
* @param dbController the dbController object * @param dbController the dbController object
*/ */
public Player(String file, String currentEp, DBController dbController) { public Player(FilmTabelDataType film, DBController dbController) {
this.dbController = dbController;
try { try {
FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml")); FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml"));
pane = (AnchorPane) fxmlLoader.load(); pane = (AnchorPane) fxmlLoader.load();
@ -56,14 +58,14 @@ public class Player {
stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png")));
stage.setOnCloseRequest(new EventHandler<WindowEvent>() { stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) { public void handle(WindowEvent we) {
dbController.setCurrentTime(file, playerController.getCurrentTime()); dbController.setCurrentTime(film.getStreamUrl(), playerController.getCurrentTime());
playerController.getMediaPlayer().stop(); playerController.getMediaPlayer().stop();
stage.close(); stage.close();
} }
}); });
playerController = fxmlLoader.getController(); playerController = fxmlLoader.getController();
playerController.init(file, currentEp, this, dbController); playerController.init(film, this, dbController);
stage.setFullScreen(true); stage.setFullScreen(true);
stage.show(); stage.show();
@ -71,6 +73,10 @@ public class Player {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void playNewFilm(FilmTabelDataType film) {
playerController.init(film, this, dbController);
}
public Stage getStage() { public Stage getStage() {
return stage; return stage;

View File

@ -47,6 +47,7 @@ import javafx.scene.media.MediaPlayer.Status;
import javafx.scene.media.MediaView; import javafx.scene.media.MediaView;
import javafx.util.Duration; import javafx.util.Duration;
import kellerkinder.HomeFlix.controller.DBController; import kellerkinder.HomeFlix.controller.DBController;
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
public class PlayerController { public class PlayerController {
@ -76,13 +77,14 @@ public class PlayerController {
private Media media; private Media media;
private MediaPlayer mediaPlayer; private MediaPlayer mediaPlayer;
private FilmTabelDataType film;
private double currentTime = 0; private double currentTime = 0;
private double futureTime= 0; private double seekTime = 0;
private double startTime = 0;
private double duration = 0; private double duration = 0;
private boolean mousePressed = false; private boolean mousePressed = false;
private boolean showControls = true; private boolean showControls = true;
private String file; private boolean autoplay = true;
private int nextEp;
private ImageView stop_black = new ImageView(new Image("icons/ic_stop_black_24dp_1x.png")); private ImageView stop_black = new ImageView(new Image("icons/ic_stop_black_24dp_1x.png"));
private ImageView play_arrow_black = new ImageView(new Image("icons/ic_play_arrow_black_24dp_1x.png")); private ImageView play_arrow_black = new ImageView(new Image("icons/ic_play_arrow_black_24dp_1x.png"));
@ -92,24 +94,23 @@ public class PlayerController {
/** /**
* initialize the new PlayerWindow * initialize the new PlayerWindow
* @param file the file you want to play * @param entry the film object
* @param currentEp the current episode (needed for autoplay)
* @param player the player object (needed for closing action) * @param player the player object (needed for closing action)
* @param dbController the dbController object * @param dbController the dbController object
*/ */
public void init(String file, String currentEp, Player player, DBController dbController) { public void init(FilmTabelDataType film, Player player, DBController dbController) {
this.file = file; this.film = film;
this.player = player; this.player = player;
this.dbController = dbController; this.dbController = dbController;
initActions(); initActions();
if (currentEp.length() > 0) { if (film.getStreamUrl().startsWith("http")) {
nextEp = Integer.parseInt(currentEp) + 1; media = new Media(film.getStreamUrl());
} else { } else {
nextEp = 0; media = new Media(new File(film.getStreamUrl()).toURI().toString());
} }
startTime = dbController.getCurrentTime(film.getStreamUrl());
media = new Media(new File(file).toURI().toString());
mediaPlayer = new MediaPlayer(media); mediaPlayer = new MediaPlayer(media);
mediaView.setPreserveRatio(true); mediaView.setPreserveRatio(true);
mediaView.setMediaPlayer(mediaPlayer); mediaView.setMediaPlayer(mediaPlayer);
@ -119,7 +120,7 @@ public class PlayerController {
width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width")); width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width"));
height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height")); height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height"));
mediaPlayer.setOnReady(new Runnable() { mediaPlayer.setOnReady(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -127,29 +128,29 @@ public class PlayerController {
timeSlider.setMax((duration/1000)/60); timeSlider.setMax((duration/1000)/60);
mediaPlayer.setStartTime(Duration.millis(dbController.getCurrentTime(file))); mediaPlayer.play();
mediaPlayer.play(); mediaPlayer.seek(Duration.millis(startTime));
} }
}); });
mediaPlayer.currentTimeProperty().addListener(new ChangeListener<Duration>() { mediaPlayer.currentTimeProperty().addListener(new ChangeListener<Duration>() {
@Override @Override
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) { public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
currentTime = newValue.toMillis(); currentTime = newValue.toMillis();
int episode = Integer.parseInt(film.getEpisode());
if (duration - currentTime < 10000) { if ((duration - currentTime) < 10000 && episode != 0 && autoplay) {
if (nextEp != 0) { autoplay = false;
dbController.getNextEpisode(new File(file).getName(), nextEp); dbController.setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
System.out.println("next episode is: " + dbController.getNextEpisode(file, nextEp));
} else { //start the new film
if (duration - currentTime < 100) { System.out.println("next episode is: " + dbController.getNextEpisode(film.getTitle(), episode + 1));
dbController.setCurrentTime(file, 0); mediaPlayer.stop();
mediaPlayer.stop(); player.playNewFilm(dbController.getNextEpisode(film.getTitle(), episode + 1));
player.getStage().close(); } else if ((duration - currentTime) < 100) {
} dbController.setCurrentTime(film.getStreamUrl(), 0);
} mediaPlayer.stop();
player.getStage().close();
} }
if (!mousePressed) { if (!mousePressed) {
@ -159,8 +160,9 @@ public class PlayerController {
}); });
stopBtn.setGraphic(stop_black); stopBtn.setGraphic(stop_black);
playBtn.setGraphic(play_arrow_black); playBtn.setGraphic(pause_black);
fullscreenBtn.setGraphic(fullscreen_exit_black); fullscreenBtn.setGraphic(fullscreen_exit_black);
timeSlider.setValue(0);
} }
/** /**
@ -202,7 +204,7 @@ public class PlayerController {
timeSlider.setOnMouseReleased(new EventHandler<MouseEvent>() { timeSlider.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override @Override
public void handle(MouseEvent event) { public void handle(MouseEvent event) {
mediaPlayer.seek(new Duration(futureTime)); mediaPlayer.seek(new Duration(seekTime));
mousePressed = false; mousePressed = false;
} }
}); });
@ -217,7 +219,7 @@ public class PlayerController {
timeSlider.valueProperty().addListener(new ChangeListener<Number>() { timeSlider.valueProperty().addListener(new ChangeListener<Number>() {
@Override @Override
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) { public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
futureTime = (double) new_val*1000*60; seekTime = (double) new_val*1000*60;
} }
}); });
} }
@ -225,7 +227,7 @@ public class PlayerController {
@FXML @FXML
void stopBtnAction(ActionEvent event) { void stopBtnAction(ActionEvent event) {
dbController.setCurrentTime(file, currentTime); dbController.setCurrentTime(film.getStreamUrl(), currentTime);
mediaPlayer.stop(); mediaPlayer.stop();
player.getStage().close(); player.getStage().close();