From 3b7429cab960f854df68c2897b2db6a6a576498b Mon Sep 17 00:00:00 2001 From: Oliver Foster Date: Mon, 6 Jan 2025 16:52:46 +0000 Subject: [PATCH 1/3] DefaultSeek, event.target and import await --- js/mediaView.js | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/js/mediaView.js b/js/mediaView.js index fd5fd80..1b0ff3d 100644 --- a/js/mediaView.js +++ b/js/mediaView.js @@ -10,12 +10,12 @@ import './mediaLibrariesOverrides'; // instruct adapt to wait whilst loading client-side libraries wait.for(async done => { // load plugins - import('libraries/plugins/speed'); - import('libraries/plugins/speed-i18n'); - import('libraries/plugins/jump-forward'); - import('libraries/plugins/jump-forward-i18n'); - import('libraries/plugins/skip-back'); - import('libraries/plugins/skip-back-i18n'); + await import('libraries/plugins/speed'); + await import('libraries/plugins/speed-i18n'); + await import('libraries/plugins/jump-forward'); + await import('libraries/plugins/jump-forward-i18n'); + await import('libraries/plugins/skip-back'); + await import('libraries/plugins/skip-back-i18n'); done(); }); @@ -114,12 +114,12 @@ class MediaView extends ComponentView { } } - /* - Unless we are on Android/iOS and using native controls, when MediaElementJS initializes the player - it will invoke the success callback prior to performing one last call to setPlayerSize. - This call to setPlayerSize is deferred by 50ms so we add a delay of 100ms here to ensure that - we don't invoke setReadyStatus until the player is definitely finished rendering. - */ + /** + * Unless we are on Android/iOS and using native controls, when MediaElementJS initializes the player + * it will invoke the success callback prior to performing one last call to setPlayerSize. + * This call to setPlayerSize is deferred by 50ms so we add a delay of 100ms here to ensure that + * we don't invoke setReadyStatus until the player is definitely finished rendering. + */ modelOptions.success = _.debounce(this.onPlayerReady.bind(this), 100); if (this.model.get('_useClosedCaptions')) { @@ -149,6 +149,19 @@ class MediaView extends ComponentView { */ modelOptions.keyActions = []; + /** + * Convert string seek functions into compiled functions + */ + if (typeof modelOptions.defaultSeekBackwardInterval === 'string') { + // eslint-disable-next-line no-new-func + modelOptions.defaultSeekBackwardInterval = new Function('media', `return ${modelOptions.defaultSeekBackwardInterval}`); + } + + if (typeof modelOptions.defaultSeekForwardInterval === 'string') { + // eslint-disable-next-line no-new-func + modelOptions.defaultSeekForwardInterval = new Function('media', `return ${modelOptions.defaultSeekBackwardInterval}`); + } + return modelOptions; } @@ -330,8 +343,9 @@ class MediaView extends ComponentView { if (!maxViewed) { maxViewed = 0; } - if (event.target.currentTime <= maxViewed) return; - event.target.currentTime = maxViewed; + const target = event.currentTarget; + if (target.currentTime <= maxViewed) return; + target.currentTime = maxViewed; } onMediaElementTimeUpdate(event) { @@ -339,8 +353,9 @@ class MediaView extends ComponentView { if (!maxViewed) { maxViewed = 0; } - if (event.target.currentTime <= maxViewed) return; - this.model.set('_maxViewed', event.target.currentTime); + const target = event.currentTarget; + if (target.currentTime <= maxViewed) return; + this.model.set('_maxViewed', target.currentTime); } onMediaStop(view) { From 87899f455107fa7ea09eb8082900bbf7da85375e Mon Sep 17 00:00:00 2001 From: Oliver Foster Date: Mon, 6 Jan 2025 17:04:43 +0000 Subject: [PATCH 2/3] PreventForward scrubbing android --- js/mediaView.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/mediaView.js b/js/mediaView.js index 1b0ff3d..36bea35 100644 --- a/js/mediaView.js +++ b/js/mediaView.js @@ -49,7 +49,10 @@ class MediaView extends ComponentView { 'media:stop': this.onMediaStop }); - _.bindAll(this, 'onMediaElementPlay', 'onMediaElementPause', 'onMediaElementEnded', 'onMediaVolumeChange', 'onMediaElementTimeUpdate', 'onMediaElementSeeking', 'onOverlayClick', 'onMediaElementClick', 'onWidgetInview'); + // android, force timeupdate handler to call after seeking handler in order to prevent forward scrubbing + this.onMediaElementTimeUpdate = _.debounce(this.onMediaElementTimeUpdate.bind(this), 0); + + _.bindAll(this, 'onMediaElementPlay', 'onMediaElementPause', 'onMediaElementEnded', 'onMediaVolumeChange', 'onMediaElementSeeking', 'onOverlayClick', 'onMediaElementClick', 'onWidgetInview'); // set initial player state attributes this.model.set({ From 0338a1279a8f281ab6bb67fca77bc78c95bc1ad7 Mon Sep 17 00:00:00 2001 From: Oliver Foster Date: Tue, 7 Jan 2025 11:19:33 +0000 Subject: [PATCH 3/3] Fullscreen inview fix --- js/mediaLibrariesOverrides.js | 44 ++++++++--------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/js/mediaLibrariesOverrides.js b/js/mediaLibrariesOverrides.js index 76334a3..6bf970a 100644 --- a/js/mediaLibrariesOverrides.js +++ b/js/mediaLibrariesOverrides.js @@ -1,5 +1,4 @@ import Adapt from 'core/js/adapt'; -import device from 'core/js/device'; import 'libraries/mediaelement-and-player'; /** @@ -61,40 +60,17 @@ Adapt.on('app:dataReady', () => { * and switch it back on again after exiting full screen mode */ const mepPrototype = Object.assign({}, window.mejs.MediaElementPlayer.prototype); - Object.assign(window.mejs.MediaElementPlayer.prototype, { - detectFullscreenMode() { - const vendorPrefix = this.getVendorPrefix(); - const fsEventName = 'on' + vendorPrefix + 'fullscreenchange'; - - if (document[fsEventName] === null) { - document[fsEventName] = function fullScreenEventHandler() { - - const elementName = (vendorPrefix === '' ? 'fullscreenElement' : vendorPrefix + 'FullscreenElement'); - - if (document[elementName] !== null) { - $.inview.lock('mediaelement'); - Adapt.trigger('media:fullscreen:enter'); - } else { - $.inview.unlock('mediaelement'); - Adapt.trigger('media:fullscreen:exit'); - } - }; - } - return mepPrototype.detectFullscreenMode.apply(this, arguments); + enterFullScreen(...args) { + $.inview.lock('mediaelement'); + Adapt.trigger('media:fullscreen:enter'); + return mepPrototype.enterFullScreen.call(this, ...args); }, - - /** - * Fullscreen events and properties are still vendor-prefixed in some browsers. - * https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenchange_event#browser_compatibility - */ - getVendorPrefix() { - const browser = device.browser; - - if (browser === 'safari') { - return 'webkit'; - } - - return ''; + exitFullScreen(...args) { + setTimeout(() => { + $.inview.unlock('mediaelement'); + Adapt.trigger('media:fullscreen:exit'); + }, 250); + return mepPrototype.exitFullScreen.call(this, ...args); } });