diff --git a/pom.xml b/pom.xml
index f85e989..1e91303 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,19 +27,25 @@
org.openjfx
javafx-controls
- 12.0.2
+ 14
org.openjfx
javafx-fxml
- 12.0.2
+ 14
org.openjfx
javafx-media
- 12.0.2
+ 14
+
+
+
+ uk.co.caprica
+ vlcj
+ 4.4.0
@@ -69,13 +75,13 @@
org.apache.logging.log4j
log4j-api
- 2.13.0
+ 2.13.1
org.apache.logging.log4j
log4j-core
- 2.13.0
+ 2.13.1
@@ -114,7 +120,7 @@
org.apache.maven.plugins
maven-shade-plugin
- 3.2.1
+ 3.2.2
Project-HomeFlix
true
diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java
index da229a7..5e1a79a 100644
--- a/src/main/java/kellerkinder/HomeFlix/application/Main.java
+++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java
@@ -46,6 +46,8 @@ public class Main extends Application {
public static final String version = "0.8.0";
public static final String buildNumber = "173";
public static final String versionName = "toothless dragon";
+
+ // TODO rename streamURL to mediaURL
@Override
public void start(Stage primaryStage) throws IOException {
diff --git a/src/main/java/kellerkinder/HomeFlix/player/HFMediaPlayerEventListener.java b/src/main/java/kellerkinder/HomeFlix/player/HFMediaPlayerEventListener.java
new file mode 100644
index 0000000..0bd74fb
--- /dev/null
+++ b/src/main/java/kellerkinder/HomeFlix/player/HFMediaPlayerEventListener.java
@@ -0,0 +1,172 @@
+/**
+ * Project-HomeFlix
+ *
+ * Copyright 2016-2020
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ */
+
+package kellerkinder.HomeFlix.player;
+
+import uk.co.caprica.vlcj.media.MediaRef;
+import uk.co.caprica.vlcj.media.TrackType;
+import uk.co.caprica.vlcj.player.base.MediaPlayer;
+import uk.co.caprica.vlcj.player.base.MediaPlayerEventListener;
+
+public class HFMediaPlayerEventListener implements MediaPlayerEventListener {
+
+ @Override
+ public void mediaChanged(MediaPlayer mediaPlayer, MediaRef media) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void opening(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void buffering(MediaPlayer mediaPlayer, float newCache) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void playing(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void paused(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void stopped(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void forward(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void backward(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void finished(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void timeChanged(MediaPlayer mediaPlayer, long newTime) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void positionChanged(MediaPlayer mediaPlayer, float newPosition) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void seekableChanged(MediaPlayer mediaPlayer, int newSeekable) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void pausableChanged(MediaPlayer mediaPlayer, int newPausable) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void titleChanged(MediaPlayer mediaPlayer, int newTitle) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void snapshotTaken(MediaPlayer mediaPlayer, String filename) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void lengthChanged(MediaPlayer mediaPlayer, long newLength) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void videoOutput(MediaPlayer mediaPlayer, int newCount) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void scrambledChanged(MediaPlayer mediaPlayer, int newScrambled) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void elementaryStreamAdded(MediaPlayer mediaPlayer, TrackType type, int id) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void elementaryStreamDeleted(MediaPlayer mediaPlayer, TrackType type, int id) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void elementaryStreamSelected(MediaPlayer mediaPlayer, TrackType type, int id) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void corked(MediaPlayer mediaPlayer, boolean corked) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void muted(MediaPlayer mediaPlayer, boolean muted) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void volumeChanged(MediaPlayer mediaPlayer, float volume) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void audioDeviceChanged(MediaPlayer mediaPlayer, String audioDevice) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void chapterChanged(MediaPlayer mediaPlayer, int newChapter) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void error(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+ @Override
+ public void mediaPlayerReady(MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+ }
+
+}
diff --git a/src/main/java/kellerkinder/HomeFlix/player/NewMediaPlayer.java b/src/main/java/kellerkinder/HomeFlix/player/NewMediaPlayer.java
new file mode 100644
index 0000000..c6952a0
--- /dev/null
+++ b/src/main/java/kellerkinder/HomeFlix/player/NewMediaPlayer.java
@@ -0,0 +1,115 @@
+package kellerkinder.HomeFlix.player;
+
+import java.nio.ByteBuffer;
+
+import javafx.application.Platform;
+import javafx.scene.Scene;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.image.PixelBuffer;
+import javafx.scene.image.PixelFormat;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.StackPane;
+import javafx.stage.Stage;
+import kellerkinder.HomeFlix.application.Main;
+import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
+import uk.co.caprica.vlcj.player.base.MediaPlayer;
+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;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormat;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormatCallback;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.RenderCallback;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.format.RV32BufferFormat;
+
+public class NewMediaPlayer {
+
+ private MediaPlayerFactory mediaPlayerFactory;
+ private EmbeddedMediaPlayer embeddedMediaPlayer;
+ private WritableImage videoImage;
+ private PixelBuffer videoPixelBuffer;
+ private ImageView videoImageView;
+
+ private Stage stage;
+ private StackPane pane;
+ private Scene scene;
+
+ public NewMediaPlayer() {
+ mediaPlayerFactory = new MediaPlayerFactory();
+ embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();
+ embeddedMediaPlayer.videoSurface().set(new FXCallbackVideoSurface());
+ }
+
+ public void init() {
+ // Auto-generated method stub
+ stage = new Stage();
+ pane = new StackPane();
+ scene = new Scene(pane);
+
+ videoImageView = new ImageView();
+ videoImageView.setPreserveRatio(true);
+ videoImageView.fitWidthProperty().bind(pane.widthProperty());
+ videoImageView.fitHeightProperty().bind(pane.heightProperty());
+ pane.getChildren().add(videoImageView);
+
+ stage.setScene(scene);
+ stage.setTitle("HomeFlix");
+ stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png")));
+ stage.setOnCloseRequest(event -> {
+ //DBController.getInstance().setCurrentTime(streamURL, playerController.getCurrentTime());
+ //playerController.getMediaPlayer().stop();
+ stop();
+ stage.close();
+ });
+ stage.show();
+ }
+
+ public void play(String streamURL) {
+ embeddedMediaPlayer.media().play(streamURL);
+ }
+
+ public void stop() {
+ embeddedMediaPlayer.controls().stop();
+ embeddedMediaPlayer.release();
+ mediaPlayerFactory.release();
+ System.out.println("released");
+ }
+
+ private class FXCallbackVideoSurface extends CallbackVideoSurface {
+ FXCallbackVideoSurface() {
+ super(new FXBufferFormatCallback(), new FXRenderCallback(), true,
+ VideoSurfaceAdapters.getVideoSurfaceAdapter());
+ }
+ }
+
+ private class FXBufferFormatCallback implements BufferFormatCallback {
+ private int sourceWidth;
+ private int sourceHeight;
+
+ @Override
+ public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) {
+ this.sourceWidth = sourceWidth;
+ this.sourceHeight = sourceHeight;
+ return new RV32BufferFormat(sourceWidth, sourceHeight);
+ }
+
+ @Override
+ public void allocatedBuffers(ByteBuffer[] buffers) {
+ assert buffers[0].capacity() == sourceWidth * sourceHeight * 4;
+ PixelFormat pixelFormat = PixelFormat.getByteBgraPreInstance();
+ videoPixelBuffer = new PixelBuffer<>(sourceWidth, sourceHeight, buffers[0], pixelFormat);
+ videoImage = new WritableImage(videoPixelBuffer);
+ videoImageView.setImage(videoImage);
+ }
+ }
+
+ private class FXRenderCallback implements RenderCallback {
+ @Override
+ public void display(MediaPlayer mediaPlayer, ByteBuffer[] nativeBuffers, BufferFormat bufferFormat) {
+ Platform.runLater(() -> {
+ videoPixelBuffer.updateBuffer(pb -> null);
+ });
+ }
+ }
+
+}
diff --git a/src/main/java/kellerkinder/HomeFlix/player/Player.java b/src/main/java/kellerkinder/HomeFlix/player/Player.java
index 4d3c297..6544a51 100644
--- a/src/main/java/kellerkinder/HomeFlix/player/Player.java
+++ b/src/main/java/kellerkinder/HomeFlix/player/Player.java
@@ -1,7 +1,7 @@
/**
* Project-HomeFlix
*
- * Copyright 2016-2019 <@Seil0>
+ * Copyright 2016-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,9 +36,10 @@ import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import kellerkinder.HomeFlix.application.Main;
-import kellerkinder.HomeFlix.controller.DBController;
+
public class Player {
private PlayerController playerController;
@@ -54,21 +55,20 @@ public class Player {
* @param currentTableFilm the currently selected film
*/
public Player(String streamURL) {
-
- if (isSupportedFormat(streamURL)) {
- hfPlayer(streamURL);
- } else {
+ try {
+ newHFPlayer(streamURL);
+ } catch (Exception e) {
+ LOGGER.error("Error while playing media", e);
legacyPlayer(streamURL);
}
-
}
/**
* start the integrated player
* @param streamURL
*/
- private void hfPlayer(String streamURL) {
- playerController = new PlayerController(this, streamURL);
+ private void newHFPlayer(String mediaURL) {
+ playerController = new PlayerController(this, mediaURL);
try {
FXMLLoader fxmlLoader = new FXMLLoader();
@@ -81,15 +81,14 @@ public class Player {
stage.setTitle("HomeFlix");
stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png")));
stage.setOnCloseRequest(event -> {
- DBController.getInstance().setCurrentTime(streamURL, playerController.getCurrentTime());
- playerController.getMediaPlayer().stop();
+ playerController.stop2();
stage.close();
});
-
- playerController.init();
-
- stage.setFullScreen(true);
+ //stage.setFullScreen(true);
stage.show();
+
+ playerController.init2();
+ playerController.start2();
} catch (Exception e) {
e.printStackTrace();
}
@@ -158,4 +157,8 @@ public class Player {
return scene;
}
+ public Pane getPane() {
+ return pane;
+ }
+
}
diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java
index 39eed19..bc131a4 100644
--- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java
+++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java
@@ -1,7 +1,7 @@
/**
* Project-HomeFlix
*
- * Copyright 2016-2019 <@Seil0>
+ * Copyright 2016-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,15 +22,14 @@
package kellerkinder.HomeFlix.player;
-import java.io.File;
+import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXSlider;
-import javafx.beans.binding.Bindings;
-import javafx.beans.property.DoubleProperty;
+import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
@@ -39,21 +38,34 @@ import javafx.fxml.FXML;
import javafx.scene.Cursor;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
+import javafx.scene.image.PixelBuffer;
+import javafx.scene.image.PixelFormat;
+import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
-import javafx.scene.media.MediaPlayer.Status;
import javafx.scene.media.MediaView;
import javafx.util.Duration;
+
import kellerkinder.HomeFlix.controller.DBController;
import kellerkinder.HomeFlix.controller.XMLController;
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
+import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
+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;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormat;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.BufferFormatCallback;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.RenderCallback;
+import uk.co.caprica.vlcj.player.embedded.videosurface.callback.format.RV32BufferFormat;
+
public class PlayerController {
@FXML private MediaView mediaView;
+ @FXML private ImageView videoImageView;
@FXML private VBox bottomVBox;
@@ -72,13 +84,19 @@ public class PlayerController {
private Player player;
private Media media;
- private MediaPlayer mediaPlayer;
+ private MediaPlayer mediaPlayer2;
+
+ private MediaPlayerFactory mediaPlayerFactory;
+ private EmbeddedMediaPlayer embeddedMediaPlayer;
+ private WritableImage videoImage;
+ private PixelBuffer videoPixelBuffer;
private FilmTabelDataType film;
- private double currentTime = 0;
- private double seekTime = 0;
- private double startTime = 0;
- private double duration = 0;
+ private long currentTime = 0;
+ private long seekTime = 0;
+ private long startTime = 0;
+ private long duration = 0;
+
private int season = 0;
private int episode = 0;
private int countdown = 0;
@@ -100,7 +118,62 @@ public class PlayerController {
public PlayerController(Player player, String streamURL) {
this.player = player;
this.film = DBController.getInstance().getStream(streamURL);
+
+ mediaPlayerFactory = new MediaPlayerFactory();
+ embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();
+ embeddedMediaPlayer.videoSurface().set(new FXCallbackVideoSurface());
}
+
+ public void init2() {
+ // initialize the image view
+ videoImageView.setPreserveRatio(true);
+ videoImageView.fitWidthProperty().bind(player.getStage().widthProperty());
+ videoImageView.fitHeightProperty().bind(player.getStage().heightProperty());
+
+ // set needed variables
+ startTime = (long) DBController.getInstance().getCurrentTime(film.getStreamUrl());
+ autoplay = XMLController.isAutoplay();
+ season = !film.getSeason().isEmpty() ? Integer.parseInt(film.getSeason()) : 0;
+ episode = !film.getEpisode().isEmpty() ? Integer.parseInt(film.getEpisode()) : 0;
+
+ initActions2();
+ }
+
+ private void initActions2() {
+ embeddedMediaPlayer.events().addMediaPlayerEventListener( new HFMediaPlayerEventListener() {
+
+ @Override
+ public void timeChanged(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer, long newTime) {
+ timeSlider.setValue((newTime / 1000) / 60);
+ }
+
+ @Override
+ public void error(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer) {
+ // Auto-generated method stub
+
+ }
+
+ @Override
+ public void lengthChanged(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer, long newLength) {
+ duration = newLength;
+ timeSlider.setMax((duration / 1000) / 60);
+ }
+
+ });
+ }
+
+ public void start2() {
+ embeddedMediaPlayer.media().play(film.getStreamUrl());
+ embeddedMediaPlayer.controls().skipTime((long) startTime);
+ }
+
+ public void stop2() {
+ DBController.getInstance().setCurrentTime(film.getStreamUrl(), embeddedMediaPlayer.status().time());
+ embeddedMediaPlayer.controls().stop();
+ embeddedMediaPlayer.release();
+ mediaPlayerFactory.release();
+ }
+
/**
* initialize the PlayerWindow
@@ -108,54 +181,27 @@ public class PlayerController {
public void init() {
initActions();
- if (film.getStreamUrl().startsWith("http")) {
- media = new Media(film.getStreamUrl());
- } else {
- media = new Media(new File(film.getStreamUrl()).toURI().toString());
- }
-
- // create the MediaPlayer object
- mediaPlayer = new MediaPlayer(media);
- mediaView.setPreserveRatio(true);
- mediaView.setMediaPlayer(mediaPlayer);
-
- final DoubleProperty width = mediaView.fitWidthProperty();
- final DoubleProperty height = mediaView.fitHeightProperty();
-
- width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width"));
- height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height"));
-
- startTime = DBController.getInstance().getCurrentTime(film.getStreamUrl());
- autoplay = XMLController.isAutoplay();
- season = !film.getSeason().isEmpty() ? Integer.parseInt(film.getSeason()) : 0;
- episode = !film.getEpisode().isEmpty() ? Integer.parseInt(film.getEpisode()) : 0;
-
initMediaPlayer();
-
- // set the control elements to the correct value
- playIcon.setImage(pause);
- fullscreenIcon.setImage(fullscreenExit);
- timeSlider.setValue(0);
}
private void initMediaPlayer() {
// start the media if the player is ready
- mediaPlayer.setOnReady(new Runnable() {
+ mediaPlayer2.setOnReady(new Runnable() {
@Override
public void run() {
- duration = media.getDuration().toMillis();
+ duration = (long) media.getDuration().toMillis();
timeSlider.setMax((duration / 1000) / 60);
- mediaPlayer.play();
- mediaPlayer.seek(Duration.millis(startTime));
+ mediaPlayer2.play();
+ mediaPlayer2.seek(Duration.millis(startTime));
}
});
// every time the play time changes execute this
- mediaPlayer.currentTimeProperty().addListener(new ChangeListener() {
+ mediaPlayer2.currentTimeProperty().addListener(new ChangeListener() {
@Override
public void changed(ObservableValue extends Duration> observable, Duration oldValue, Duration newValue) {
- currentTime = newValue.toMillis(); // set the current time
+ currentTime = (long) newValue.toMillis(); // set the current time
double timeToEnd = (duration - currentTime);
if (timeToEnd < 20000 && episode != 0 && autoplay) {
@@ -176,7 +222,7 @@ public class PlayerController {
}
} else if (timeToEnd < 120) {
// if we are 120ms to the end stop the media
- mediaPlayer.stop();
+ mediaPlayer2.stop();
DBController.getInstance().setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
playIcon.setImage(playArrow);
} else {
@@ -232,7 +278,7 @@ public class PlayerController {
timeSlider.setOnMouseReleased(new EventHandler() {
@Override
public void handle(MouseEvent event) {
- mediaPlayer.seek(new Duration(seekTime));
+ mediaPlayer2.seek(new Duration(seekTime));
mousePressed = false;
}
});
@@ -248,15 +294,14 @@ public class PlayerController {
timeSlider.valueProperty().addListener(new ChangeListener() {
@Override
public void changed(ObservableValue extends Number> ov, Number old_val, Number new_val) {
- seekTime = (double) new_val * 1000 * 60;
+ seekTime = (long) ((double) new_val * 1000 * 60);
}
});
}
@FXML
void stopBtnAction(ActionEvent event) {
- DBController.getInstance().setCurrentTime(film.getStreamUrl(), currentTime);
- mediaPlayer.stop();
+ stop2();
player.getStage().close();
}
@@ -273,11 +318,11 @@ public class PlayerController {
@FXML
void playBtnAction(ActionEvent event) {
- if (mediaPlayer.getStatus().equals(Status.PLAYING)) {
- mediaPlayer.pause();
+ if (embeddedMediaPlayer.status().isPlaying()) {
+ embeddedMediaPlayer.controls().pause();
playIcon.setImage(playArrow);
} else {
- mediaPlayer.play();
+ embeddedMediaPlayer.controls().play();
playIcon.setImage(pause);
}
}
@@ -292,7 +337,7 @@ public class PlayerController {
DBController.getInstance().setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
FilmTabelDataType nextFilm = DBController.getInstance().getNextEpisode(film.getTitle(), episode, season);
if (nextFilm != null) {
- mediaPlayer.stop();
+ mediaPlayer2.stop();
film = nextFilm;
init();
autoplay = true;
@@ -300,11 +345,52 @@ public class PlayerController {
}
public MediaPlayer getMediaPlayer() {
- return mediaPlayer;
+ return mediaPlayer2;
}
public double getCurrentTime() {
return currentTime;
}
+
+ private class FXCallbackVideoSurface extends CallbackVideoSurface {
+ FXCallbackVideoSurface() {
+ super(new FXBufferFormatCallback(), new FXRenderCallback(), true,
+ VideoSurfaceAdapters.getVideoSurfaceAdapter());
+ }
+ }
+
+ private class FXBufferFormatCallback implements BufferFormatCallback {
+ private int sourceWidth;
+ private int sourceHeight;
+
+ @Override
+ public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) {
+ this.sourceWidth = sourceWidth;
+ this.sourceHeight = sourceHeight;
+ return new RV32BufferFormat(sourceWidth, sourceHeight);
+ }
+
+ @Override
+ public void allocatedBuffers(ByteBuffer[] buffers) {
+ assert buffers[0].capacity() == sourceWidth * sourceHeight * 4;
+ PixelFormat pixelFormat = PixelFormat.getByteBgraPreInstance();
+ videoPixelBuffer = new PixelBuffer<>(sourceWidth, sourceHeight, buffers[0], pixelFormat);
+ videoImage = new WritableImage(videoPixelBuffer);
+ videoImageView.setImage(videoImage);
+ }
+ }
+
+ private class FXRenderCallback implements RenderCallback {
+
+ @Override
+ public void display(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer, ByteBuffer[] nativeBuffers,
+ BufferFormat bufferFormat) {
+ Platform.runLater(() -> {
+ videoPixelBuffer.updateBuffer(pb -> null);
+ });
+ }
+ }
+
+
}
diff --git a/src/main/resources/fxml/PlayerWindow.fxml b/src/main/resources/fxml/PlayerWindow.fxml
index 40a58b4..2e89abe 100644
--- a/src/main/resources/fxml/PlayerWindow.fxml
+++ b/src/main/resources/fxml/PlayerWindow.fxml
@@ -16,6 +16,7 @@
+
@@ -39,7 +40,7 @@
-
+