From 75131cd325186455a9469d54a92f3cc7b808b89b Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sun, 29 Nov 2020 16:36:39 +0100 Subject: [PATCH] Fix MV Live downloads and search --- CHANGELOG.md | 5 +- .../java/ctbrec/sites/manyvids/MVLive.java | 36 +++++---- .../ctbrec/sites/manyvids/MVLiveClient.java | 75 ++++++------------- .../manyvids/MVLiveMergedHlsDownload.java | 15 ++-- .../ctbrec/sites/manyvids/MVLiveModel.java | 56 +++++++------- 5 files changed, 74 insertions(+), 113 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 152936fa..a33decb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/common/src/main/java/ctbrec/sites/manyvids/MVLive.java b/common/src/main/java/ctbrec/sites/manyvids/MVLive.java index bf7b0cfc..a1bbbfc1 100644 --- a/common/src/main/java/ctbrec/sites/manyvids/MVLive.java +++ b/common/src/main/java/ctbrec/sites/manyvids/MVLive.java @@ -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 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()) { diff --git a/common/src/main/java/ctbrec/sites/manyvids/MVLiveClient.java b/common/src/main/java/ctbrec/sites/manyvids/MVLiveClient.java index 370c00b0..1793154f 100644 --- a/common/src/main/java/ctbrec/sites/manyvids/MVLiveClient.java +++ b/common/src/main/java/ctbrec/sites/manyvids/MVLiveClient.java @@ -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 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 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 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) { diff --git a/common/src/main/java/ctbrec/sites/manyvids/MVLiveMergedHlsDownload.java b/common/src/main/java/ctbrec/sites/manyvids/MVLiveMergedHlsDownload.java index 6db9f879..4a7d2327 100644 --- a/common/src/main/java/ctbrec/sites/manyvids/MVLiveMergedHlsDownload.java +++ b/common/src/main/java/ctbrec/sites/manyvids/MVLiveMergedHlsDownload.java @@ -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 { diff --git a/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java b/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java index 681ddab0..f5b2de30 100644 --- a/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java +++ b/common/src/main/java/ctbrec/sites/manyvids/MVLiveModel.java @@ -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());