forked from j62/ctbrec
94 lines
3.8 KiB
Java
94 lines
3.8 KiB
Java
package ctbrec.sites.mfc;
|
|
|
|
import static ctbrec.io.HttpConstants.*;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.concurrent.ExecutionException;
|
|
|
|
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.Config;
|
|
import ctbrec.io.HttpClient;
|
|
import ctbrec.io.HttpException;
|
|
import ctbrec.recorder.download.StreamSource;
|
|
import okhttp3.Request;
|
|
import okhttp3.Response;
|
|
|
|
public class HlsStreamSourceProvider implements StreamSourceProvider {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(HlsStreamSourceProvider.class);
|
|
private HttpClient httpClient;
|
|
|
|
public HlsStreamSourceProvider(HttpClient httpClient) {
|
|
this.httpClient = httpClient;
|
|
}
|
|
|
|
@Override
|
|
public List<StreamSource> getStreamSources(String streamUrl) throws IOException, ExecutionException, ParseException, PlaylistException {
|
|
MasterPlaylist masterPlaylist = getMasterPlaylist(streamUrl);
|
|
List<StreamSource> sources = new ArrayList<>();
|
|
for (PlaylistData playlist : masterPlaylist.getPlaylists()) {
|
|
if (playlist.hasStreamInfo()) {
|
|
StreamSource src = new StreamSource();
|
|
src.bandwidth = playlist.getStreamInfo().getBandwidth();
|
|
if(playlist.getStreamInfo().getResolution() != null) {
|
|
src.width = playlist.getStreamInfo().getResolution().width;
|
|
src.height = playlist.getStreamInfo().getResolution().height;
|
|
} else {
|
|
src.width = StreamSource.UNKNOWN;
|
|
src.height = StreamSource.UNKNOWN;
|
|
}
|
|
String masterUrl = streamUrl;
|
|
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
|
|
String segmentUri = baseUrl + playlist.getUri();
|
|
src.mediaPlaylistUrl = segmentUri;
|
|
LOG.trace("Media playlist {}", src.mediaPlaylistUrl);
|
|
sources.add(src);
|
|
}
|
|
}
|
|
return sources;
|
|
}
|
|
|
|
private MasterPlaylist getMasterPlaylist(String streamUrl) throws IOException, ParseException, PlaylistException {
|
|
if(streamUrl == null) {
|
|
throw new IllegalStateException("Stream url unknown");
|
|
}
|
|
LOG.trace("Loading master playlist {}", streamUrl);
|
|
Request req = new Request.Builder()
|
|
.url(streamUrl)
|
|
.header(ACCEPT, "*/*")
|
|
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
|
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
|
.header(CONNECTION, KEEP_ALIVE)
|
|
.header(ORIGIN, MyFreeCams.baseUrl)
|
|
.header(REFERER, MyFreeCams.baseUrl + '/')
|
|
.build();
|
|
try (Response response = httpClient.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;
|
|
} else {
|
|
throw new HttpException(response.code(), response.message() + " - Forbidden: " + streamUrl);
|
|
}
|
|
}
|
|
}
|
|
}
|