on mobile go directly to full screen video

This commit is contained in:
Simon
2026-02-09 12:31:07 +00:00
parent df8aaa5f9f
commit 1651e5a375
2 changed files with 128 additions and 3 deletions

View File

@@ -7,6 +7,10 @@ let isLoading = false;
let hlsPlayer = null;
let currentLoadController = null;
let errorToastTimer = null;
let playerMode = 'modal';
let playerHome = null;
let onFullscreenChange = null;
let onWebkitEndFullscreen = null;
// 2. Observer Definition (Must be defined before initApp uses it)
const observer = new IntersectionObserver((entries) => {
@@ -178,6 +182,25 @@ function formatDuration(seconds) {
return `${minutes}m`;
}
function isMobilePlayback() {
if (navigator.userAgentData && typeof navigator.userAgentData.mobile === 'boolean') {
return navigator.userAgentData.mobile;
}
const ua = navigator.userAgent || '';
if (/iPhone|iPad|iPod|Android/i.test(ua)) return true;
return window.matchMedia('(pointer: coarse)').matches && window.matchMedia('(max-width: 900px)').matches;
}
function getMobileVideoHost() {
let host = document.getElementById('mobile-video-host');
if (!host) {
host = document.createElement('div');
host.id = 'mobile-video-host';
document.body.appendChild(host);
}
return host;
}
// 4. Initialization (Run this last)
async function initApp() {
// Clear old data if you want a fresh start every refresh
@@ -238,6 +261,12 @@ function showError(message) {
async function openPlayer(url) {
const modal = document.getElementById('video-modal');
const video = document.getElementById('player');
const useMobileFullscreen = isMobilePlayback();
let playbackStarted = false;
if (!playerHome) {
playerHome = video.parentElement;
}
// 1. Define isHls (the missing piece!)
let refererParam = '';
@@ -275,14 +304,65 @@ async function openPlayer(url) {
}
}
if (useMobileFullscreen) {
const host = getMobileVideoHost();
if (video.parentElement !== host) {
host.appendChild(video);
}
playerMode = 'mobile';
video.removeAttribute('playsinline');
video.removeAttribute('webkit-playsinline');
video.playsInline = false;
} else {
if (playerHome && video.parentElement !== playerHome) {
playerHome.appendChild(video);
}
playerMode = 'modal';
video.setAttribute('playsinline', '');
video.setAttribute('webkit-playsinline', '');
video.playsInline = true;
}
const requestFullscreen = () => {
if (playerMode !== 'mobile') return;
if (typeof video.webkitEnterFullscreen === 'function') {
try {
video.webkitEnterFullscreen();
} catch (err) {
// Ignore if fullscreen is not allowed.
}
return;
}
if (video.requestFullscreen) {
video.requestFullscreen().catch(() => {});
}
};
const startPlayback = () => {
if (playbackStarted) return;
playbackStarted = true;
const playPromise = video.play();
if (playPromise && typeof playPromise.catch === 'function') {
playPromise.catch(() => {});
}
if (playerMode === 'mobile') {
if (video.readyState >= 1) {
requestFullscreen();
} else {
video.addEventListener('loadedmetadata', requestFullscreen, { once: true });
}
}
};
if (isHls) {
if (window.Hls && window.Hls.isSupported()) {
hlsPlayer = new window.Hls();
hlsPlayer.loadSource(streamUrl);
hlsPlayer.attachMedia(video);
hlsPlayer.on(window.Hls.Events.MANIFEST_PARSED, function() {
video.play();
startPlayback();
});
startPlayback();
hlsPlayer.on(window.Hls.Events.ERROR, function(event, data) {
if (data && data.fatal) {
showError('Unable to play this stream.');
@@ -291,6 +371,7 @@ async function openPlayer(url) {
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = streamUrl;
startPlayback();
} else {
console.error("HLS not supported in this browser.");
showError('HLS is not supported in this browser.');
@@ -298,6 +379,7 @@ async function openPlayer(url) {
}
} else {
video.src = streamUrl;
startPlayback();
}
video.onerror = () => {
@@ -305,8 +387,29 @@ async function openPlayer(url) {
closePlayer();
};
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
if (playerMode === 'modal') {
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
} else {
modal.style.display = 'none';
document.body.style.overflow = 'auto';
if (!onFullscreenChange) {
onFullscreenChange = () => {
if (playerMode === 'mobile' && !document.fullscreenElement) {
closePlayer();
}
};
}
document.addEventListener('fullscreenchange', onFullscreenChange);
if (!onWebkitEndFullscreen) {
onWebkitEndFullscreen = () => {
if (playerMode === 'mobile') {
closePlayer();
}
};
}
video.addEventListener('webkitendfullscreen', onWebkitEndFullscreen);
}
}
function closePlayer() {
@@ -316,11 +419,24 @@ function closePlayer() {
hlsPlayer.destroy();
hlsPlayer = null;
}
if (document.fullscreenElement && document.exitFullscreen) {
document.exitFullscreen().catch(() => {});
}
if (onFullscreenChange) {
document.removeEventListener('fullscreenchange', onFullscreenChange);
}
if (onWebkitEndFullscreen) {
video.removeEventListener('webkitendfullscreen', onWebkitEndFullscreen);
}
video.onerror = null;
video.pause();
video.src = '';
modal.style.display = 'none';
document.body.style.overflow = 'auto';
if (playerHome && video.parentElement !== playerHome) {
playerHome.appendChild(video);
}
playerMode = 'modal';
}
function handleSearch(value) {