mp4, rtsp
This commit is contained in:
parent
28c5cb8c0c
commit
c5d5685734
@ -338,7 +338,11 @@ public final class XtreamPlayerApplication {
|
|||||||
String streamUrl;
|
String streamUrl;
|
||||||
String directUrl = query.getOrDefault("url", "").trim();
|
String directUrl = query.getOrDefault("url", "").trim();
|
||||||
if (!directUrl.isBlank()) {
|
if (!directUrl.isBlank()) {
|
||||||
if (!directUrl.startsWith("http://") && !directUrl.startsWith("https://")) {
|
String lowerUrl = directUrl.toLowerCase(Locale.ROOT);
|
||||||
|
if (!lowerUrl.startsWith("http://")
|
||||||
|
&& !lowerUrl.startsWith("https://")
|
||||||
|
&& !lowerUrl.startsWith("rtsp://")
|
||||||
|
&& !lowerUrl.startsWith("rtsps://")) {
|
||||||
writeJson(exchange, 400, errorJson("Unsupported URL protocol."));
|
writeJson(exchange, 400, errorJson("Unsupported URL protocol."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -817,8 +821,13 @@ public final class XtreamPlayerApplication {
|
|||||||
List<String> attemptErrors = new ArrayList<>();
|
List<String> attemptErrors = new ArrayList<>();
|
||||||
for (URI candidate : attempts) {
|
for (URI candidate : attempts) {
|
||||||
try {
|
try {
|
||||||
|
String incomingRange = firstNonBlank(
|
||||||
|
exchange.getRequestHeaders().getFirst("Range"),
|
||||||
|
"bytes=0-"
|
||||||
|
);
|
||||||
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(candidate)
|
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(candidate)
|
||||||
.GET()
|
.GET()
|
||||||
|
.timeout(Duration.ofSeconds(60))
|
||||||
.header("User-Agent", firstNonBlank(
|
.header("User-Agent", firstNonBlank(
|
||||||
exchange.getRequestHeaders().getFirst("User-Agent"),
|
exchange.getRequestHeaders().getFirst("User-Agent"),
|
||||||
DEFAULT_BROWSER_UA
|
DEFAULT_BROWSER_UA
|
||||||
@ -826,12 +835,16 @@ public final class XtreamPlayerApplication {
|
|||||||
.header("Accept", firstNonBlank(
|
.header("Accept", firstNonBlank(
|
||||||
exchange.getRequestHeaders().getFirst("Accept"),
|
exchange.getRequestHeaders().getFirst("Accept"),
|
||||||
"*/*"
|
"*/*"
|
||||||
|
))
|
||||||
|
.header("Range", incomingRange)
|
||||||
|
.header("Accept-Encoding", firstNonBlank(
|
||||||
|
exchange.getRequestHeaders().getFirst("Accept-Encoding"),
|
||||||
|
"identity"
|
||||||
));
|
));
|
||||||
copyRequestHeaderIfPresent(exchange, requestBuilder, "Range");
|
|
||||||
copyRequestHeaderIfPresent(exchange, requestBuilder, "If-Range");
|
copyRequestHeaderIfPresent(exchange, requestBuilder, "If-Range");
|
||||||
copyRequestHeaderIfPresent(exchange, requestBuilder, "Accept-Encoding");
|
|
||||||
copyRequestHeaderIfPresent(exchange, requestBuilder, "Cache-Control");
|
copyRequestHeaderIfPresent(exchange, requestBuilder, "Cache-Control");
|
||||||
copyRequestHeaderIfPresent(exchange, requestBuilder, "Pragma");
|
copyRequestHeaderIfPresent(exchange, requestBuilder, "Pragma");
|
||||||
|
copyRequestHeaderIfPresent(exchange, requestBuilder, "Origin");
|
||||||
String referer = resolveRefererForCandidate(exchange, candidate, sourceUrl);
|
String referer = resolveRefererForCandidate(exchange, candidate, sourceUrl);
|
||||||
if (!referer.isBlank()) {
|
if (!referer.isBlank()) {
|
||||||
requestBuilder.header("Referer", referer);
|
requestBuilder.header("Referer", referer);
|
||||||
|
|||||||
@ -310,6 +310,10 @@
|
|||||||
if (!name || !url) {
|
if (!name || !url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!isSupportedCustomUrl(url)) {
|
||||||
|
setSettingsMessage("Custom stream URL must start with http://, https://, rtsp://, or rtsps://", "err");
|
||||||
|
return;
|
||||||
|
}
|
||||||
state.customStreams.push({
|
state.customStreams.push({
|
||||||
id: String(Date.now()),
|
id: String(Date.now()),
|
||||||
name,
|
name,
|
||||||
@ -1748,6 +1752,15 @@
|
|||||||
setSubtitleStatus("No subtitle loaded.", false);
|
setSubtitleStatus("No subtitle loaded.", false);
|
||||||
scheduleEmbeddedSubtitleScan();
|
scheduleEmbeddedSubtitleScan();
|
||||||
|
|
||||||
|
if (isRtspUrl(playbackUrl)) {
|
||||||
|
state.currentStreamInfo.playbackEngine = "external player (RTSP)";
|
||||||
|
state.currentStreamInfo.resolution = "n/a";
|
||||||
|
state.currentStreamInfo.duration = "n/a";
|
||||||
|
renderStreamInfo();
|
||||||
|
setSettingsMessage("RTSP is not supported in browser player. Use Open in system player.", "err");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isLikelyHls(playbackUrl) && shouldUseHlsJs()) {
|
if (isLikelyHls(playbackUrl) && shouldUseHlsJs()) {
|
||||||
state.currentStreamInfo.playbackEngine = "hls.js";
|
state.currentStreamInfo.playbackEngine = "hls.js";
|
||||||
renderStreamInfo();
|
renderStreamInfo();
|
||||||
@ -1820,6 +1833,9 @@
|
|||||||
if (!url) {
|
if (!url) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
if (isRtspUrl(url)) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const pageIsHttps = window.location.protocol === "https:";
|
const pageIsHttps = window.location.protocol === "https:";
|
||||||
const target = new URL(url, window.location.href);
|
const target = new URL(url, window.location.href);
|
||||||
@ -1832,6 +1848,19 @@
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRtspUrl(urlRaw) {
|
||||||
|
const value = String(urlRaw || "").trim().toLowerCase();
|
||||||
|
return value.startsWith("rtsp://") || value.startsWith("rtsps://");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSupportedCustomUrl(urlRaw) {
|
||||||
|
const value = String(urlRaw || "").trim().toLowerCase();
|
||||||
|
return value.startsWith("http://")
|
||||||
|
|| value.startsWith("https://")
|
||||||
|
|| value.startsWith("rtsp://")
|
||||||
|
|| value.startsWith("rtsps://");
|
||||||
|
}
|
||||||
|
|
||||||
function resetPlayerElement() {
|
function resetPlayerElement() {
|
||||||
disposeHls();
|
disposeHls();
|
||||||
el.player.pause();
|
el.player.pause();
|
||||||
|
|||||||
@ -129,7 +129,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
URL
|
URL
|
||||||
<input id="custom-url" required placeholder="https://...m3u8">
|
<input id="custom-url" required placeholder="https://...m3u8 or rtsp://...">
|
||||||
</label>
|
</label>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="submit">Add</button>
|
<button type="submit">Add</button>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user