diff --git a/demo/index.html b/demo/index.html index 777611d9f..d351e3779 100644 --- a/demo/index.html +++ b/demo/index.html @@ -92,7 +92,7 @@

Player

>YouTube - and + , + and +

@@ -237,6 +241,15 @@

Player

+ diff --git a/demo/src/js/sources.js b/demo/src/js/sources.js index e21885af7..95b76d9e8 100644 --- a/demo/src/js/sources.js +++ b/demo/src/js/sources.js @@ -76,6 +76,15 @@ const sources = { }, ], }, + dailymotion: { + type: 'video', + sources: [ + { + src: 'https://www.dailymotion.com/video/x7tritx', + provider: 'dailymotion', + }, + ], + }, }; export default sources; diff --git a/src/js/captions.js b/src/js/captions.js index 98d7d6137..431b9507e 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -31,7 +31,7 @@ const captions = { } // Only Vimeo and HTML5 video supported at this point - if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) { + if (!this.isVideo || this.isYouTube || this.isDailyMotion || (this.isHTML5 && !support.textTracks)) { // Clear menu and hide if ( is.array(this.config.controls) && diff --git a/src/js/config/defaults.js b/src/js/config/defaults.js index 7a73c318a..1e18c2216 100644 --- a/src/js/config/defaults.js +++ b/src/js/config/defaults.js @@ -206,6 +206,11 @@ const defaults = { sdk: 'https://www.youtube.com/iframe_api', api: 'https://noembed.com/embed?url=https://www.youtube.com/watch?v={0}', }, + dailymotion: { + sdk: 'https://api.dmcdn.net/all.js', + api: + 'https://api.dailymotion.com/video/{0}?fields=aspect_ratio,duration,embed_url,height,thumbnail_1080_url,width,title', + }, googleIMA: { sdk: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js', }, @@ -440,6 +445,16 @@ const defaults = { customControls: true, noCookie: false, // Whether to use an alternative version of YouTube without cookies }, + + // DailyMotion plugin + dailymotion: { + api: 'postMessage', // Enable the Player API https://developer.dailymotion.com/player/#player-parameters + 'autoplay-mute': false, // Try to autoplay while muting the video if autoplay didn't work + syndication: '', // Syndication key for the player + 'ui-logo': false, // Hide the dailymotion logo + 'ui-start-screen-info': false, // Hide video information (title and owner) on the start screen + apimode: 'queryString', // How to encode/decode messages sent from the player. https://developer.dailymotion.com/player/#player-parameters + }, }; export default defaults; diff --git a/src/js/config/types.js b/src/js/config/types.js index 31e488eb8..1a760f02d 100644 --- a/src/js/config/types.js +++ b/src/js/config/types.js @@ -6,6 +6,7 @@ export const providers = { html5: 'html5', youtube: 'youtube', vimeo: 'vimeo', + dailymotion: 'dailymotion', }; export const types = { @@ -28,6 +29,11 @@ export function getProviderByUrl(url) { return providers.vimeo; } + // DailyMotion + if (/^(https?:\/\/)?(www\.)?(dailymotion\.com|dai\.ly)\/.+$/.test(url)) { + return providers.dailymotion; + } + return null; } diff --git a/src/js/media.js b/src/js/media.js index ddac5ebf3..5f929b733 100644 --- a/src/js/media.js +++ b/src/js/media.js @@ -3,6 +3,7 @@ // ========================================================================== import html5 from './html5'; +import dailymotion from './plugins/dailymotion'; import vimeo from './plugins/vimeo'; import youtube from './plugins/youtube'; import { createElement, toggleClass, wrap } from './utils/elements'; @@ -53,6 +54,8 @@ const media = { youtube.setup.call(this); } else if (this.isVimeo) { vimeo.setup.call(this); + } else if (this.isDailyMotion) { + dailymotion.setup.call(this); } }, }; diff --git a/src/js/plugins/dailymotion.js b/src/js/plugins/dailymotion.js new file mode 100644 index 000000000..e92b487e9 --- /dev/null +++ b/src/js/plugins/dailymotion.js @@ -0,0 +1,298 @@ +// ========================================================================== +// Dailymotion plugin +// ========================================================================== + +import ui from '../ui'; +import { createElement, replaceElement, toggleClass } from '../utils/elements'; +import { triggerEvent } from '../utils/events'; +import fetch from '../utils/fetch'; +import is from '../utils/is'; +import loadScript from '../utils/load-script'; +import { extend } from '../utils/objects'; +import { format } from '../utils/strings'; +import { setAspectRatio } from '../utils/style'; + +// Parse DailyMotion ID from URL +function parseId(url) { + if (is.empty(url)) { + return null; + } + + if (is.number(Number(url))) { + return url; + } + + const regex = /^.*(dai.ly\/|dailymotion.com\/|video\/)(\w+).*/; + return url.match(regex) ? RegExp.$2 : url; +} + +// Set playback state and trigger change (only on actual change) +function assurePlaybackState(play) { + if (play && !this.embed.hasPlayed) { + this.embed.hasPlayed = true; + } + if (this.media.paused === play) { + this.media.paused = !play; + triggerEvent.call(this, this.media, play ? 'play' : 'pause'); + } +} + +const dailymotion = { + setup() { + const player = this; + // Add embed class for responsive + toggleClass(player.elements.wrapper, player.config.classNames.embed, true); + + // Can't set speed for dailymotion + player.options.speed = [1]; + + // Set intial ratio + setAspectRatio.call(player); + + // Load the SDK if not already + if (is.object(window.DM) && is.function(window.DM.player)) { + dailymotion.ready.call(player); + } else { + loadScript(player.config.urls.dailymotion.sdk) + .then(() => { + dailymotion.ready.call(player); + }) + .catch(error => { + player.debug.warn('DailyMotion SDK (all.js) failed to load', error); + }); + } + }, + + // API Ready + ready() { + // Following previous plugin procedure + const player = this; + // Getting dailymotion config + const config = player.config.dailymotion; + // Get the source URL or ID if it's an