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