mirror of
https://github.com/p-stream/p-stream.git
synced 2026-01-11 20:10:32 +00:00
Improve autoplay handling after PiP and fullscreen on iOS
Adds logic to attempt autoplay when entering Picture-in-Picture or fullscreen modes, particularly to address autoplay restrictions on iOS. Introduces a flag to track if autoplay should be retried after loading, and ensures the UI updates appropriately if autoplay remains blocked.
This commit is contained in:
parent
3b5a1bb76e
commit
c7dcec2560
1 changed files with 56 additions and 1 deletions
|
|
@ -96,6 +96,7 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
|||
let lastVolume = 1;
|
||||
let lastValidDuration = 0; // Store the last valid duration to prevent reset during source switches
|
||||
let lastValidTime = 0; // Store the last valid time to prevent reset during source switches
|
||||
let shouldAutoplayAfterLoad = false; // Flag to track if we should autoplay after loading completes
|
||||
|
||||
const languagePromises = new Map<
|
||||
string,
|
||||
|
|
@ -335,6 +336,15 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
|||
isPictureInPicture = isInWebkitPip;
|
||||
// Use native tracks in WebKit PiP mode for iOS compatibility
|
||||
emit("needstrack", isInWebkitPip);
|
||||
|
||||
// On iOS, entering PiP may allow autoplay that was previously blocked
|
||||
if (isInWebkitPip && videoElement.paused && shouldAutoplayAfterLoad) {
|
||||
shouldAutoplayAfterLoad = false;
|
||||
videoElement.play().catch(() => {
|
||||
// If still blocked, emit pause to show play button
|
||||
emit("pause", undefined);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setSource() {
|
||||
|
|
@ -356,7 +366,22 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
|||
});
|
||||
videoElement.addEventListener("playing", () => emit("play", undefined));
|
||||
videoElement.addEventListener("pause", () => emit("pause", undefined));
|
||||
videoElement.addEventListener("canplay", () => emit("loading", false));
|
||||
videoElement.addEventListener("canplay", () => {
|
||||
emit("loading", false);
|
||||
// Attempt autoplay if this was an autoplay transition (startAt = 0)
|
||||
if (shouldAutoplayAfterLoad && startAt === 0 && videoElement) {
|
||||
shouldAutoplayAfterLoad = false; // Reset the flag
|
||||
// Try to play - this will work on most platforms, but iOS may block it
|
||||
const playPromise = videoElement.play();
|
||||
if (playPromise !== undefined) {
|
||||
playPromise.catch(() => {
|
||||
// Play was blocked (likely iOS), emit that we're not playing
|
||||
// The AutoPlayStart component will show a play button
|
||||
emit("pause", undefined);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
videoElement.addEventListener("waiting", () => emit("loading", true));
|
||||
videoElement.addEventListener("volumechange", () =>
|
||||
emit(
|
||||
|
|
@ -465,6 +490,20 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
|||
!!(document as any).webkitFullscreenElement; // safari
|
||||
emit("fullscreen", isFullscreen);
|
||||
if (!isFullscreen) emit("needstrack", false);
|
||||
|
||||
// On iOS, entering fullscreen may allow autoplay that was previously blocked
|
||||
if (
|
||||
isFullscreen &&
|
||||
videoElement &&
|
||||
videoElement.paused &&
|
||||
shouldAutoplayAfterLoad
|
||||
) {
|
||||
shouldAutoplayAfterLoad = false;
|
||||
videoElement.play().catch(() => {
|
||||
// If still blocked, emit pause to show play button
|
||||
emit("pause", undefined);
|
||||
});
|
||||
}
|
||||
}
|
||||
fscreen.addEventListener("fullscreenchange", fullscreenChange);
|
||||
|
||||
|
|
@ -472,6 +511,20 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
|||
isPictureInPicture = !!document.pictureInPictureElement;
|
||||
// Use native tracks in PiP mode for better compatibility with iOS and other platforms
|
||||
emit("needstrack", isPictureInPicture);
|
||||
|
||||
// Entering PiP may allow autoplay that was previously blocked
|
||||
if (
|
||||
isPictureInPicture &&
|
||||
videoElement &&
|
||||
videoElement.paused &&
|
||||
shouldAutoplayAfterLoad
|
||||
) {
|
||||
shouldAutoplayAfterLoad = false;
|
||||
videoElement.play().catch(() => {
|
||||
// If still blocked, emit pause to show play button
|
||||
emit("pause", undefined);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("enterpictureinpicture", pictureInPictureChange);
|
||||
|
|
@ -502,6 +555,8 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
|||
source = ops.source;
|
||||
emit("loading", true);
|
||||
startAt = ops.startAt;
|
||||
// Set autoplay flag if starting from beginning (indicates autoplay transition)
|
||||
shouldAutoplayAfterLoad = ops.startAt === 0;
|
||||
setSource();
|
||||
},
|
||||
changeQuality(newAutomaticQuality, newPreferredQuality) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue