diff --git a/common/src/main/java/ctbrec/sites/cam4/Cam4.java b/common/src/main/java/ctbrec/sites/cam4/Cam4.java index 20a3143c..2e21c239 100644 --- a/common/src/main/java/ctbrec/sites/cam4/Cam4.java +++ b/common/src/main/java/ctbrec/sites/cam4/Cam4.java @@ -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); diff --git a/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java b/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java index be5da187..20c0b8f2 100644 --- a/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java +++ b/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java @@ -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,18 +96,14 @@ public class Cam4Model extends AbstractModel { @Override public State getOnlineState(boolean failFast) throws IOException, ExecutionException { - if(failFast) { - return onlineState; - } else { - if(onlineState == UNKNOWN) { - try { - loadModelDetails(); - } catch (Exception e) { - LOG.warn("Couldn't load model details {}", e.getMessage()); - } + if (!failFast && onlineState == UNKNOWN) { + try { + loadModelDetails(); + } catch (Exception e) { + LOG.warn("Couldn't load model details {}", e.getMessage()); } - return onlineState; } + return onlineState; } private String getPlaylistUrl() throws IOException { @@ -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 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; + } }