Compare commits

...

24 Commits
5.3.2 ... main

Author SHA1 Message Date
j62 b3618714ca changelog updates-J62 2025-03-14 23:33:15 -07:00
J62 2ce6bcbece bump ver for previous changes 2025-03-14 19:38:40 -07:00
J62 5dcdd9a483 revert 2025-03-14 19:33:53 -07:00
J62 3dc0531331 rename recordings to recorded models 2025-03-14 15:04:16 -07:00
J62 6de66abea1 add option 2025-03-14 15:02:14 -07:00
J62 429aff3fb7 update news tab to releases list 2025-03-14 15:02:06 -07:00
J62 e9c3087f19 update donate tab 2025-03-14 14:58:20 -07:00
J62 8ad01a1de4 update qr 2025-03-14 14:58:09 -07:00
J62 899df66c91 update issues links on website 2025-03-14 13:19:44 -07:00
J62 a74fc50002 update gitea releases dl links 2025-03-14 12:35:53 -07:00
J62 8003d5614d update site 2025-03-14 12:14:31 -07:00
J62 c09f44642e initial update website code 2025-03-14 11:39:02 -07:00
J62 27e759009b add *.code-workspace to gitignore 2025-03-14 11:38:28 -07:00
J62 911d2acff3 update readme 2025-03-14 10:07:28 -07:00
J62 15d99481af donate addresses for hosting-maintenance-etc 2025-03-14 10:06:46 -07:00
j62 3e4c52f4e2 Update README.md 2025-03-13 23:43:28 -07:00
j62 6225038626 Upload files to "/" 2025-03-13 23:42:59 -07:00
j62 17931dd7b6 Update README.md 2025-03-13 23:38:56 -07:00
j62 93d4d581ba bump official ver 2025-03-13 22:48:39 -07:00
j62 c001cc26f4 chmod 2025-03-13 22:42:46 -07:00
j62 aafce5afd9 Merge pull request '"topic" no longer sent, replaced with empty string' (#1) from jafea7/ctbrec:main into main
Reviewed-on: #1
2025-03-13 22:35:41 -07:00
jafea7 7d952e42d6 "topic" no longer sent, replaced with empty string 2025-03-14 16:22:18 +11:00
j62 366114e55e Update README.md 2025-03-13 18:48:49 -07:00
j62 e9825868b3 Update common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java
revert change (for now, i case its needed later)
2025-03-13 17:05:36 -07:00
18 changed files with 678 additions and 557 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@
.project .project
*/.factorypath */.factorypath
**/.antlr/ **/.antlr/
*.code-workspace

View File

@ -1,3 +1,20 @@
5.3.4-J62
========================
Current Good working copy after chaturbate reverting their changes. Chaturbate Video and audio currently working.
* jre bundled (in releases) (fixed permissions) (linux and macos)
* updated ffmpeg (in releases) (fixed permissions) (windows, linux and macos)
* fixed run script permissions (linux and macos)
* bump ver
* all builds checked
5.3.3-J62
========================
Reverted for chaturbate reverting their changes. Chaturbate Video and audio currently working.
* jre bundled (in releases)
* flirt4free fix - "topic" no longer sent, replaced with empty string
* bump ver
* all builds checked
5.3.0 5.3.0
======================== ========================
* Added menu entry to force recording of models without changing the prio * Added menu entry to force recording of models without changing the prio

View File

@ -1,12 +1,30 @@
# CTB Recorder # CTB Recorder
![splash](https://git.ctbrec.com/j62/ctbrec/raw/branch/main/splash-small.png)
## Current State Version 5.3.3
Reverted for chaturbate reverting their changes. Chaturbate Video and audio currently working.<br>
## Current State Version 5.3.2-a - jre bundled<br>
- f4f fix<br>
- bump ver<br>
- all builds checked<br>
## updates to fix chaturbate broken audio coming soon ### ABOUT This Repo, server and domain hosted and maintained by J62
I (j62) now have a fully set up development environment again(have been here and assisted in different ways since 2020), allowing me to handle all builds with ease. Ive also set up a domain, Git server, and hosting—at my own expense—to provide a stable and maintained platform for the foreseeable future.<br>
A free recording software for different camsites. Currently supported: BongaCams, Cam4, CamSoda, Chaturbate, FC2Live, LiveJasmin, MyFreeCams, Streamate I took this step after witnessing the chaotic distribution of zip files in Discord, where multiple developers were scrambling to fix the Chaturbate issue. It became clear that there was a need (once again) for a centralized collaboration and download hub.<br>
![Screenshot](https://git.ctbrec.com/j62/ctbrec/raw/branch/master/docs/img/featured-s.jpg) Ideally, everyone should utilize the Git server and create their own forks(of this repo). This way, we can manage changes efficiently through pull requests between forks.<br>
Support me:<br>
Bitcoin: bc1q7fvtkx8wklvd4zttsec7sfgxqh9zadk0x236lt <br>
Ether: 0x2e687A5628ff16c8f9624A914C1f727000089C3A <br>
Solana: Z5YwNPkLheSHuaSJjyHhg3L8UxjpJPt5WU6vu4hFsNR <br>
Monero: 47tjD1z63wu3FEnDCvWnFaRAZbpDKc3Ys1WCbgzvB2Gg8XbqU8bARpcCC37mWzuWBAeZPu2UGY4TAcYGhb6fptoTR8X9vjc
## A free recording software for different camsites. Currently supported: BongaCams, Cam4, CamSoda, Chaturbate, FC2Live, LiveJasmin, MyFreeCams, Streamate
![Screenshot](https://git.ctbrec.com/j62/ctbrec/raw/branch/main/docs/img/featured-s.jpg)
If you ever wanted to record a cam girl show to watch it later or if your favorite model lives in another timezone and is never online when you are, CTB Recorder is the solution for you. If you ever wanted to record a cam girl show to watch it later or if your favorite model lives in another timezone and is never online when you are, CTB Recorder is the solution for you.

0
build-all.sh Normal file → Executable file
View File

View File

@ -8,7 +8,7 @@
<parent> <parent>
<groupId>ctbrec</groupId> <groupId>ctbrec</groupId>
<artifactId>master</artifactId> <artifactId>master</artifactId>
<version>5.3.2</version> <version>5.3.4</version>
<relativePath>../master</relativePath> <relativePath>../master</relativePath>
</parent> </parent>

View File

@ -268,7 +268,8 @@ public class CamrecApplication extends Application {
tabPane.getTabs().add(new RecentlyWatchedTab(recorder, sites)); tabPane.getTabs().add(new RecentlyWatchedTab(recorder, sites));
} }
tabPane.getTabs().add(new SettingsTab(sites, recorder)); tabPane.getTabs().add(new SettingsTab(sites, recorder));
tabPane.getTabs().add(new NewsTab(config)); //tabPane.getTabs().add(new NewsTab(config));
tabPane.getTabs().add(new NewsTab(config, getHostServices()));
tabPane.getTabs().add(new DonateTabFx()); tabPane.getTabs().add(new DonateTabFx());
tabPane.getTabs().add(new HelpTab()); tabPane.getTabs().add(new HelpTab());
tabPane.getTabs().add(new LoggingTab()); tabPane.getTabs().add(new LoggingTab());

View File

@ -6,17 +6,22 @@ import ctbrec.GlobalThreadPool;
import ctbrec.Version; import ctbrec.Version;
import ctbrec.io.HttpException; import ctbrec.io.HttpException;
import ctbrec.io.json.ObjectMapperFactory; import ctbrec.io.json.ObjectMapperFactory;
import ctbrec.ui.CamrecApplication;
import ctbrec.ui.controls.Dialogs; import ctbrec.ui.controls.Dialogs;
import ctbrec.ui.tabs.TabSelectionListener; import ctbrec.ui.tabs.TabSelectionListener;
import javafx.application.HostServices;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
@ -27,16 +32,17 @@ import static ctbrec.io.HttpConstants.USER_AGENT;
@Slf4j @Slf4j
public class NewsTab extends Tab implements TabSelectionListener { public class NewsTab extends Tab implements TabSelectionListener {
private static final String ACCESS_TOKEN = "a2804d73a89951a22e0f8483a6fcec8943afd88b7ba17c459c095aa9e6f94fd0"; private static final String URL = "https://git.ctbrec.com/api/v1/repos/j62/ctbrec/releases";
private static final String URL = "https://mastodon.cloud/api/v1/accounts/480960/statuses?limit=20&exclude_replies=true";
private final Config config; private final Config config;
private final HostServices hostServices;
private final VBox layout = new VBox(); private final VBox layout = new VBox();
private final ObjectMapper mapper = ObjectMapperFactory.getMapper(); private final ObjectMapper mapper = ObjectMapperFactory.getMapper();
private final OkHttpClient httpClient = new OkHttpClient();
public NewsTab(Config config) { public NewsTab(Config config, HostServices hostServices) {
this.config = config; this.config = config;
setText("News"); this.hostServices = hostServices;
setText("Releases");
layout.setMaxWidth(800); layout.setMaxWidth(800);
layout.setAlignment(Pos.CENTER); layout.setAlignment(Pos.CENTER);
setContent(new ScrollPane(layout)); setContent(new ScrollPane(layout));
@ -44,24 +50,21 @@ public class NewsTab extends Tab implements TabSelectionListener {
@Override @Override
public void selected() { public void selected() {
GlobalThreadPool.submit(this::loadToots); GlobalThreadPool.submit(this::loadReleases);
} }
private void loadToots() { private void loadReleases() {
try { try {
var request = new Request.Builder() var request = new Request.Builder()
.url(URL) .url(URL)
.header("Authorization", "Bearer " + ACCESS_TOKEN)
.header(USER_AGENT, "ctbrec " + Version.getVersion()) .header(USER_AGENT, "ctbrec " + Version.getVersion())
.build(); .build();
try (var response = CamrecApplication.httpClient.execute(request)) { try (Response response = httpClient.newCall(request).execute()) {
if (response.isSuccessful()) { if (response.isSuccessful()) {
var body = Objects.requireNonNull(response.body(), HTTP_RESPONSE_BODY_IS_NULL).string(); var body = Objects.requireNonNull(response.body(), HTTP_RESPONSE_BODY_IS_NULL).string();
log.debug(body); log.debug(body);
if (body.startsWith("[")) { if (body.startsWith("[")) {
onSuccess(body); onSuccess(body);
} else if (body.startsWith("{")) {
onError(body);
} else { } else {
throw new IOException("Unexpected response: " + body); throw new IOException("Unexpected response: " + body);
} }
@ -70,30 +73,53 @@ public class NewsTab extends Tab implements TabSelectionListener {
} }
} }
} catch (IOException e) { } catch (IOException e) {
log.info("Error while loading news", e); log.info("Error while loading releases", e);
Dialogs.showError(getTabPane().getScene(), "News", "Couldn't load news from mastodon", e); Dialogs.showError(getTabPane().getScene(), "Releases", "Couldn't load release information", e);
}
}
private void onError(String body) throws IOException {
var json = new JSONObject(body);
if (json.has("error")) {
throw new IOException("Request not successful: " + json.getString("error"));
} else {
throw new IOException("Unexpected response: " + body);
} }
} }
private void onSuccess(String body) throws IOException { private void onSuccess(String body) throws IOException {
Status[] statusArray = mapper.readValue(body, Status[].class); JSONArray releases = new JSONArray(body);
Platform.runLater(() -> { Platform.runLater(() -> {
layout.getChildren().clear(); layout.getChildren().clear();
for (Status status : statusArray) { for (int i = 0; i < releases.length(); i++) {
if (status.getInReplyToId() == null && !Objects.equals("direct", status.getVisibility())) { JSONObject release = releases.getJSONObject(i);
var stp = new StatusPane(status, config.getDateTimeFormatter()); String tagName = release.optString("tag_name", "Unknown Version");
layout.getChildren().add(stp); String releaseName = release.optString("name", "No Name");
VBox.setMargin(stp, new Insets(10)); String description = release.optString("body", "No description available.");
JSONArray assets = release.optJSONArray("assets");
var releasePane = new VBox();
releasePane.setPadding(new Insets(10));
releasePane.setSpacing(5);
Label versionLabel = new Label("Version: " + tagName);
versionLabel.setStyle("-fx-font-weight: bold;");
Label nameLabel = new Label("Release: " + releaseName);
Label descLabel = new Label(description);
releasePane.getChildren().addAll(versionLabel, nameLabel, descLabel);
if (assets != null) {
Label assetsLabel = new Label("Assets:");
releasePane.getChildren().add(assetsLabel);
for (int j = 0; j < assets.length(); j++) {
JSONObject asset = assets.getJSONObject(j);
String assetName = asset.optString("name", "Unknown File");
String downloadUrl = asset.optString("browser_download_url", "#");
int size = asset.optInt("size", 0);
int downloads = asset.optInt("download_count", 0);
Hyperlink assetLink = new Hyperlink(assetName + " (" + size / 1024 / 1024 + " MB, " + downloads + " downloads)");
assetLink.setOnAction(event -> hostServices.showDocument(downloadUrl));
releasePane.getChildren().add(assetLink);
}
} }
layout.getChildren().add(releasePane);
VBox.setMargin(releasePane, new Insets(10));
} }
}); });
} }

View File

@ -90,7 +90,7 @@ public class Flirt4FreeUpdateService extends PaginatedScheduledService {
var name = modelData.getString("model_seo_name"); var name = modelData.getString("model_seo_name");
Flirt4FreeModel model = (Flirt4FreeModel) flirt4Free.createModel(name); Flirt4FreeModel model = (Flirt4FreeModel) flirt4Free.createModel(name);
model.setDisplayName(Entities.unescape(modelData.getString("display"))); model.setDisplayName(Entities.unescape(modelData.getString("display")));
model.setDescription(modelData.getString("topic")); model.setDescription("");
model.setUrl(Flirt4Free.BASE_URI + "/rooms/" + model.getName() + '/'); model.setUrl(Flirt4Free.BASE_URI + "/rooms/" + model.getName() + '/');
model.setNew(modelData.optString("is_new", "0").equals("1")); model.setNew(modelData.optString("is_new", "0").equals("1"));
var videoHost = modelData.getString("video_host"); var videoHost = modelData.getString("video_host");

View File

@ -24,9 +24,9 @@ public class DonateTabFx extends Tab {
var headerVbox = new VBox(10); var headerVbox = new VBox(10);
headerVbox.setAlignment(Pos.CENTER); headerVbox.setAlignment(Pos.CENTER);
var beer = new Label("Buy me some beer?!"); var beer = new Label("Buy me a drink?!");
beer.setFont(new Font(36)); beer.setFont(new Font(36));
var desc = new Label("If you like this software and want to buy me some beer or pizza, here are some possibilities!"); var desc = new Label("If you like this software and want to buy me some MtDew or Energy Drinks(boost ctbrec dev productivity! :), Beer or Pizza, here are some possibilities!");
desc.setFont(new Font(24)); desc.setFont(new Font(24));
headerVbox.getChildren().addAll(beer, desc); headerVbox.getChildren().addAll(beer, desc);
var header = new HBox(); var header = new HBox();
@ -36,7 +36,7 @@ public class DonateTabFx extends Tab {
container.setTop(header); container.setTop(header);
var prefWidth = 360; var prefWidth = 360;
var bitcoinAddress = new TextField("15sLWZon8diPqAX4UdPQU1DcaPuvZs2GgA"); var bitcoinAddress = new TextField("bc1q7fvtkx8wklvd4zttsec7sfgxqh9zadk0x236lt");
bitcoinAddress.setEditable(false); bitcoinAddress.setEditable(false);
bitcoinAddress.setPrefWidth(prefWidth); bitcoinAddress.setPrefWidth(prefWidth);
var bitcoinQrCode = new ImageView(getClass().getResource("/html/bitcoin-address.png").toString()); var bitcoinQrCode = new ImageView(getClass().getResource("/html/bitcoin-address.png").toString());
@ -46,7 +46,7 @@ public class DonateTabFx extends Tab {
bitcoinBox.setAlignment(Pos.TOP_CENTER); bitcoinBox.setAlignment(Pos.TOP_CENTER);
bitcoinBox.getChildren().addAll(bitcoinLabel, bitcoinAddress, bitcoinQrCode); bitcoinBox.getChildren().addAll(bitcoinLabel, bitcoinAddress, bitcoinQrCode);
var ethereumAddress = new TextField("0x996041638eEAE7E31f39Ef6e82068d69bA7C090e"); var ethereumAddress = new TextField("0x2e687A5628ff16c8f9624A914C1f727000089C3A");
ethereumAddress.setEditable(false); ethereumAddress.setEditable(false);
ethereumAddress.setPrefWidth(prefWidth); ethereumAddress.setPrefWidth(prefWidth);
var ethereumQrCode = new ImageView(getClass().getResource("/html/ethereum-address.png").toString()); var ethereumQrCode = new ImageView(getClass().getResource("/html/ethereum-address.png").toString());
@ -56,7 +56,7 @@ public class DonateTabFx extends Tab {
ethereumBox.setAlignment(Pos.TOP_CENTER); ethereumBox.setAlignment(Pos.TOP_CENTER);
ethereumBox.getChildren().addAll(ethereumLabel, ethereumAddress, ethereumQrCode); ethereumBox.getChildren().addAll(ethereumLabel, ethereumAddress, ethereumQrCode);
var moneroAddress = new TextField("871K7xaLR2X8E84CUBi7D88diXgKjbhjZHTEFfJv9ec9eo4NVPCQ2UsGxkroseCcKQbZsHMgW3kg6HR4tfct3fX2HoFDzK6"); var moneroAddress = new TextField("47tjD1z63wu3FEnDCvWnFaRAZbpDKc3Ys1WCbgzvB2Gg8XbqU8bARpcCC37mWzuWBAeZPu2UGY4TAcYGhb6fptoTR8X9vjc");
moneroAddress.setEditable(false); moneroAddress.setEditable(false);
moneroAddress.setPrefWidth(prefWidth); moneroAddress.setPrefWidth(prefWidth);
var moneroQrCode = new ImageView(getClass().getResource("/html/monero-address.png").toString()); var moneroQrCode = new ImageView(getClass().getResource("/html/monero-address.png").toString());

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -8,7 +8,7 @@
<parent> <parent>
<groupId>ctbrec</groupId> <groupId>ctbrec</groupId>
<artifactId>master</artifactId> <artifactId>master</artifactId>
<version>5.3.2</version> <version>5.3.4</version>
<relativePath>../master</relativePath> <relativePath>../master</relativePath>
</parent> </parent>

View File

@ -311,7 +311,7 @@ public class ChaturbateModel extends AbstractModel {
String content = response.body().string(); String content = response.body().string();
log.trace("Raw stream info for model {}: {}", getName(), content); log.trace("Raw stream info for model {}: {}", getName(), content);
streamInfo = mapper.readValue(content, StreamInfo.class); streamInfo = mapper.readValue(content, StreamInfo.class);
streamInfo.url = streamInfo.url.replaceAll("live-hls", "live-c-fhls").replaceAll("playlist\\.m3u8", "playlist_sfm4s.m3u8"); //streamInfo.url = streamInfo.url.replaceAll("live-hls", "live-c-fhls").replaceAll("playlist\\.m3u8", "playlist_sfm4s.m3u8");
return streamInfo; return streamInfo;
} else { } else {
int code = response.code(); int code = response.code();

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
<groupId>ctbrec</groupId> <groupId>ctbrec</groupId>
<artifactId>master</artifactId> <artifactId>master</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>5.3.2</version> <version>5.3.4</version>
<modules> <modules>
<module>../common</module> <module>../common</module>

View File

@ -8,7 +8,7 @@
<parent> <parent>
<groupId>ctbrec</groupId> <groupId>ctbrec</groupId>
<artifactId>master</artifactId> <artifactId>master</artifactId>
<version>5.3.2</version> <version>5.3.4</version>
<relativePath>../master</relativePath> <relativePath>../master</relativePath>
</parent> </parent>

BIN
splash-small.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB