Compare commits
10 Commits
c91b410307
...
cb44a32079
Author | SHA1 | Date |
---|---|---|
|
cb44a32079 | |
|
df77c6faee | |
|
0aa5dadda7 | |
|
e583aad604 | |
|
7a0dc3a371 | |
|
c9fd95c247 | |
|
1f26371283 | |
|
f549580526 | |
|
f8613c8817 | |
|
cac8ee37d9 |
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<version>5.3.2</version>
|
||||
<version>5.3.3</version>
|
||||
<relativePath>../master</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import okhttp3.Request;
|
|||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -35,7 +36,7 @@ public class ChaturbateApiUpdateService extends PaginatedScheduledService {
|
|||
protected List<Model> call() throws Exception {
|
||||
var request = new Request.Builder()
|
||||
.url(url)
|
||||
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
||||
.build();
|
||||
try (var response = chaturbate.getHttpClient().execute(request)) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
@ -35,7 +36,7 @@ public class ChaturbateElectronLoginDialog {
|
|||
config.put("url", site.getBaseUrl() + "/auth/login/");
|
||||
config.put("w", 640);
|
||||
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();
|
||||
msg.put("config", config);
|
||||
browser.run(msg, msgHandler);
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.json.JSONObject;
|
|||
import org.jsoup.Jsoup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -54,7 +55,7 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
|
|||
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
||||
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, chaturbate.getHttpClient().getEffectiveUserAgent(URI.create(pageUrl).getHost()))
|
||||
.build();
|
||||
try (var response = chaturbate.getHttpClient().execute(request)) {
|
||||
if (response.isSuccessful()) {
|
||||
|
|
|
@ -19,7 +19,7 @@ public abstract class AbstractStripchatUpdateService extends PaginatedScheduledS
|
|||
if (timestamp == 0) {
|
||||
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) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package ctbrec.ui.tabs.recorded;
|
|||
import ctbrec.Config;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.Recording;
|
||||
import ctbrec.Model.State;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.sites.Site;
|
||||
import ctbrec.ui.JavaFxModel;
|
||||
|
@ -327,7 +328,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS
|
|||
if (Objects.equals(onlineModel, fxm)) {
|
||||
fxm.setOnlineProperty(true);
|
||||
try {
|
||||
fxm.setOnlineStateProperty(onlineModel.getOnlineState(true));
|
||||
fxm.setOnlineStateProperty(Model.State.ONLINE);
|
||||
} catch (Exception e) {}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<version>5.3.2</version>
|
||||
<version>5.3.3</version>
|
||||
<relativePath>../master</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -93,6 +93,11 @@
|
|||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -34,7 +33,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.time.*;
|
||||
import java.util.Optional;
|
||||
|
||||
import static ctbrec.io.HttpConstants.ACCEPT_ENCODING_GZIP;
|
||||
import static ctbrec.io.HttpConstants.CONTENT_ENCODING;
|
||||
|
@ -51,6 +49,7 @@ public abstract class HttpClient {
|
|||
protected OkHttpClient client;
|
||||
protected Cache cache;
|
||||
protected Config config;
|
||||
@Getter
|
||||
protected boolean loggedIn = false;
|
||||
protected long cacheSize;
|
||||
protected int cacheLifeTime = 600;
|
||||
|
@ -454,7 +453,11 @@ public abstract class HttpClient {
|
|||
}
|
||||
|
||||
// overridable default user agent (used for Flaresolverr)
|
||||
public String getEffectiveUserAgent() {
|
||||
return config.getSettings().httpUserAgent;
|
||||
public String getEffectiveUserAgent(String host) {
|
||||
if (config.getSettings().flaresolverr.useForDomains.contains(host)) {
|
||||
return config.getSettings().flaresolverr.userAgent;
|
||||
} else {
|
||||
return config.getSettings().httpUserAgent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import java.util.Objects;
|
|||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.List;
|
||||
|
||||
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
|
||||
// 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()
|
||||
.map(modelUrl -> getModelForUrl(modelUrl))
|
||||
.filter(x -> x.isPresent())
|
||||
.map(x -> x.get())
|
||||
var models = modelGroup.get().getModelUrls().stream()
|
||||
.map(modelUrl -> getModelForUrl(modelUrl))
|
||||
.filter(x -> x.isPresent())
|
||||
.map(x -> x.get())
|
||||
.toList();
|
||||
for (var groupModel : IntStream.range(0, models.size()).boxed()
|
||||
.sorted(Comparator
|
||||
.comparing((Model m) -> m.getPriority()).reversed() // high to low
|
||||
.thenComparing((Model m) -> m.getUrl().equals(model.getUrl()))) // this model last (false -> true)
|
||||
.comparing((Integer i) -> models.get(i).getPriority()).reversed() // high to low
|
||||
.thenComparing((Integer i) -> i)) // in group's order
|
||||
.map((Integer i) -> models.get(i))
|
||||
.toList()) {
|
||||
if (model.getUrl().equals(groupModel.getUrl())) {
|
||||
// no other model with higher prio is online, start recording
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.json.JSONArray;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
@ -55,7 +56,7 @@ public class Chaturbate extends AbstractSite {
|
|||
ChaturbateModel m = new ChaturbateModel(this);
|
||||
m.setName(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;
|
||||
}
|
||||
|
||||
|
@ -69,7 +70,7 @@ public class Chaturbate extends AbstractSite {
|
|||
String url = "https://chaturbate.com/p/" + username + "/";
|
||||
Request req = new Request.Builder()
|
||||
.url(url)
|
||||
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||
.build();
|
||||
try (Response resp = getHttpClient().execute(req)) {
|
||||
if (resp.isSuccessful()) {
|
||||
|
@ -131,7 +132,7 @@ public class Chaturbate extends AbstractSite {
|
|||
// search online models
|
||||
Request req = new Request.Builder()
|
||||
.url(url)
|
||||
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||
.header(ACCEPT, "*/*")
|
||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||
.header(REFERER, getBaseUrl())
|
||||
|
|
|
@ -8,6 +8,7 @@ import okhttp3.*;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.URI;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
|
@ -28,15 +29,6 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
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) {
|
||||
try {
|
||||
Cookie csrfToken = cookieJar.getCookie(request.url(), "csrftoken");
|
||||
|
@ -65,7 +57,7 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
}
|
||||
Request login = new Request.Builder()
|
||||
.url(Chaturbate.baseUrl + PATH)
|
||||
.header(USER_AGENT, getEffectiveUserAgent())
|
||||
.header(USER_AGENT, getEffectiveUserAgent(URI.create(Chaturbate.baseUrl).getHost()))
|
||||
.build();
|
||||
try (var initResponse = client.newCall(login).execute()) {
|
||||
String content = initResponse.body().string();
|
||||
|
@ -81,7 +73,7 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
login = new Request.Builder()
|
||||
.url(Chaturbate.baseUrl + PATH)
|
||||
.header(REFERER, Chaturbate.baseUrl + PATH)
|
||||
.header(USER_AGENT, getEffectiveUserAgent())
|
||||
.header(USER_AGENT, getEffectiveUserAgent(URI.create(Chaturbate.baseUrl).getHost()))
|
||||
.post(body)
|
||||
.build();
|
||||
|
||||
|
@ -106,7 +98,7 @@ public class ChaturbateHttpClient extends HttpClient {
|
|||
String url = "https://chaturbate.com/api/ts/chatmessages/pm_users/?offset=0";
|
||||
Request req = new Request.Builder()
|
||||
.url(url)
|
||||
.header(USER_AGENT, getEffectiveUserAgent())
|
||||
.header(USER_AGENT, getEffectiveUserAgent(URI.create(url).getHost()))
|
||||
.build();
|
||||
try (Response response = execute(req)) {
|
||||
boolean result = false;
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
@ -30,11 +31,14 @@ import java.util.concurrent.ExecutionException;
|
|||
import static ctbrec.Model.State.*;
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Slf4j
|
||||
public class ChaturbateModel extends AbstractModel {
|
||||
|
||||
private static final String PUBLIC = "public";
|
||||
private static final Pattern serverPattern = Pattern.compile("live-.+amlst");
|
||||
|
||||
private int[] resolution = new int[2];
|
||||
private transient StreamInfo streamInfo;
|
||||
private transient Instant lastStreamInfoRequest = Instant.EPOCH;
|
||||
|
@ -75,7 +79,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
|
||||
private boolean isOffline() {
|
||||
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) {
|
||||
offlineImageSize = getOfflineImageSize(); // NOSONAR
|
||||
}
|
||||
|
@ -85,7 +89,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
private int getOfflineImageSize() {
|
||||
String[] names = {"Sophia", "Helena", "Olivia", "Natasha", "Emmy", "Jenny", "Diana", "Teresa", "Julia", "Polly", "Amanda"};
|
||||
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);
|
||||
if (imageSize == 0) {
|
||||
imageSize = 21971;
|
||||
|
@ -97,7 +101,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
int imageSize = 0;
|
||||
Request req = new Request.Builder()
|
||||
.url(url)
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(url).getHost()))
|
||||
.head()
|
||||
.build();
|
||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||
|
@ -190,7 +194,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
.post(body)
|
||||
.header(REFERER, "https://chaturbate.com/" + getName() + "/")
|
||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent("chaturbate.com"))
|
||||
.build();
|
||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||
if (!response.isSuccessful()) {
|
||||
|
@ -211,7 +215,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
src.setBandwidth(playlist.getStreamInfo().getBandwidth());
|
||||
src.setHeight(playlist.getStreamInfo().getResolution().height);
|
||||
src.setWidth(playlist.getStreamInfo().getResolution().width);
|
||||
String masterUrl = streamInfo.url;
|
||||
String masterUrl = streamInfo.hls_source;
|
||||
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
||||
String segmentUri = baseUrl + playlist.getUri();
|
||||
src.setMediaPlaylistUrl(segmentUri);
|
||||
|
@ -239,7 +243,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
// do an initial request to get cookies
|
||||
Request req = new Request.Builder()
|
||||
.url(getUrl())
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(getUrl()).getHost()))
|
||||
.build();
|
||||
Response resp = site.getHttpClient().execute(req);
|
||||
resp.close();
|
||||
|
@ -258,7 +262,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
.header(ACCEPT, "*/*")
|
||||
.header(ACCEPT_LANGUAGE, "en-US,en;q=0.5")
|
||||
.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_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||
.build();
|
||||
|
@ -295,14 +299,9 @@ public class ChaturbateModel extends AbstractModel {
|
|||
if (streamInfo != null && Duration.between(lastStreamInfoRequest, Instant.now()).getSeconds() < 5) {
|
||||
return streamInfo;
|
||||
}
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("room_slug", getName())
|
||||
.add("bandwidth", "high")
|
||||
.build();
|
||||
Request req = new Request.Builder()
|
||||
.url(getSite().getBaseUrl() + "/get_edge_hls_url_ajax/")
|
||||
.post(body)
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
||||
.url(getSite().getBaseUrl() + "/api/chatvideocontext/" + getName() + '/')
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(getSite().getBaseUrl()).getHost()))
|
||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||
.build();
|
||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||
|
@ -311,6 +310,23 @@ public class ChaturbateModel extends AbstractModel {
|
|||
String content = response.body().string();
|
||||
log.trace("Raw stream info for model {}: {}", getName(), content);
|
||||
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;
|
||||
} else {
|
||||
int code = response.code();
|
||||
|
@ -322,7 +338,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
|
||||
private int[] getResolution() throws IOException, ParseException, PlaylistException {
|
||||
int[] res = new int[2];
|
||||
if (!getStreamInfo().url.startsWith("http")) {
|
||||
if (!getStreamInfo().hls_source.startsWith("http")) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -361,10 +377,10 @@ public class ChaturbateModel extends AbstractModel {
|
|||
}
|
||||
|
||||
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()
|
||||
.url(streamInfo.url)
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
||||
.url(streamInfo.hls_source)
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(streamInfo.hls_source).getHost()))
|
||||
.build();
|
||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||
if (response.isSuccessful()) {
|
||||
|
@ -385,7 +401,7 @@ public class ChaturbateModel extends AbstractModel {
|
|||
public boolean exists() throws IOException {
|
||||
Request req = new Request.Builder() // @formatter:off
|
||||
.url(getUrl())
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent())
|
||||
.header(USER_AGENT, site.getHttpClient().getEffectiveUserAgent(URI.create(getUrl()).getHost()))
|
||||
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
||||
.build(); // @formatter:on
|
||||
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package ctbrec.sites.chaturbate;
|
||||
|
||||
public class StreamInfo {
|
||||
public String url;
|
||||
public String hls_source;
|
||||
public String room_status;
|
||||
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.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
import org.apache.commons.text.StringSubstitutor;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
@ -30,6 +32,8 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static ctbrec.Model.State.*;
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
|
@ -196,6 +200,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 {
|
||||
JSONObject info = getModelInfo();
|
||||
|
@ -215,8 +239,15 @@ public class StripchatModel extends AbstractModel {
|
|||
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 {
|
||||
throw new IOException("Playlist URL not found");
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>5.3.2</version>
|
||||
<version>5.3.3</version>
|
||||
|
||||
<modules>
|
||||
<module>../common</module>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>ctbrec</groupId>
|
||||
<artifactId>master</artifactId>
|
||||
<version>5.3.2</version>
|
||||
<version>5.3.3</version>
|
||||
<relativePath>../master</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ function loadConfig() {
|
|||
return this.value.join('\n');
|
||||
},
|
||||
write: function (value) {
|
||||
this.value = value.split('\n')
|
||||
this.value = value === '' ? [] : value.split('\n')
|
||||
},
|
||||
owner: param
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue