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