pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

Pas c7dcec25 3b5a1bb7

+56 -1
+56 -1
src/components/player/display/base.ts
··· 96 96 let lastVolume = 1; 97 97 let lastValidDuration = 0; // Store the last valid duration to prevent reset during source switches 98 98 let lastValidTime = 0; // Store the last valid time to prevent reset during source switches 99 + let shouldAutoplayAfterLoad = false; // Flag to track if we should autoplay after loading completes 99 100 100 101 const languagePromises = new Map< 101 102 string, ··· 335 336 isPictureInPicture = isInWebkitPip; 336 337 // Use native tracks in WebKit PiP mode for iOS compatibility 337 338 emit("needstrack", isInWebkitPip); 339 + 340 + // On iOS, entering PiP may allow autoplay that was previously blocked 341 + if (isInWebkitPip && videoElement.paused && shouldAutoplayAfterLoad) { 342 + shouldAutoplayAfterLoad = false; 343 + videoElement.play().catch(() => { 344 + // If still blocked, emit pause to show play button 345 + emit("pause", undefined); 346 + }); 347 + } 338 348 } 339 349 340 350 function setSource() { ··· 356 366 }); 357 367 videoElement.addEventListener("playing", () => emit("play", undefined)); 358 368 videoElement.addEventListener("pause", () => emit("pause", undefined)); 359 - videoElement.addEventListener("canplay", () => emit("loading", false)); 369 + videoElement.addEventListener("canplay", () => { 370 + emit("loading", false); 371 + // Attempt autoplay if this was an autoplay transition (startAt = 0) 372 + if (shouldAutoplayAfterLoad && startAt === 0 && videoElement) { 373 + shouldAutoplayAfterLoad = false; // Reset the flag 374 + // Try to play - this will work on most platforms, but iOS may block it 375 + const playPromise = videoElement.play(); 376 + if (playPromise !== undefined) { 377 + playPromise.catch(() => { 378 + // Play was blocked (likely iOS), emit that we're not playing 379 + // The AutoPlayStart component will show a play button 380 + emit("pause", undefined); 381 + }); 382 + } 383 + } 384 + }); 360 385 videoElement.addEventListener("waiting", () => emit("loading", true)); 361 386 videoElement.addEventListener("volumechange", () => 362 387 emit( ··· 465 490 !!(document as any).webkitFullscreenElement; // safari 466 491 emit("fullscreen", isFullscreen); 467 492 if (!isFullscreen) emit("needstrack", false); 493 + 494 + // On iOS, entering fullscreen may allow autoplay that was previously blocked 495 + if ( 496 + isFullscreen && 497 + videoElement && 498 + videoElement.paused && 499 + shouldAutoplayAfterLoad 500 + ) { 501 + shouldAutoplayAfterLoad = false; 502 + videoElement.play().catch(() => { 503 + // If still blocked, emit pause to show play button 504 + emit("pause", undefined); 505 + }); 506 + } 468 507 } 469 508 fscreen.addEventListener("fullscreenchange", fullscreenChange); 470 509 ··· 472 511 isPictureInPicture = !!document.pictureInPictureElement; 473 512 // Use native tracks in PiP mode for better compatibility with iOS and other platforms 474 513 emit("needstrack", isPictureInPicture); 514 + 515 + // Entering PiP may allow autoplay that was previously blocked 516 + if ( 517 + isPictureInPicture && 518 + videoElement && 519 + videoElement.paused && 520 + shouldAutoplayAfterLoad 521 + ) { 522 + shouldAutoplayAfterLoad = false; 523 + videoElement.play().catch(() => { 524 + // If still blocked, emit pause to show play button 525 + emit("pause", undefined); 526 + }); 527 + } 475 528 } 476 529 477 530 document.addEventListener("enterpictureinpicture", pictureInPictureChange); ··· 502 555 source = ops.source; 503 556 emit("loading", true); 504 557 startAt = ops.startAt; 558 + // Set autoplay flag if starting from beginning (indicates autoplay transition) 559 + shouldAutoplayAfterLoad = ops.startAt === 0; 505 560 setSource(); 506 561 }, 507 562 changeQuality(newAutomaticQuality, newPreferredQuality) {