Add setting to use the shortest side to restrict the resolution
This commit is contained in:
parent
257bdda8f7
commit
b03a1acc20
|
@ -4,6 +4,8 @@
|
|||
* Added blacklist and whitelist settings to automatically filter out models
|
||||
* Added setting to delete orphaned recording metadata (switched off by default)
|
||||
* Fixed thumbnail caching
|
||||
* Added setting to restrict recording by bit rate
|
||||
* Added setting to use the shortest side to restrict the resolution
|
||||
|
||||
5.2.3
|
||||
========================
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package ctbrec.ui.settings;
|
||||
|
||||
import ctbrec.Config;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.layout.HBox;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class RestrictResolutionSidePane extends HBox {
|
||||
|
||||
private ComboBox<String> combo;
|
||||
private final Config config;
|
||||
private static final List<String> names = List.of("by video height", "by shortest side");
|
||||
|
||||
public RestrictResolutionSidePane(Config config) {
|
||||
this.config = config;
|
||||
setSpacing(5);
|
||||
getChildren().addAll(buildCombo());
|
||||
}
|
||||
|
||||
private ComboBox<String> buildCombo() {
|
||||
ObservableList<String> lst = FXCollections.observableList(names);
|
||||
combo = new ComboBox<>(lst);
|
||||
combo.setOnAction(evt -> saveConfig());
|
||||
int index = config.getSettings().checkResolutionByMinSide ? 1 : 0;
|
||||
combo.getSelectionModel().select(index);
|
||||
return combo;
|
||||
}
|
||||
|
||||
private void saveConfig() {
|
||||
int index = combo.getSelectionModel().getSelectedIndex();
|
||||
config.getSettings().checkResolutionByMinSide = (index == 1);
|
||||
try {
|
||||
config.save();
|
||||
} catch (IOException e) {
|
||||
log.error("Can't save config", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -277,6 +277,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
|||
Setting.of("Split recordings after", splitAfter).converter(SplitAfterOption.converter()).onChange(this::splitValuesChanged),
|
||||
Setting.of("Split recordings bigger than", splitBiggerThan).converter(SplitBiggerThanOption.converter()).onChange(this::splitValuesChanged),
|
||||
Setting.of("Restrict Resolution", resolutionRange, "Only record streams with resolution within the given range"),
|
||||
Setting.of("Restrict Resolution", new RestrictResolutionSidePane(config)),
|
||||
Setting.of("Restrict Video Bitrate (kbps, 0 = unlimited)", restrictBitrate, "Only record streams with a video bitrate below this limit (kbps)"),
|
||||
Setting.of("Concurrent Recordings (0 = unlimited)", concurrentRecordings),
|
||||
Setting.of("Default Priority", defaultPriority, "lowest 0 - 10000 highest"),
|
||||
|
|
|
@ -219,5 +219,6 @@ public class Settings {
|
|||
public boolean dreamcamVR = false;
|
||||
public String filterBlacklist = "";
|
||||
public String filterWhitelist = "";
|
||||
public boolean checkResolutionByMinSide = false;
|
||||
public int restrictBitrate = 0;
|
||||
}
|
||||
|
|
|
@ -97,15 +97,10 @@ public abstract class AbstractDownload implements RecordingProcess {
|
|||
return source;
|
||||
} else {
|
||||
// filter out stream resolutions, which are out of range of the configured min and max
|
||||
int minRes = Config.getInstance().getSettings().minimumResolution;
|
||||
int maxRes = Config.getInstance().getSettings().maximumResolution;
|
||||
int bitrateLimit = Config.getInstance().getSettings().restrictBitrate * 1024;
|
||||
List<StreamSource> filteredStreamSources = streamSources.stream()
|
||||
.filter(src -> src.getHeight() == 0 || src.getHeight() == UNKNOWN || minRes <= src.getHeight())
|
||||
.filter(src -> src.getHeight() == 0 || src.getHeight() == UNKNOWN || maxRes >= src.getHeight())
|
||||
.filter(src -> bitrateLimit == 0 || src.getBandwidth() == UNKNOWN || src.getBandwidth() <= bitrateLimit)
|
||||
.filter(this::isResolutionInLimits)
|
||||
.filter(this::isBitRateInLimits)
|
||||
.toList();
|
||||
|
||||
if (filteredStreamSources.isEmpty()) {
|
||||
// TODO save, why a stream has been filtered out and convey this information to the UI, so that the user understands why a recording
|
||||
// doesn't start
|
||||
|
@ -119,6 +114,21 @@ public abstract class AbstractDownload implements RecordingProcess {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isResolutionInLimits(StreamSource src) {
|
||||
int minRes = Config.getInstance().getSettings().minimumResolution;
|
||||
int maxRes = Config.getInstance().getSettings().maximumResolution;
|
||||
boolean checkResolutionByMinSide = Config.getInstance().getSettings().checkResolutionByMinSide;
|
||||
int resolution = checkResolutionByMinSide ? Math.min(src.getHeight(), src.getWidth()) : src.getHeight();
|
||||
return resolution == 0 || resolution == UNKNOWN || (minRes <= resolution && maxRes >= resolution);
|
||||
}
|
||||
|
||||
private boolean isBitRateInLimits(StreamSource src) {
|
||||
int bitrateLimit = Config.getInstance().getSettings().restrictBitrate * 1024;
|
||||
return bitrateLimit == 0
|
||||
|| src.getBandwidth() == UNKNOWN
|
||||
|| src.getBandwidth() <= bitrateLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtomicLong getDownloadedBytes() {
|
||||
return downloadedBytes;
|
||||
|
|
|
@ -189,6 +189,7 @@ public class Cam4Model extends AbstractModel {
|
|||
StreamSource src = new StreamSource();
|
||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(Optional.ofNullable(playlist.getStreamInfo()).map(StreamInfo::getResolution).map(res -> res.height).orElse(0));
|
||||
src.setWidth(Optional.ofNullable(playlist.getStreamInfo()).map(StreamInfo::getResolution).map(res -> res.width).orElse(0));
|
||||
if (playlist.getUri().startsWith("http")) {
|
||||
src.setMediaPlaylistUrl(playlist.getUri());
|
||||
} else {
|
||||
|
|
|
@ -92,6 +92,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
}
|
||||
|
||||
private int getImageSize(String url) {
|
||||
log.debug("######## Get image size");
|
||||
int imageSize = 0;
|
||||
Request req = new Request.Builder()
|
||||
.url(url)
|
||||
|
@ -204,6 +205,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
StreamSource src = new StreamSource();
|
||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
||||
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
||||
String masterUrl = streamInfo.url;
|
||||
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
||||
String segmentUri = baseUrl + playlist.getUri();
|
||||
|
|
|
@ -119,6 +119,7 @@ public class CherryTvModel extends AbstractModel {
|
|||
StreamSource src = new StreamSource();
|
||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
||||
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
||||
String masterUrl = masterPlaylistUrl;
|
||||
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
||||
String segmentUri = baseUrl + playlist.getUri();
|
||||
|
|
|
@ -80,6 +80,7 @@ public class MVLiveModel extends AbstractModel {
|
|||
StreamSource src = new StreamSource();
|
||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
||||
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
||||
String masterUrl = streamLocation.masterPlaylist;
|
||||
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
||||
String segmentUri = baseUrl + playlist.getUri();
|
||||
|
|
|
@ -141,6 +141,7 @@ public class StripchatModel extends AbstractModel {
|
|||
StreamSource src = new StreamSource();
|
||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
||||
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
||||
src.setMediaPlaylistUrl(playlist.getUri());
|
||||
if (src.getMediaPlaylistUrl().contains("?")) {
|
||||
src.setMediaPlaylistUrl(src.getMediaPlaylistUrl().substring(0, src.getMediaPlaylistUrl().lastIndexOf('?')));
|
||||
|
|
|
@ -99,6 +99,7 @@ public class WinkTvModel extends AbstractModel {
|
|||
StreamSource src = new StreamSource();
|
||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
||||
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
||||
src.setMediaPlaylistUrl(playlist.getUri());
|
||||
log.trace("Media playlist {}", src.getMediaPlaylistUrl());
|
||||
sources.add(src);
|
||||
|
|
|
@ -69,6 +69,7 @@ public class XloveCamModel extends AbstractModel {
|
|||
StreamSource src = new StreamSource();
|
||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(Optional.ofNullable(playlist.getStreamInfo().getResolution()).map(r -> r.height).orElse(0));
|
||||
src.setWidth(Optional.ofNullable(playlist.getStreamInfo().getResolution()).map(r -> r.width).orElse(0));
|
||||
src.setMediaPlaylistUrl(playlist.getUri());
|
||||
log.trace("Media playlist {}", src.getMediaPlaylistUrl());
|
||||
sources.add(src);
|
||||
|
|
Loading…
Reference in New Issue