Add resolution to recordings table

This commit is contained in:
0xb00bface 2021-09-10 16:27:40 +02:00
parent e7b688906c
commit 9c2a8242de
7 changed files with 55 additions and 21 deletions

View File

@ -4,6 +4,7 @@
* Add buttons to settings to delete cookies per site * Add buttons to settings to delete cookies per site
* Fix bug in minimal browser * Fix bug in minimal browser
* Added model notes to the recordings table * Added model notes to the recordings table
* Added resolution to the recordings table
* Model placeholders can now be used for player params * Model placeholders can now be used for player params
${modelName} ${modelName}
${modelDisplayName} ${modelDisplayName}

View File

@ -306,4 +306,8 @@ public class JavaFxRecording extends Recording {
return delegate.getContactSheet(); return delegate.getContactSheet();
} }
@Override
public int getSelectedResolution() {
return delegate.getSelectedResolution();
}
} }

View File

@ -58,6 +58,7 @@ import ctbrec.ui.controls.Toast;
import ctbrec.ui.menu.ModelMenuContributor; import ctbrec.ui.menu.ModelMenuContributor;
import ctbrec.ui.tabs.recorded.ModelName; import ctbrec.ui.tabs.recorded.ModelName;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
@ -171,6 +172,11 @@ public class RecordingsTab extends Tab implements TabSelectionListener, Shutdown
size.setPrefWidth(100); size.setPrefWidth(100);
size.setCellValueFactory(cdf -> cdf.getValue().getSizeProperty()); size.setCellValueFactory(cdf -> cdf.getValue().getSizeProperty());
size.setCellFactory(param -> createSizeCell()); size.setCellFactory(param -> createSizeCell());
TableColumn<JavaFxRecording, Number> 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<JavaFxRecording, String> notes = new TableColumn<>("Notes"); TableColumn<JavaFxRecording, String> notes = new TableColumn<>("Notes");
notes.setId("notes"); notes.setId("notes");
notes.setPrefWidth(400); notes.setPrefWidth(400);
@ -180,7 +186,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener, Shutdown
modelNotes.setPrefWidth(400); modelNotes.setPrefWidth(400);
modelNotes.setCellValueFactory(cdf -> new SimpleStringProperty(config.getModelNotes(cdf.getValue().getModel()))); 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.setItems(observableRecordings);
table.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, this::onContextMenuRequested); table.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, this::onContextMenuRequested);
table.addEventHandler(MouseEvent.MOUSE_PRESSED, this::onMousePressed); table.addEventHandler(MouseEvent.MOUSE_PRESSED, this::onMousePressed);

View File

