From 9c2a8242debbdd4e3be14638d3538d0d85f2837a Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Fri, 10 Sep 2021 16:27:40 +0200 Subject: [PATCH] Add resolution to recordings table --- CHANGELOG.md | 1 + .../main/java/ctbrec/ui/JavaFxRecording.java | 4 ++ .../java/ctbrec/ui/tabs/RecordingsTab.java | 8 +++- common/src/main/java/ctbrec/Recording.java | 8 ++++ .../recorder/download/AbstractDownload.java | 5 ++ .../ctbrec/recorder/download/Download.java | 4 +- .../download/hls/AbstractHlsDownload.java | 46 +++++++++++-------- 7 files changed, 55 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a804ec92..1590bcf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Add buttons to settings to delete cookies per site * Fix bug in minimal browser * Added model notes to the recordings table +* Added resolution to the recordings table * Model placeholders can now be used for player params ${modelName} ${modelDisplayName} diff --git a/client/src/main/java/ctbrec/ui/JavaFxRecording.java b/client/src/main/java/ctbrec/ui/JavaFxRecording.java index b4ef7dc2..4f5ce0ca 100644 --- a/client/src/main/java/ctbrec/ui/JavaFxRecording.java +++ b/client/src/main/java/ctbrec/ui/JavaFxRecording.java @@ -306,4 +306,8 @@ public class JavaFxRecording extends Recording { return delegate.getContactSheet(); } + @Override + public int getSelectedResolution() { + return delegate.getSelectedResolution(); + } } diff --git a/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java b/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java index e3465102..57b0dee9 100644 --- a/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/RecordingsTab.java @@ -58,6 +58,7 @@ import ctbrec.ui.controls.Toast; import ctbrec.ui.menu.ModelMenuContributor; import ctbrec.ui.tabs.recorded.ModelName; import javafx.application.Platform; +import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; @@ -171,6 +172,11 @@ public class RecordingsTab extends Tab implements TabSelectionListener, Shutdown size.setPrefWidth(100); size.setCellValueFactory(cdf -> cdf.getValue().getSizeProperty()); size.setCellFactory(param -> createSizeCell()); + TableColumn resolution = new TableColumn<>("Resolution"); + resolution.setId("resolution"); + resolution.setStyle("-fx-alignment: CENTER-RIGHT;"); + resolution.setPrefWidth(100); + resolution.setCellValueFactory(cdf -> new SimpleIntegerProperty(cdf.getValue().getSelectedResolution())); TableColumn notes = new TableColumn<>("Notes"); notes.setId("notes"); notes.setPrefWidth(400); @@ -180,7 +186,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener, Shutdown modelNotes.setPrefWidth(400); modelNotes.setCellValueFactory(cdf -> new SimpleStringProperty(config.getModelNotes(cdf.getValue().getModel()))); - table.getColumns().addAll(name, date, status, progress, size, notes, modelNotes); + table.getColumns().addAll(name, date, status, progress, size, resolution, notes, modelNotes); table.setItems(observableRecordings); table.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, this::onContextMenuRequested); table.addEventHandler(MouseEvent.MOUSE_PRESSED, this::onMousePressed); diff --git a/common/src/main/java/ctbrec/Recording.java b/common/src/main/java/ctbrec/Recording.java index 4963a598..12d59727 100644 --- a/common/src/main/java/ctbrec/Recording.java +++ b/common/src/main/java/ctbrec/Recording.java @@ -42,6 +42,7 @@ public class Recording implements Serializable, Callable { private Set associatedFiles = new HashSet<>(); private File absoluteFile = null; private File postProcessedFile = null; + private int selectedResolution = -1; public enum State { RECORDING("recording"), @@ -70,6 +71,9 @@ public class Recording implements Serializable, Callable { @Override public Recording call() throws Exception { download.call(); + if (selectedResolution == -1) { + selectedResolution = download.getSelectedResolution(); + } return this; } @@ -205,6 +209,10 @@ public class Recording implements Serializable, Callable { this.note = note; } + public int getSelectedResolution() { + return selectedResolution; + } + public Duration getLength() { File ppFile = getPostProcessedFile(); if (ppFile.isDirectory()) { diff --git a/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java b/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java index bdb1b032..d66393c4 100644 --- a/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java +++ b/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java @@ -69,4 +69,9 @@ public abstract class AbstractDownload implements Download { public Model getModel() { return model; } + + @Override + public int getSelectedResolution() { + return StreamSource.UNKNOWN; + } } diff --git a/common/src/main/java/ctbrec/recorder/download/Download.java b/common/src/main/java/ctbrec/recorder/download/Download.java index 391fb230..4ff9a632 100644 --- a/common/src/main/java/ctbrec/recorder/download/Download.java +++ b/common/src/main/java/ctbrec/recorder/download/Download.java @@ -2,7 +2,6 @@ package ctbrec.recorder.download; import java.io.File; import java.io.IOException; -import java.io.Serializable; import java.time.Instant; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -11,7 +10,7 @@ import ctbrec.Config; import ctbrec.Model; import ctbrec.Recording; -public interface Download extends Serializable, Callable { +public interface Download extends Callable { void init(Config config, Model model, Instant startTime, ExecutorService executorService) throws IOException; void stop(); void finalizeDownload(); @@ -20,6 +19,7 @@ public interface Download extends Serializable, Callable { Instant getStartTime(); Instant getRescheduleTime(); void postprocess(Recording recording); + int getSelectedResolution(); /** * Returns the path to the recording in the filesystem as file object diff --git a/common/src/main/java/ctbrec/recorder/download/hls/AbstractHlsDownload.java b/common/src/main/java/ctbrec/recorder/download/hls/AbstractHlsDownload.java index 25c92864..8f79f160 100644 --- a/common/src/main/java/ctbrec/recorder/download/hls/AbstractHlsDownload.java +++ b/common/src/main/java/ctbrec/recorder/download/hls/AbstractHlsDownload.java @@ -70,27 +70,28 @@ import okhttp3.Response; public abstract class AbstractHlsDownload extends AbstractDownload { - private static final transient Logger LOG = LoggerFactory.getLogger(AbstractHlsDownload.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractHlsDownload.class); private static final int A_FEW_SECONDS = 10_000; private static final int MAX_SECONDS_WITHOUT_TRANSFER = 30; - private transient NumberFormat nf = new DecimalFormat("000000"); - private transient int playlistEmptyCount = 0; - private transient int segmentCounter = 1; + private NumberFormat nf = new DecimalFormat("000000"); + private int playlistEmptyCount = 0; + private int segmentCounter = 1; - protected transient HttpClient client; - protected transient volatile boolean running = true; + protected HttpClient client; + protected volatile boolean running = true; - protected transient int lastSegmentNumber = 0; - protected transient int nextSegmentNumber = 0; - protected transient String segmentPlaylistUrl; + protected int lastSegmentNumber = 0; + protected int nextSegmentNumber = 0; + protected String segmentPlaylistUrl; - private transient Instant beforeLastPlaylistRequest= Instant.EPOCH; - private transient int consecutivePlaylistTimeouts = 0; - private transient int consecutivePlaylistErrors = 0; - private transient Instant lastSegmentDownload = Instant.MAX; + private Instant beforeLastPlaylistRequest= Instant.EPOCH; + private int consecutivePlaylistTimeouts = 0; + private int consecutivePlaylistErrors = 0; + private Instant lastSegmentDownload = Instant.MAX; + private int selectedResolution = UNKNOWN; - private transient List recordingEvents = new LinkedList<>(); + private List recordingEvents = new LinkedList<>(); protected AbstractHlsDownload(HttpClient client) { this.client = client; @@ -221,8 +222,10 @@ public abstract class AbstractHlsDownload extends AbstractDownload { String url = null; if (model.getStreamUrlIndex() >= 0 && model.getStreamUrlIndex() < streamSources.size()) { // TODO don't use the index, but the bandwidth. if the bandwidth does not match, take the closest one - LOG.debug("{} selected {}", model.getName(), streamSources.get(model.getStreamUrlIndex())); - url = streamSources.get(model.getStreamUrlIndex()).getMediaPlaylistUrl(); + StreamSource source = streamSources.get(model.getStreamUrlIndex()); + LOG.debug("{} selected {}", model.getName(), source); + url = source.getMediaPlaylistUrl(); + selectedResolution = source.height; } else { // filter out stream resolutions, which are out of range of the configured min and max int minRes = Config.getInstance().getSettings().minimumResolution; @@ -235,8 +238,10 @@ public abstract class AbstractHlsDownload extends AbstractDownload { if (filteredStreamSources.isEmpty()) { throw new ExecutionException(new RuntimeException("No stream left in playlist")); } else { - LOG.debug("{} selected {}", model.getName(), filteredStreamSources.get(filteredStreamSources.size() - 1)); - url = filteredStreamSources.get(filteredStreamSources.size() - 1).getMediaPlaylistUrl(); + StreamSource source = filteredStreamSources.get(filteredStreamSources.size() - 1); + LOG.debug("{} selected {}", model.getName(), source); + url = source.getMediaPlaylistUrl(); + selectedResolution = source.height; } } LOG.debug("Segment playlist url {}", url); @@ -420,6 +425,11 @@ public abstract class AbstractHlsDownload extends AbstractDownload { return running; } + @Override + public int getSelectedResolution() { + return selectedResolution; + } + private static class RecordingEvent { Instant timestamp; String message;