fix player bug with apple mpegurl

This commit is contained in:
Simon
2026-02-12 08:23:27 +00:00
parent ece4852d4f
commit 7ba8896405

View File

@@ -78,6 +78,7 @@ App.player = App.player || {};
const refererParam = resolved.referer ? `&referer=${encodeURIComponent(resolved.referer)}` : '';
const streamUrl = `/api/stream?url=${encodeURIComponent(resolved.url)}${refererParam}`;
let isHls = /\.m3u8($|\?)/i.test(resolved.url);
let isDirectMedia = /\.(mp4|m4v|m4s|webm|ts|mov)($|\?)/i.test(resolved.url);
// Cleanup existing player instance to prevent aborted bindings.
if (state.hlsPlayer) {
@@ -98,6 +99,8 @@ App.player = App.player || {};
const contentType = headResp.headers.get('Content-Type') || '';
if (contentType.includes('application/vnd.apple.mpegurl')) {
isHls = true;
} else if (contentType.startsWith('video/') || contentType.startsWith('audio/')) {
isDirectMedia = true;
}
} catch (err) {
console.warn('Failed to detect stream type', err);
@@ -155,41 +158,73 @@ App.player = App.player || {};
}
};
if (isHls) {
if (window.Hls && window.Hls.isSupported()) {
state.hlsPlayer = new window.Hls();
state.hlsPlayer.loadSource(streamUrl);
state.hlsPlayer.attachMedia(video);
state.hlsPlayer.on(window.Hls.Events.MANIFEST_PARSED, function() {
startPlayback();
});
startPlayback();
state.hlsPlayer.on(window.Hls.Events.ERROR, function(event, data) {
if (data && data.fatal) {
clearLoading();
if (App.ui && App.ui.showError) {
App.ui.showError('Unable to play this stream.');
}
App.player.close();
}
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = streamUrl;
startPlayback();
} else {
console.error("HLS not supported in this browser.");
if (App.ui && App.ui.showError) {
App.ui.showError('HLS is not supported in this browser.');
}
clearLoading();
return;
}
} else {
const canUseHls = !!(window.Hls && window.Hls.isSupported());
const prefersHls = isHls || (canUseHls && !isDirectMedia && !video.canPlayType('application/vnd.apple.mpegurl'));
let hlsTried = false;
let nativeTried = false;
let usingHls = false;
const startNative = () => {
if (nativeTried) return;
nativeTried = true;
usingHls = false;
video.src = streamUrl;
startPlayback();
};
const startHls = (allowFallback) => {
if (!canUseHls || hlsTried) return false;
hlsTried = true;
usingHls = true;
state.hlsPlayer = new window.Hls();
state.hlsPlayer.loadSource(streamUrl);
state.hlsPlayer.attachMedia(video);
state.hlsPlayer.on(window.Hls.Events.MANIFEST_PARSED, function() {
startPlayback();
});
startPlayback();
state.hlsPlayer.on(window.Hls.Events.ERROR, function(event, data) {
if (data && data.fatal) {
const shouldFallback = allowFallback && !nativeTried && !isHls;
if (state.hlsPlayer) {
state.hlsPlayer.destroy();
state.hlsPlayer = null;
}
if (shouldFallback) {
startNative();
return;
}
clearLoading();
if (App.ui && App.ui.showError) {
App.ui.showError('Unable to play this stream.');
}
App.player.close();
}
});
return true;
};
if (prefersHls) {
if (!startHls(true)) {
if (video.canPlayType('application/vnd.apple.mpegurl')) {
startNative();
} else {
console.error("HLS not supported in this browser.");
if (App.ui && App.ui.showError) {
App.ui.showError('HLS is not supported in this browser.');
}
clearLoading();
return;
}
}
} else {
startNative();
}
video.onerror = () => {
if (!usingHls && canUseHls && !hlsTried && !isDirectMedia) {
if (startHls(true)) return;
}
clearLoading();
if (App.ui && App.ui.showError) {
App.ui.showError('Video failed to load.');