Compare commits
3 Commits
26e76f228d
...
4876cad920
Author | SHA1 | Date |
---|---|---|
|
4876cad920 | |
|
90d0479ea7 | |
|
23b38bb6a2 |
113
CHANGELOG.md
113
CHANGELOG.md
|
@ -1,4 +1,115 @@
|
|||
5.3.0
|
||||
**DO NOT OVERWRITE YOUR CURRENT INSTALL**, (I will have a good laugh if it deletes your "educational" videos).
|
||||
|
||||
I've tested this on Windows 10 and LMDE and it records from each site, haven't tested anything else apart from basic post-processing but, in theory, I haven't messed with anything other than what I've noted below, so groups, etc should still work.
|
||||
|
||||
**NOTE:** The included ffmpeg is a static compiled version from the Jellyfin project, if it causes problems for you, replace it with the version out of the original v5.3.0 archives.
|
||||
|
||||
**DISCLAIMER:** There most likely are bugs, shit happens.
|
||||
|
||||
If this version doesn't do what you want, don't use it ... simple.
|
||||
|
||||
|
||||
Changes from reusedname's v5.3.2 version.
|
||||
|
||||
25.06.02
|
||||
========================
|
||||
* Updated Help tab layout a little, now displays WAN IP if it can get it
|
||||
connects to `icanhazip.com` so you can check if VPN/Proxy is working
|
||||
* Added Search input for Settings->Filtering->Ignore list
|
||||
* Increased -Xmx to 4g/1g for standalone/server respectively
|
||||
|
||||
25.05.13
|
||||
========================
|
||||
* Added more search options
|
||||
* Revert 05f83f7c96b280a9b5d74b041421e46ed514364f
|
||||
* Add Record Until to WebUI
|
||||
|
||||
25.05.11
|
||||
========================
|
||||
* Fix a bug with Models list display (would sometimes not show anything)
|
||||
|
||||
25.05.06
|
||||
========================
|
||||
* Move portrait directory from `config/<version>/` to `config` **MOVE YOUR EXISTING DIRECTORY**
|
||||
**Will no longer be included in the auto-backup of the config**
|
||||
* Recordings tab is optional
|
||||
* Replace some deprecated calls
|
||||
* Replace Logback calls with Slf4j calls (there was a mix)
|
||||
* Open config directory from Settings->Help
|
||||
* Version numbering change to vYY.MM.DD
|
||||
* Update NR Tool URL
|
||||
|
||||
25.04.28
|
||||
========================
|
||||
* Make side tabs optional for most sites
|
||||
* Fix WinkTv capture
|
||||
* Misc deprecated/redundant changes
|
||||
* Add NR Tool search context menu
|
||||
* Fix CGF search for CB (new preview URL)
|
||||
* Change Record Later to Bookmark in various references
|
||||
|
||||
25.04.27
|
||||
========================
|
||||
* Fix SC login (v3 API from WinkRU)
|
||||
|
||||
25.04.03
|
||||
========================
|
||||
* Removed:
|
||||
* News/Logging tabs, see Settings->Help for Logging
|
||||
* Check for updates
|
||||
* Non-working sites (ATv, CTv, LJ, MV, & SF)
|
||||
* Live previews
|
||||
* Progress column in Recordings tab
|
||||
* Gaming, Trending, Top-rated side tabs for CB
|
||||
* Various options in Settings related to above
|
||||
* Added:
|
||||
* Button to open the log file under Settings->Help
|
||||
* Bongacams Mobile tab
|
||||
* Superchatlive alternative for SC
|
||||
* Region tab selection for CB, (Restart after selecting)
|
||||
* Extra Thumbnail sizes
|
||||
* Extra steps under Split by time/size
|
||||
* Allow server to access contact sheets
|
||||
* Pre-input parameters for post-processing remux/transcode
|
||||
(⚠️ Do not even try it if you have no idea how to use ffmpeg, you can end up with
|
||||
no recording ... which can happen even if you do know what you're doing)
|
||||
* Changed:
|
||||
* Recording tab is now Models (ala WinkRU's version)
|
||||
* Help and Donate moved to Settings (ala WinkRU's version)
|
||||
* Config file is saved to a ./config by default (I hate hiding files all over the place)
|
||||
* Fixed:
|
||||
* CS audio (reusedname's patch instead of my hack)
|
||||
* BC room detection (reusedname's improved patch instead of mine)
|
||||
* F4F thumbnails
|
||||
|
||||
5.3.2 - reusedname
|
||||
========================
|
||||
* Generalise Flaresolverr for any domain: replace per-site setting (it was just one for CB though) with list of hosts. Previous setting is migrated to new format on first start.
|
||||
* Improve group handling somewhat. Models in the group are started in priority order when changing priority, pausing/resuming, and after recording restart has failed. The solution is kind of brute force right now and may cause excessive checks in some cases. I also noticed that sometimes the highest priority model is not on the recording.
|
||||
* Fix Bongacams online check: remove basic one, do the complete check straight away. Also update its logic to check new field.
|
||||
* Reduce config save spam from recorder operations (400ms delay default, configurable). Helps with Suspend/Resume all actions.
|
||||
* Add a couple of server relevant settings to the WebUI Settings page by @Jafea7
|
||||
* Better spec compliance regarding playlist update timing. The delay was hardcoded to 1 second, now it is taken from the playlist (usually 2 seconds). This also Should reduce network pressure and timeouts.
|
||||
* New settings for max concurrent http requests (total and per host). Increasing them should reduce timeouts with a lot of active recordings. Found in Advanced group.
|
||||
* Fix zombie recordings in some cases.
|
||||
* Fix group precondition not respecting priority.
|
||||
* Add online state column (hidden by default). Fix capitalization.
|
||||
* Fix Stripchat login
|
||||
* Set model state offline if online check is skipped.
|
||||
* Optimize model updates in the WebUI.
|
||||
|
||||
5.3.1 - reusedname
|
||||
========================
|
||||
* Flaresolverr support for CB.
|
||||
* Performance fixes/improvements (handle more concurrent recordings).
|
||||
* Camsoda sound fix (@Jafea7 I ended up editing the site model class, not the AbstractHlsDownload).
|
||||
* Missing Stripchat thumbnails fix.
|
||||
* Client: Show grouped model count in status bar.
|
||||
* Web interface performance fix by crazy hacker man.
|
||||
* Some hlsdl stability improvements.
|
||||
* Bandwidth meter support for hlsdl downloads.
|
||||
|
||||
5.3.0 - b00bface
|
||||
========================
|
||||
* Added menu entry to force recording of models without changing the prio
|
||||
* Added blacklist and whitelist settings to automatically filter out models
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<version>25.05.06</version>
|
||||
<version>25.06.02</version>
|
||||
<relativePath>../master</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,9 +6,13 @@ import ctbrec.Config;
|
|||
import ctbrec.io.json.ObjectMapperFactory;
|
||||
import ctbrec.ui.AutosizeAlert;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
@ -31,7 +35,9 @@ import static javafx.scene.control.ButtonType.YES;
|
|||
public class IgnoreList extends GridPane {
|
||||
|
||||
private ListView<String> ignoreListView;
|
||||
|
||||
private TextField searchField;
|
||||
private ObservableList<String> masterList;
|
||||
private FilteredList<String> filteredList;
|
||||
private final ObjectMapper mapper = ObjectMapperFactory.getMapper();
|
||||
|
||||
public IgnoreList() {
|
||||
|
@ -43,7 +49,12 @@ public class IgnoreList extends GridPane {
|
|||
setHgap(10);
|
||||
setVgap(10);
|
||||
setPadding(new Insets(20, 10, 10, 10));
|
||||
// Create search field with clear button
|
||||
HBox searchBox = createSearchField();
|
||||
add(searchBox, 0, 0);
|
||||
GridPane.setHgrow(searchBox, Priority.ALWAYS);
|
||||
|
||||
// Initialize ListView
|
||||
ignoreListView = new ListView<>();
|
||||
ignoreListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
ignoreListView.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
|
||||
|
@ -51,9 +62,28 @@ public class IgnoreList extends GridPane {
|
|||
removeSelectedModels();
|
||||
}
|
||||
});
|
||||
add(ignoreListView, 0, 0);
|
||||
// Set custom cell factory for highlighting
|
||||
ignoreListView.setCellFactory(listView -> new ListCell<>() {
|
||||
@Override
|
||||
protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty || item == null) {
|
||||
setText(null);
|
||||
setStyle("");
|
||||
} else {
|
||||
setText(item);
|
||||
// Highlight if the item matches the search text
|
||||
String searchText = searchField.getText().trim().toLowerCase();
|
||||
if (searchText.isEmpty() || !item.toLowerCase().contains(searchText)) {
|
||||
setStyle("");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
add(ignoreListView, 0, 1);
|
||||
GridPane.setHgrow(ignoreListView, Priority.ALWAYS);
|
||||
|
||||
// Buttons
|
||||
var remove = new Button("Remove");
|
||||
remove.setOnAction(evt -> removeSelectedModels());
|
||||
var exportIgnoreList = new Button("Export");
|
||||
|
@ -65,12 +95,52 @@ public class IgnoreList extends GridPane {
|
|||
buttons.setStyle("-fx-background-color: -fx-background"); // workaround so that the buttons don't shrink
|
||||
}
|
||||
|
||||
private HBox createSearchField() {
|
||||
HBox searchBox = new HBox(5);
|
||||
searchField = new TextField();
|
||||
searchField.setPromptText("Search ignore list...");
|
||||
HBox.setHgrow(searchField, Priority.ALWAYS);
|
||||
|
||||
// Create clear button
|
||||
Button clearButton = new Button("✖");
|
||||
clearButton.setStyle("-fx-font-size: 12px; -fx-padding: 2px 5px; -fx-background-radius: 50%;");
|
||||
clearButton.setVisible(false); // Initially hidden
|
||||
clearButton.setOnAction(event -> {
|
||||
searchField.clear();
|
||||
searchField.requestFocus(); // Return focus to the TextField
|
||||
});
|
||||
|
||||
// Bind clear button visibility to text presence
|
||||
clearButton.visibleProperty().bind(
|
||||
Bindings.createBooleanBinding(
|
||||
() -> !searchField.getText().trim().isEmpty(),
|
||||
searchField.textProperty()
|
||||
)
|
||||
);
|
||||
|
||||
// Bind the filter to the search field text property
|
||||
searchField.textProperty().addListener((obs, oldValue, newValue) -> {
|
||||
filteredList.setPredicate(item -> {
|
||||
if (newValue == null || newValue.trim().isEmpty()) {
|
||||
return true; // Show all items if search is empty
|
||||
}
|
||||
return item.toLowerCase().contains(newValue.trim().toLowerCase());
|
||||
});
|
||||
// Force ListView to refresh to update highlighting
|
||||
ignoreListView.refresh();
|
||||
});
|
||||
|
||||
searchBox.getChildren().addAll(searchField, clearButton);
|
||||
searchBox.setAlignment(javafx.geometry.Pos.CENTER_LEFT);
|
||||
return searchBox;
|
||||
}
|
||||
|
||||
|
||||
private void removeSelectedModels() {
|
||||
List<String> selectedModels = ignoreListView.getSelectionModel().getSelectedItems();
|
||||
if (!selectedModels.isEmpty()) {
|
||||
Config.getInstance().getSettings().ignoredModels.removeAll(selectedModels);
|
||||
ignoreListView.getItems().removeAll(selectedModels);
|
||||
log.debug(Config.getInstance().getSettings().ignoredModels.toString());
|
||||
masterList.removeAll(selectedModels); // Update master list
|
||||
try {
|
||||
Config.getInstance().save();
|
||||
} catch (IOException e) {
|
||||
|
@ -81,9 +151,10 @@ public class IgnoreList extends GridPane {
|
|||
|
||||
private void loadIgnoredModels() {
|
||||
List<String> ignored = Config.getInstance().getSettings().ignoredModels;
|
||||
ignoreListView.getItems().clear();
|
||||
ignoreListView.getItems().addAll(ignored);
|
||||
Collections.sort(ignoreListView.getItems());
|
||||
masterList = FXCollections.observableArrayList(ignored);
|
||||
Collections.sort(masterList);
|
||||
filteredList = new FilteredList<>(masterList, p -> true);
|
||||
ignoreListView.setItems(filteredList);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
|
|
|
@ -3,12 +3,13 @@ package ctbrec.ui.tabs;
|
|||
import ctbrec.Config;
|
||||
import ctbrec.docs.DocServer;
|
||||
import ctbrec.ui.DesktopIntegration;
|
||||
import ctbrec.WANIPFetcher;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -22,33 +23,65 @@ public class HelpTab extends Tab {
|
|||
|
||||
private boolean serverStarted = false;
|
||||
|
||||
private String getWanIp() {
|
||||
try {
|
||||
return WANIPFetcher.getWANIP();
|
||||
} catch (Exception e) {
|
||||
return "Unavailable";
|
||||
}
|
||||
}
|
||||
|
||||
public HelpTab() {
|
||||
setClosable(false);
|
||||
setText("Help");
|
||||
|
||||
Label wanStaticLabel = new Label("WAN IP:");
|
||||
wanStaticLabel.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 14px; -fx-font-weight: bold; -fx-alignment: center;");
|
||||
Label wanValueLabel = new Label(getWanIp());
|
||||
wanValueLabel.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 14px; -fx-underline: true; -fx-alignment: center;");
|
||||
VBox wanLabelBox = new VBox(2);
|
||||
wanLabelBox.setAlignment(Pos.CENTER);
|
||||
wanLabelBox.getChildren().addAll(wanStaticLabel, wanValueLabel);
|
||||
|
||||
Button openHelp = new Button("Open Help");
|
||||
openHelp.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 16px; -fx-font-weight: bold; -fx-text-fill: #ffffff; -fx-background-color: #4CAF50; -fx-padding: 15 30; -fx-border-radius: 5; -fx-background-radius: 5;");
|
||||
|
||||
Button openLog = new Button("Open Log File");
|
||||
Button openCfg = new Button("Open config dir");
|
||||
openHelp.setPadding(new Insets(20));
|
||||
openLog.setPadding(new Insets(20));
|
||||
openCfg.setPadding(new Insets(20));
|
||||
Label logFilePathLabel = new Label("Log file: " + new File("ctbrec.log").getAbsolutePath());
|
||||
openLog.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 16px; -fx-font-weight: bold; -fx-text-fill: #ffffff; -fx-background-color: #2196F3; -fx-padding: 15 30; -fx-border-radius: 5; -fx-background-radius: 5;");
|
||||
|
||||
Button openCfg = new Button("Open Config Dir");
|
||||
openCfg.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 16px; -fx-font-weight: bold; -fx-text-fill: #ffffff; -fx-background-color: #FF9800; -fx-padding: 15 30; -fx-border-radius: 5; -fx-background-radius: 5;");
|
||||
|
||||
File cfgDir = Config.getInstance().getConfigDir();
|
||||
String path = (cfgDir != null) ? cfgDir.getAbsolutePath() : "Unknown";
|
||||
Label configPathLabel = new Label("Config dir: " + path);
|
||||
Label configStaticLabel = new Label("Config Dir:");
|
||||
configStaticLabel.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 14px; -fx-font-weight: bold; -fx-alignment: center;");
|
||||
Label configValueLabel = new Label(path);
|
||||
configValueLabel.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 14px; -fx-underline: true; -fx-alignment: center;");
|
||||
VBox configLabelBox = new VBox(2);
|
||||
configLabelBox.setAlignment(Pos.CENTER);
|
||||
configLabelBox.getChildren().addAll(configStaticLabel, configValueLabel);
|
||||
|
||||
Label logStaticLabel = new Label("Log File:");
|
||||
logStaticLabel.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 14px; -fx-font-weight: bold; -fx-alignment: center;");
|
||||
Label logValueLabel = new Label(new File("ctbrec.log").getAbsolutePath());
|
||||
logValueLabel.setStyle("-fx-font-family: 'Arial'; -fx-font-size: 14px; -fx-underline: true; -fx-alignment: center;");
|
||||
VBox logLabelBox = new VBox(2);
|
||||
logLabelBox.setAlignment(Pos.CENTER);
|
||||
logLabelBox.getChildren().addAll(logStaticLabel, logValueLabel);
|
||||
|
||||
// Create VBox for all components
|
||||
VBox vbox = new VBox();
|
||||
vbox.setAlignment(Pos.CENTER); // Center align the buttons
|
||||
vbox.setSpacing(20); // Set a 20 pixel gap between the buttons
|
||||
vbox.getChildren().addAll(openHelp, openCfg, configPathLabel, openLog, logFilePathLabel);
|
||||
vbox.setAlignment(Pos.CENTER);
|
||||
vbox.setSpacing(20);
|
||||
vbox.getChildren().addAll(wanLabelBox, openHelp, configLabelBox, openCfg, logLabelBox, openLog);
|
||||
|
||||
BorderPane layout = new BorderPane();
|
||||
|
||||
// Add the VBox to the center region of the BorderPane
|
||||
layout.setCenter(vbox);
|
||||
|
||||
setContent(layout);
|
||||
|
||||
// Button actions remain unchanged
|
||||
openHelp.setOnAction(e -> {
|
||||
if (!serverStarted) {
|
||||
startDocumentationServer();
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<version>25.05.06</version>
|
||||
<version>25.06.02</version>
|
||||
<relativePath>../master</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package ctbrec;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
public class WANIPFetcher {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
String ip = getWANIP();
|
||||
System.out.println("Your WAN IP address is: " + ip);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getWANIP() throws Exception {
|
||||
URI uri = new URI("https://icanhazip.com");
|
||||
URL url = uri.toURL(); // Convert URI to URL
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String inputLine;
|
||||
StringBuilder content = new StringBuilder();
|
||||
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
content.append(inputLine);
|
||||
}
|
||||
|
||||
in.close();
|
||||
connection.disconnect();
|
||||
|
||||
return content.toString().trim();
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>25.05.06</version>
|
||||
<version>25.06.02</version>
|
||||
|
||||
<modules>
|
||||
<module>../common</module>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<version>25.05.06</version>
|
||||
<version>25.06.02</version>
|
||||
<relativePath>../master</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
Loading…
Reference in New Issue