UNPKG

@lawchihon/videojs-dailymotion

Version:
557 lines (460 loc) 15.1 kB
/*global define, DM*/ (function (root, factory) { if (typeof window !== 'undefined' && window.videojs) { factory(window.videojs); } else if (typeof exports==='object' && typeof module!=='undefined') { var videojs = require('video.js'); module.exports = factory(videojs.default || videojs); } else if (typeof define === 'function' && define.amd) { define(['videojs'], function(videojs){ return (root.Dailymotion = factory(videojs)); }); } else { root.Dailymotion = factory(root.videojs); } }(this, function(videojs) { 'use strict'; var _isOnMobile = videojs.browser.IS_IOS || videojs.browser.IS_NATIVE_ANDROID; var Tech = videojs.getTech('Tech'); var Dailymotion = videojs.extend(Tech, { constructor: function(options, ready) { Tech.call(this, options, ready); this.setSrc(this.options_.source); // Set the vjs-dailymotion class to the player // Parent is not set yet so we have to wait a tick var vm = this; setTimeout(function() { if (this.el_) { this.el_.parentNode.className += ' vjs-dailymotion'; if (_isOnMobile) { this.el_.parentNode.className += ' vjs-dailymotion-mobile'; } if (Dailymotion.isSdkReady) { vm.initDMPlayer(); } else { Dailymotion.sdkReadyQueue.push(vm); } } }.bind(this)); }, _getPlayerParams: function() { var playerParams = { autoplay: false, mute: false, 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: function() { 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; }, initDMPlayer: function() { if (this.dmPlayer) { return; } this.dmPlayer = new DM.player( document.getElementById(this.options_.techId), this._getPlayerConfig() ); var vm = this; this.isApiReady = false; this.dmPlayer.addEventListener('apiready', function() { vm.triggerReady(); vm.isApiReady = true; }); this.dmPlayer.addEventListener('durationchange', function() { vm.trigger('durationchange'); }); this.dmPlayer.addEventListener('end', function() { vm.trigger('ended'); }); this.dmPlayer.addEventListener('error', function() { vm.trigger('error'); }); this.dmPlayer.addEventListener('loadedmetadata', function() { vm.trigger('loadeddata'); vm.trigger('loadedmetadata'); }); this.dmPlayer.addEventListener('pause', function() { vm.trigger('pause'); }); this.dmPlayer.addEventListener('play', function() { vm.trigger('loadStart'); vm.trigger('play'); vm.trigger('playing'); vm.trigger('waiting'); }); this.dmPlayer.addEventListener('playback_ready', function() { vm.trigger('loadeddata'); }); this.dmPlayer.addEventListener('timeupdate', function() { vm.trigger('timeupdate'); }); this.dmPlayer.addEventListener('volumechange', function() { vm.trigger('volumechange'); }); }, autoplay: function(autoplay) { if (typeof autoplay !== 'undefined') { return this.setAutoplay(autoplay); } return this.options_.autoplay; }, setAutoplay: function(val) { return this.options_.autoplay = val; }, buffered: function() { if(!this.dmPlayer || !this.dmPlayer.bufferedTime) { return videojs.createTimeRange(); } return videojs.createTimeRange(0, this.dmPlayer.bufferedTime); }, createEl: function() { 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: function() { return this.source && this.source.src; }, currentTime: function(seconds) { if (typeof seconds !== 'undefined') { return this.setCurrentTime(seconds); } return this.dmPlayer && this.dmPlayer.currentTime; }, setCurrentTime: function(seconds) { if (!this.dmPlayer || !this.dmPlayer.seek) { return; } return this.dmPlayer.seek(seconds); }, dispose: function() { if (DM && DM.destroy) { //Destroy the Dailymotion Player DM.destroy(this.options_.techId); } 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: function(seconds) { if (typeof seconds !== 'undefined') { return this.setDuration(seconds); } return this.dmPlayer ? this.dmPlayer.duration : 0; }, setDuration: function(seconds) { if (!this.dmPlayer || !this.dmPlayer.seek) { return; } return this.dmPlayer.seek(seconds); }, ended: function() { return this.dmPlayer && this.dmPlayer.ended; }, enterFullWindow: function() { if (!this.dmPlayer || !this.dmPlayer.setFullscreen) { return; } return this.dmPlayer.setFullscreen(true); }, error: function() { return this.dmPlayer && this.dmPlayer.error; }, exitFullscreen: function() { if (!this.dmPlayer || !this.dmPlayer.setFullscreen) { return; } return this.dmPlayer.setFullscreen(false); }, isFullscreen: function() { return this.dmPlayer && this.dmPlayer.fullscreen; }, // Not supported by Dailymotion language: function() { return undefined; }, // Not supported by Dailymotion languages: function() { return undefined; }, load: function() { if (!this.dmPlayer || !this.dmPlayer.load) { return; } return this.dmPlayer.load(this._getPlayerConfig()); }, // Not supported by Dailymotion loop: function() { return undefined; }, muted: function(muted) { if (typeof muted !== undefined) { return this.setMuted(muted); } return this.dmPlayer && this.dmPlayer.mute; }, setMuted: function(mute) { if (typeof mute === 'undefined' || !this.dmPlayer || !this.dmPlayer.setMuted) { return; } if (mute) { this.volumeBeforeMute = this.volume(); this.setVolume(0); } else { this.setVolume(this.volumeBeforeMute); } this.dmPlayer.setMuted(mute); // var vm = this; // setTimeout( function(){ // vm.trigger('volumechange'); // }, 50); }, networkState: function () { if (!this.dmPlayer || this.dmPlayer.error) { return 0; //NETWORK_EMPTY } if (this.dmPlayer.seeking) { return 2; //NETWORK_LOADING } }, pause: function() { if (!this.dmPlayer || !this.dmPlayer.pause) { return; } return this.dmPlayer.pause(); }, paused: function() { return this.dmPlayer && this.dmPlayer.paused; }, play: function() { if (!this.isApiReady || !this.dmPlayer || !this.dmPlayer.play) { return; } this.trigger('loadStart'); this.trigger('waiting'); return this.dmPlayer.play(); }, // Playback rate is not support by Dailymotion playbackRate: function() { return 1; }, // Not supported by Dailymotion poster: function() { return undefined; }, // Not supported by Dailymotion preload: function() { return undefined; }, // TODO: Confirm if it can be more detail readyState: function() { if (!this.dmPlayer || this.dmPlayer.error) { return 0; //NETWORK_EMPTY } if (this.dmPlayer.seeking) { return 1; //HAVE_METADATA } return 4; //HAVE_ENOUGH_DATA }, remainingTime: function() { return this.dmPlayer && (this.dmPlayer.duration - this.dmPlayer.currentTime); }, requestFullscreen: function() { return this.enterFullWindow(); }, enterFullScreen: function() { return this.enterFullWindow(); }, reset: function() { this.load(); }, seekable: function () { if(!this.dmPlayer) { return videojs.createTimeRange(); } return videojs.createTimeRange(0, this.dmPlayer.duration); }, seeking: function () { return this.dmPlayer && this.dmPlayer.seeking; }, src: function(source) { if (typeof source !== 'undefined') { return this.setSrc(source); } return this.source; }, setSrc: function(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: function() { return true; }, volume: function() { return this.dmPlayer ? this.dmPlayer.volume : 1; }, setVolume: function(percentAsDecimal) { if (!this.dmPlayer || !this.dmPlayer.setMuted || !this.dmPlayer.setVolume) { return; } this.dmPlayer.setMuted(false); this.dmPlayer.setVolume(percentAsDecimal); }, }); 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; }; function apiLoaded() { Dailymotion.isSdkReady = true; for (var i = 0; i < Dailymotion.sdkReadyQueue.length; ++i) { 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 = []; if (typeof document !== 'undefined'){ loadScript('https://api.dmcdn.net/all.js', apiLoaded); injectCss(); } // Older versions of VJS5 doesn't have the registerTech function if (typeof videojs.registerTech !== 'undefined') { videojs.registerTech('Dailymotion', Dailymotion); } else { videojs.registerComponent('Dailymotion', Dailymotion); } }));