From d210655dcff3217262a9d1113d89c629a369a6eb Mon Sep 17 00:00:00 2001 From: Jannik Seiler Date: Thu, 9 Jul 2020 19:42:26 +0200 Subject: [PATCH] add audio track selection popup, slider displays time as h:mm:ss now --- pom.xml | 4 +- .../application/MainWindowController.java | 2 +- .../org/mosad/homeflix/player/Player.java | 1 + .../homeflix/player/PlayerController.java | 119 ++++++++++++++---- src/main/resources/css/MainWindow.css | 1 - src/main/resources/css/Player.css | 22 ++++ 6 files changed, 123 insertions(+), 26 deletions(-) create mode 100644 src/main/resources/css/Player.css diff --git a/pom.xml b/pom.xml index 71ced54..d9c15d8 100644 --- a/pom.xml +++ b/pom.xml @@ -51,13 +51,13 @@ commons-io commons-io - 2.6 + 2.7 com.jfoenix jfoenix - 9.0.9 + 9.0.10 diff --git a/src/main/java/org/mosad/homeflix/application/MainWindowController.java b/src/main/java/org/mosad/homeflix/application/MainWindowController.java index 10125d5..3ff34a8 100644 --- a/src/main/java/org/mosad/homeflix/application/MainWindowController.java +++ b/src/main/java/org/mosad/homeflix/application/MainWindowController.java @@ -149,7 +149,7 @@ public class MainWindowController { // load data list in gui posterModeStartup(); - + checkAutoUpdate(); // TODO async } diff --git a/src/main/java/org/mosad/homeflix/player/Player.java b/src/main/java/org/mosad/homeflix/player/Player.java index 25168d5..99bb532 100644 --- a/src/main/java/org/mosad/homeflix/player/Player.java +++ b/src/main/java/org/mosad/homeflix/player/Player.java @@ -77,6 +77,7 @@ 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"))); diff --git a/src/main/java/org/mosad/homeflix/player/PlayerController.java b/src/main/java/org/mosad/homeflix/player/PlayerController.java index 4b35584..6c74399 100644 --- a/src/main/java/org/mosad/homeflix/player/PlayerController.java +++ b/src/main/java/org/mosad/homeflix/player/PlayerController.java @@ -23,6 +23,8 @@ 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; @@ -33,6 +35,7 @@ import org.mosad.homeflix.datatypes.FilmTabelDataType; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXDialogLayout; +import com.jfoenix.controls.JFXListView; import com.jfoenix.controls.JFXPopup; import com.jfoenix.controls.JFXPopup.PopupHPosition; import com.jfoenix.controls.JFXPopup.PopupVPosition; @@ -44,6 +47,7 @@ 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; @@ -54,11 +58,14 @@ import javafx.scene.image.WritableImage; import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.media.MediaView; import javafx.scene.text.Text; +import javafx.util.StringConverter; import uk.co.caprica.vlcj.factory.MediaPlayerFactory; 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; @@ -107,6 +114,8 @@ public class PlayerController { private long endTime = 0; private long skipTime = 0; private long duration = 0; + private List tracks = new ArrayList<>(); + private int currentTrack = 0; private int season = 0; private int episode = 0; @@ -119,6 +128,8 @@ public class PlayerController { 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; + /** * create a new PlayerWindow object * @param player the player object (needed for closing action) @@ -150,6 +161,11 @@ public class PlayerController { initPlayerWindow(); initMediaPlayer(); initTimeSlider(); + + + Pane thumb = (Pane) timeSlider.lookup(".thumb"); + System.out.println(thumb.getChildren()); + } /** @@ -162,11 +178,11 @@ public class PlayerController { // 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 + final long delayTime = 4000; // hide the controls after 2 seconds @Override public void handle(MouseEvent mouseEvent) { - + // show controls if (!showControls) { player.getScene().setCursor(Cursor.DEFAULT); @@ -181,6 +197,7 @@ public class PlayerController { controlAnimationTask = new TimerTask() { @Override public void run() { + // TODO a animation would be nice hBoxTop.setVisible(false); bottomVBox.setVisible(false); player.getScene().setCursor(Cursor.NONE); @@ -200,12 +217,8 @@ public class PlayerController { @Override public void mediaPlayerReady(MediaPlayer mediaPlayer) { - System.out.println(mediaPlayer.audio().trackCount()); - - mediaPlayer.audio().trackDescriptions().forEach(trackDesc -> { - System.out.println(trackDesc.description()); - }); - + tracks = mediaPlayer.audio().trackDescriptions(); + currentTrack = mediaPlayer.audio().track(); } @Override @@ -226,7 +239,7 @@ public class PlayerController { @Override public void lengthChanged(MediaPlayer mediaPlayer, long newLength) { duration = newLength; - timeSlider.setMax((duration / 1000) / 60); // TODO move timeslider to seconds + timeSlider.setMax(duration / 1000); } }); @@ -256,9 +269,38 @@ public class PlayerController { timeSlider.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, Number old_val, Number new_val) { - skipTime = ((new_val.longValue() * 1000 * 60) - currentTime); + skipTime = ((new_val.longValue() * 1000) - currentTime); + //System.out.println(timeSlider.getChildrenUnmodifiable()); } }); + + timeSlider.setOnMouseMoved(new EventHandler() { + @Override + public void handle(MouseEvent event) { + //System.out.println("TEST"); + } + }); + + // show h:mm:ss in the animated thumb + StringConverter convert = new StringConverter() { + @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); + + // TODO add a preview to the animated thumb, if that's possible } public void start() { @@ -283,7 +325,7 @@ public class PlayerController { private void updateControls() { // update slider position, if the mouse does not press on the time if (!mousePressed) { - timeSlider.setValue((currentTime / 1000) / 60); + timeSlider.setValue(currentTime / 1000); } // update endTime label @@ -341,17 +383,38 @@ public class PlayerController { @FXML void btnAudioAction(ActionEvent event) { - // TODO move to separate class "AudioPopup" - - JFXDialogLayout content = new JFXDialogLayout(); - content.setHeading(new Text("Test")); - content.setBody(new Text("Hallo 123")); - content.setPrefSize(150, 200); - - JFXPopup popup = new JFXPopup(); - popup.setPopupContent(content); - popup.show(btnAudio, PopupVPosition.BOTTOM, PopupHPosition.RIGHT, - 0, -1 * bottomVBox.getHeight()); + if (audioPopup == null) { + audioPopup = new JFXPopup(); + + JFXListView list = new JFXListView(); + tracks.forEach(track -> { + list.getItems().add(track.description()); + }); + + list.getSelectionModel().select(currentTrack); + list.setOnMouseClicked(ev -> { + setAudioTrack(list.getSelectionModel().getSelectedIndex()); + audioPopup.hide(); + }); + // TODO style the JFXListView + + JFXDialogLayout content = new JFXDialogLayout(); + content.setPrefSize(150, 200); + content.setHeading(new Text("Audio")); + content.setBody(list); + 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 @@ -371,6 +434,9 @@ public class PlayerController { playNextMedia(); } + /** + * play the next media + */ private void playNextMedia() { autoplay = false; DBController.getInstance().setCurrentTime(media.getStreamUrl(), 0); // reset old video start time @@ -381,6 +447,15 @@ public class PlayerController { autoplay = true; } } + + /** + * change the audio track + * @param track the index of the audio track + */ + private void setAudioTrack(int track) { + embeddedMediaPlayer.audio().setTrack(track); + currentTrack = track; + } public double getCurrentTime() { return currentTime; diff --git a/src/main/resources/css/MainWindow.css b/src/main/resources/css/MainWindow.css index e17c481..0838092 100644 --- a/src/main/resources/css/MainWindow.css +++ b/src/main/resources/css/MainWindow.css @@ -209,4 +209,3 @@ .scroll-pane > .viewport { -fx-background-color: transparent; } - diff --git a/src/main/resources/css/Player.css b/src/main/resources/css/Player.css new file mode 100644 index 0000000..d4ba019 --- /dev/null +++ b/src/main/resources/css/Player.css @@ -0,0 +1,22 @@ +/******************************************************************************* + * * + * Slider * + * * + ******************************************************************************/ +.jfx-slider .slider-value{ + -fx-rotate: 0; +} + +/* +.jfx-slider > .track { + -fx-background-color: yellow; +} +*/ + +.jfx-slider .animated-thumb{ + -fx-rotate: 0; + -fx-pref-height: 30; + -fx-pref-width: 80; + -fx-background-color: #0F9D58; + -fx-background-radius: 50% 50% 50% 50%; +}