1
0
mirror of https://github.com/hakimel/reveal.js.git synced 2025-09-01 18:54:29 +02:00

fix bug where multiple videos started simultaneously sometimes failed to render in mobile safari

This commit is contained in:
Hakim El Hattab
2025-08-26 19:49:24 +02:00
parent 5412639a54
commit e8cd04da83
3 changed files with 43 additions and 2 deletions

2
dist/reveal.js vendored

File diff suppressed because one or more lines are too long

2
dist/reveal.js.map vendored

File diff suppressed because one or more lines are too long

View File

@@ -14,6 +14,7 @@ export default class SlideContent {
this.Reveal = Reveal; this.Reveal = Reveal;
this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this ); this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
this.ensureMobileMediaPlaying = this.ensureMobileMediaPlaying.bind( this );
} }
@@ -320,6 +321,8 @@ export default class SlideContent {
else if( isMobile ) { else if( isMobile ) {
let promise = el.play(); let promise = el.play();
el.addEventListener( 'canplay', this.ensureMobileMediaPlaying );
// If autoplay does not work, ensure that the controls are visible so // If autoplay does not work, ensure that the controls are visible so
// that the viewer can start the media on their own // that the viewer can start the media on their own
if( promise && typeof promise.catch === 'function' && el.controls === false ) { if( promise && typeof promise.catch === 'function' && el.controls === false ) {
@@ -374,6 +377,40 @@ export default class SlideContent {
} }
/**
* Ensure that an HTMLMediaElement is playing on mobile devices.
*
* This is a workaround for a bug in mobile Safari where
* the media fails to display if many videos are started
* at the same moment. When this happens, Mobile Safari
* reports the video is playing, and the current time
* advances, but nothing is visible.
*
* @param {Event} event
*/
ensureMobileMediaPlaying( event ) {
const el = event.target;
// Ignore this check incompatible browsers
if( typeof el.getVideoPlaybackQuality !== 'function' ) {
return;
}
setTimeout( () => {
const playing = el.paused === false;
const totalFrames = el.getVideoPlaybackQuality().totalVideoFrames;
if( playing && totalFrames === 0 ) {
el.load();
el.play();
}
}, 1000 );
}
/** /**
* Starts playing an embedded video/audio element after * Starts playing an embedded video/audio element after
* it has finished loading. * it has finished loading.
@@ -461,6 +498,10 @@ export default class SlideContent {
if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) { if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
el.setAttribute('data-paused-by-reveal', ''); el.setAttribute('data-paused-by-reveal', '');
el.pause(); el.pause();
if( isMobile ) {
el.removeEventListener( 'canplay', this.ensureMobileMediaPlaying );
}
} }
} ); } );