Fix MV Live downloads and search

This commit is contained in:
0xb00bface 2020-11-29 16:36:39 +01:00
parent cc277022f0
commit 75131cd325
5 changed files with 74 additions and 113 deletions

View File

@ -1,7 +1,8 @@
3.10.5
========================
* MFC websocket now uses the TLS URL
* Fix: date placeholders with patterns with more than one ocurrence are
* Fixed MV Live downloads
* MFC web socket now uses the TLS URL
* Fix: date placeholders with patterns with more than one occurrence are
replaced with the value of the first one
* Some smaller UI tweaks
* adjusted component sizes for small resolutions

View File

@ -1,19 +1,5 @@
package ctbrec.sites.manyvids;
import static ctbrec.io.HttpConstants.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.Model.State;
@ -25,11 +11,23 @@ import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static ctbrec.io.HttpConstants.*;
public class MVLive extends AbstractSite {
public static final String WS_URL = "wss://live.manyvids.com";
//public static final String WS_URL = "http://localhost:8080";
public static final String WS_URL = "wss://app-v2.live.manyvids.com";
public static final String WS_ORIGIN = "https://live.manyvids.com";
public static final String BASE_URL = "https://www.manyvids.com/MVLive/";
@ -111,7 +109,8 @@ public class MVLive extends AbstractSite {
}
@Override
public void init() throws IOException {
public void init() {
// nothing special to do for manyvids
}
public List<Model> getModels() throws IOException {
@ -175,9 +174,8 @@ public class MVLive extends AbstractSite {
String getMvToken() throws IOException {
if (mvtoken == null) {
Request request = new Request.Builder()
.url(getBaseUrl())
.url("https://www.manyvids.com/")
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header(REFERER, MVLive.BASE_URL)
.build();
try (Response response = getHttpClient().execute(request)) {
if (response.isSuccessful()) {

View File

@ -1,56 +1,43 @@
package ctbrec.sites.manyvids;
import static ctbrec.StringUtil.*;
import static ctbrec.io.HttpConstants.*;
import static ctbrec.sites.manyvids.MVLive.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Objects;
import ctbrec.Config;
import ctbrec.sites.manyvids.wsmsg.*;
import okhttp3.Response;
import okhttp3.*;
import okio.ByteString;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Objects;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import ctbrec.Config;
import ctbrec.io.HttpException;
import ctbrec.sites.manyvids.wsmsg.GetBroadcastHealth;
import ctbrec.sites.manyvids.wsmsg.Message;
import ctbrec.sites.manyvids.wsmsg.Ping;
import ctbrec.sites.manyvids.wsmsg.RegisterMessage;
import ctbrec.sites.manyvids.wsmsg.SendMessage;
import okhttp3.Cookie;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
import static ctbrec.StringUtil.isNotBlank;
import static ctbrec.io.HttpConstants.*;
import static ctbrec.sites.manyvids.MVLive.WS_ORIGIN;
import static ctbrec.sites.manyvids.MVLive.WS_URL;
public class MVLiveClient {
private static final Logger LOG = LoggerFactory.getLogger(MVLiveClient.class);
private final Map<String, Message> futureResponses = new HashMap<>();
private final MVLiveHttpClient httpClient;
private final Object streamUrlMonitor = new Object();
private final Random rng = new Random();
private WebSocket ws;
private Random rng = new Random();
private volatile boolean running = false;
private volatile boolean connecting = false;
private Object streamUrlMonitor = new Object();
private String masterPlaylist = null;
private String roomNumber;
private String roomId;
private ScheduledExecutorService scheduler;
private Map<String, Message> futureResponses = new HashMap<>();
private MVLiveHttpClient httpClient;
public MVLiveClient(MVLiveHttpClient httpClient) {
this.httpClient = httpClient;
@ -61,7 +48,7 @@ public class MVLiveClient {
if (ws == null && !connecting) {
httpClient.fetchAuthenticationCookies();
JSONObject response = getRoomLocation(model);
JSONObject response = model.getRoomLocation();
roomNumber = response.optString("floorId");
roomId = response.optString("roomId");
int randomNumber = 100 + rng.nextInt(800);
@ -73,22 +60,6 @@ public class MVLiveClient {
}
}
private JSONObject getRoomLocation(MVLiveModel model) throws IOException {
Request req = new Request.Builder()
.url(WS_ORIGIN + "/api/roomlocation/" + model.getDisplayName() + "?private=false")
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
.header(COOKIE, getPhpSessionIdCookie())
.build();
try (Response response = httpClient.execute(req)) {
if (response.isSuccessful()) {
return new JSONObject(response.body().string());
} else {
throw new HttpException(response.code(), response.message());
}
}
}
private String getPhpSessionIdCookie() {
List<Cookie> cookies = httpClient.getCookiesByName("PHPSESSID");
return cookies.stream().map(c -> c.name() + "=" + c.value()).findFirst().orElse("");
@ -109,7 +80,7 @@ public class MVLiveClient {
.header(ORIGIN, WS_ORIGIN)
.header(COOKIE, getPhpSessionIdCookie())
.build();
WebSocket websocket = httpClient.newWebSocket(req, new WebSocketListener() {
return httpClient.newWebSocket(req, new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
@ -157,7 +128,6 @@ public class MVLiveClient {
@Override
public void onMessage(WebSocket webSocket, String text) {
super.onMessage(webSocket, text);
//msgBuffer.append(text);
LOG.trace("Message: {}", text);
text = Optional.ofNullable(text).orElse("");
if (Objects.equal("o", text)) {
@ -202,7 +172,6 @@ public class MVLiveClient {
LOG.debug("Binary Message: {}", bytes.hex());
}
});
return websocket;
}
void sendMessages(Message... messages) {

View File

@ -1,21 +1,20 @@
package ctbrec.sites.manyvids;
import ctbrec.io.HttpClient;
import ctbrec.recorder.download.hls.MergedFfmpegHlsDownload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.io.HttpClient;
import ctbrec.recorder.download.hls.MergedFfmpegHlsDownload;
public class MVLiveMergedHlsDownload extends MergedFfmpegHlsDownload {
private static final Logger LOG = LoggerFactory.getLogger(MVLiveMergedHlsDownload.class);
private ScheduledExecutorService scheduler;
private transient ScheduledExecutorService scheduler;
public MVLiveMergedHlsDownload(HttpClient client) {
super(client);
@ -31,7 +30,7 @@ public class MVLiveMergedHlsDownload extends MergedFfmpegHlsDownload {
t.setPriority(Thread.MIN_PRIORITY);
return t;
});
scheduler.scheduleAtFixedRate(() -> updateCloudFlareCookies(), 2, 2, TimeUnit.MINUTES);
scheduler.scheduleAtFixedRate(this::updateCloudFlareCookies, 2, 2, TimeUnit.MINUTES);
updateCloudFlareCookies();
super.start();
} finally {

View File

@ -1,8 +1,21 @@
package ctbrec.sites.manyvids;
import static ctbrec.Model.State.*;
import static ctbrec.io.HttpConstants.*;
import static java.nio.charset.StandardCharsets.*;
import com.iheartradio.m3u8.*;
import com.iheartradio.m3u8.data.MasterPlaylist;
import com.iheartradio.m3u8.data.Playlist;
import com.iheartradio.m3u8.data.PlaylistData;
import ctbrec.AbstractModel;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.StringUtil;
import ctbrec.io.HttpException;
import ctbrec.recorder.download.Download;
import ctbrec.recorder.download.StreamSource;
import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -13,29 +26,9 @@ import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.iheartradio.m3u8.Encoding;
import com.iheartradio.m3u8.Format;
import com.iheartradio.m3u8.ParseException;
import com.iheartradio.m3u8.ParsingMode;
import com.iheartradio.m3u8.PlaylistException;
import com.iheartradio.m3u8.PlaylistParser;
import com.iheartradio.m3u8.data.MasterPlaylist;
import com.iheartradio.m3u8.data.Playlist;
import com.iheartradio.m3u8.data.PlaylistData;
import ctbrec.AbstractModel;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.StringUtil;
import ctbrec.io.HttpException;
import ctbrec.recorder.download.Download;
import ctbrec.recorder.download.StreamSource;
import okhttp3.Request;
import okhttp3.Response;
import static ctbrec.Model.State.ONLINE;
import static ctbrec.io.HttpConstants.*;
import static java.nio.charset.StandardCharsets.UTF_8;
public class MVLiveModel extends AbstractModel {
@ -116,7 +109,7 @@ public class MVLiveModel extends AbstractModel {
}
public void updateCloudFlareCookies() throws IOException, InterruptedException {
String url = MVLive.WS_ORIGIN + "/api/" + getRoomNumber() + "/player-settings/" + getDisplayName();
String url = "https://app-v2.live.manyvids.com/api/" + getRoomNumber() + "/player-settings/" + getDisplayName();
LOG.trace("Getting CF cookies: {}", url);
Request req = new Request.Builder()
.url(url)
@ -158,8 +151,8 @@ public class MVLiveModel extends AbstractModel {
public JSONObject getRoomLocation() throws IOException {
fetchGeneralCookies();
httpClient.fetchAuthenticationCookies();
String url = MVLive.WS_ORIGIN + "/api/roomlocation/" + getDisplayName() + "?private=false";
LOG.trace("Fetching room location from {}", url);
String url = "https://roompool.live.manyvids.com/roompool/" + getDisplayName() + "?private=false";
LOG.debug("Fetching room location from {}", url);
Request req = new Request.Builder()
.url(url)
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
@ -169,8 +162,9 @@ public class MVLiveModel extends AbstractModel {
.build();
try (Response response = getHttpClient().execute(req)) {
if (response.isSuccessful()) {
JSONObject json = new JSONObject(response.body().string());
LOG.trace("Room location response: {}", json.toString(2));
String body = response.body().string();
JSONObject json = new JSONObject(body);
LOG.trace("Room location response: {}", json);
return json;
} else {
throw new HttpException(response.code(), response.message());