Fix MV Live downloads and search
This commit is contained in:
parent
cc277022f0
commit
75131cd325
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue