diff -r 92cb33eb7a75 -r 510fd2a482f4 src/widgets/videojs_plugins/Dailymotion.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/videojs_plugins/Dailymotion.js Tue Oct 22 07:03:54 2024 +0200 @@ -0,0 +1,546 @@ +// Adapted from https://github.com/lawchihon/videojs-dailymotion +/*global define, dailymotion*/ +import videojs from "video.js"; + +var _isOnMobile = videojs.browser.IS_IOS || videojs.browser.IS_NATIVE_ANDROID; +var Tech = videojs.getTech("Tech"); + + +class Dailymotion extends Tech { + constructor(options, ready) { + super(options, ready); + + this.setSrc(this.options_.source); + console.log(this.options_.source) + + // Set the vjs-dailymotion class to the player + // Parent is not set yet so we have to wait a tick + setTimeout( () => { + if (this.el_) { + this.el_.parentNode.className += " vjs-dailymotion"; + + if (_isOnMobile) { + this.el_.parentNode.className += " vjs-dailymotion-mobile"; + } + + if (Dailymotion.isSdkReady) { + this.initDMPlayer(); + } else { + Dailymotion.sdkReadyQueue.push(this); + } + } + }); + }; + + _getPlayerParams() { + var playerParams = { + autoplay: false, + mute: false, + controls: false, + "enable-playback-controls": false, + "queue-autoplay-next": false, + "queue-enable": false, + }; + // Let the user set any Dailymotion parameter + // https://developer.dailymotion.com/player/#player-parameters + // To use Dailymotion controls, you must use dmControls instead + + var params = [ + "api", + "autoplay", + "autoplay-mute", + "id", + "mute", + "origin", + "quality", + "queue-autoplay-next", + "queue-enable", + "sharing-enable", + "start", + "subtitles-default", + "syndication", + "ui-highlight", + "ui-logo", + "ui-start-screen-info", + "ui-theme", + "apimode", + "playlist", + ]; + var options = this.options_; + params.forEach(function (param) { + if (typeof options[param] === "undefined") { + return; + } + playerParams[param] = options[param]; + }); + + if (typeof this.options_.dmControls !== "undefined") { + playerParams.controls = this.options_.dmControls; + } + + // Overwriting playlist if it is included in url + if (this.url && typeof this.url.playlist !== "undefined") { + playerParams.playlist = this.url.playlist; + } + + // Allow undocumented options to be passed along via customVars + if (typeof this.options_.customVars !== "undefined") { + var customVars = this.options_.customVars; + Object.keys(customVars).forEach(function (key) { + playerParams[key] = customVars[key]; + }); + } + + return playerParams; + } + + _getPlayerConfig() { + var playerConfig = { + width: "100%", + height: "100%", + params: this._getPlayerParams(), + }; + + if (this.url && typeof this.url.video !== "undefined") { + playerConfig.video = this.url.video; + } else if (typeof this.options_.video !== "undefined") { + playerConfig.video = this.options_.video; + } + + return playerConfig; + } + + async initDMPlayer() { + console.log("INIT DM Player", this._getPlayerConfig()); + if (this.dmPlayer) { + return; + } + const eventMapping = { + [dailymotion.events.VIDEO_DURATIONCHANGE]: [ "durationchange" ], + [dailymotion.events.PLAYER_END]: [ "ended" ], + [dailymotion.events.PLAYER_ERROR]: [ "error" ], + [dailymotion.events.PLAYER_VIDEOCHANGE]: [ "loadeddata", "loadedmetadata"], + [dailymotion.events.VIDEO_PAUSE]: [ "pause" ], + //[dailymotion.events.VIDEO_PLAY]: [ "loadstart", "play", "playing", "waiting" ], + [dailymotion.events.VIDEO_PLAY]: [ "loadstart", "play", "playing" ], + [dailymotion.events.VIDEO_PLAYING]: [ "playing" ], + [dailymotion.events.VIDEO_TIMECHANGE]: [ "timeupdate" ], + [dailymotion.events.PLAYER_VOLUMECHANGE]: [ "volumechange", "mute" ], + }; + this.dmPlayer = await dailymotion.createPlayer( + this.options_.techId, + this._getPlayerConfig() + ); + this.dmState = await this.getPlayerState(); + //var vm = this; + this.isApiReady = true; + this.dmPlayer.enable_playback_controls = false; + console.log("AUTONEXT", this.dmPlayer.enable_playback_controls); + + for (const ev in eventMapping) { + this.dmPlayer.on(ev, (s) => { + this.dmState = s; + for (const tev of eventMapping[ev]) { + this.trigger(tev) + } + }); + } + this.dmPlayer.on(dailymotion.events.PLAYER_ERROR, (s) => { + vm.trigger("error", s.playerError); + }); + this.triggerReady(); + } + + autoplay(autoplay) { + if (typeof autoplay !== "undefined") { + return this.setAutoplay(autoplay); + } + + return this.options_.autoplay; + } + + setAutoplay(val) { + return (this.options_.autoplay = val); + } + + buffered() { + if (!this.dmPlayer || !this.dmPlayer.bufferedTime) { + return videojs.createTimeRange(); + } + + return videojs.createTimeRange(0, this.dmPlayer.bufferedTime); + } + + createEl() { + var div = document.createElement("div"); + div.setAttribute("id", this.options_.techId); + div.setAttribute( + "style", + "width:100%;height:100%;top:0;left:0;position:absolute" + ); + div.setAttribute("class", "vjs-tech"); + + var divWrapper = document.createElement("div"); + divWrapper.appendChild(div); + + if (!_isOnMobile && !this.options_.dmControls) { + // var divBlocker = document.createElement('div'); + // divBlocker.setAttribute('class', 'vjs-iframe-blocker'); + // divBlocker.setAttribute('style', 'position:absolute;top:0;left:0;width:100%;height:100%'); + // + // // In case the blocker is still there and we want to pause + // divBlocker.onclick = function() { + // this.pause(); + // }.bind(this); + // + // divWrapper.appendChild(divBlocker); + } + + return divWrapper; + } + + currentSrc() { + return this.source && this.source.src; + } + + currentTime() { + + return this.dmPlayer && this.dmState && this.dmState.videoTime; + } + + setCurrentTime(seconds) { + if (!this.dmPlayer || !this.dmPlayer.seek) { + return; + } + + return this.dmPlayer.seek(seconds); + } + + dispose() { + if (this.dmPlayer) { + //Destroy the Dailymotion Player + this.dmPlayer.destroy(this.options_.techId); + Tech.prototype.dispose.call(this); + } else { + //Dailymotion API hasn't finished loading or the player is already disposed + var index = Dailymotion.sdkReadyQueue.indexOf(this); + if (index !== -1) { + Dailymotion.sdkReadyQueue.splice(index, 1); + } + } + this.dmPlayer = undefined; + + this.el_.parentNode.className = this.el_.parentNode.className + .replace(" vjs-dailymotion", "") + .replace(" vjs-dailymotion-mobile", ""); + this.el_.parentNode.removeChild(this.el_); + + // Needs to be called after the Dailymotion player is destroyed, + // otherwise there will be a undefined reference exception + Tech.prototype.dispose.call(this); + } + + duration() { + return this.dmState ? this.dmState.videoDuration : 0; + } + + setDuration(seconds) { + } + + ended() { + } + + enterFullWindow() { + if (!this.dmPlayer || !this.dmPlayer.setFullscreen) { + return; + } + return this.dmPlayer.setFullscreen(true); + } + + error() { + return this.dmState && this.dmState.playerError; + } + + exitFullscreen() { + if (!this.dmPlayer || !this.dmPlayer.setFullscreen) { + return; + } + return this.dmPlayer.setFullscreen(false); + } + + isFullscreen() { + return this.dmState && this.dmState.playerPresentationMode === "fullscreen"; + } + + // Not supported by Dailymotion + language() { + } + + // Not supported by Dailymotion + languages() { + } + + load() { + if (!this.dmPlayer || !this.dmPlayer.loadContent) { + return; + } + return this.dmPlayer.loadContent(this._getPlayerConfig()); + } + + // Not supported by Dailymotion + loop() { + } + + async muted() { + + if(!this.dmState) { + return false; + } + return this.dmState.playerIsMuted; + } + + async setMuted(mute) { + if (typeof mute === "undefined") { + const state = await this.getPlayerState(); + mute = state.playerIsMuted ? false : true; + } + + await this.dmPlayer.setMute(mute); + } + + networkState() { + } + + async pause() { + if (!this.dmPlayer || !this.dmPlayer.pause) { + return; + } + + return await this.dmPlayer.pause(); + } + + paused() { + return this.dmState && this.dmState.playerIsPlaying === false; + } + + play() { + if (!this.isApiReady || !this.dmPlayer || !this.dmPlayer.play) { + return; + } + + return this.dmPlayer.play(); + } + + // Playback rate is not support by Dailymotion + playbackRate() { + return 1; + } + + // Not supported by Dailymotion + poster() { + return undefined; + } + + // Not supported by Dailymotion + preload() { + return undefined; + } + + // TODO: Confirm if it can be more detail + readyState() { + if (!this.dmState || this.dmState.playerError) { + return 0; //NETWORK_EMPTY + } + + return 4; //HAVE_ENOUGH_DATA + } + + remainingTime() { + return this.dmState && this.dmState.videoDuration - this.dmState.videoTime; + } + + requestFullscreen() { + return this.enterFullWindow(); + } + + enterFullScreen() { + return this.enterFullWindow(); + } + + reset() { + this.load(); + } + + seekable() { + } + + seeking() { + } + + src(source) { + if (typeof source !== "undefined") { + return this.setSrc(source); + } + + return this.source; + } + + setSrc(source) { + if (typeof source === "undefined") { + return; + } + + this.source = source; + this.url = Dailymotion.parseUrl(source.src || source); + + // Load the video if sdk is ready + if (Dailymotion.isSdkReady) { + this.load(); + } + return this.source; + } + + supportsFullScreen() { + return true; + } + + async volume() { + if(!this.dmPlayer ) { + return 1 + } + const state = await this.dmPlayer.getState(); + return state.playerVolume; + } + + setVolume(percentAsDecimal) { + if (!this.dmPlayer || !this.dmPlayer.setMute || !this.dmPlayer.setVolume) { + return; + } + + if (percentAsDecimal > 0) { + this.dmPlayer.setMute(false); + } else { + this.dmPlayer.setMute(true); + } + this.dmPlayer.setVolume(percentAsDecimal); + } + + async getPlayerState() { + if (!this.dmPlayer) { + return {}; + } + return await this.dmPlayer.getState(); + } +}; + +Dailymotion.isSupported = function () { + return true; +}; + +Dailymotion.canPlaySource = function (e) { + return Dailymotion.canPlayType(e.type); +}; + +Dailymotion.canPlayType = function (e) { + return e === "video/dailymotion"; +}; + +Dailymotion.parseUrl = function (url) { + var result = {}; + + var regex = /video\/[^?|^\/]*/; + var match = url.match(regex); + + if (match && match[0]) { + result.video = match[0].replace("video/", ""); + } + + var regPlaylist = /playlist(=|\/)[^&]*/; + match = url.match(regPlaylist); + + if (match && match[0]) { + result.playlist = match[0].replace(/playlist(=|\/)/, ""); + } + + return result; +}; + +async function apiLoaded() { + Dailymotion.isSdkReady = true; + + for (var i = 0; i < Dailymotion.sdkReadyQueue.length; ++i) { + await Dailymotion.sdkReadyQueue[i].initDMPlayer(); + } +} + +function loadScript(src, callback) { + var loaded = false; + var tag = document.createElement("script"); + var firstScriptTag = document.getElementsByTagName("script")[0]; + if (!firstScriptTag) { + // when loaded in jest without jsdom setup it doesn't get any element. + // In jest it doesn't really make sense to do anything, because no one is watching dailymotion in jest + return; + } + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + tag.onload = function () { + if (!loaded) { + loaded = true; + callback(); + } + }; + tag.onreadystatechange = function () { + if ( + !loaded && + (this.readyState === "complete" || this.readyState === "loaded") + ) { + loaded = true; + callback(); + } + }; + tag.src = src; +} + +function injectCss() { + var css = // iframe blocker to catch mouse events + ".vjs-dailymotion .vjs-iframe-blocker { display: none; }" + + ".vjs-dailymotion.vjs-user-inactive .vjs-iframe-blocker { display: block; }" + + ".vjs-dailymotion .vjs-poster { background-size: cover; }" + + ".vjs-dailymotion-mobile .vjs-big-play-button { display: none; }"; + + var head = document.head || document.getElementsByTagName("head")[0]; + + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + + if (style.styleSheet) { + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } + + head.appendChild(style); +} + +Dailymotion.sdkReadyQueue = []; + +// x10ckq +Dailymotion.loadLibrary = function(playerId) { + + if (typeof document !== "undefined") { + loadScript(`https://geo.dailymotion.com/libs/player/${playerId}.js`, () => { + if (window.dailymotion === undefined) { + window.dailymotion = { + onScriptLoaded: apiLoaded + } + } else { + apiLoaded(); + } + }); + injectCss(); + } +} + +videojs.registerTech("Dailymotion", Dailymotion); + +export default Dailymotion;