forked from j62/ctbrec
Improved robustness of live previews
This commit is contained in:
parent
1e8c47a76a
commit
f9b09775e3
|
@ -27,7 +27,7 @@ import javafx.scene.media.MediaPlayer;
|
||||||
import javafx.scene.media.MediaView;
|
import javafx.scene.media.MediaView;
|
||||||
|
|
||||||
public class StreamPreview extends StackPane {
|
public class StreamPreview extends StackPane {
|
||||||
private static final transient Logger LOG = LoggerFactory.getLogger(StreamPreview.class);
|
private static final Logger LOG = LoggerFactory.getLogger(StreamPreview.class);
|
||||||
|
|
||||||
private ImageView preview = new ImageView();
|
private ImageView preview = new ImageView();
|
||||||
private MediaView videoPreview;
|
private MediaView videoPreview;
|
||||||
|
@ -35,7 +35,8 @@ public class StreamPreview extends StackPane {
|
||||||
private Media video;
|
private Media video;
|
||||||
private ProgressIndicator progressIndicator;
|
private ProgressIndicator progressIndicator;
|
||||||
private static ExecutorService executor = Executors.newSingleThreadExecutor();
|
private static ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
private static Future<?> future;
|
private Future<?> future;
|
||||||
|
private volatile boolean running = false;
|
||||||
|
|
||||||
public StreamPreview() {
|
public StreamPreview() {
|
||||||
videoPreview = new MediaView();
|
videoPreview = new MediaView();
|
||||||
|
@ -63,20 +64,24 @@ public class StreamPreview extends StackPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startStream(Model model) {
|
public void startStream(Model model) {
|
||||||
Platform.runLater(() -> {
|
if (running) {
|
||||||
progressIndicator.setVisible(true);
|
return;
|
||||||
if(model.getPreview() != null) {
|
}
|
||||||
try {
|
running = true;
|
||||||
videoPreview.setVisible(false);
|
LOG.debug("Starting preview stream for model {}", model);
|
||||||
Image img = new Image(model.getPreview(), true);
|
progressIndicator.setVisible(true);
|
||||||
preview.setImage(img);
|
if(model.getPreview() != null) {
|
||||||
double aspect = img.getWidth() / img.getHeight();
|
try {
|
||||||
double w = Config.getInstance().getSettings().thumbWidth;
|
videoPreview.setVisible(false);
|
||||||
double h = w / aspect;
|
Image img = new Image(model.getPreview(), true);
|
||||||
resizeTo(w, h);
|
preview.setImage(img);
|
||||||
} catch (Exception e) {}
|
double aspect = img.getWidth() / img.getHeight();
|
||||||
}
|
double w = Config.getInstance().getSettings().thumbWidth;
|
||||||
});
|
double h = w / aspect;
|
||||||
|
resizeTo(w, h);
|
||||||
|
} catch (Exception e) {}
|
||||||
|
}
|
||||||
|
|
||||||
if(future != null && !future.isDone()) {
|
if(future != null && !future.isDone()) {
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +90,7 @@ public class StreamPreview extends StackPane {
|
||||||
List<StreamSource> sources = model.getStreamSources();
|
List<StreamSource> sources = model.getStreamSources();
|
||||||
Collections.sort(sources);
|
Collections.sort(sources);
|
||||||
StreamSource best = sources.get(0);
|
StreamSource best = sources.get(0);
|
||||||
|
LOG.debug("StreamSource {}", best);
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
LOG.debug("Preview url for {} is {}", model.getName(), best.getMediaPlaylistUrl());
|
LOG.debug("Preview url for {} is {}", model.getName(), best.getMediaPlaylistUrl());
|
||||||
video = new Media(best.getMediaPlaylistUrl());
|
video = new Media(best.getMediaPlaylistUrl());
|
||||||
|
@ -148,6 +154,7 @@ public class StreamPreview extends StackPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
running = false;
|
||||||
MediaPlayer old = videoPlayer;
|
MediaPlayer old = videoPlayer;
|
||||||
Future<?> oldFuture = future;
|
Future<?> oldFuture = future;
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
|
|
|
@ -87,6 +87,7 @@ public class ThumbCell extends StackPane {
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
private Circle recordingIndicator;
|
private Circle recordingIndicator;
|
||||||
private PausedIndicator pausedIndicator;
|
private PausedIndicator pausedIndicator;
|
||||||
|
private StackPane previewTrigger;
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
ContextMenu popup;
|
ContextMenu popup;
|
||||||
private static final Color colorNormal = Color.BLACK;
|
private static final Color colorNormal = Color.BLACK;
|
||||||
|
@ -105,6 +106,7 @@ public class ThumbCell extends StackPane {
|
||||||
.maximumSize(10000)
|
.maximumSize(10000)
|
||||||
.build(CacheLoader.from(ThumbCell::getStreamResolution));
|
.build(CacheLoader.from(ThumbCell::getStreamResolution));
|
||||||
private ThumbOverviewTab parent;
|
private ThumbOverviewTab parent;
|
||||||
|
private CompletableFuture<Boolean> startPreview;
|
||||||
|
|
||||||
public ThumbCell(ThumbOverviewTab parent, Model model, Recorder recorder, double aspectRatio) {
|
public ThumbCell(ThumbOverviewTab parent, Model model, Recorder recorder, double aspectRatio) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
@ -231,7 +233,7 @@ public class ThumbCell extends StackPane {
|
||||||
|
|
||||||
private Node createPreviewTrigger() {
|
private Node createPreviewTrigger() {
|
||||||
int s = 32;
|
int s = 32;
|
||||||
StackPane previewTrigger = new StackPane();
|
previewTrigger = new StackPane();
|
||||||
previewTrigger.setStyle("-fx-background-color: white;");
|
previewTrigger.setStyle("-fx-background-color: white;");
|
||||||
previewTrigger.setOpacity(.8);
|
previewTrigger.setOpacity(.8);
|
||||||
previewTrigger.setMaxSize(s, s);
|
previewTrigger.setMaxSize(s, s);
|
||||||
|
@ -247,11 +249,36 @@ public class ThumbCell extends StackPane {
|
||||||
previewTrigger.setClip(clip);
|
previewTrigger.setClip(clip);
|
||||||
StackPane.setAlignment(previewTrigger, Pos.BOTTOM_LEFT);
|
StackPane.setAlignment(previewTrigger, Pos.BOTTOM_LEFT);
|
||||||
StackPane.setMargin(previewTrigger, new Insets(0, 0, 24, 4));
|
StackPane.setMargin(previewTrigger, new Insets(0, 0, 24, 4));
|
||||||
previewTrigger.setOnMouseEntered(evt -> setPreviewVisible(previewTrigger, true));
|
previewTrigger.setOnMouseEntered(evt -> startPreview());
|
||||||
previewTrigger.setOnMouseExited(evt -> setPreviewVisible(previewTrigger, false));
|
previewTrigger.setOnMouseExited(evt -> stopPreview());
|
||||||
return previewTrigger;
|
return previewTrigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void stopPreview() {
|
||||||
|
if (startPreview != null) {
|
||||||
|
startPreview.cancel(true);
|
||||||
|
}
|
||||||
|
setPreviewVisible(previewTrigger, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startPreview() {
|
||||||
|
previewTrigger.setCursor(Cursor.HAND);
|
||||||
|
startPreview = CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
Thread.sleep(500);
|
||||||
|
return true;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}).whenComplete((result, exception) -> {
|
||||||
|
startPreview = null;
|
||||||
|
if (result.booleanValue()) {
|
||||||
|
setPreviewVisible(previewTrigger, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void setPreviewVisible(Node previewTrigger, boolean visible) {
|
private void setPreviewVisible(Node previewTrigger, boolean visible) {
|
||||||
parent.suspendUpdates(visible);
|
parent.suspendUpdates(visible);
|
||||||
iv.setVisible(!visible);
|
iv.setVisible(!visible);
|
||||||
|
@ -260,7 +287,11 @@ public class ThumbCell extends StackPane {
|
||||||
name.setVisible(!visible);
|
name.setVisible(!visible);
|
||||||
nameBackground.setVisible(!visible);
|
nameBackground.setVisible(!visible);
|
||||||
streamPreview.setVisible(visible);
|
streamPreview.setVisible(visible);
|
||||||
streamPreview.startStream(model);
|
if (visible) {
|
||||||
|
streamPreview.startStream(model);
|
||||||
|
} else {
|
||||||
|
streamPreview.stop();
|
||||||
|
}
|
||||||
recordingIndicator.setVisible(!visible);
|
recordingIndicator.setVisible(!visible);
|
||||||
pausedIndicator.setVisible(!visible);
|
pausedIndicator.setVisible(!visible);
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
|
|
Loading…
Reference in New Issue