Add HTTP header factory to Cam4Model
The edge URL requires a Referer header as @gohufrapoc@mastodon.cloud found out. Otherwise you get a HTTP 403 error. We also set a few other standard headers.
This commit is contained in:
parent
7a36f49896
commit
dc12e12dc0
|
@ -1,17 +1,5 @@
|
|||
package ctbrec.sites.cam4;
|
||||
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.StringUtil;
|
||||
|
@ -20,6 +8,18 @@ import ctbrec.io.HttpException;
|
|||
import ctbrec.sites.AbstractSite;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static ctbrec.io.HttpClient.bodyToJsonObject;
|
||||
import static ctbrec.io.HttpConstants.USER_AGENT;
|
||||
|
||||
public class Cam4 extends AbstractSite {
|
||||
|
||||
|
@ -130,7 +130,7 @@ public class Cam4 extends AbstractSite {
|
|||
.build();
|
||||
try(Response response = getHttpClient().execute(req)) {
|
||||
if(response.isSuccessful()) {
|
||||
String body = response.body().string();
|
||||
String body = bodyToJsonObject(response);
|
||||
JSONArray results = new JSONArray(body);
|
||||
for (int i = 0; i < results.length(); i++) {
|
||||
JSONObject result = results.getJSONObject(i);
|
||||
|
|
|
@ -1,46 +1,39 @@
|
|||
package ctbrec.sites.cam4;
|
||||
|
||||
import static ctbrec.Model.State.*;
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
import static java.util.regex.Pattern.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.nodes.Element;
|
||||
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.*;
|
||||
import com.iheartradio.m3u8.data.MasterPlaylist;
|
||||
import com.iheartradio.m3u8.data.Playlist;
|
||||
import com.iheartradio.m3u8.data.PlaylistData;
|
||||
import com.iheartradio.m3u8.data.StreamInfo;
|
||||
|
||||
import ctbrec.AbstractModel;
|
||||
import ctbrec.Config;
|
||||
import ctbrec.StringUtil;
|
||||
import ctbrec.io.HtmlParser;
|
||||
import ctbrec.io.HttpException;
|
||||
import ctbrec.recorder.download.HttpHeaderFactory;
|
||||
import ctbrec.recorder.download.HttpHeaderFactoryImpl;
|
||||
import ctbrec.recorder.download.StreamSource;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static ctbrec.Model.State.*;
|
||||
import static ctbrec.io.HttpClient.bodyToJsonObject;
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
import static java.util.regex.Pattern.DOTALL;
|
||||
import static java.util.regex.Pattern.MULTILINE;
|
||||
|
||||
public class Cam4Model extends AbstractModel {
|
||||
|
||||
|
@ -103,10 +96,7 @@ public class Cam4Model extends AbstractModel {
|
|||
|
||||
@Override
|
||||
public State getOnlineState(boolean failFast) throws IOException, ExecutionException {
|
||||
if(failFast) {
|
||||
return onlineState;
|
||||
} else {
|
||||
if(onlineState == UNKNOWN) {
|
||||
if (!failFast && onlineState == UNKNOWN) {
|
||||
try {
|
||||
loadModelDetails();
|
||||
} catch (Exception e) {
|
||||
|
@ -115,7 +105,6 @@ public class Cam4Model extends AbstractModel {
|
|||
}
|
||||
return onlineState;
|
||||
}
|
||||
}
|
||||
|
||||
private String getPlaylistUrl() throws IOException {
|
||||
String page = loadModelPage();
|
||||
|
@ -146,8 +135,8 @@ public class Cam4Model extends AbstractModel {
|
|||
.build(); // @formatter:on
|
||||
try (Response response = site.getHttpClient().execute(req)) {
|
||||
if (response.isSuccessful()) {
|
||||
JSONObject json = new JSONObject(response.body().string());
|
||||
LOG.trace(json.toString(2));
|
||||
JSONObject json = new JSONObject(bodyToJsonObject(response));
|
||||
if (LOG.isTraceEnabled()) LOG.trace(json.toString(2));
|
||||
if (json.has("canUseCDN")) {
|
||||
if (json.getBoolean("canUseCDN")) {
|
||||
playlistUrl = json.getString("cdnURL");
|
||||
|
@ -191,8 +180,7 @@ public class Cam4Model extends AbstractModel {
|
|||
src.height = Optional.ofNullable(playlist.getStreamInfo()).map(StreamInfo::getResolution).map(res -> res.height).orElse(0);
|
||||
String masterUrl = getPlaylistUrl();
|
||||
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
||||
String segmentUri = baseUrl + playlist.getUri();
|
||||
src.mediaPlaylistUrl = segmentUri;
|
||||
src.mediaPlaylistUrl = baseUrl + playlist.getUri();
|
||||
LOG.trace("Media playlist {}", src.mediaPlaylistUrl);
|
||||
sources.add(src);
|
||||
}
|
||||
|
@ -201,19 +189,18 @@ public class Cam4Model extends AbstractModel {
|
|||
}
|
||||
|
||||
private MasterPlaylist getMasterPlaylist() throws IOException, ParseException, PlaylistException {
|
||||
String playlistUrl = getPlaylistUrl();
|
||||
LOG.trace("Loading master playlist [{}]", playlistUrl);
|
||||
Request req = new Request.Builder().url(playlistUrl).build();
|
||||
String masterPlaylistUrl = getPlaylistUrl();
|
||||
LOG.trace("Loading master playlist [{}]", masterPlaylistUrl);
|
||||
Request req = new Request.Builder().url(masterPlaylistUrl).build();
|
||||
|
||||
try (Response response = site.getHttpClient().execute(req)) {
|
||||
if (response.isSuccessful()) {
|
||||
InputStream inputStream = response.body().byteStream();
|
||||
PlaylistParser parser = new PlaylistParser(inputStream, Format.EXT_M3U, Encoding.UTF_8, ParsingMode.LENIENT);
|
||||
Playlist playlist = parser.parse();
|
||||
MasterPlaylist master = playlist.getMasterPlaylist();
|
||||
return master;
|
||||
return playlist.getMasterPlaylist();
|
||||
} else {
|
||||
throw new HttpException(response.code(), "Couldn't download HLS playlist " + playlistUrl);
|
||||
throw new HttpException(response.code(), "Couldn't download HLS playlist " + masterPlaylistUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,12 +308,6 @@ public class Cam4Model extends AbstractModel {
|
|||
this.playlistUrl = playlistUrl;
|
||||
}
|
||||
|
||||
public class ModelDetailsEmptyException extends Exception {
|
||||
public ModelDetailsEmptyException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUrl(String url) {
|
||||
String normalizedUrl = url.toLowerCase();
|
||||
|
@ -335,4 +316,22 @@ public class Cam4Model extends AbstractModel {
|
|||
}
|
||||
super.setUrl(normalizedUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaderFactory getHttpHeaderFactory() {
|
||||
HttpHeaderFactoryImpl fac = new HttpHeaderFactoryImpl();
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(ACCEPT, "*/*");
|
||||
headers.put(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage());
|
||||
headers.put(CONNECTION, KEEP_ALIVE);
|
||||
if (getSite() != null) {
|
||||
headers.put(ORIGIN, getSite().getBaseUrl());
|
||||
headers.put(REFERER, getSite().getBaseUrl());
|
||||
}
|
||||
headers.put(USER_AGENT, Config.getInstance().getSettings().httpUserAgent);
|
||||
fac.setMasterPlaylistHeaders(headers);
|
||||
fac.setSegmentPlaylistHeaders(headers);
|
||||
fac.setSegmentHeaders(headers);
|
||||
return fac;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue