Skip to content

Commit e8cd04d

Browse files
committed
fix bug where multiple videos started simultaneously sometimes failed to render in mobile safari
1 parent 5412639 commit e8cd04d

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

dist/reveal.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/reveal.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/controllers/slidecontent.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default class SlideContent {
1414
this.Reveal = Reveal;
1515

1616
this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
17+
this.ensureMobileMediaPlaying = this.ensureMobileMediaPlaying.bind( this );
1718

1819
}
1920

@@ -320,6 +321,8 @@ export default class SlideContent {
320321
else if( isMobile ) {
321322
let promise = el.play();
322323

324+
el.addEventListener( 'canplay', this.ensureMobileMediaPlaying );
325+
323326
// If autoplay does not work, ensure that the controls are visible so
324327
// that the viewer can start the media on their own
325328
if( promise && typeof promise.catch === 'function' && el.controls === false ) {
@@ -374,6 +377,40 @@ export default class SlideContent {
374377

375378
}
376379

380+
/**
381+
* Ensure that an HTMLMediaElement is playing on mobile devices.
382+
*
383+
* This is a workaround for a bug in mobile Safari where
384+
* the media fails to display if many videos are started
385+
* at the same moment. When this happens, Mobile Safari
386+
* reports the video is playing, and the current time
387+
* advances, but nothing is visible.
388+
*
389+
* @param {Event} event
390+
*/
391+
ensureMobileMediaPlaying( event ) {
392+
393+
const el = event.target;
394+
395+
// Ignore this check incompatible browsers
396+
if( typeof el.getVideoPlaybackQuality !== 'function' ) {
397+
return;
398+
}
399+
400+
setTimeout( () => {
401+
402+
const playing = el.paused === false;
403+
const totalFrames = el.getVideoPlaybackQuality().totalVideoFrames;
404+
405+
if( playing && totalFrames === 0 ) {
406+
el.load();
407+
el.play();
408+
}
409+
410+
}, 1000 );
411+
412+
}
413+
377414
/**
378415
* Starts playing an embedded video/audio element after
379416
* it has finished loading.
@@ -461,6 +498,10 @@ export default class SlideContent {
461498
if( !el.hasAttribute( 'data-ignore' ) && typeof el.pause === 'function' ) {
462499
el.setAttribute('data-paused-by-reveal', '');
463500
el.pause();
501+
502+
if( isMobile ) {
503+
el.removeEventListener( 'canplay', this.ensureMobileMediaPlaying );
504+
}
464505
}
465506
} );
466507

0 commit comments

Comments
 (0)