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
* 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}

View File

@ -306,4 +306,8 @@ public class JavaFxRecording extends Recording {
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.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<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");
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);

View File

@ -42,6 +42,7 @@ public class Recording implements Serializable, Callable<Recording> {
private Set<String> 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<Recording> {
@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<Recording> {
this.note = note;
}
public int getSelectedResolution() {
return selectedResolution;
}
public Duration getLength() {
File ppFile = getPostProcessedFile();
if (ppFile.isDirectory()) {

View File

@ -69,4 +69,9 @@ public abstract class AbstractDownload implements Download {
public Model getModel() {
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.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<Download> {
public interface Download extends Callable<Download> {
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<Download> {
Instant getStartTime();
Instant getRescheduleTime();
void postprocess(Recording recording);
int getSelectedResolution();
/**
* 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 {
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<RecordingEvent> recordingEvents = new LinkedList<>();
private List<RecordingEvent> 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;