Compare commits
10 Commits
c91b410307
...
cb44a32079
Author | SHA1 | Date |
---|---|---|
|
cb44a32079 | |
|
df77c6faee | |
|
0aa5dadda7 | |
|
e583aad604 | |
|
7a0dc3a371 | |
|
c9fd95c247 | |
|
1f26371283 | |
|
f549580526 | |
|
f8613c8817 | |
|
cac8ee37d9 |
|
@ -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.3</version>
|
||||||
<relativePath>../master</relativePath>
|
<relativePath>../master</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import okhttp3.Request;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ public class ChaturbateApiUpdateService extends PaginatedScheduledService {
|
||||||
protected List<Model> call() throws Exception {
|
protected List<Model> call() throws Exception {
|
||||||
var request = new Request.Builder()
|
var request = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||||
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
||||||
.build();
|
.build();
|
||||||
try (var response = chaturbate.getHttpClient().execute(request)) {
|
try (var response = chaturbate.getHttpClient().execute(request)) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -35,7 +36,7 @@ public class ChaturbateElectronLoginDialog {
|
||||||
config.put("url", site.getBaseUrl() + "/auth/login/");
|
config.put("url", site.getBaseUrl() + "/auth/login/");
|
||||||
config.put("w", 640);
|
config.put("w", 640);
|
||||||
config.put("h", 480);
|
config.put("h", 480);
|
||||||
config.put("userAgent", site.getHttpClient().getEffectiveUserAgent());
|
config.put("userAgent", site.getHttpClient().getEffectiveUserAgent(URI.create(site.getBaseUrl()).getHost()));
|
||||||
var msg = new JSONObject();
|
var msg = new JSONObject();
|
||||||
msg.put("config", config);
|
msg.put("config", config);
|
||||||
browser.run(msg, msgHandler);
|
browser.run(msg, msgHandler);
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.json.JSONObject;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -54,7 +55,7 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
|
||||||
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
||||||
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
||||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||||
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent(URI.create(pageUrl).getHost()))
|
||||||
.build();
|
.build();
|
||||||
try (var response = chaturbate.getHttpClient().execute(request)) {
|
try (var response = chaturbate.getHttpClient().execute(request)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ public abstract class AbstractStripchatUpdateService extends PaginatedScheduledS
|
||||||
if (timestamp == 0) {
|
if (timestamp == 0) {
|
||||||
return model.optString("previewUrlThumbBig");
|
return model.optString("previewUrlThumbBig");
|
||||||
}
|
}
|
||||||
return MessageFormat.format("https://img.strpst.com/thumbs/{0}/{1}", String.valueOf(timestamp), String.valueOf(id));
|
return MessageFormat.format("https://img.doppiocdn.net/thumbs/{0}/{1}", String.valueOf(timestamp), String.valueOf(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> createTags(JSONObject model) {
|
protected List<String> createTags(JSONObject model) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ctbrec.ui.tabs.recorded;
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.Recording;
|
import ctbrec.Recording;
|
||||||
|
import ctbrec.Model.State;
|
||||||
import ctbrec.recorder.Recorder;
|
import ctbrec.recorder.Recorder;
|
||||||
import ctbrec.sites.Site;
|
import ctbrec.sites.Site;
|
||||||
import ctbrec.ui.JavaFxModel;
|
import ctbrec.ui.JavaFxModel;
|
||||||
|
@ -327,7 +328,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS
|
||||||
if (Objects.equals(onlineModel, fxm)) {
|
if (Objects.equals(onlineModel, fxm)) {
|
||||||
fxm.setOnlineProperty(true);
|
fxm.setOnlineProperty(true);
|
||||||
try {
|
try {
|
||||||
fxm.setOnlineStateProperty(onlineModel.getOnlineState(true));
|
fxm.setOnlineStateProperty(Model.State.ONLINE);
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.3</version>
|
||||||
<relativePath>../master</relativePath>
|
<relativePath>../master</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -94,6 +94,11 @@
|
||||||
<artifactId>commons-collections</artifactId>
|
<artifactId>commons-collections</artifactId>
|
||||||
<version>3.2.2</version>
|
<version>3.2.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-text</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
@ -34,7 +33,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.time.*;
|
import java.time.*;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static ctbrec.io.HttpConstants.ACCEPT_ENCODING_GZIP;
|
import static ctbrec.io.HttpConstants.ACCEPT_ENCODING_GZIP;
|
||||||
import static ctbrec.io.HttpConstants.CONTENT_ENCODING;
|
import static ctbrec.io.HttpConstants.CONTENT_ENCODING;
|
||||||
|
@ -51,6 +49,7 @@ public abstract class HttpClient {
|
||||||
protected OkHttpClient client;
|
protected OkHttpClient client;
|
||||||
protected Cache cache;
|
protected Cache cache;
|
||||||
protected Config config;
|
protected Config config;
|
||||||
|
@Getter
|
||||||
protected boolean loggedIn = false;
|
protected boolean loggedIn = false;
|
||||||
protected long cacheSize;
|
protected long cacheSize;
|
||||||
protected int cacheLifeTime = 600;
|
protected int cacheLifeTime = 600;
|
||||||
|
@ -454,7 +453,11 @@ public abstract class HttpClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
// overridable default user agent (used for Flaresolverr)
|
// overridable default user agent (used for Flaresolverr)
|
||||||
public String getEffectiveUserAgent() {
|
public String getEffectiveUserAgent(String host) {
|
||||||
|
if (config.getSettings().flaresolverr.useForDomains.contains(host)) {
|
||||||
|
return config.getSettings().flaresolverr.userAgent;
|
||||||
|
} else {
|
||||||
return config.getSettings().httpUserAgent;
|
return config.getSettings().httpUserAgent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class RecordingPreconditions {
|
public class RecordingPreconditions {
|
||||||
|
|
||||||
|
@ -199,13 +201,16 @@ public class RecordingPreconditions {
|
||||||
|
|
||||||
// go through each model in group in descendind priority order, checking this model last amongst same-prio models
|
// go through each model in group in descendind priority order, checking this model last amongst same-prio models
|
||||||
// this is to make sure that we only stop lower priority recordings in favor of this one. I.e. if same-prio model is recordnig, let it run
|
// this is to make sure that we only stop lower priority recordings in favor of this one. I.e. if same-prio model is recordnig, let it run
|
||||||
for (var groupModel : modelGroup.get().getModelUrls().stream()
|
var models = modelGroup.get().getModelUrls().stream()
|
||||||
.map(modelUrl -> getModelForUrl(modelUrl))
|
.map(modelUrl -> getModelForUrl(modelUrl))
|
||||||
.filter(x -> x.isPresent())
|
.filter(x -> x.isPresent())
|
||||||
.map(x -> x.get())
|
.map(x -> x.get())
|
||||||
|
.toList();
|
||||||
|
for (var groupModel : IntStream.range(0, models.size()).boxed()
|
||||||
.sorted(Comparator
|
.sorted(Comparator
|
||||||
.comparing((Model m) -> m.getPriority()).reversed() // high to low
|
.comparing((Integer i) -> models.get(i).getPriority()).reversed() // high to low
|
||||||
.thenComparing((Model m) -> m.getUrl().equals(model.getUrl()))) // this model last (false -> true)
|
.thenComparing((Integer i) -> i)) // in group's order
|
||||||
|
.map((Integer i) -> models.get(i))
|
||||||
.toList()) {
|
.toList()) {
|
||||||
if (model.getUrl().equals(groupModel.getUrl())) {
|
if (model.getUrl().equals(groupModel.getUrl())) {
|
||||||
// no other model with higher prio is online, start recording
|
// no other model with higher prio is online, start recording
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -55,7 +56,7 @@ public class Chaturbate extends AbstractSite {
|
||||||
ChaturbateModel m = new ChaturbateModel(this);
|
ChaturbateModel m = new ChaturbateModel(this);
|
||||||
m.setName(normalizedName);
|
m.setName(normalizedName);
|
||||||
m.setUrl(getBaseUrl() + '/' + normalizedName + '/');
|
m.setUrl(getBaseUrl() + '/' + normalizedName + '/');
|
||||||
m.setPreview("https://roomimg.stream.highwebmedia.com/ri/" + normalizedName + ".jpg?" + Instant.now().getEpochSecond());
|
m.setPreview("https://thumb.live.mmcdn.com/riw/" + normalizedName + ".jpg?" + Instant.now().getEpochSecond());
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public class Chaturbate extends AbstractSite {
|
||||||
String url = "https://chaturbate.com/p/" + username + "/";
|
String url = "https://chaturbate.com/p/" + username + "/";
|
||||||
Request req = new Request.Builder()
|
Request req = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||||
.build();
|
.build();
|
||||||
try (Response resp = getHttpClient().execute(req)) {
|
try (Response resp = getHttpClient().execute(req)) {
|
||||||
if (resp.isSuccessful()) {
|
if (resp.isSuccessful()) {
|
||||||
|
@ -131,7 +132,7 @@ public class Chaturbate extends AbstractSite {
|
||||||
// search online models
|
// search online models
|
||||||
Request req = new Request.Builder()
|
Request req = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||||
.header(ACCEPT, "*/*")
|
.header(ACCEPT, "*/*")
|
||||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||||
.header(REFERER, getBaseUrl())
|
.header(REFERER, getBaseUrl())
|
||||||
|
|
|
@ -8,6 +8,7 @@ import okhttp3.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
@ -28,15 +29,6 @@ public class ChaturbateHttpClient extends HttpClient {
|
||||||
super("chaturbate", config);
|
super("chaturbate", config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEffectiveUserAgent() {
|
|
||||||
if (flaresolverr != null) {
|
|
||||||
return config.getSettings().flaresolverr.userAgent;
|
|
||||||
} else {
|
|
||||||
return config.getSettings().httpUserAgent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void extractCsrfToken(Request request) {
|
private void extractCsrfToken(Request request) {
|
||||||
try {
|
try {
|
||||||
Cookie csrfToken = cookieJar.getCookie(request.url(), "csrftoken");
|
Cookie csrfToken = cookieJar.getCookie(request.url(), "csrftoken");
|
||||||
|
@ -65,7 +57,7 @@ public class ChaturbateHttpClient extends HttpClient {
|
||||||
}
|
}
|
||||||
Request login = new Request.Builder()
|
Request login = new Request.Builder()
|
||||||
.url(Chaturbate.baseUrl + PATH)
|
.url(Chaturbate.baseUrl + PATH)
|
||||||
.header(USER_AGENT, getEffectiveUserAgent())
|
.header(USER_AGENT, getEffectiveUserAgent(URI.create(Chaturbate.baseUrl).getHost()))
|
||||||
.build();
|
.build();
|
||||||
try (var initResponse = client.newCall(login).execute()) {
|
try (var initResponse = client.newCall(login).execute()) {
|
||||||
String content = initResponse.body().string();
|
String content = initResponse.body().string();
|
||||||
|
@ -81,7 +73,7 @@ public class ChaturbateHttpClient extends HttpClient {
|
||||||
login = new Request.Builder()
|
login = new Request.Builder()
|
||||||
.url(Chaturbate.baseUrl + PATH)
|
.url(Chaturbate.baseUrl + PATH)
|
||||||
.header(REFERER, Chaturbate.baseUrl + PATH)
|
.header(REFERER, Chaturbate.baseUrl + PATH)
|
||||||
.header(USER_AGENT, getEffectiveUserAgent())
|
.header(USER_AGENT, getEffectiveUserAgent(URI.create(Chaturbate.baseUrl).getHost()))
|
||||||
.post(body)
|
.post(body)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -106,7 +98,7 @@ public class ChaturbateHttpClient extends HttpClient {
|
||||||
String url = "https://chaturbate.com/api/ts/chatmessages/pm_users/?offset=0";
|
String url = "https://chaturbate.com/api/ts/chatmessages/pm_users/?offset=0";
|
||||||
Request req = new Request.Builder()
|
Request req = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(USER_AGENT, getEffectiveUserAgent())
|
.header(USER_AGENT, getEffectiveUserAgent(URI.create(url).getHost()))
|
||||||
.build();
|
.build();
|
||||||
try (Response response = execute(req)) {
|
try (Response response = execute(req)) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -30,11 +31,14 @@ import java.util.concurrent.ExecutionException;
|
||||||
import static ctbrec.Model.State.*;
|
import static ctbrec.Model.State.*;
|
||||||
import static ctbrec.io.HttpConstants.*;
|
import static ctbrec.io.HttpConstants.*;
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ChaturbateModel extends AbstractModel {
|
public class ChaturbateModel extends AbstractModel {
|
||||||
|
|
||||||
private static final String PUBLIC = "public";
|
private static final String PUBLIC = "public";
|
||||||
|
private static final Pattern serverPattern = Pattern.compile("live-.+amlst");
|
||||||
|
|
||||||
private int[] resolution = new int[2];
|
private int[] resolution = new int[2];
|
||||||
private transient StreamInfo streamInfo;
|
private transient StreamInfo streamInfo;
|
||||||
private transient Instant lastStreamInfoRequest = Instant.EPOCH;
|
private transient Instant lastStreamInfoRequest = Instant.EPOCH;
|
||||||
|
@ -75,7 +79,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
|
|
||||||
private boolean isOffline() {
|
private boolean isOffline() {
|
||||||
String normalizedName = getName().toLowerCase().trim();
|
String normalizedName = getName().toLowerCase().trim();
|
||||||
String previewUrl = "https://roomimg.stream.highwebmedia.com/ri/" + normalizedName + ".jpg?" + Instant.now().getEpochSecond();
|
String previewUrl = "https://thumb.live.mmcdn.com/riw/" + normalizedName + ".jpg?" + Instant.now().getEpochSecond();
|
||||||
if (offlineImageSize == 0) {
|
if (offlineImageSize == 0) {
|
||||||
offlineImageSize = getOfflineImageSize(); // NOSONAR
|
offlineImageSize = getOfflineImageSize(); // NOSONAR
|
||||||
}
|
}
|
||||||
|
@ -85,7 +89,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
private int getOfflineImageSize() {
|
private int getOfflineImageSize() {
|
||||||
String[] names = {"Sophia", "Helena", "Olivia", "Natasha", "Emmy", "Jenny", "Diana", "Teresa", "Julia", "Polly", "Amanda"};
|
String[] names = {"Sophia", "Helena", "Olivia", "Natasha", "Emmy", "Jenny", "Diana", "Teresa", "Julia", "Polly", "Amanda"};
|
||||||
String randomName = names[RNG.nextInt(names.length)] + RNG.nextInt(99);
|
String randomName = names[RNG.nextInt(names.length)] + RNG.nextInt(99);
|
||||||
String previewUrl = "https://roomimg.stream.highwebmedia.com/ri/" + randomName + ".jpg?" + Instant.now().getEpochSecond();
|
String previewUrl = "https://thumb.live.mmcdn.com/riw/" + randomName + ".jpg?" + Instant.now().getEpochSecond();
|
||||||
int imageSize = getImageSize(previewUrl);
|
int imageSize = getImageSize(previewUrl);
|
||||||
if (imageSize == 0) {
|
if (imageSize == 0) {
|
||||||
imageSize = 21971;
|
imageSize = 21971;
|
||||||
|
@ -97,7 +101,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
int imageSize = 0;
|
int imageSize = 0;
|
||||||
Request req = new Request.Builder()
|
Request req = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||||
.head()
|
.head()
|
||||||
.build();
|
.build();
|
||||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
|
@ -190,7 +194,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
.post(body)
|
.post(body)
|
||||||
.header(REFERER, "https://chaturbate.com/" + getName() + "/")
|
.header(REFERER, "https://chaturbate.com/" + getName() + "/")
|
||||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent("chaturbate.com"))
|
||||||
.build();
|
.build();
|
||||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
if (!response.isSuccessful()) {
|
if (!response.isSuccessful()) {
|
||||||
|
@ -211,7 +215,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||||
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
||||||
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
||||||
String masterUrl = streamInfo.url;
|
String masterUrl = streamInfo.hls_source;
|
||||||
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
||||||
String segmentUri = baseUrl + playlist.getUri();
|
String segmentUri = baseUrl + playlist.getUri();
|
||||||
src.setMediaPlaylistUrl(segmentUri);
|
src.setMediaPlaylistUrl(segmentUri);
|
||||||
|
@ -239,7 +243,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
// do an initial request to get cookies
|
// do an initial request to get cookies
|
||||||
Request req = new Request.Builder()
|
Request req = new Request.Builder()
|
||||||
.url(getUrl())
|
.url(getUrl())
|
||||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(getUrl()).getHost()))
|
||||||
.build();
|
.build();
|
||||||
Response resp = site.getHttpClient().execute(req);
|
Response resp = site.getHttpClient().execute(req);
|
||||||
resp.close();
|
resp.close();
|
||||||
|
@ -258,7 +262,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
.header(ACCEPT, "*/*")
|
.header(ACCEPT, "*/*")
|
||||||
.header(ACCEPT_LANGUAGE, "en-US,en;q=0.5")
|
.header(ACCEPT_LANGUAGE, "en-US,en;q=0.5")
|
||||||
.header(REFERER, getUrl())
|
.header(REFERER, getUrl())
|
||||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||||
.header("X-CSRFToken", ((ChaturbateHttpClient) site.getHttpClient()).getToken())
|
.header("X-CSRFToken", ((ChaturbateHttpClient) site.getHttpClient()).getToken())
|
||||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||||
.build();
|
.build();
|
||||||
|
@ -295,14 +299,9 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
if (streamInfo != null && Duration.between(lastStreamInfoRequest, Instant.now()).getSeconds() < 5) {
|
if (streamInfo != null && Duration.between(lastStreamInfoRequest, Instant.now()).getSeconds() < 5) {
|
||||||
return streamInfo;
|
return streamInfo;
|
||||||
}
|
}
|
||||||
RequestBody body = new FormBody.Builder()
|
|
||||||
.add("room_slug", getName())
|
|
||||||
.add("bandwidth", "high")
|
|
||||||
.build();
|
|
||||||
Request req = new Request.Builder()
|
Request req = new Request.Builder()
|
||||||
.url(getSite().getBaseUrl() + "/get_edge_hls_url_ajax/")
|
.url(getSite().getBaseUrl() + "/api/chatvideocontext/" + getName() + '/')
|
||||||
.post(body)
|
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(getSite().getBaseUrl()).getHost()))
|
||||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
|
||||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
|
@ -311,6 +310,23 @@ 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);
|
||||||
|
|
||||||
|
if (streamInfo.cmaf_edge) {
|
||||||
|
if (streamInfo.hls_source.contains("playlist.m3u8")) {
|
||||||
|
streamInfo.hls_source = streamInfo.hls_source.replace("playlist.m3u8", "playlist_sfm4s.m3u8");
|
||||||
|
} else if (streamInfo.hls_source.contains("playlist_sfm4s.m3u8")) {
|
||||||
|
streamInfo.hls_source = streamInfo.hls_source.replace("playlist_sfm4s.m3u8", "playlist.m3u8");
|
||||||
|
}
|
||||||
|
|
||||||
|
var match = serverPattern.matcher(streamInfo.hls_source);
|
||||||
|
|
||||||
|
if (getSite().getHttpClient().isLoggedIn()) {
|
||||||
|
streamInfo.hls_source = match.replaceFirst("live-fhls/amlst");
|
||||||
|
} else {
|
||||||
|
streamInfo.hls_source = match.replaceFirst("live-c-fhls/amlst");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return streamInfo;
|
return streamInfo;
|
||||||
} else {
|
} else {
|
||||||
int code = response.code();
|
int code = response.code();
|
||||||
|
@ -322,7 +338,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
|
|
||||||
private int[] getResolution() throws IOException, ParseException, PlaylistException {
|
private int[] getResolution() throws IOException, ParseException, PlaylistException {
|
||||||
int[] res = new int[2];
|
int[] res = new int[2];
|
||||||
if (!getStreamInfo().url.startsWith("http")) {
|
if (!getStreamInfo().hls_source.startsWith("http")) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,10 +377,10 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private MasterPlaylist getMasterPlaylist(StreamInfo streamInfo) throws IOException, ParseException, PlaylistException {
|
private MasterPlaylist getMasterPlaylist(StreamInfo streamInfo) throws IOException, ParseException, PlaylistException {
|
||||||
log.trace("Loading master playlist {}", streamInfo.url);
|
log.trace("Loading master playlist {}", streamInfo.hls_source);
|
||||||
Request req = new Request.Builder()
|
Request req = new Request.Builder()
|
||||||
.url(streamInfo.url)
|
.url(streamInfo.hls_source)
|
||||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(streamInfo.hls_source).getHost()))
|
||||||
.build();
|
.build();
|
||||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
|
@ -385,7 +401,7 @@ public class ChaturbateModel extends AbstractModel {
|
||||||
public boolean exists() throws IOException {
|
public boolean exists() throws IOException {
|
||||||
Request req = new Request.Builder() // @formatter:off
|
Request req = new Request.Builder() // @formatter:off
|
||||||
.url(getUrl())
|
.url(getUrl())
|
||||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(getUrl()).getHost()))
|
||||||
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
||||||
.build(); // @formatter:on
|
.build(); // @formatter:on
|
||||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package ctbrec.sites.chaturbate;
|
package ctbrec.sites.chaturbate;
|
||||||
|
|
||||||
public class StreamInfo {
|
public class StreamInfo {
|
||||||
public String url;
|
public String hls_source;
|
||||||
public String room_status;
|
public String room_status;
|
||||||
public String hidden_message;
|
public String hidden_message;
|
||||||
public boolean success;
|
public boolean cmaf_edge;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
import org.apache.commons.text.StringSubstitutor;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
@ -30,6 +32,8 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static ctbrec.Model.State.*;
|
import static ctbrec.Model.State.*;
|
||||||
import static ctbrec.io.HttpConstants.*;
|
import static ctbrec.io.HttpConstants.*;
|
||||||
|
@ -197,6 +201,26 @@ public class StripchatModel extends AbstractModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getHlsUrlTemplate() throws IOException {
|
||||||
|
log.trace("Loading URL template for {}", getName());
|
||||||
|
Request req = new Request.Builder()
|
||||||
|
.url(getSite().getBaseUrl() + "/api/front/v3/config/initial?requestPath=%2F" + getName() + "&timezoneOffset=0")
|
||||||
|
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||||
|
.build();
|
||||||
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
JSONObject jsonResponse = new JSONObject(response.body().string());
|
||||||
|
var common = jsonResponse.getJSONObject("initial").getJSONObject("common");
|
||||||
|
var urlTemplate = common.getString("hlsStreamUrlTemplate");
|
||||||
|
var host = common.getString("hlsStreamHost");
|
||||||
|
|
||||||
|
return urlTemplate.replace("{cdnHost}", host);
|
||||||
|
} else {
|
||||||
|
throw new HttpException(response.code(), response.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String getMasterPlaylistUrl() throws IOException {
|
private String getMasterPlaylistUrl() throws IOException {
|
||||||
JSONObject info = getModelInfo();
|
JSONObject info = getModelInfo();
|
||||||
if (info.has("user")) {
|
if (info.has("user")) {
|
||||||
|
@ -215,8 +239,15 @@ public class StripchatModel extends AbstractModel {
|
||||||
log.debug("Spy start for {}", getName());
|
log.debug("Spy start for {}", getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String hlsUrlTemplate = "https://edge-hls.doppiocdn.com/hls/{0}{1}/master/{0}{1}_auto.m3u8?playlistType=Standart{2}";
|
|
||||||
return MessageFormat.format(hlsUrlTemplate, String.valueOf(id), vrSuffix, token);
|
// the master playlist host can vary per model
|
||||||
|
String hlsUrlTemplate = getHlsUrlTemplate();
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("streamName", String.valueOf(id) + vrSuffix);
|
||||||
|
params.put("suffix", "_auto");
|
||||||
|
|
||||||
|
var result = StringSubstitutor.replace(hlsUrlTemplate, params, "{", "}") + "?playlistType=Standart" + token;
|
||||||
|
return result;
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Playlist URL not found");
|
throw new IOException("Playlist URL not found");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.3</version>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>../common</module>
|
<module>../common</module>
|
||||||
|
|
|
@ -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.3</version>
|
||||||
<relativePath>../master</relativePath>
|
<relativePath>../master</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ function loadConfig() {
|
||||||
return this.value.join('\n');
|
return this.value.join('\n');
|
||||||
},
|
},
|
||||||
write: function (value) {
|
write: function (value) {
|
||||||
this.value = value.split('\n')
|
this.value = value === '' ? [] : value.split('\n')
|
||||||
},
|
},
|
||||||
owner: param
|
owner: param
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue