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 extends Number> 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%;
+}