@ -42,6 +42,7 @@ public class Recording implements Serializable, Callable<Recording> {
private Set<String> associatedFiles = new HashSet<>(); private Set<String> associatedFiles = new HashSet<>();
private File absoluteFile = null; private File absoluteFile = null;
private File postProcessedFile = null; private File postProcessedFile = null;
private int selectedResolution = -1;
public enum State { public enum State {
RECORDING("recording"), RECORDING("recording"),
@ -70,6 +71,9 @@ public class Recording implements Serializable, Callable<Recording> {
@Override @Override
public Recording call() throws Exception { public Recording call() throws Exception {
download.call(); download.call();
if (selectedResolution == -1) {
selectedResolution = download.getSelectedResolution();
}
return this; return this;
} }
@ -205,6 +209,10 @@ public class Recording implements Serializable, Callable<Recording> {
this.note = note; this.note = note;
} }
public int getSelectedResolution() {
return selectedResolution;
}
public Duration getLength() { public Duration getLength() {
File ppFile = getPostProcessedFile(); File ppFile = getPostProcessedFile();
if (ppFile.isDirectory()) { if (ppFile.isDirectory()) {

View File

@ -69,4 +69,9 @@ public abstract class AbstractDownload implements Download {
public Model getModel() { public Model getModel() {
return model; return model;
} }
@Override
public int getSelectedResolution() {
return StreamSource.UNKNOWN;
}
} }

View File

@ -2,7 +2,6 @@ package ctbrec.recorder.download;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable;
import java.time.Instant; import java.time.Instant;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -11,7 +10,7 @@ import ctbrec.Config;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.Recording; import ctbrec.Recording;
public interface Download extends Serializable, Callable<Download> { public interface Download extends Callable<Download> {
void init(Config config, Model model, Instant startTime, ExecutorService executorService) throws IOException; void init(Config config, Model model, Instant startTime, ExecutorService executorService) throws IOException;
void stop(); void stop();
void finalizeDownload(); void finalizeDownload();
@ -20,6 +19,7 @@ public interface Download extends Serializable, Callable<Download> {
Instant getStartTime(); Instant getStartTime();
Instant getRescheduleTime(); Instant getRescheduleTime();
void postprocess(Recording recording); void postprocess(Recording recording);
int getSelectedResolution();
/** /**
* Returns the path to the recording in the filesystem as file object * Returns the path to the recording in the filesystem as file object

View File

@ -70,27 +70,28 @@ import okhttp3.Response;
public abstract class AbstractHlsDownload extends AbstractDownload { 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 A_FEW_SECONDS = 10_000;
private static final int MAX_SECONDS_WITHOUT_TRANSFER = 30; private static final int MAX_SECONDS_WITHOUT_TRANSFER = 30;
private transient NumberFormat nf = new DecimalFormat("000000"); private NumberFormat nf = new DecimalFormat("000000");
private transient int playlistEmptyCount = 0; private int playlistEmptyCount = 0;
private transient int segmentCounter = 1; private int segmentCounter = 1;
protected transient HttpClient client; protected HttpClient client;
protected transient volatile boolean running = true; protected volatile boolean running = true;
protected transient int lastSegmentNumber = 0; protected int lastSegmentNumber = 0;
protected transient int nextSegmentNumber = 0; protected int nextSegmentNumber = 0;
protected transient String segmentPlaylistUrl; protected String segmentPlaylistUrl;
private transient Instant beforeLastPlaylistRequest= Instant.EPOCH; private Instant beforeLastPlaylistRequest= Instant.EPOCH;
private transient int consecutivePlaylistTimeouts = 0; private int consecutivePlaylistTimeouts = 0;
private transient int consecutivePlaylistErrors = 0; private int consecutivePlaylistErrors = 0;
private transient Instant lastSegmentDownload = Instant.MAX; private Instant lastSegmentDownload = Instant.MAX;
private int selectedResolution = UNKNOWN;
private transient List<RecordingEvent> recordingEvents = new LinkedList<>(); private List<RecordingEvent> recordingEvents = new LinkedList<>();
protected AbstractHlsDownload(HttpClient client) { protected AbstractHlsDownload(HttpClient client) {
this.client = client; this.client = client;
@ -221,8 +222,10 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
String url = null; String url = null;
if (model.getStreamUrlIndex() >= 0 && model.getStreamUrlIndex() < streamSources.size()) { 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 // 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())); StreamSource source = streamSources.get(model.getStreamUrlIndex());
url = streamSources.get(model.getStreamUrlIndex()).getMediaPlaylistUrl(); LOG.debug("{} selected {}", model.getName(), source);
url = source.getMediaPlaylistUrl();
selectedResolution = source.height;
} else { } else {
// filter out stream resolutions, which are out of range of the configured min and max // filter out stream resolutions, which are out of range of the configured min and max
int minRes = Config.getInstance().getSettings().minimumResolution; int minRes = Config.getInstance().getSettings().minimumResolution;
@ -235,8 +238,10 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
if (filteredStreamSources.isEmpty()) { if (filteredStreamSources.isEmpty()) {
throw new ExecutionException(new RuntimeException("No stream left in playlist")); throw new ExecutionException(new RuntimeException("No stream left in playlist"));
} else { } else {
LOG.debug("{} selected {}", model.getName(), filteredStreamSources.get(filteredStreamSources.size() - 1)); StreamSource source = filteredStreamSources.get(filteredStreamSources.size() - 1);
url = filteredStreamSources.get(filteredStreamSources.size() - 1).getMediaPlaylistUrl(); LOG.debug("{} selected {}", model.getName(), source);
url = source.getMediaPlaylistUrl();
selectedResolution = source.height;
} }
} }
LOG.debug("Segment playlist url {}", url); LOG.debug("Segment playlist url {}", url);
@ -420,6 +425,11 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
return running; return running;
} }
@Override
public int getSelectedResolution() {
return selectedResolution;
}
private static class RecordingEvent { private static class RecordingEvent {
Instant timestamp; Instant timestamp;
String message; String message;