From b03a1acc20df64fb3c0abc538d6782af8bbaf47b Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sat, 30 Dec 2023 19:55:58 +0100 Subject: [PATCH] Add setting to use the shortest side to restrict the resolution --- CHANGELOG.md | 2 + .../settings/RestrictResolutionSidePane.java | 44 +++++++++++++++++++ .../java/ctbrec/ui/settings/SettingsTab.java | 1 + common/src/main/java/ctbrec/Settings.java | 1 + .../recorder/download/AbstractDownload.java | 24 +++++++--- .../java/ctbrec/sites/cam4/Cam4Model.java | 1 + .../sites/chaturbate/ChaturbateModel.java | 2 + .../ctbrec/sites/cherrytv/CherryTvModel.java | 1 + .../ctbrec/sites/manyvids/MVLiveModel.java | 1 + .../sites/stripchat/StripchatModel.java | 1 + .../java/ctbrec/sites/winktv/WinkTvModel.java | 1 + .../ctbrec/sites/xlovecam/XloveCamModel.java | 1 + 12 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 client/src/main/java/ctbrec/ui/settings/RestrictResolutionSidePane.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 468f06bb..63744afc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 ======================== diff --git a/client/src/main/java/ctbrec/ui/settings/RestrictResolutionSidePane.java b/client/src/main/java/ctbrec/ui/settings/RestrictResolutionSidePane.java new file mode 100644 index 00000000..e764ccaf --- /dev/null +++ b/client/src/main/java/ctbrec/ui/settings/RestrictResolutionSidePane.java @@ -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 combo; + private final Config config; + private static final List names = List.of("by video height", "by shortest side"); + + public RestrictResolutionSidePane(Config config) { + this.config = config; + setSpacing(5); + getChildren().addAll(buildCombo()); + } + + private ComboBox buildCombo() { + ObservableList 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); + } + } +} diff --git a/client/src/main/java/ctbrec/ui/settings/SettingsTab.java b/client/src/main/java/ctbrec/ui/settings/SettingsTab.java index aefad270..0e548f80 100644 --- a/client/src/main/java/ctbrec/ui/settings/SettingsTab.java +++ b/client/src/main/java/ctbrec/ui/settings/SettingsTab.java @@ -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"), diff --git a/common/src/main/java/ctbrec/Settings.java b/common/src/main/java/ctbrec/Settings.java index da831a2f..55f50c4b 100644 --- a/common/src/main/java/ctbrec/Settings.java +++ b/common/src/main/java/ctbrec/Settings.java @@ -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; } diff --git a/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java b/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java index 0e3e64e2..c8d3a798 100644 --- a/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java +++ b/common/src/main/java/ctbrec/recorder/download/AbstractDownload.java @@ -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 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; diff --git a/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java b/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java index c4544fc1..24eb3539 100644 --- a/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java +++ b/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java @@ -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 { diff --git a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java index a1023db5..c90ac254 100644 --- a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java +++ b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java @@ -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(); diff --git a/common/src/main/java/ctbrec/sites/cherrytv/CherryTvModel.java b/common/src/main/java/ctbrec/sites/cherrytv/CherryTvModel.java index b5d70cac..ee358e6e 100644 --- a/common/src/main/java/ctbrec/sites/cherrytv/CherryTvModel.java +++ b/common/src/main/java/ctbrec/sites/cherrytv/CherryTvModel.java @@ -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(); diff --git a/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java b/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java index dad1e995..a17a115d 100644 --- a/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java +++ b/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java @@ -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(); diff --git a/common/src/main/java/ctbrec/sites/stripchat/StripchatModel.java b/common/src/main/java/ctbrec/sites/stripchat/StripchatModel.java index f88dee5b..56dd7e2d 100644 --- a/common/src/main/java/ctbrec/sites/stripchat/StripchatModel.java +++ b/common/src/main/java/ctbrec/sites/stripchat/StripchatModel.java @@ -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('?'))); diff --git a/common/src/main/java/ctbrec/sites/winktv/WinkTvModel.java b/common/src/main/java/ctbrec/sites/winktv/WinkTvModel.java index aae1fa37..e61ba7d9 100644 --- a/common/src/main/java/ctbrec/sites/winktv/WinkTvModel.java +++ b/common/src/main/java/ctbrec/sites/winktv/WinkTvModel.java @@ -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); diff --git a/common/src/main/java/ctbrec/sites/xlovecam/XloveCamModel.java b/common/src/main/java/ctbrec/sites/xlovecam/XloveCamModel.java index 038fd634..69d05257 100644 --- a/common/src/main/java/ctbrec/sites/xlovecam/XloveCamModel.java +++ b/common/src/main/java/ctbrec/sites/xlovecam/XloveCamModel.java @@ -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);