forked from j62/ctbrec
Tweak video preview in thumb cell
This commit is contained in:
parent
d09aad1bf6
commit
f631306768
|
@ -22,6 +22,7 @@ import ctbrec.Model;
|
|||
import ctbrec.io.HttpException;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.action.PlayAction;
|
||||
import ctbrec.ui.controls.StreamPreview;
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.animation.FillTransition;
|
||||
import javafx.animation.ParallelTransition;
|
||||
|
@ -43,6 +44,7 @@ import javafx.scene.layout.StackPane;
|
|||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.scene.shape.Shape;
|
||||
import javafx.scene.text.Font;
|
||||
|
@ -58,6 +60,7 @@ public class ThumbCell extends StackPane {
|
|||
private static final Duration ANIMATION_DURATION = new Duration(250);
|
||||
|
||||
private Model model;
|
||||
private StreamPreview streamPreview;
|
||||
private ImageView iv;
|
||||
private Rectangle resolutionBackground;
|
||||
private final Paint resolutionOnlineColor = new Color(0.22, 0.8, 0.29, 1);
|
||||
|
@ -87,8 +90,10 @@ public class ThumbCell extends StackPane {
|
|||
.expireAfterAccess(4, TimeUnit.HOURS)
|
||||
.maximumSize(1000)
|
||||
.build();
|
||||
private ThumbOverviewTab parent;
|
||||
|
||||
public ThumbCell(ThumbOverviewTab parent, Model model, Recorder recorder) {
|
||||
this.parent = parent;
|
||||
this.thumbCellList = parent.grid.getChildren();
|
||||
this.model = model;
|
||||
this.recorder = recorder;
|
||||
|
@ -96,6 +101,11 @@ public class ThumbCell extends StackPane {
|
|||
model.setSuspended(recorder.isSuspended(model));
|
||||
this.setStyle("-fx-background-color: -fx-base");
|
||||
|
||||
streamPreview = new StreamPreview();
|
||||
streamPreview.prefWidthProperty().bind(widthProperty());
|
||||
streamPreview.prefHeightProperty().bind(heightProperty());
|
||||
getChildren().add(streamPreview);
|
||||
|
||||
iv = new ImageView();
|
||||
iv.setSmooth(true);
|
||||
iv.setPreserveRatio(true);
|
||||
|
@ -164,8 +174,10 @@ public class ThumbCell extends StackPane {
|
|||
StackPane.setAlignment(pausedIndicator, Pos.TOP_LEFT);
|
||||
getChildren().add(pausedIndicator);
|
||||
|
||||
getChildren().add(createPreviewTrigger());
|
||||
|
||||
selectionOverlay = new Rectangle();
|
||||
selectionOverlay.setOpacity(0);
|
||||
selectionOverlay.visibleProperty().bind(selectionProperty);
|
||||
selectionOverlay.widthProperty().bind(widthProperty());
|
||||
selectionOverlay.heightProperty().bind(heightProperty());
|
||||
StackPane.setAlignment(selectionOverlay, Pos.TOP_LEFT);
|
||||
|
@ -197,6 +209,50 @@ public class ThumbCell extends StackPane {
|
|||
update();
|
||||
}
|
||||
|
||||
private Node createPreviewTrigger() {
|
||||
int s = 32;
|
||||
StackPane previewTrigger = new StackPane();
|
||||
previewTrigger.setStyle("-fx-background-color: white;");
|
||||
previewTrigger.setOpacity(.8);
|
||||
previewTrigger.setMaxSize(s, s);
|
||||
|
||||
Polygon play = new Polygon(new double[] {
|
||||
16, 8,
|
||||
26, 15,
|
||||
16, 22
|
||||
});
|
||||
StackPane.setMargin(play, new Insets(0, 0, 0, 3));
|
||||
play.setStyle("-fx-background-color: black;");
|
||||
previewTrigger.getChildren().add(play);
|
||||
|
||||
Circle clip = new Circle(s / 2);
|
||||
clip.setTranslateX(clip.getRadius());
|
||||
clip.setTranslateY(clip.getRadius());
|
||||
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));
|
||||
return previewTrigger;
|
||||
}
|
||||
|
||||
private void setPreviewVisible(Node previewTrigger, boolean visible) {
|
||||
parent.suspendUpdates(visible);
|
||||
iv.setVisible(!visible);
|
||||
topic.setVisible(!visible);
|
||||
topicBackground.setVisible(!visible);
|
||||
name.setVisible(!visible);
|
||||
nameBackground.setVisible(!visible);
|
||||
streamPreview.setVisible(visible);
|
||||
streamPreview.startStream(model);
|
||||
recordingIndicator.setVisible(!visible);
|
||||
pausedIndicator.setVisible(!visible);
|
||||
if(!visible) {
|
||||
updateRecordingIndicator();
|
||||
}
|
||||
previewTrigger.setCursor(visible ? Cursor.HAND : Cursor.DEFAULT);
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
selectionProperty.set(selected);
|
||||
selectionOverlay.getStyleClass().add("selection-background");
|
||||
|
@ -356,6 +412,10 @@ public class ThumbCell extends StackPane {
|
|||
nameBackground.setFill(c);
|
||||
}
|
||||
|
||||
updateRecordingIndicator();
|
||||
}
|
||||
|
||||
private void updateRecordingIndicator() {
|
||||
if(recording) {
|
||||
recordingIndicator.setVisible(!model.isSuspended());
|
||||
pausedIndicator.setVisible(model.isSuspended());
|
||||
|
@ -574,13 +634,15 @@ public class ThumbCell extends StackPane {
|
|||
nameBackground.setWidth(w);
|
||||
nameBackground.setHeight(20);
|
||||
topicBackground.setWidth(w);
|
||||
topicBackground.setHeight(getHeight()-nameBackground.getHeight());
|
||||
topicBackground.setHeight(h - nameBackground.getHeight());
|
||||
topic.prefHeight(getHeight()-25);
|
||||
topic.maxHeight(getHeight()-25);
|
||||
int margin = 4;
|
||||
topic.maxWidth(w-margin*2);
|
||||
topic.setWrappingWidth(w-margin*2);
|
||||
|
||||
streamPreview.resizeTo(w, h);
|
||||
|
||||
Rectangle clip = new Rectangle(w, h);
|
||||
clip.setArcWidth(10);
|
||||
clip.arcHeightProperty().bind(clip.arcWidthProperty());
|
||||
|
|
|
@ -34,8 +34,8 @@ public class StreamPreview extends StackPane {
|
|||
private MediaPlayer videoPlayer;
|
||||
private Media video;
|
||||
private ProgressIndicator progressIndicator;
|
||||
private ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
private Future<?> future;
|
||||
private static ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
private static Future<?> future;
|
||||
|
||||
public StreamPreview() {
|
||||
videoPreview = new MediaView();
|
||||
|
@ -53,7 +53,6 @@ public class StreamPreview extends StackPane {
|
|||
|
||||
progressIndicator = new ProgressIndicator();
|
||||
progressIndicator.setVisible(false);
|
||||
progressIndicator.prefWidthProperty().bind(videoPreview.fitWidthProperty());
|
||||
|
||||
Region veil = new Region();
|
||||
veil.setStyle("-fx-background-color: rgba(0, 0, 0, 0.8)");
|
||||
|
@ -64,14 +63,25 @@ 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(future != null && !future.isDone()) {
|
||||
future.cancel(true);
|
||||
}
|
||||
future = executor.submit(() -> {
|
||||
try {
|
||||
Platform.runLater(() -> {
|
||||
progressIndicator.setVisible(true);
|
||||
});
|
||||
List<StreamSource> sources = model.getStreamSources();
|
||||
Collections.sort(sources);
|
||||
StreamSource best = sources.get(0);
|
||||
|
@ -90,7 +100,7 @@ public class StreamPreview extends StackPane {
|
|||
double aspect = (double)video.getWidth() / video.getHeight();
|
||||
double w = Config.getInstance().getSettings().thumbWidth;
|
||||
double h = w / aspect;
|
||||
resizeToFitContent(w, h);
|
||||
resizeTo(w, h);
|
||||
progressIndicator.setVisible(false);
|
||||
videoPreview.setVisible(true);
|
||||
videoPreview.setMediaPlayer(videoPlayer);
|
||||
|
@ -127,23 +137,23 @@ public class StreamPreview extends StackPane {
|
|||
});
|
||||
}
|
||||
|
||||
private void resizeToFitContent(double w, double h) {
|
||||
setPrefSize(w, h);
|
||||
public void resizeTo(double w, double h) {
|
||||
preview.setFitWidth(w);
|
||||
preview.setFitHeight(h);
|
||||
videoPreview.setFitWidth(w);
|
||||
videoPreview.setFitHeight(h);
|
||||
progressIndicator.setPrefSize(w, h);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if(future != null && !future.isDone()) {
|
||||
future.cancel(true);
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
new Thread(() -> {
|
||||
if(videoPlayer != null) {
|
||||
videoPlayer.dispose();
|
||||
}
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void onError(MediaPlayer videoPlayer) {
|
||||
|
@ -151,7 +161,7 @@ public class StreamPreview extends StackPane {
|
|||
if(videoPlayer.getError().getCause() != null) {
|
||||
LOG.error("Error while starting preview stream root cause:", videoPlayer.getError().getCause());
|
||||
}
|
||||
videoPlayer.dispose();
|
||||
stop();
|
||||
Platform.runLater(() -> {
|
||||
showTestImage();
|
||||
});
|
||||
|
@ -165,7 +175,7 @@ public class StreamPreview extends StackPane {
|
|||
double aspect = img.getWidth() / img.getHeight();
|
||||
double w = Config.getInstance().getSettings().thumbWidth;
|
||||
double h = w / aspect;
|
||||
resizeToFitContent(w, h);
|
||||
resizeTo(w, h);
|
||||
progressIndicator.setVisible(false);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue