├── docs
└── api.md
├── .npmignore
├── .gitignore
├── scripts
├── banner.ejs
├── npm-postversion-for-bower.sh
├── npm-preversion-for-bower.sh
├── npm-version-for-bower.sh
└── server.js
├── test
├── karma
│ ├── ie.js
│ ├── chrome.js
│ ├── firefox.js
│ ├── safari.js
│ ├── detected.js
│ └── common.js
├── index.html
├── dailymotion.test.js
├── player-proxy.js
└── plugin.test.js
├── .travis.yml
├── src
├── plugin.js
├── videojs-dailymotion.js
└── dailymotion.js
├── bower.json
├── .editorconfig
├── .jshintrc
├── es5
├── plugin.js
├── dailymotion.js
└── videojs-dailymotion.js
├── index.html
├── README.md
├── package.json
└── dist-test
└── videojs-dailymotion.js
/docs/api.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Exclude everything but the contents of the src and dist directory.
2 | **/*
3 | !dist/**
4 | !src/**
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 | dist
4 |
5 | node_modules
6 | bower_components
7 | npm-debug.log
8 |
9 | mongoose*.exe
10 |
11 | *.orig
12 |
13 | *.log
--------------------------------------------------------------------------------
/scripts/banner.ejs:
--------------------------------------------------------------------------------
1 | /**
2 | * <%- pkg.name %>
3 | * @version <%- pkg.version %>
4 | * @copyright <%- date.getFullYear() %> <%- pkg.author %>
5 | * @license <%- pkg.license %>
6 | */
7 |
--------------------------------------------------------------------------------
/test/karma/ie.js:
--------------------------------------------------------------------------------
1 | var common = require('./common');
2 |
3 | module.exports = function(config) {
4 | config.set(common({
5 | plugins: ['karma-ie-launcher'],
6 | browsers: ['IE']
7 | }));
8 | };
9 |
--------------------------------------------------------------------------------
/test/karma/chrome.js:
--------------------------------------------------------------------------------
1 | var common = require('./common');
2 |
3 | module.exports = function(config) {
4 | config.set(common({
5 | plugins: ['karma-chrome-launcher'],
6 | browsers: ['Chrome']
7 | }));
8 | };
9 |
--------------------------------------------------------------------------------
/test/karma/firefox.js:
--------------------------------------------------------------------------------
1 | var common = require('./common');
2 |
3 | module.exports = function(config) {
4 | config.set(common({
5 | plugins: ['karma-firefox-launcher'],
6 | browsers: ['Firefox']
7 | }));
8 | };
9 |
--------------------------------------------------------------------------------
/test/karma/safari.js:
--------------------------------------------------------------------------------
1 | var common = require('./common');
2 |
3 | module.exports = function(config) {
4 | config.set(common({
5 | plugins: ['karma-safari-launcher'],
6 | browsers: ['Safari']
7 | }));
8 | };
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "4.2.4"
4 | before_script:
5 | - if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then curl https://gist.githubusercontent.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash; fi
6 | script: npm run build
7 |
8 |
--------------------------------------------------------------------------------
/src/plugin.js:
--------------------------------------------------------------------------------
1 | import videojs from 'video.js';
2 | import chromecast from './videojs-dailymotion';
3 |
4 | /**
5 | * The video.js Dailymotion plugin.
6 | *
7 | * @param {Object} options
8 | */
9 | const plugin = function (options) {
10 | dailymotion(this, options);
11 | };
12 |
13 | videojs.plugin('dailymotion', plugin);
14 |
15 | export default plugin;
16 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "videojs-dailymotion",
3 | "description": "Dailymotion playback technology for Video.js",
4 | "version": "2.0.0",
5 | "main": [
6 | "dist/videojs-dailymotion.js"
7 | ],
8 | "ignore": [
9 | "examples",
10 | "sandbox",
11 | "test",
12 | ".editorconfig",
13 | ".gitignore",
14 | ".jshintrc",
15 | ".travis.yml",
16 | "bower.json",
17 | "package.json",
18 | "README.md"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/scripts/npm-postversion-for-bower.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cd $( cd "$( dirname "$( dirname "${BASH_SOURCE[0]}" )" )" && pwd )
4 |
5 | VERSION="$(node -p "require('./package.json').version")"
6 |
7 | if [ -d "./.git" ]; then
8 | ORIGIN=`git remote | grep "^origin$"`;
9 |
10 | if [ "$ORIGIN" != "" ]; then
11 | git reset --hard origin/master
12 | git push origin --tags
13 | fi
14 |
15 | echo "Finished version bump to v$VERSION!"
16 | fi
17 |
--------------------------------------------------------------------------------
/scripts/npm-preversion-for-bower.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cd $( cd "$( dirname "$( dirname "${BASH_SOURCE[0]}" )" )" && pwd )
4 |
5 | if [ -d "./.git" ]; then
6 | BRANCH=`git rev-parse --abbrev-ref HEAD`
7 |
8 | if [ "$BRANCH" != "master" ]; then
9 | echo "The current branch should be 'master'; please checkout 'master' before versioning."
10 | exit 1
11 | else
12 | npm test
13 | fi
14 | else
15 | echo "This plugin project is not a Git repository; skipping versioning scripts."
16 | exit 1
17 | fi
18 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
23 | [*.coffee]
24 | indent_style = space
25 | indent_size = 2
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | videojs-dailymotion Unit Tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/dailymotion.test.js:
--------------------------------------------------------------------------------
1 | import window from 'global/window';
2 | import QUnit from 'qunit';
3 | import chromecastMaker from '../src/videojs-dailymotion';
4 | import playerProxy from './player-proxy';
5 |
6 | QUnit.module('dailymotion', {
7 |
8 | beforeEach() {
9 | this.oldTimeout = window.setTimeout;
10 | window.setTimeout = Function.prototype;
11 | },
12 |
13 | afterEach() {
14 | window.setTimeout = this.oldTimeout;
15 | }
16 | });
17 |
18 | QUnit.test(
19 | 'chromecastMaker takes a player and returns a dailymotion plugin',
20 | function (assert) {
21 | let chromecast = chromecastMaker(playerProxy(), {});
22 |
23 | assert.equal(typeof chromecast, 'object', 'dailymotion is an object');
24 | }
25 | );
26 |
--------------------------------------------------------------------------------
/test/player-proxy.js:
--------------------------------------------------------------------------------
1 | import extend from 'node.extend';
2 | import videojs from 'video.js';
3 |
4 | const proxy = (props) => {
5 | let player = extend(true, {}, videojs.EventTarget.prototype, {
6 | play: Function.prototype,
7 | paused: Function.prototype,
8 | ended: Function.prototype,
9 | poster: Function.prototype,
10 | src: Function.prototype,
11 | addRemoteTextTrack: Function.prototype,
12 | removeRemoteTextTrack: Function.prototype,
13 | remoteTextTracks: Function.prototype,
14 | currentSrc: Function.prototype,
15 | dailymotion: {}
16 | }, props);
17 |
18 | player.constructor = videojs.getComponent('Player');
19 | player.chromecast.player_ = player;
20 |
21 | return player;
22 | };
23 |
24 | export default proxy;
25 |
--------------------------------------------------------------------------------
/scripts/npm-version-for-bower.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cd $( cd "$( dirname "$( dirname "${BASH_SOURCE[0]}" )" )" && pwd )
4 |
5 | VERSION="$(node -p "require('./package.json').version")"
6 |
7 | if [ -d "./.git" ]; then
8 | ORIGIN=`git remote | grep "^origin$"`;
9 |
10 | # Commit package.json with a new version and push it.
11 | git add package.json
12 | git commit -m "$VERSION"
13 |
14 | if [ "$ORIGIN" != "" ]; then
15 | git push origin master
16 | else
17 | echo "No 'origin' remote was found, so pushing will be skipped!"
18 | fi
19 |
20 | # Build the plugin and force-add dist/ so that npm's commit picks that up
21 | # instead of the package.json change. This is what should be tagged!
22 | npm run build
23 | git add -f dist
24 | fi
25 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "camelcase": true,
3 | "indent": 2,
4 | //"maxlen" : 120,
5 | "trailing": true,
6 | "bitwise": true,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "forin": true,
10 | "noarg": true,
11 | "noempty": true,
12 | "nonew": true,
13 | "undef": true,
14 | "unused": true,
15 | "devel": true,
16 | "node": false,
17 | "sub": true,
18 | "quotmark": "single",
19 | "predef": [
20 | // standard
21 | "navigator",
22 | "document",
23 | "window",
24 | "console",
25 | "alert",
26 | "setTimeout",
27 | "toString",
28 | "isNaN",
29 | // mocha
30 | "describe",
31 | "it",
32 | "before",
33 | "beforeEach",
34 | "after",
35 | "afterEach",
36 | // video.js
37 | "videojs"
38 | ]
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/test/plugin.test.js:
--------------------------------------------------------------------------------
1 | import QUnit from 'qunit';
2 | import sinon from 'sinon';
3 | import videojs from 'video.js';
4 | import plugin from '../src/plugin';
5 |
6 | QUnit.test('the environment is sane', function (assert) {
7 | assert.strictEqual(typeof Array.isArray, 'function', 'es5 exists');
8 | assert.strictEqual(typeof sinon, 'object', 'sinon exists');
9 | assert.strictEqual(typeof videojs, 'function', 'videojs exists');
10 | assert.strictEqual(typeof plugin, 'function', 'plugin is a function');
11 | });
12 |
13 | QUnit.test('registers itself with video.js', function (assert) {
14 | assert.expect(1);
15 | assert.strictEqual(
16 | videojs.getComponent('Player').prototype.dailymotion,
17 | plugin,
18 | 'videojs-dailymotion plugin was registered'
19 | );
20 | });
21 |
--------------------------------------------------------------------------------
/es5/plugin.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, '__esModule', {
4 | value: true
5 | });
6 |
7 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8 |
9 | var _videoJs = require('video.js');
10 |
11 | var _videoJs2 = _interopRequireDefault(_videoJs);
12 |
13 | var _videojsDailymotion = require('./videojs-dailymotion');
14 |
15 | var _videojsDailymotion2 = _interopRequireDefault(_videojsDailymotion);
16 |
17 | /**
18 | * The video.js Dailymotion plugin.
19 | *
20 | * @param {Object} options
21 | */
22 | var plugin = function plugin(options) {
23 | dailymotion(this, options);
24 | };
25 |
26 | _videoJs2['default'].plugin('dailymotion', plugin);
27 |
28 | exports['default'] = plugin;
29 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/test/karma/detected.js:
--------------------------------------------------------------------------------
1 | var common = require('./common');
2 |
3 | // Runs default testing configuration in multiple environments.
4 |
5 | module.exports = function(config) {
6 |
7 | // Travis CI should run in its available Firefox headless browser.
8 | if (process.env.TRAVIS) {
9 |
10 | config.set(common({
11 | browsers: ['Firefox'],
12 | plugins: ['karma-firefox-launcher']
13 | }))
14 | } else {
15 | config.set(common({
16 |
17 | frameworks: ['detectBrowsers'],
18 |
19 | plugins: [
20 | 'karma-chrome-launcher',
21 | 'karma-detect-browsers',
22 | 'karma-firefox-launcher',
23 | 'karma-ie-launcher',
24 | 'karma-safari-launcher'
25 | ],
26 |
27 | detectBrowsers: {
28 | usePhantomJS: false
29 | }
30 | }));
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/scripts/server.js:
--------------------------------------------------------------------------------
1 | import connect from 'connect';
2 | import cowsay from 'cowsay';
3 | import path from 'path';
4 | import portscanner from 'portscanner';
5 | import serveStatic from 'serve-static';
6 |
7 | // Configuration for the server.
8 | const PORT = 9999;
9 | const MAX_PORT = PORT + 100;
10 | const HOST = '127.0.0.1';
11 |
12 | const app = connect();
13 |
14 | const verbs = [
15 | 'Chewing the cud',
16 | 'Grazing',
17 | 'Mooing',
18 | 'Lowing',
19 | 'Churning the cream'
20 | ];
21 |
22 | app.use(serveStatic(path.join(__dirname, '..')));
23 |
24 | portscanner.findAPortNotInUse(PORT, MAX_PORT, HOST, (error, port) => {
25 | if (error) {
26 | throw error;
27 | }
28 |
29 | process.stdout.write(cowsay.say({
30 | text: `${verbs[Math.floor(Math.random() * 5)]} on ${HOST}:${port}`
31 | }) + '\n\n');
32 |
33 | app.listen(port);
34 | });
35 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | videojs-dailymotion Demo
6 |
7 |
8 |
9 |
10 |
11 |
15 |
18 |
19 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/test/karma/common.js:
--------------------------------------------------------------------------------
1 | var merge = require('lodash-compat/object/merge');
2 |
3 | var DEFAULTS = {
4 | basePath: '../..',
5 | frameworks: ['browserify', 'qunit'],
6 |
7 | files: [
8 | 'node_modules/sinon/pkg/sinon.js',
9 | 'node_modules/sinon/pkg/sinon-ie.js',
10 | 'node_modules/video.js/dist/video.js',
11 | 'test/**/*.js'
12 | ],
13 |
14 | exclude: [
15 | 'test/bundle.js'
16 | ],
17 |
18 | plugins: [
19 | 'karma-browserify',
20 | 'karma-qunit'
21 | ],
22 |
23 | preprocessors: {
24 | 'test/**/*.js': ['browserify']
25 | },
26 |
27 | reporters: ['dots'],
28 | port: 9876,
29 | colors: true,
30 | autoWatch: false,
31 | singleRun: true,
32 | concurrency: Infinity,
33 |
34 | browserify: {
35 | transform: [
36 | 'babelify',
37 | 'browserify-shim'
38 | ]
39 | }
40 | };
41 |
42 | /**
43 | * Customizes target/source merging with lodash merge.
44 | *
45 | * @param {Mixed} target
46 | * @param {Mixed} source
47 | * @return {Mixed}
48 | */
49 | var customizer = function(target, source) {
50 | if (Array.isArray(target)) {
51 | return target.concat(source);
52 | }
53 | };
54 |
55 | /**
56 | * Generates a new Karma config with a common set of base configuration.
57 | *
58 | * @param {Object} custom
59 | * Configuration that will be deep-merged. Arrays will be
60 | * concatenated.
61 | * @return {Object}
62 | */
63 | module.exports = function(custom) {
64 | return merge({}, custom, DEFAULTS, customizer);
65 | };
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
4 |
5 | - [Video.js - Dailymotion Source Support](#videojs---dailymotion-source-support)
6 | - [How does it work?](#how-does-it-work)
7 | - [Additional Informations](#additional-informations)
8 | - [Special Thank You](#special-thank-you)
9 |
10 |
11 |
12 | # Video.js - Dailymotion Source Support
13 | Allows you to use Dailymotion URL as source with [Video.js](https://github.com/zencoder/video-js/).
14 |
15 | ## How does it work?
16 | Including the script vjs.dailymotion.js will add the Dailymotion as a tech. You just have to add it to your techOrder option. Then, you add the option src with your Dailymotion URL.
17 |
18 | It supports:
19 | - dailymotion.com/
20 | - Regular URLs: http://www.dailymotion.com/video/xxxasl_fail-compilation-february-2013-tnl_fun
21 |
22 | **You must use the last version of VideoJS available in the folder lib, the current version on CDN will not work until it is updated**
23 |
24 | Here is an example:
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## Additional Informations
32 | dmControls: Display the Dailymotion controls instead of Video.js.
33 |
34 | ##Special Thank You
35 | Thanks to Benoit Tremblay for the original code https://github.com/eXon/videojs-youtube
36 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "videojs-dailymotion",
3 | "version": "2.0.0",
4 | "description": "Dailymotion playback technology for Video.js",
5 | "main": "es5/plugin.js",
6 | "scripts": {
7 | "prebuild": "npm run clean",
8 | "build": "npm-run-all -p build:*",
9 | "build:js": "npm-run-all mkdirs build:js:babel build:js:browserify build:js:bannerize build:js:uglify",
10 | "build:js:babel": "babel src -d es5",
11 | "build:js:bannerize": "bannerize dist/videojs-dailymotion.js --banner=scripts/banner.ejs",
12 | "build:js:browserify": "browserify . -s videojs-dailymotion -o dist/videojs-dailymotion.js",
13 | "build:js:uglify": "uglifyjs dist/videojs-dailymotion.js --comments --mangle --compress -o dist/videojs-dailymotion.min.js",
14 | "build:test": "npm-run-all mkdirs build:test:browserify",
15 | "build:test:browserify": "browserify `find test -name '*.test.js'` -t babelify -o dist-test/videojs-dailymotion.js",
16 | "copy:font": "cp -R src/fonts dist/fonts",
17 | "copy": "npm-run-all -p copy:*",
18 | "clean": "rm -rf dist dist-test es5",
19 | "docs": "doctoc README.md docs/api.md",
20 | "lint": "vjsstandard",
21 | "mkdirs": "mkdir -p dist dist-test es5",
22 | "prepublish": "npm run build",
23 | "prestart": "npm-run-all -p docs build",
24 | "dev": "npm-run-all -p start watch",
25 | "start": "npm-run-all -p start:serve",
26 | "start:serve": "babel-node --optional es7.functionBind,es7.classProperties,es7.decorators scripts/server.js",
27 | "pretest": "npm-run-all build:test",
28 | "test": "karma start --single-run test/karma/detected.js",
29 | "test:chrome": "npm run pretest && karma start test/karma/chrome.js",
30 | "test:firefox": "npm run pretest && karma start test/karma/firefox.js",
31 | "test:ie": "npm run pretest && karma start test/karma/ie.js",
32 | "test:safari": "npm run pretest && karma start test/karma/safari.js",
33 | "preversion": "./scripts/npm-preversion-for-bower.sh",
34 | "version": "./scripts/npm-version-for-bower.sh",
35 | "postversion": "./scripts/npm-postversion-for-bower.sh",
36 | "watch": "npm run mkdirs && npm-run-all -p watch:*",
37 | "watch:js": "watchify src/plugin.js -t babelify -v -o dist/videojs-dailymotion.js",
38 | "watch:test": "watchify `find test -name '*.test.js'` -t babelify -o dist-test/videojs-dailymotion.js"
39 | },
40 | "keywords": [
41 | "dailymotion",
42 | "videojs",
43 | "videojs-plugin"
44 | ],
45 | "author": "Benjipott, Inc.",
46 | "license": "Apache-2.0",
47 | "repository": {
48 | "type": "git",
49 | "url": "https://github.com/benjipott/video.js-dailymotion"
50 | },
51 | "files": [
52 | "CONTRIBUTING.md",
53 | "bower.json",
54 | "dist-test/",
55 | "dist/",
56 | "docs/",
57 | "es5/",
58 | "index.html",
59 | "scripts/",
60 | "src/",
61 | "test/"
62 | ],
63 | "babel": {
64 | "optional": [
65 | "es7.functionBind",
66 | "es7.classProperties",
67 | "es7.decorators"
68 | ]
69 | },
70 | "devDependencies": {
71 | "babel": "^5.8.0",
72 | "babelify": "^6.0.0",
73 | "bannerize": "^1.0.0",
74 | "browserify": "^11.0.0",
75 | "browserify-shim": "^3.0.0",
76 | "connect": "^3.4.0",
77 | "cowsay": "^1.1.0",
78 | "doctoc": "^0.15.0",
79 | "global": "^4.3.0",
80 | "karma": "^0.13.0",
81 | "karma-browserify": "^4.4.0",
82 | "karma-chrome-launcher": "^0.2.0",
83 | "karma-detect-browsers": "^2.0.0",
84 | "karma-firefox-launcher": "^0.1.0",
85 | "karma-ie-launcher": "^0.2.0",
86 | "karma-qunit": "^0.1.0",
87 | "karma-safari-launcher": "^0.1.0",
88 | "lodash-compat": "^3.10.0",
89 | "minimist": "^1.2.0",
90 | "node-sass": "^3.4.2",
91 | "node.extend": "^1.1.5",
92 | "nodemon": "^1.9.1",
93 | "npm-run-all": "~1.2.0",
94 | "portscanner": "^1.0.0",
95 | "qunitjs": "^1.0.0",
96 | "serve-static": "^1.10.0",
97 | "sinon": "1.14.1",
98 | "uglify-js": "^2.5.0",
99 | "videojs-standard": "^4.0.0",
100 | "watchify": "^3.6.0",
101 | "xhr": "^2.2.0"
102 | },
103 | "browserify": {
104 | "transform": [
105 | "browserify-shim"
106 | ]
107 | },
108 | "browserify-shim": {
109 | "qunit": "global:QUnit",
110 | "sinon": "global:sinon",
111 | "video.js": "global:videojs"
112 | },
113 | "vjsstandard": {
114 | "ignore": [
115 | "dist",
116 | "dist-test",
117 | "docs",
118 | "es5",
119 | "test/karma",
120 | "scripts"
121 | ]
122 | },
123 | "dependencies": {
124 | "object.assign": "^4.0.3",
125 | "video.js": "^5.0.0"
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/videojs-dailymotion.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Dailymotion.js
3 | * Dailymotion Media Controller - Wrapper for HTML5 Media API
4 | */
5 | import videojs from 'video.js';
6 |
7 | const Component = videojs.getComponent('Component');
8 | const Tech = videojs.getComponent('Tech');
9 |
10 | /**
11 | * Dailymotion Media Controller - Wrapper for HTML5 Media API
12 | *
13 | * @param {Object=} options Object of option names and values
14 | * @param {Function=} ready Ready callback function
15 | * @extends Tech
16 | * @class Dailymotion
17 | */
18 |
19 | class Dailymotion extends Tech {
20 | constructor(options, ready) {
21 | super(options, ready);
22 |
23 | this.params = {
24 | id: this.options_.techId,
25 | autoplay: (this.player_.options_.autoplay) ? 1 : 0,
26 | chromeless: (this.player_.options_.dmControls) ? 0 : 1,
27 | html: 1,
28 | info: 1,
29 | logo: 1,
30 | controls: 'html',
31 | wmode: 'opaque',
32 | format: 'json',
33 | url: options.source.src
34 | };
35 |
36 | // If we are not on a server, don't specify the origin (it will crash)
37 | if (window.location.protocol !== 'file:') {
38 | this.params.origin = window.location.protocol + '//' + window.location.hostname;
39 | }
40 |
41 | this.videoId = this.parseSrc(options.source.src);
42 |
43 | if (typeof this.videoId !== 'undefined') {
44 | this.setTimeout(() => {
45 | this.setPoster('//api.dailymotion.com/video/' + this.videoId + '?fields=poster_url&ads=false');
46 | }, 100);
47 | }
48 |
49 | if (Dailymotion.isApiReady) {
50 | this.loadApi();
51 | } else {
52 | // Add to the queue because the Dailymotion API is not ready
53 | Dailymotion.apiReadyQueue.push(this);
54 | }
55 |
56 | }
57 |
58 | createEl() {
59 |
60 | let el = videojs.createEl('iframe', {
61 | id: this.options_.techId,
62 | className: 'vjs-tech vjs-tech-dailymotion'
63 | });
64 |
65 | let iframeContainer = videojs.createEl('iframe', {
66 | scrolling: 'no',
67 | marginWidth: 0,
68 | marginHeight: 0,
69 | frameBorder: 0,
70 | webkitAllowFullScreen: '',
71 | mozallowfullscreen: '',
72 | allowFullScreen: '',
73 | });
74 |
75 | el.appendChild(iframeContainer);
76 |
77 | if (/MSIE (\d+\.\d+);/.test(navigator.userAgent) || !/(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent)) {
78 | let divBlocker = videojs.createEl('div',
79 | {
80 | className: 'vjs-iframe-blocker',
81 | style: 'position:absolute;top:0;left:0;width:100%;height:100%'
82 | });
83 |
84 | // In case the blocker is still there and we want to pause
85 | divBlocker.onclick = function () {
86 | this.pause();
87 | }.bind(this);
88 |
89 | el.appendChild(divBlocker);
90 | }
91 |
92 | return el;
93 | }
94 |
95 | loadApi() {
96 | this.dmPlayer = new DM.player(this.options_.techId, {
97 | video: this.videoId,
98 | width: this.options_.width,
99 | height: this.options_.height,
100 | params: this.params
101 | });
102 |
103 | this.setupTriggers();
104 |
105 | this.dmPlayer.vjsTech = this;
106 | }
107 |
108 | parseSrc(src) {
109 | if (src) {
110 | // Regex that parse the video ID for any Dailymotion URL
111 | var regExp = /^.+dailymotion.com\/((video|hub)\/([^_]+))?[^#]*(#video=([^_&]+))?/;
112 | var match = src.match(regExp);
113 |
114 | return match ? match[5] || match[3] : null;
115 | }
116 | }
117 |
118 | setupTriggers() {
119 | this.dmPlayer.listeners = [];
120 | for (var i = Dailymotion.Events.length - 1; i >= 0; i--) {
121 | //videojs.on(this.dmPlayer, Dailymotion.Events[i], videojs.bind(this, this.eventHandler));
122 | var listener = videojs.bind(this, this.eventHandler);
123 | this.dmPlayer.listeners.push({event: Dailymotion.Events[i], func: listener});
124 | this.dmPlayer.addEventListener(Dailymotion.Events[i], listener);
125 | }
126 | }
127 |
128 | eventHandler(e) {
129 | this.onStateChange(e);
130 | this.trigger(e);
131 | }
132 |
133 | onStateChange(event) {
134 | let state = event.type;
135 | if (state !== this.lastState) {
136 | switch (state) {
137 | case -1:
138 | break;
139 |
140 | case 'apiready':
141 | this.triggerReady();
142 | break;
143 |
144 | case 'video_end':
145 | this.trigger('ended');
146 | break;
147 |
148 | case 'ad_play':
149 | this.trigger('play');
150 | break;
151 |
152 | case 'video_start':
153 | case 'ad_start':
154 | this.trigger('playing');
155 | this.trigger('play');
156 | break;
157 |
158 | case 'play':
159 | break;
160 |
161 | case 'playing':
162 | break;
163 |
164 | case 'pause':
165 | break;
166 | case 'durationchange':
167 | break;
168 |
169 | case 'timeupdate':
170 | break;
171 | case 'progress':
172 | break;
173 |
174 | }
175 |
176 | this.lastState = state;
177 | }
178 | }
179 |
180 | poster() {
181 | return this.poster_;
182 | }
183 |
184 | setPoster(poster) {
185 | this.poster_ = poster;
186 | this.trigger('posterchange');
187 | }
188 |
189 | /**
190 | * Set video
191 | *
192 | * @param {Object=} src Source object
193 | * @method setSrc
194 | */
195 | src(src) {
196 | if (typeof src !== 'undefined') {
197 | this.src_ = this.parseSrc(src);
198 | this.dmPlayer.load(this.src_);
199 | }
200 | return this.src_;
201 | }
202 |
203 | currentSrc() {
204 | return this.src_;
205 | }
206 |
207 | play() {
208 | if (this.isReady_) {
209 | this.dmPlayer.play();
210 | } else {
211 | if (!this.player_.options_.dmControls) {
212 | // Keep the big play button until it plays for real
213 | this.player_.bigPlayButton.show();
214 | }
215 | }
216 | }
217 |
218 | ended() {
219 |
220 | if (this.isReady_) {
221 | var stateId = this.dmPlayer.getPlayerState();
222 | return stateId === 0;
223 | } else {
224 | // We will play it when the API will be ready
225 | return false;
226 | }
227 | }
228 |
229 | pause() {
230 | this.dmPlayer.pause(!this.dmPlayer.paused);
231 | }
232 |
233 | paused() {
234 | return this.dmPlayer.paused;
235 | }
236 |
237 | currentTime() {
238 | return (this.dmPlayer && this.dmPlayer.currentTime) ? this.dmPlayer.currentTime : 0;
239 | }
240 |
241 | setCurrentTime(position) {
242 | this.dmPlayer.seek(position);
243 | }
244 |
245 | duration() {
246 | return (this.dmPlayer && this.dmPlayer.duration) ? this.dmPlayer.duration : 0;
247 | }
248 |
249 | volume() {
250 | if (isNaN(this.volume_)) {
251 | this.volume_ = this.dmPlayer.volume;
252 | }
253 |
254 | return this.volume_;
255 | }
256 |
257 | /**
258 | * Request to enter fullscreen
259 | *
260 | * @method enterFullScreen
261 | */
262 | enterFullScreen() {
263 | this.dmPlayer.setFullscreen(true);
264 | }
265 |
266 | /**
267 | * Request to exit fullscreen
268 | *
269 | * @method exitFullScreen
270 | */
271 | exitFullScreen() {
272 | this.dmPlayer.setFullscreen(false);
273 | }
274 |
275 |
276 | setVolume(percentAsDecimal) {
277 | if (typeof(percentAsDecimal) !== 'undefined' && percentAsDecimal !== this.volume_) {
278 | this.dmPlayer.setVolume(percentAsDecimal);
279 | this.volume_ = percentAsDecimal;
280 | this.player_.trigger('volumechange');
281 | }
282 | }
283 |
284 | buffered() {
285 | return [];
286 | }
287 |
288 | controls() {
289 | return false;
290 | }
291 |
292 | muted() {
293 | return this.dmPlayer.muted;
294 | }
295 |
296 | setMuted(muted) {
297 | this.dmPlayer.setMuted(muted);
298 |
299 | this.setTimeout(function () {
300 | this.player_.trigger('volumechange');
301 | });
302 | }
303 |
304 | supportsFullScreen() {
305 | return true;
306 | }
307 |
308 |
309 | resetSrc_(callback) {
310 | callback();
311 | }
312 |
313 | dispose() {
314 | this.resetSrc_(Function.prototype);
315 | super.dispose(this);
316 | }
317 |
318 | }
319 |
320 | Dailymotion.prototype.options_ = {};
321 |
322 | Dailymotion.apiReadyQueue = [];
323 |
324 | Dailymotion.makeQueryString = function (args) {
325 | let querys = [];
326 | for (var key in args) {
327 | if (args.hasOwnProperty(key)) {
328 | querys.push(encodeURIComponent(key) + '=' + encodeURIComponent(args[key]));
329 | }
330 | }
331 |
332 | return querys.join('&');
333 | };
334 |
335 | const injectJs = function () {
336 | let tag = document.createElement('script');
337 | tag.src = '//api.dmcdn.net/all.js';
338 | let firstScriptTag = document.getElementsByTagName('script')[0];
339 | firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
340 | }
341 |
342 | /* Dailymotion Support Testing -------------------------------------------------------- */
343 |
344 | Dailymotion.isSupported = function () {
345 | return true;
346 | };
347 |
348 | // Add Source Handler pattern functions to this tech
349 | Tech.withSourceHandlers(Dailymotion);
350 |
351 | /*
352 | * The default native source handler.
353 | * This simply passes the source to the video element. Nothing fancy.
354 | *
355 | * @param {Object} source The source object
356 | * @param {Flash} tech The instance of the Flash tech
357 | */
358 | Dailymotion.nativeSourceHandler = {};
359 |
360 | /**
361 | * Check if Flash can play the given videotype
362 | * @param {String} type The mimetype to check
363 | * @return {String} 'probably', 'maybe', or '' (empty string)
364 | */
365 | Dailymotion.nativeSourceHandler.canPlayType = function (source) {
366 |
367 | const dashExtRE = /^video\/(dailymotion)/i;
368 |
369 | if (dashExtRE.test(source)) {
370 | return 'maybe';
371 | } else {
372 | return '';
373 | }
374 |
375 | };
376 |
377 | /*
378 | * Check Flash can handle the source natively
379 | *
380 | * @param {Object} source The source object
381 | * @return {String} 'probably', 'maybe', or '' (empty string)
382 | */
383 | Dailymotion.nativeSourceHandler.canHandleSource = function (source) {
384 |
385 | // If a type was provided we should rely on that
386 | if (source.type) {
387 | return Dailymotion.nativeSourceHandler.canPlayType(source.type);
388 | } else if (source.src) {
389 | return Dailymotion.nativeSourceHandler.canPlayType(source.src);
390 | }
391 |
392 | return '';
393 | };
394 |
395 | /*
396 | * Pass the source to the flash object
397 | * Adaptive source handlers will have more complicated workflows before passing
398 | * video data to the video element
399 | *
400 | * @param {Object} source The source object
401 | * @param {Flash} tech The instance of the Flash tech
402 | */
403 | Dailymotion.nativeSourceHandler.handleSource = function (source, tech) {
404 | tech.src(source.src);
405 | };
406 |
407 | /*
408 | * Clean up the source handler when disposing the player or switching sources..
409 | * (no cleanup is needed when supporting the format natively)
410 | */
411 | Dailymotion.nativeSourceHandler.dispose = function () {
412 | };
413 |
414 | // Register the native source handler
415 | Dailymotion.registerSourceHandler(Dailymotion.nativeSourceHandler);
416 |
417 |
418 | /*
419 | * Set the tech's volume control support status
420 | *
421 | * @type {Boolean}
422 | */
423 | Dailymotion.prototype['featuresVolumeControl'] = true;
424 |
425 | /*
426 | * Set the tech's playbackRate support status
427 | *
428 | * @type {Boolean}
429 | */
430 | Dailymotion.prototype['featuresPlaybackRate'] = false;
431 |
432 | /*
433 | * Set the tech's status on moving the video element.
434 | * In iOS, if you move a video element in the DOM, it breaks video playback.
435 | *
436 | * @type {Boolean}
437 | */
438 | Dailymotion.prototype['movingMediaElementInDOM'] = false;
439 |
440 | /*
441 | * Set the the tech's fullscreen resize support status.
442 | * HTML video is able to automatically resize when going to fullscreen.
443 | * (No longer appears to be used. Can probably be removed.)
444 | */
445 | Dailymotion.prototype['featuresFullscreenResize'] = false;
446 |
447 | /*
448 | * Set the tech's timeupdate event support status
449 | * (this disables the manual timeupdate events of the Tech)
450 | */
451 | Dailymotion.prototype['featuresTimeupdateEvents'] = false;
452 |
453 | /*
454 | * Set the tech's progress event support status
455 | * (this disables the manual progress events of the Tech)
456 | */
457 | Dailymotion.prototype['featuresProgressEvents'] = false;
458 |
459 | /*
460 | * Sets the tech's status on native text track support
461 | *
462 | * @type {Boolean}
463 | */
464 | Dailymotion.prototype['featuresNativeTextTracks'] = true;
465 |
466 | /*
467 | * Sets the tech's status on native audio track support
468 | *
469 | * @type {Boolean}
470 | */
471 | Dailymotion.prototype['featuresNativeAudioTracks'] = true;
472 |
473 | /*
474 | * Sets the tech's status on native video track support
475 | *
476 | * @type {Boolean}
477 | */
478 | Dailymotion.prototype['featuresNativeVideoTracks'] = false;
479 |
480 | Dailymotion.Events = 'apiready,ad_play,ad_start,ad_timeupdate,ad_pause,ad_end,video_start,video_end,play,playing,pause,ended,canplay,canplaythrough,timeupdate,progress,seeking,seeked,volumechange,durationchange,fullscreenchange,error'.split(',');
481 |
482 | videojs.options.Dailymotion = {};
483 |
484 | Component.registerComponent('Dailymotion', Dailymotion);
485 | Tech.registerTech('Dailymotion', Dailymotion);
486 |
487 | injectJs();
488 |
489 | // Called when Dailymotion API is ready to be used
490 | window.dmAsyncInit = function () {
491 | var dm;
492 | while ((dm = Dailymotion.apiReadyQueue.shift())) {
493 | dm.loadApi();
494 | }
495 | Dailymotion.apiReadyQueue = [];
496 | Dailymotion.isApiReady = true;
497 | };
498 |
499 | export default Dailymotion;
500 |
--------------------------------------------------------------------------------
/es5/dailymotion.js:
--------------------------------------------------------------------------------
1 | /* global videojs, DM */
2 | /**
3 | * @fileoverview Dailymotion Media Controller - Wrapper for Dailymotion Media API
4 | */
5 |
6 | 'use strict';
7 |
8 | (function () {
9 | /**
10 | * Dailymotion Media Controller - Wrapper for Dailymotion Media API
11 | * @param {videojs.Player|Object} player
12 | * @param {Object=} options
13 | * @param {Function=} ready
14 | * @constructor
15 | */
16 |
17 | function addEventListener(element, event, cb) {
18 | if (!element.addEventListener) {
19 | element.attachEvent(event, cb);
20 | } else {
21 | element.addEventListener(event, cb, true);
22 | }
23 | }
24 |
25 | videojs.Dailymotion = videojs.MediaTechController.extend({
26 | /** @constructor */
27 | init: function init(player, options, ready) {
28 | videojs.MediaTechController.call(this, player, options, ready);
29 |
30 | this.player_ = player;
31 | this.playerEl_ = this.player_.el();
32 |
33 | if (typeof this.player_.options().dmControls !== 'undefined') {
34 | var dmC = this.player_.options().dmControls = parseInt(this.player_.options().dmControls) && this.player_.controls();
35 |
36 | if (dmC && this.player_.controls()) {
37 | this.player_.controls(!dmC);
38 | }
39 | }
40 |
41 | // Copy the Javascript options if they exist
42 | if (typeof options.source !== 'undefined') {
43 | for (var key in options.source) {
44 | if (options['source'].hasOwnProperty(key)) {
45 | this.player_.options()[key] = options.source[key];
46 | }
47 | }
48 | }
49 |
50 | var self = this;
51 |
52 | this.bindedWaiting = function () {
53 | self.onWaiting();
54 | };
55 | this.player_.on('waiting', this.bindedWaiting);
56 |
57 | player.ready(function () {
58 | if (self.playOnReady && !self.player_.options()['dmControls']) {
59 | if (typeof self.player_.loadingSpinner !== 'undefined') {
60 | self.player_.loadingSpinner.show();
61 | }
62 | if (typeof self.player_.bigPlayButton !== 'undefined') {
63 | self.player_.bigPlayButton.hide();
64 | }
65 | }
66 |
67 | player.trigger('loadstart');
68 | });
69 |
70 | this.videoId = this.parseSrc(this.player_.options().src);
71 |
72 | if (typeof this.videoId !== 'undefined') {
73 | // Show the Dailymotion poster only if we don't use Dailymotion poster
74 | // (otherwise the controls pop, it's not nice)
75 | if (!this.player_.options().dmControls) {
76 | // Set the Dailymotion poster only if none is specified
77 | if (typeof this.player_.poster() === 'undefined') {
78 | // Don't use player.poster(), it will fail here because the tech is still null in constructor
79 | this.player_.poster();
80 | // Cover the entire iframe to have the same poster than Dailymotion
81 | // Doesn't exist right away because the DOM hasn't created it
82 | setTimeout(function () {
83 | var posterEl = self.playerEl_.querySelectorAll('.vjs-poster')[0];
84 | posterEl.style.backgroundImage = 'url(//api.dailymotion.com/video/' + self.videoId + '?fields=url&ads=false)';
85 | posterEl.style.display = '';
86 | posterEl.style.backgroundSize = 'cover';
87 | }, 100);
88 | }
89 | }
90 | }
91 |
92 | this.id_ = this.player_.id() + '_dailymotion_api';
93 |
94 | this.el_ = videojs.Component.prototype.createEl('iframe', {
95 | id: this.id_,
96 | className: 'vjs-tech',
97 | scrolling: 'no',
98 | marginWidth: 0,
99 | marginHeight: 0,
100 | frameBorder: 0,
101 | webkitAllowFullScreen: '',
102 | mozallowfullscreen: '',
103 | allowFullScreen: ''
104 | });
105 |
106 | this.playerEl_.insertBefore(this.el_, this.playerEl_.firstChild);
107 |
108 | if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
109 | var ieVersion = Number(RegExp.$1);
110 | this.addIframeBlocker(ieVersion);
111 | } else if (!/(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent)) {
112 | // the pointer-events: none block the mobile player
113 | this.el_.className += ' onDesktop';
114 | this.addIframeBlocker();
115 | }
116 |
117 | this.params = {
118 | id: this.id_,
119 | autoplay: this.player_.options().autoplay ? 1 : 0,
120 | chromeless: this.player_.options().dmControls ? 0 : 1,
121 | html: 1,
122 | info: 1,
123 | logo: 1,
124 | controls: 'html',
125 | wmode: 'opaque',
126 | format: 'json',
127 | url: this.player_.options().src
128 | };
129 |
130 | if (typeof this.params.list === 'undefined') {
131 | delete this.params.list;
132 | }
133 |
134 | // Make autoplay work for iOS
135 | if (this.player_.options().autoplay) {
136 | this.player_.bigPlayButton.hide();
137 | this.playOnReady = true;
138 | }
139 |
140 | // If we are not on a server, don't specify the origin (it will crash)
141 | if (window.location.protocol !== 'file:') {
142 | this.params.origin = window.location.protocol + '//' + window.location.hostname;
143 | }
144 |
145 | this.el_.src = '//www.dailymotion.com/services/oembed?' + videojs.Dailymotion.makeQueryString(this.params);
146 |
147 | if (videojs.Dailymotion.apiReady) {
148 | this.loadApi();
149 | } else {
150 | // Add to the queue because the Dailymotion API is not ready
151 | videojs.Dailymotion.loadingQueue.push(this);
152 |
153 | // Load the Dailymotion API if it is the first Dailymotion video
154 | if (!videojs.Dailymotion.apiLoading) {
155 | var tag = document.createElement('script');
156 | tag.onerror = function (e) {
157 | self.onError(e);
158 | };
159 | tag.src = '//api.dmcdn.net/all.js';
160 | var firstScriptTag = document.getElementsByTagName('script')[0];
161 | firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
162 | videojs.Dailymotion.apiLoading = true;
163 | }
164 | }
165 | }
166 | });
167 |
168 | videojs.Dailymotion.prototype.params = [];
169 |
170 | videojs.Dailymotion.prototype.onWaiting = function () /*e*/{
171 | // Make sure to hide the play button while the spinner is there
172 | if (typeof this.player_.bigPlayButton !== 'undefined') {
173 | this.player_.bigPlayButton.hide();
174 | }
175 | };
176 |
177 | videojs.Dailymotion.prototype.addIframeBlocker = function (ieVersion) {
178 |
179 | if (this.player_.options().dmControls) {
180 | return false;
181 | }
182 |
183 | this.iframeblocker = videojs.Component.prototype.createEl('div');
184 |
185 | this.iframeblocker.className = 'iframeblocker';
186 |
187 | this.iframeblocker.style.position = 'absolute';
188 | this.iframeblocker.style.left = 0;
189 | this.iframeblocker.style.right = 0;
190 | this.iframeblocker.style.top = 0;
191 | this.iframeblocker.style.bottom = 0;
192 |
193 | // Odd quirk for IE8 (doesn't support rgba)
194 | if (ieVersion && ieVersion < 9) {
195 | this.iframeblocker.style.opacity = 0.01;
196 | } else {
197 | this.iframeblocker.style.background = 'rgba(255, 255, 255, 0.01)';
198 | }
199 |
200 | var self = this;
201 |
202 | addEventListener(this.iframeblocker, 'mousemove', function (e) {
203 | if (!self.player_.userActive()) {
204 | self.player_.userActive(true);
205 | }
206 |
207 | e.stopPropagation();
208 | e.preventDefault();
209 | });
210 |
211 | addEventListener(this.iframeblocker, 'click', function () /*e*/{
212 | if (self.paused()) {
213 | self.play();
214 | } else {
215 | self.pause();
216 | }
217 | });
218 |
219 | this.playerEl_.insertBefore(this.iframeblocker, this.el_.nextSibling);
220 | };
221 |
222 | videojs.Dailymotion.prototype.dispose = function () {
223 | if (this.dmPlayer) {
224 | this.pause();
225 | for (var i = 0; i < this.dmPlayer.listeners.length; i++) {
226 | var listener = this.dmPlayer.listeners[i];
227 | this.dmPlayer.removeEventListener(listener.event, listener.func);
228 | }
229 | this.dmPlayer = null;
230 | }
231 |
232 | // Remove the poster
233 | this.playerEl_.querySelectorAll('.vjs-poster')[0].style.backgroundImage = 'none';
234 |
235 | // If still connected to the DOM, remove it.
236 | var el = document.getElementById(this.id_);
237 | if (el.parentNode) {
238 | el.parentNode.removeChild(el);
239 | }
240 |
241 | if (typeof this.player_.loadingSpinner !== 'undefined') {
242 | this.player_.loadingSpinner.hide();
243 | }
244 | if (typeof this.player_.bigPlayButton !== 'undefined') {
245 | this.player_.bigPlayButton.hide();
246 | }
247 |
248 | videojs.MediaTechController.prototype.dispose.call(this);
249 | };
250 |
251 | videojs.Dailymotion.prototype.src = function (src) {
252 | if (typeof src !== 'undefined') {
253 | this.dmPlayer.load(this.parseSrc(src));
254 | }
255 | return this.srcVal;
256 | };
257 |
258 | videojs.Dailymotion.prototype.currentSrc = function () {
259 | return this.srcVal;
260 | };
261 |
262 | videojs.Dailymotion.prototype.play = function () {
263 | if (this.isReady_) {
264 | this.dmPlayer.play();
265 | } else {
266 | // We will play it when the API will be ready
267 | this.playOnReady = true;
268 |
269 | if (!this.player_.options.dmControls) {
270 | // Keep the big play button until it plays for real
271 | this.player_.bigPlayButton.show();
272 | }
273 | }
274 | };
275 |
276 | videojs.Dailymotion.prototype.ended = function () {
277 |
278 | if (this.isReady_) {
279 | var stateId = this.dmPlayer.getPlayerState();
280 | return stateId === 0;
281 | } else {
282 | // We will play it when the API will be ready
283 | return false;
284 | }
285 | };
286 |
287 | videojs.Dailymotion.prototype.pause = function () {
288 | this.dmPlayer.pause(!this.dmPlayer.paused);
289 | };
290 |
291 | videojs.Dailymotion.prototype.paused = function () {
292 | return this.dmPlayer.paused;
293 | };
294 |
295 | videojs.Dailymotion.prototype.currentTime = function () {
296 | return this.dmPlayer && this.dmPlayer.currentTime ? this.dmPlayer.currentTime : 0;
297 | };
298 |
299 | videojs.Dailymotion.prototype.setCurrentTime = function (seconds) {
300 | this.dmPlayer.seek(seconds, true);
301 | this.player_.trigger('timeupdate');
302 | };
303 |
304 | videojs.Dailymotion.prototype.duration = function () {
305 | return this.dmPlayer && this.dmPlayer.duration ? this.dmPlayer.duration : 0;
306 | };
307 |
308 | videojs.Dailymotion.prototype.buffered = function () {
309 | /*var loadedBytes = this.dmPlayer.getVideoBytesLoaded();
310 | var totalBytes = this.dmPlayer.getVideoBytesTotal();
311 | if (!loadedBytes || !totalBytes) return 0;
312 | var duration = this.dmPlayer.getDuration();
313 | var secondsBuffered = (loadedBytes / totalBytes) * duration;
314 | var secondsOffset = (this.dmPlayer.getCurrentTime() / totalBytes) * duration;
315 | return videojs.createTimeRange(secondsOffset, secondsOffset + secondsBuffered);*/
316 | return [];
317 | };
318 |
319 | videojs.Dailymotion.prototype.volume = function () {
320 | if (isNaN(this.volumeVal)) {
321 | this.volumeVal = this.dmPlayer.volume;
322 | }
323 |
324 | return this.volumeVal;
325 | };
326 |
327 | videojs.Dailymotion.prototype.setVolume = function (percentAsDecimal) {
328 | if (typeof percentAsDecimal !== 'undefined' && percentAsDecimal !== this.volumeVal) {
329 | this.dmPlayer.setVolume(percentAsDecimal);
330 | this.volumeVal = percentAsDecimal;
331 | this.player_.trigger('volumechange');
332 | }
333 | };
334 |
335 | videojs.Dailymotion.prototype.muted = function () {
336 | return this.dmPlayer.muted;
337 | };
338 | videojs.Dailymotion.prototype.setMuted = function (muted) {
339 | this.dmPlayer.setMuted(muted);
340 |
341 | var self = this;
342 | setTimeout(function () {
343 | self.player_.trigger('volumechange');
344 | }, 50);
345 | };
346 |
347 | videojs.Dailymotion.prototype.onReady = function () {
348 | this.isReady_ = true;
349 | this.player_.trigger('techready');
350 |
351 | // Hide the poster when ready because Dailymotion has it's own
352 | this.triggerReady();
353 | this.player_.trigger('durationchange');
354 |
355 | // Play right away if we clicked before ready
356 | if (this.playOnReady) {
357 | this.dmPlayer.play();
358 | }
359 | };
360 |
361 | videojs.Dailymotion.isSupported = function () {
362 | return true;
363 | };
364 |
365 | videojs.Dailymotion.prototype.supportsFullScreen = function () {
366 | return false;
367 | };
368 |
369 | videojs.Dailymotion.canPlaySource = function (srcObj) {
370 | return srcObj.type === 'video/dailymotion';
371 | };
372 |
373 | // All videos created before Dailymotion API is loaded
374 | videojs.Dailymotion.loadingQueue = [];
375 |
376 | videojs.Dailymotion.prototype.load = function () {};
377 |
378 | // Create the Dailymotion player
379 | videojs.Dailymotion.prototype.loadApi = function () {
380 |
381 | this.dmPlayer = new DM.player(this.id_, {
382 | video: this.videoId,
383 | width: this.options.width,
384 | height: this.options.height,
385 | params: this.params
386 | });
387 |
388 | this.setupTriggers();
389 |
390 | this.dmPlayer.vjsTech = this;
391 | };
392 |
393 | videojs.Dailymotion.prototype.onStateChange = function (event) {
394 | var state = event.type;
395 | if (state !== this.lastState) {
396 | switch (state) {
397 | case -1:
398 | this.player_.trigger('durationchange');
399 | break;
400 |
401 | case 'apiready':
402 | this.onReady();
403 | break;
404 |
405 | case 'ended':
406 |
407 | if (!this.player_.options().dmControls) {
408 | this.player_.bigPlayButton.show();
409 | }
410 | break;
411 |
412 | case 'play':
413 | this.player_.trigger('play');
414 | break;
415 |
416 | case 'playing':
417 | break;
418 |
419 | case 'pause':
420 | break;
421 | case 'durationchange':
422 | break;
423 |
424 | case 'timeupdate':
425 | // Hide the waiting spinner since Dailymotion has its own
426 | this.player_.loadingSpinner.hide();
427 | break;
428 | case 'progress':
429 | break;
430 |
431 | }
432 |
433 | this.lastState = state;
434 | }
435 | };
436 |
437 | videojs.Dailymotion.prototype.onError = function (error) {
438 | this.player_.error(error);
439 |
440 | if (error === 100 || error === 101 || error === 150) {
441 | this.player_.bigPlayButton.hide();
442 | this.player_.loadingSpinner.hide();
443 | this.player_.posterImage.hide();
444 | }
445 | };
446 |
447 | videojs.Dailymotion.makeQueryString = function (args) {
448 | var array = [];
449 | for (var key in args) {
450 | if (args.hasOwnProperty(key)) {
451 | array.push(encodeURIComponent(key) + '=' + encodeURIComponent(args[key]));
452 | }
453 | }
454 |
455 | return array.join('&');
456 | };
457 |
458 | videojs.Dailymotion.prototype.parseSrc = function (src) {
459 | this.srcVal = src;
460 |
461 | if (src) {
462 | // Regex that parse the video ID for any Dailymotion URL
463 | var regExp = /^.+dailymotion.com\/((video|hub)\/([^_]+))?[^#]*(#video=([^_&]+))?/;
464 | var match = src.match(regExp);
465 |
466 | return match ? match[5] || match[3] : null;
467 | }
468 | };
469 |
470 | videojs.Dailymotion.parsePlaylist = function (src) {
471 | // Check if we have a playlist
472 | var regExp = /[?&]list=([^#\&\?]+)/;
473 | var match = src.match(regExp);
474 |
475 | if (match !== null && match.length > 1) {
476 | return match[1];
477 | }
478 | };
479 |
480 | // Make video events trigger player events
481 | // May seem verbose here, but makes other APIs possible.
482 | videojs.Dailymotion.prototype.setupTriggers = function () {
483 | this.dmPlayer.listeners = [];
484 | for (var i = videojs.Dailymotion.Events.length - 1; i >= 0; i--) {
485 | //videojs.on(this.dmPlayer, videojs.Dailymotion.Events[i], videojs.bind(this, this.eventHandler));
486 | var listener = videojs.bind(this, this.eventHandler);
487 | this.dmPlayer.listeners.push({ event: videojs.Dailymotion.Events[i], func: listener });
488 | this.dmPlayer.addEventListener(videojs.Dailymotion.Events[i], listener);
489 | }
490 | };
491 | // Triggers removed using this.off when disposed
492 |
493 | videojs.Dailymotion.prototype.eventHandler = function (e) {
494 | this.onStateChange(e);
495 | this.trigger(e);
496 | };
497 |
498 | // List of all HTML5 events (various uses).
499 | videojs.Dailymotion.Events = ('apiready,play,playing,pause,ended,canplay,' + 'canplaythrough,timeupdate,progress,seeking,seeked,volumechange,durationchange,fullscreenchange,error').split(',');
500 |
501 | // Called when Dailymotion API is ready to be used
502 | window.dmAsyncInit = function () {
503 | var dm;
504 | while (dm = videojs.Dailymotion.loadingQueue.shift()) {
505 | dm.loadApi();
506 | }
507 | videojs.Dailymotion.loadingQueue = [];
508 | videojs.Dailymotion.apiReady = true;
509 | };
510 | })();
--------------------------------------------------------------------------------
/src/dailymotion.js:
--------------------------------------------------------------------------------
1 | /* global videojs, DM */
2 | /**
3 | * @fileoverview Dailymotion Media Controller - Wrapper for Dailymotion Media API
4 | */
5 |
6 |
7 | (function () {
8 | /**
9 | * Dailymotion Media Controller - Wrapper for Dailymotion Media API
10 | * @param {videojs.Player|Object} player
11 | * @param {Object=} options
12 | * @param {Function=} ready
13 | * @constructor
14 | */
15 |
16 | function addEventListener(element, event, cb) {
17 | if (!element.addEventListener) {
18 | element.attachEvent(event, cb);
19 | } else {
20 | element.addEventListener(event, cb, true);
21 | }
22 | }
23 |
24 | videojs.Dailymotion = videojs.MediaTechController.extend({
25 | /** @constructor */
26 | init: function (player, options, ready) {
27 | videojs.MediaTechController.call(this, player, options, ready);
28 |
29 | this.player_ = player;
30 | this.playerEl_ = this.player_.el();
31 |
32 | if (typeof this.player_.options().dmControls !== 'undefined') {
33 | var dmC = this.player_.options().dmControls = parseInt(this.player_.options().dmControls) &&
34 | this.player_.controls();
35 |
36 | if (dmC && this.player_.controls()) {
37 | this.player_.controls(!dmC);
38 | }
39 | }
40 |
41 |
42 | // Copy the Javascript options if they exist
43 | if (typeof options.source !== 'undefined') {
44 | for (var key in options.source) {
45 | if (options['source'].hasOwnProperty(key)) {
46 | this.player_.options()[key] = options.source[key];
47 | }
48 | }
49 | }
50 |
51 | var self = this;
52 |
53 |
54 | this.bindedWaiting = function () {
55 | self.onWaiting();
56 | };
57 | this.player_.on('waiting', this.bindedWaiting);
58 |
59 | player.ready(function () {
60 | if (self.playOnReady && !self.player_.options()['dmControls']) {
61 | if (typeof self.player_.loadingSpinner !== 'undefined') {
62 | self.player_.loadingSpinner.show();
63 | }
64 | if (typeof self.player_.bigPlayButton !== 'undefined') {
65 | self.player_.bigPlayButton.hide();
66 | }
67 | }
68 |
69 | player.trigger('loadstart');
70 | });
71 |
72 | this.videoId = this.parseSrc(this.player_.options().src);
73 |
74 | if (typeof this.videoId !== 'undefined') {
75 | // Show the Dailymotion poster only if we don't use Dailymotion poster
76 | // (otherwise the controls pop, it's not nice)
77 | if (!this.player_.options().dmControls) {
78 | // Set the Dailymotion poster only if none is specified
79 | if (typeof this.player_.poster() === 'undefined') {
80 | // Don't use player.poster(), it will fail here because the tech is still null in constructor
81 | this.player_.poster();
82 | // Cover the entire iframe to have the same poster than Dailymotion
83 | // Doesn't exist right away because the DOM hasn't created it
84 | setTimeout(function () {
85 | var posterEl = self.playerEl_.querySelectorAll('.vjs-poster')[0];
86 | posterEl.style.backgroundImage = 'url(//api.dailymotion.com/video/' + self.videoId + '?fields=url&ads=false)';
87 | posterEl.style.display = '';
88 | posterEl.style.backgroundSize = 'cover';
89 | }, 100);
90 | }
91 | }
92 | }
93 |
94 | this.id_ = this.player_.id() + '_dailymotion_api';
95 |
96 | this.el_ = videojs.Component.prototype.createEl('iframe', {
97 | id: this.id_,
98 | className: 'vjs-tech',
99 | scrolling: 'no',
100 | marginWidth: 0,
101 | marginHeight: 0,
102 | frameBorder: 0,
103 | webkitAllowFullScreen: '',
104 | mozallowfullscreen: '',
105 | allowFullScreen: ''
106 | });
107 |
108 | this.playerEl_.insertBefore(this.el_, this.playerEl_.firstChild);
109 |
110 | if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
111 | var ieVersion = Number(RegExp.$1);
112 | this.addIframeBlocker(ieVersion);
113 | } else if (!/(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent)) {
114 | // the pointer-events: none block the mobile player
115 | this.el_.className += ' onDesktop';
116 | this.addIframeBlocker();
117 | }
118 |
119 | this.params = {
120 | id: this.id_,
121 | autoplay: (this.player_.options().autoplay) ? 1 : 0,
122 | chromeless: (this.player_.options().dmControls) ? 0 : 1,
123 | html: 1,
124 | info: 1,
125 | logo: 1,
126 | controls: 'html',
127 | wmode: 'opaque',
128 | format: 'json',
129 | url: this.player_.options().src
130 | };
131 |
132 | if (typeof this.params.list === 'undefined') {
133 | delete this.params.list;
134 | }
135 |
136 | // Make autoplay work for iOS
137 | if (this.player_.options().autoplay) {
138 | this.player_.bigPlayButton.hide();
139 | this.playOnReady = true;
140 | }
141 |
142 | // If we are not on a server, don't specify the origin (it will crash)
143 | if (window.location.protocol !== 'file:') {
144 | this.params.origin = window.location.protocol + '//' + window.location.hostname;
145 | }
146 |
147 |
148 | this.el_.src = '//www.dailymotion.com/services/oembed?' + videojs.Dailymotion.makeQueryString(this.params);
149 |
150 | if (videojs.Dailymotion.apiReady) {
151 | this.loadApi();
152 | } else {
153 | // Add to the queue because the Dailymotion API is not ready
154 | videojs.Dailymotion.loadingQueue.push(this);
155 |
156 | // Load the Dailymotion API if it is the first Dailymotion video
157 | if (!videojs.Dailymotion.apiLoading) {
158 | var tag = document.createElement('script');
159 | tag.onerror = function (e) {
160 | self.onError(e);
161 | };
162 | tag.src = '//api.dmcdn.net/all.js';
163 | var firstScriptTag = document.getElementsByTagName('script')[0];
164 | firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
165 | videojs.Dailymotion.apiLoading = true;
166 | }
167 | }
168 |
169 | }
170 | });
171 |
172 | videojs.Dailymotion.prototype.params = [];
173 |
174 |
175 | videojs.Dailymotion.prototype.onWaiting = function (/*e*/) {
176 | // Make sure to hide the play button while the spinner is there
177 | if (typeof this.player_.bigPlayButton !== 'undefined') {
178 | this.player_.bigPlayButton.hide();
179 | }
180 | };
181 |
182 | videojs.Dailymotion.prototype.addIframeBlocker = function (ieVersion) {
183 |
184 | if (this.player_.options().dmControls) {
185 | return false;
186 | }
187 |
188 | this.iframeblocker = videojs.Component.prototype.createEl('div');
189 |
190 | this.iframeblocker.className = 'iframeblocker';
191 |
192 | this.iframeblocker.style.position = 'absolute';
193 | this.iframeblocker.style.left = 0;
194 | this.iframeblocker.style.right = 0;
195 | this.iframeblocker.style.top = 0;
196 | this.iframeblocker.style.bottom = 0;
197 |
198 | // Odd quirk for IE8 (doesn't support rgba)
199 | if (ieVersion && ieVersion < 9) {
200 | this.iframeblocker.style.opacity = 0.01;
201 | } else {
202 | this.iframeblocker.style.background = 'rgba(255, 255, 255, 0.01)';
203 | }
204 |
205 | var self = this;
206 |
207 | addEventListener(this.iframeblocker, 'mousemove', function (e) {
208 | if (!self.player_.userActive()) {
209 | self.player_.userActive(true);
210 | }
211 |
212 | e.stopPropagation();
213 | e.preventDefault();
214 | });
215 |
216 | addEventListener(this.iframeblocker, 'click', function (/*e*/) {
217 | if (self.paused()) {
218 | self.play();
219 | } else {
220 | self.pause();
221 | }
222 | });
223 |
224 | this.playerEl_.insertBefore(this.iframeblocker, this.el_.nextSibling);
225 | };
226 |
227 | videojs.Dailymotion.prototype.dispose = function () {
228 | if (this.dmPlayer) {
229 | this.pause();
230 | for (var i = 0; i < this.dmPlayer.listeners.length; i++) {
231 | var listener = this.dmPlayer.listeners[i];
232 | this.dmPlayer.removeEventListener(listener.event, listener.func);
233 | }
234 | this.dmPlayer = null;
235 | }
236 |
237 | // Remove the poster
238 | this.playerEl_.querySelectorAll('.vjs-poster')[0].style.backgroundImage = 'none';
239 |
240 | // If still connected to the DOM, remove it.
241 | var el = document.getElementById(this.id_);
242 | if (el.parentNode) {
243 | el.parentNode.removeChild(el);
244 | }
245 |
246 | if (typeof this.player_.loadingSpinner !== 'undefined') {
247 | this.player_.loadingSpinner.hide();
248 | }
249 | if (typeof this.player_.bigPlayButton !== 'undefined') {
250 | this.player_.bigPlayButton.hide();
251 | }
252 |
253 | videojs.MediaTechController.prototype.dispose.call(this);
254 | };
255 |
256 | videojs.Dailymotion.prototype.src = function (src) {
257 | if (typeof src !== 'undefined') {
258 | this.dmPlayer.load(this.parseSrc(src));
259 | }
260 | return this.srcVal;
261 | };
262 |
263 | videojs.Dailymotion.prototype.currentSrc = function () {
264 | return this.srcVal;
265 | };
266 |
267 | videojs.Dailymotion.prototype.play = function () {
268 | if (this.isReady_) {
269 | this.dmPlayer.play();
270 | } else {
271 | // We will play it when the API will be ready
272 | this.playOnReady = true;
273 |
274 | if (!this.player_.options.dmControls) {
275 | // Keep the big play button until it plays for real
276 | this.player_.bigPlayButton.show();
277 | }
278 | }
279 | };
280 |
281 | videojs.Dailymotion.prototype.ended = function () {
282 |
283 | if (this.isReady_) {
284 | var stateId = this.dmPlayer.getPlayerState();
285 | return stateId === 0;
286 | } else {
287 | // We will play it when the API will be ready
288 | return false;
289 | }
290 | };
291 |
292 | videojs.Dailymotion.prototype.pause = function () {
293 | this.dmPlayer.pause(!this.dmPlayer.paused);
294 | };
295 |
296 | videojs.Dailymotion.prototype.paused = function () {
297 | return this.dmPlayer.paused;
298 | };
299 |
300 | videojs.Dailymotion.prototype.currentTime = function () {
301 | return (this.dmPlayer && this.dmPlayer.currentTime) ? this.dmPlayer.currentTime : 0;
302 | };
303 |
304 | videojs.Dailymotion.prototype.setCurrentTime = function (seconds) {
305 | this.dmPlayer.seek(seconds, true);
306 | this.player_.trigger('timeupdate');
307 | };
308 |
309 | videojs.Dailymotion.prototype.duration = function () {
310 | return (this.dmPlayer && this.dmPlayer.duration) ? this.dmPlayer.duration : 0;
311 | };
312 |
313 | videojs.Dailymotion.prototype.buffered = function () {
314 | /*var loadedBytes = this.dmPlayer.getVideoBytesLoaded();
315 | var totalBytes = this.dmPlayer.getVideoBytesTotal();
316 | if (!loadedBytes || !totalBytes) return 0;
317 |
318 | var duration = this.dmPlayer.getDuration();
319 | var secondsBuffered = (loadedBytes / totalBytes) * duration;
320 | var secondsOffset = (this.dmPlayer.getCurrentTime() / totalBytes) * duration;
321 | return videojs.createTimeRange(secondsOffset, secondsOffset + secondsBuffered);*/
322 | return [];
323 | };
324 |
325 | videojs.Dailymotion.prototype.volume = function () {
326 | if (isNaN(this.volumeVal)) {
327 | this.volumeVal = this.dmPlayer.volume;
328 | }
329 |
330 | return this.volumeVal;
331 | };
332 |
333 | videojs.Dailymotion.prototype.setVolume = function (percentAsDecimal) {
334 | if (typeof(percentAsDecimal) !== 'undefined' && percentAsDecimal !== this.volumeVal) {
335 | this.dmPlayer.setVolume(percentAsDecimal);
336 | this.volumeVal = percentAsDecimal;
337 | this.player_.trigger('volumechange');
338 | }
339 | };
340 |
341 | videojs.Dailymotion.prototype.muted = function () {
342 | return this.dmPlayer.muted;
343 | };
344 | videojs.Dailymotion.prototype.setMuted = function (muted) {
345 | this.dmPlayer.setMuted(muted);
346 |
347 | var self = this;
348 | setTimeout(function () {
349 | self.player_.trigger('volumechange');
350 | }, 50);
351 | };
352 |
353 | videojs.Dailymotion.prototype.onReady = function () {
354 | this.isReady_ = true;
355 | this.player_.trigger('techready');
356 |
357 | // Hide the poster when ready because Dailymotion has it's own
358 | this.triggerReady();
359 | this.player_.trigger('durationchange');
360 |
361 | // Play right away if we clicked before ready
362 | if (this.playOnReady) {
363 | this.dmPlayer.play();
364 | }
365 | };
366 |
367 |
368 | videojs.Dailymotion.isSupported = function () {
369 | return true;
370 | };
371 |
372 | videojs.Dailymotion.prototype.supportsFullScreen = function () {
373 | return false;
374 | };
375 |
376 | videojs.Dailymotion.canPlaySource = function (srcObj) {
377 | return (srcObj.type === 'video/dailymotion');
378 | };
379 |
380 | // All videos created before Dailymotion API is loaded
381 | videojs.Dailymotion.loadingQueue = [];
382 |
383 |
384 | videojs.Dailymotion.prototype.load = function () {
385 | };
386 |
387 | // Create the Dailymotion player
388 | videojs.Dailymotion.prototype.loadApi = function () {
389 |
390 | this.dmPlayer = new DM.player(this.id_, {
391 | video: this.videoId,
392 | width: this.options.width,
393 | height: this.options.height,
394 | params: this.params
395 | });
396 |
397 |
398 | this.setupTriggers();
399 |
400 | this.dmPlayer.vjsTech = this;
401 | };
402 |
403 | videojs.Dailymotion.prototype.onStateChange = function (event) {
404 | var state = event.type;
405 | if (state !== this.lastState) {
406 | switch (state) {
407 | case -1:
408 | this.player_.trigger('durationchange');
409 | break;
410 |
411 | case 'apiready':
412 | this.onReady();
413 | break;
414 |
415 | case 'ended':
416 |
417 | if (!this.player_.options().dmControls) {
418 | this.player_.bigPlayButton.show();
419 | }
420 | break;
421 |
422 | case 'play':
423 | this.player_.trigger('play');
424 | break;
425 |
426 | case 'playing':
427 | break;
428 |
429 | case 'pause':
430 | break;
431 | case 'durationchange':
432 | break;
433 |
434 | case 'timeupdate':
435 | // Hide the waiting spinner since Dailymotion has its own
436 | this.player_.loadingSpinner.hide();
437 | break;
438 | case 'progress':
439 | break;
440 |
441 | }
442 |
443 | this.lastState = state;
444 | }
445 | };
446 |
447 | videojs.Dailymotion.prototype.onError = function (error) {
448 | this.player_.error(error);
449 |
450 | if (error === 100 || error === 101 || error === 150) {
451 | this.player_.bigPlayButton.hide();
452 | this.player_.loadingSpinner.hide();
453 | this.player_.posterImage.hide();
454 | }
455 | };
456 |
457 | videojs.Dailymotion.makeQueryString = function (args) {
458 | var array = [];
459 | for (var key in args) {
460 | if (args.hasOwnProperty(key)) {
461 | array.push(encodeURIComponent(key) + '=' + encodeURIComponent(args[key]));
462 | }
463 | }
464 |
465 | return array.join('&');
466 | };
467 |
468 | videojs.Dailymotion.prototype.parseSrc = function (src) {
469 | this.srcVal = src;
470 |
471 | if (src) {
472 | // Regex that parse the video ID for any Dailymotion URL
473 | var regExp = /^.+dailymotion.com\/((video|hub)\/([^_]+))?[^#]*(#video=([^_&]+))?/;
474 | var match = src.match(regExp);
475 |
476 | return match ? match[5] || match[3] : null;
477 | }
478 | };
479 |
480 | videojs.Dailymotion.parsePlaylist = function (src) {
481 | // Check if we have a playlist
482 | var regExp = /[?&]list=([^#\&\?]+)/;
483 | var match = src.match(regExp);
484 |
485 | if (match !== null && match.length > 1) {
486 | return match[1];
487 | }
488 | };
489 |
490 | // Make video events trigger player events
491 | // May seem verbose here, but makes other APIs possible.
492 | videojs.Dailymotion.prototype.setupTriggers = function () {
493 | this.dmPlayer.listeners = [];
494 | for (var i = videojs.Dailymotion.Events.length - 1; i >= 0; i--) {
495 | //videojs.on(this.dmPlayer, videojs.Dailymotion.Events[i], videojs.bind(this, this.eventHandler));
496 | var listener = videojs.bind(this, this.eventHandler);
497 | this.dmPlayer.listeners.push({event: videojs.Dailymotion.Events[i], func: listener});
498 | this.dmPlayer.addEventListener(videojs.Dailymotion.Events[i], listener);
499 | }
500 | };
501 | // Triggers removed using this.off when disposed
502 |
503 | videojs.Dailymotion.prototype.eventHandler = function (e) {
504 | this.onStateChange(e);
505 | this.trigger(e);
506 | };
507 |
508 | // List of all HTML5 events (various uses).
509 | videojs.Dailymotion.Events = ('apiready,play,playing,pause,ended,canplay,' +
510 | 'canplaythrough,timeupdate,progress,seeking,seeked,volumechange,durationchange,fullscreenchange,error').split(',');
511 |
512 |
513 | // Called when Dailymotion API is ready to be used
514 | window.dmAsyncInit = function () {
515 | var dm;
516 | while ((dm = videojs.Dailymotion.loadingQueue.shift())) {
517 | dm.loadApi();
518 | }
519 | videojs.Dailymotion.loadingQueue = [];
520 | videojs.Dailymotion.apiReady = true;
521 | };
522 | })();
523 |
--------------------------------------------------------------------------------
/es5/videojs-dailymotion.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Dailymotion.js
3 | * Dailymotion Media Controller - Wrapper for HTML5 Media API
4 | */
5 | 'use strict';
6 |
7 | Object.defineProperty(exports, '__esModule', {
8 | value: true
9 | });
10 |
11 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
12 |
13 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
18 |
19 | function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
20 |
21 | var _videoJs = require('video.js');
22 |
23 | var _videoJs2 = _interopRequireDefault(_videoJs);
24 |
25 | var Component = _videoJs2['default'].getComponent('Component');
26 | var Tech = _videoJs2['default'].getComponent('Tech');
27 |
28 | /**
29 | * Dailymotion Media Controller - Wrapper for HTML5 Media API
30 | *
31 | * @param {Object=} options Object of option names and values
32 | * @param {Function=} ready Ready callback function
33 | * @extends Tech
34 | * @class Dailymotion
35 | */
36 |
37 | var Dailymotion = (function (_Tech) {
38 | _inherits(Dailymotion, _Tech);
39 |
40 | function Dailymotion(options, ready) {
41 | var _this = this;
42 |
43 | _classCallCheck(this, Dailymotion);
44 |
45 | _get(Object.getPrototypeOf(Dailymotion.prototype), 'constructor', this).call(this, options, ready);
46 |
47 | this.params = {
48 | id: this.options_.techId,
49 | autoplay: this.player_.options_.autoplay ? 1 : 0,
50 | chromeless: this.player_.options_.dmControls ? 0 : 1,
51 | html: 1,
52 | info: 1,
53 | logo: 1,
54 | controls: 'html',
55 | wmode: 'opaque',
56 | format: 'json',
57 | url: options.source.src
58 | };
59 |
60 | // If we are not on a server, don't specify the origin (it will crash)
61 | if (window.location.protocol !== 'file:') {
62 | this.params.origin = window.location.protocol + '//' + window.location.hostname;
63 | }
64 |
65 | this.videoId = this.parseSrc(options.source.src);
66 |
67 | if (typeof this.videoId !== 'undefined') {
68 | this.setTimeout(function () {
69 | _this.setPoster('//api.dailymotion.com/video/' + _this.videoId + '?fields=poster_url&ads=false');
70 | }, 100);
71 | }
72 |
73 | if (Dailymotion.isApiReady) {
74 | this.loadApi();
75 | } else {
76 | // Add to the queue because the Dailymotion API is not ready
77 | Dailymotion.apiReadyQueue.push(this);
78 | }
79 | }
80 |
81 | _createClass(Dailymotion, [{
82 | key: 'createEl',
83 | value: function createEl() {
84 |
85 | var el = _videoJs2['default'].createEl('iframe', {
86 | id: this.options_.techId,
87 | className: 'vjs-tech vjs-tech-dailymotion'
88 | });
89 |
90 | var iframeContainer = _videoJs2['default'].createEl('iframe', {
91 | scrolling: 'no',
92 | marginWidth: 0,
93 | marginHeight: 0,
94 | frameBorder: 0,
95 | webkitAllowFullScreen: '',
96 | mozallowfullscreen: '',
97 | allowFullScreen: ''
98 | });
99 |
100 | el.appendChild(iframeContainer);
101 |
102 | if (/MSIE (\d+\.\d+);/.test(navigator.userAgent) || !/(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent)) {
103 | var divBlocker = _videoJs2['default'].createEl('div', {
104 | className: 'vjs-iframe-blocker',
105 | style: 'position:absolute;top:0;left:0;width:100%;height:100%'
106 | });
107 |
108 | // In case the blocker is still there and we want to pause
109 | divBlocker.onclick = (function () {
110 | this.pause();
111 | }).bind(this);
112 |
113 | el.appendChild(divBlocker);
114 | }
115 |
116 | return el;
117 | }
118 | }, {
119 | key: 'loadApi',
120 | value: function loadApi() {
121 | this.dmPlayer = new DM.player(this.options_.techId, {
122 | video: this.videoId,
123 | width: this.options_.width,
124 | height: this.options_.height,
125 | params: this.params
126 | });
127 |
128 | this.setupTriggers();
129 |
130 | this.dmPlayer.vjsTech = this;
131 | }
132 | }, {
133 | key: 'parseSrc',
134 | value: function parseSrc(src) {
135 | if (src) {
136 | // Regex that parse the video ID for any Dailymotion URL
137 | var regExp = /^.+dailymotion.com\/((video|hub)\/([^_]+))?[^#]*(#video=([^_&]+))?/;
138 | var match = src.match(regExp);
139 |
140 | return match ? match[5] || match[3] : null;
141 | }
142 | }
143 | }, {
144 | key: 'setupTriggers',
145 | value: function setupTriggers() {
146 | this.dmPlayer.listeners = [];
147 | for (var i = Dailymotion.Events.length - 1; i >= 0; i--) {
148 | //videojs.on(this.dmPlayer, Dailymotion.Events[i], videojs.bind(this, this.eventHandler));
149 | var listener = _videoJs2['default'].bind(this, this.eventHandler);
150 | this.dmPlayer.listeners.push({ event: Dailymotion.Events[i], func: listener });
151 | this.dmPlayer.addEventListener(Dailymotion.Events[i], listener);
152 | }
153 | }
154 | }, {
155 | key: 'eventHandler',
156 | value: function eventHandler(e) {
157 | this.onStateChange(e);
158 | this.trigger(e);
159 | }
160 | }, {
161 | key: 'onStateChange',
162 | value: function onStateChange(event) {
163 | var state = event.type;
164 | if (state !== this.lastState) {
165 | switch (state) {
166 | case -1:
167 | break;
168 |
169 | case 'apiready':
170 | this.triggerReady();
171 | break;
172 |
173 | case 'video_end':
174 | this.trigger('ended');
175 | break;
176 |
177 | case 'ad_play':
178 | this.trigger('play');
179 | break;
180 |
181 | case 'video_start':
182 | case 'ad_start':
183 | this.trigger('playing');
184 | this.trigger('play');
185 | break;
186 |
187 | case 'play':
188 | break;
189 |
190 | case 'playing':
191 | break;
192 |
193 | case 'pause':
194 | break;
195 | case 'durationchange':
196 | break;
197 |
198 | case 'timeupdate':
199 | break;
200 | case 'progress':
201 | break;
202 |
203 | }
204 |
205 | this.lastState = state;
206 | }
207 | }
208 | }, {
209 | key: 'poster',
210 | value: function poster() {
211 | return this.poster_;
212 | }
213 | }, {
214 | key: 'setPoster',
215 | value: function setPoster(poster) {
216 | this.poster_ = poster;
217 | this.trigger('posterchange');
218 | }
219 |
220 | /**
221 | * Set video
222 | *
223 | * @param {Object=} src Source object
224 | * @method setSrc
225 | */
226 | }, {
227 | key: 'src',
228 | value: function src(_src) {
229 | if (typeof _src !== 'undefined') {
230 | this.src_ = this.parseSrc(_src);
231 | this.dmPlayer.load(this.src_);
232 | }
233 | return this.src_;
234 | }
235 | }, {
236 | key: 'currentSrc',
237 | value: function currentSrc() {
238 | return this.src_;
239 | }
240 | }, {
241 | key: 'play',
242 | value: function play() {
243 | if (this.isReady_) {
244 | this.dmPlayer.play();
245 | } else {
246 | if (!this.player_.options_.dmControls) {
247 | // Keep the big play button until it plays for real
248 | this.player_.bigPlayButton.show();
249 | }
250 | }
251 | }
252 | }, {
253 | key: 'ended',
254 | value: function ended() {
255 |
256 | if (this.isReady_) {
257 | var stateId = this.dmPlayer.getPlayerState();
258 | return stateId === 0;
259 | } else {
260 | // We will play it when the API will be ready
261 | return false;
262 | }
263 | }
264 | }, {
265 | key: 'pause',
266 | value: function pause() {
267 | this.dmPlayer.pause(!this.dmPlayer.paused);
268 | }
269 | }, {
270 | key: 'paused',
271 | value: function paused() {
272 | return this.dmPlayer.paused;
273 | }
274 | }, {
275 | key: 'currentTime',
276 | value: function currentTime() {
277 | return this.dmPlayer && this.dmPlayer.currentTime ? this.dmPlayer.currentTime : 0;
278 | }
279 | }, {
280 | key: 'setCurrentTime',
281 | value: function setCurrentTime(position) {
282 | this.dmPlayer.seek(position);
283 | }
284 | }, {
285 | key: 'duration',
286 | value: function duration() {
287 | return this.dmPlayer && this.dmPlayer.duration ? this.dmPlayer.duration : 0;
288 | }
289 | }, {
290 | key: 'volume',
291 | value: function volume() {
292 | if (isNaN(this.volume_)) {
293 | this.volume_ = this.dmPlayer.volume;
294 | }
295 |
296 | return this.volume_;
297 | }
298 |
299 | /**
300 | * Request to enter fullscreen
301 | *
302 | * @method enterFullScreen
303 | */
304 | }, {
305 | key: 'enterFullScreen',
306 | value: function enterFullScreen() {
307 | this.dmPlayer.setFullscreen(true);
308 | }
309 |
310 | /**
311 | * Request to exit fullscreen
312 | *
313 | * @method exitFullScreen
314 | */
315 | }, {
316 | key: 'exitFullScreen',
317 | value: function exitFullScreen() {
318 | this.dmPlayer.setFullscreen(false);
319 | }
320 | }, {
321 | key: 'setVolume',
322 | value: function setVolume(percentAsDecimal) {
323 | if (typeof percentAsDecimal !== 'undefined' && percentAsDecimal !== this.volume_) {
324 | this.dmPlayer.setVolume(percentAsDecimal);
325 | this.volume_ = percentAsDecimal;
326 | this.player_.trigger('volumechange');
327 | }
328 | }
329 | }, {
330 | key: 'buffered',
331 | value: function buffered() {
332 | return [];
333 | }
334 | }, {
335 | key: 'controls',
336 | value: function controls() {
337 | return false;
338 | }
339 | }, {
340 | key: 'muted',
341 | value: function muted() {
342 | return this.dmPlayer.muted;
343 | }
344 | }, {
345 | key: 'setMuted',
346 | value: function setMuted(muted) {
347 | this.dmPlayer.setMuted(muted);
348 |
349 | this.setTimeout(function () {
350 | this.player_.trigger('volumechange');
351 | });
352 | }
353 | }, {
354 | key: 'supportsFullScreen',
355 | value: function supportsFullScreen() {
356 | return true;
357 | }
358 | }, {
359 | key: 'resetSrc_',
360 | value: function resetSrc_(callback) {
361 | callback();
362 | }
363 | }, {
364 | key: 'dispose',
365 | value: function dispose() {
366 | this.resetSrc_(Function.prototype);
367 | _get(Object.getPrototypeOf(Dailymotion.prototype), 'dispose', this).call(this, this);
368 | }
369 | }]);
370 |
371 | return Dailymotion;
372 | })(Tech);
373 |
374 | Dailymotion.prototype.options_ = {};
375 |
376 | Dailymotion.apiReadyQueue = [];
377 |
378 | Dailymotion.makeQueryString = function (args) {
379 | var querys = [];
380 | for (var key in args) {
381 | if (args.hasOwnProperty(key)) {
382 | querys.push(encodeURIComponent(key) + '=' + encodeURIComponent(args[key]));
383 | }
384 | }
385 |
386 | return querys.join('&');
387 | };
388 |
389 | var injectJs = function injectJs() {
390 | var tag = document.createElement('script');
391 | tag.src = '//api.dmcdn.net/all.js';
392 | var firstScriptTag = document.getElementsByTagName('script')[0];
393 | firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
394 | };
395 |
396 | /* Dailymotion Support Testing -------------------------------------------------------- */
397 |
398 | Dailymotion.isSupported = function () {
399 | return true;
400 | };
401 |
402 | // Add Source Handler pattern functions to this tech
403 | Tech.withSourceHandlers(Dailymotion);
404 |
405 | /*
406 | * The default native source handler.
407 | * This simply passes the source to the video element. Nothing fancy.
408 | *
409 | * @param {Object} source The source object
410 | * @param {Flash} tech The instance of the Flash tech
411 | */
412 | Dailymotion.nativeSourceHandler = {};
413 |
414 | /**
415 | * Check if Flash can play the given videotype
416 | * @param {String} type The mimetype to check
417 | * @return {String} 'probably', 'maybe', or '' (empty string)
418 | */
419 | Dailymotion.nativeSourceHandler.canPlayType = function (source) {
420 |
421 | var dashExtRE = /^video\/(dailymotion)/i;
422 |
423 | if (dashExtRE.test(source)) {
424 | return 'maybe';
425 | } else {
426 | return '';
427 | }
428 | };
429 |
430 | /*
431 | * Check Flash can handle the source natively
432 | *
433 | * @param {Object} source The source object
434 | * @return {String} 'probably', 'maybe', or '' (empty string)
435 | */
436 | Dailymotion.nativeSourceHandler.canHandleSource = function (source) {
437 |
438 | // If a type was provided we should rely on that
439 | if (source.type) {
440 | return Dailymotion.nativeSourceHandler.canPlayType(source.type);
441 | } else if (source.src) {
442 | return Dailymotion.nativeSourceHandler.canPlayType(source.src);
443 | }
444 |
445 | return '';
446 | };
447 |
448 | /*
449 | * Pass the source to the flash object
450 | * Adaptive source handlers will have more complicated workflows before passing
451 | * video data to the video element
452 | *
453 | * @param {Object} source The source object
454 | * @param {Flash} tech The instance of the Flash tech
455 | */
456 | Dailymotion.nativeSourceHandler.handleSource = function (source, tech) {
457 | tech.src(source.src);
458 | };
459 |
460 | /*
461 | * Clean up the source handler when disposing the player or switching sources..
462 | * (no cleanup is needed when supporting the format natively)
463 | */
464 | Dailymotion.nativeSourceHandler.dispose = function () {};
465 |
466 | // Register the native source handler
467 | Dailymotion.registerSourceHandler(Dailymotion.nativeSourceHandler);
468 |
469 | /*
470 | * Set the tech's volume control support status
471 | *
472 | * @type {Boolean}
473 | */
474 | Dailymotion.prototype['featuresVolumeControl'] = true;
475 |
476 | /*
477 | * Set the tech's playbackRate support status
478 | *
479 | * @type {Boolean}
480 | */
481 | Dailymotion.prototype['featuresPlaybackRate'] = false;
482 |
483 | /*
484 | * Set the tech's status on moving the video element.
485 | * In iOS, if you move a video element in the DOM, it breaks video playback.
486 | *
487 | * @type {Boolean}
488 | */
489 | Dailymotion.prototype['movingMediaElementInDOM'] = false;
490 |
491 | /*
492 | * Set the the tech's fullscreen resize support status.
493 | * HTML video is able to automatically resize when going to fullscreen.
494 | * (No longer appears to be used. Can probably be removed.)
495 | */
496 | Dailymotion.prototype['featuresFullscreenResize'] = false;
497 |
498 | /*
499 | * Set the tech's timeupdate event support status
500 | * (this disables the manual timeupdate events of the Tech)
501 | */
502 | Dailymotion.prototype['featuresTimeupdateEvents'] = false;
503 |
504 | /*
505 | * Set the tech's progress event support status
506 | * (this disables the manual progress events of the Tech)
507 | */
508 | Dailymotion.prototype['featuresProgressEvents'] = false;
509 |
510 | /*
511 | * Sets the tech's status on native text track support
512 | *
513 | * @type {Boolean}
514 | */
515 | Dailymotion.prototype['featuresNativeTextTracks'] = true;
516 |
517 | /*
518 | * Sets the tech's status on native audio track support
519 | *
520 | * @type {Boolean}
521 | */
522 | Dailymotion.prototype['featuresNativeAudioTracks'] = true;
523 |
524 | /*
525 | * Sets the tech's status on native video track support
526 | *
527 | * @type {Boolean}
528 | */
529 | Dailymotion.prototype['featuresNativeVideoTracks'] = false;
530 |
531 | Dailymotion.Events = 'apiready,ad_play,ad_start,ad_timeupdate,ad_pause,ad_end,video_start,video_end,play,playing,pause,ended,canplay,canplaythrough,timeupdate,progress,seeking,seeked,volumechange,durationchange,fullscreenchange,error'.split(',');
532 |
533 | _videoJs2['default'].options.Dailymotion = {};
534 |
535 | Component.registerComponent('Dailymotion', Dailymotion);
536 | Tech.registerTech('Dailymotion', Dailymotion);
537 |
538 | injectJs();
539 |
540 | // Called when Dailymotion API is ready to be used
541 | window.dmAsyncInit = function () {
542 | var dm;
543 | while (dm = Dailymotion.apiReadyQueue.shift()) {
544 | dm.loadApi();
545 | }
546 | Dailymotion.apiReadyQueue = [];
547 | Dailymotion.isApiReady = true;
548 | };
549 |
550 | exports['default'] = Dailymotion;
551 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/dist-test/videojs-dailymotion.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0;
384 | };
385 |
386 | /**
387 | * Test boolean.
388 | */
389 |
390 | /**
391 | * is.bool
392 | * Test if `value` is a boolean.
393 | *
394 | * @param {Mixed} value value to test
395 | * @return {Boolean} true if `value` is a boolean, false otherwise
396 | * @api public
397 | */
398 |
399 | is.bool = is['boolean'] = function (value) {
400 | return toStr.call(value) === '[object Boolean]';
401 | };
402 |
403 | /**
404 | * is.false
405 | * Test if `value` is false.
406 | *
407 | * @param {Mixed} value value to test
408 | * @return {Boolean} true if `value` is false, false otherwise
409 | * @api public
410 | */
411 |
412 | is['false'] = function (value) {
413 | return is.bool(value) && Boolean(Number(value)) === false;
414 | };
415 |
416 | /**
417 | * is.true
418 | * Test if `value` is true.
419 | *
420 | * @param {Mixed} value value to test
421 | * @return {Boolean} true if `value` is true, false otherwise
422 | * @api public
423 | */
424 |
425 | is['true'] = function (value) {
426 | return is.bool(value) && Boolean(Number(value)) === true;
427 | };
428 |
429 | /**
430 | * Test date.
431 | */
432 |
433 | /**
434 | * is.date
435 | * Test if `value` is a date.
436 | *
437 | * @param {Mixed} value value to test
438 | * @return {Boolean} true if `value` is a date, false otherwise
439 | * @api public
440 | */
441 |
442 | is.date = function (value) {
443 | return toStr.call(value) === '[object Date]';
444 | };
445 |
446 | /**
447 | * Test element.
448 | */
449 |
450 | /**
451 | * is.element
452 | * Test if `value` is an html element.
453 | *
454 | * @param {Mixed} value value to test
455 | * @return {Boolean} true if `value` is an HTML Element, false otherwise
456 | * @api public
457 | */
458 |
459 | is.element = function (value) {
460 | return value !== undefined
461 | && typeof HTMLElement !== 'undefined'
462 | && value instanceof HTMLElement
463 | && value.nodeType === 1;
464 | };
465 |
466 | /**
467 | * Test error.
468 | */
469 |
470 | /**
471 | * is.error
472 | * Test if `value` is an error object.
473 | *
474 | * @param {Mixed} value value to test
475 | * @return {Boolean} true if `value` is an error object, false otherwise
476 | * @api public
477 | */
478 |
479 | is.error = function (value) {
480 | return toStr.call(value) === '[object Error]';
481 | };
482 |
483 | /**
484 | * Test function.
485 | */
486 |
487 | /**
488 | * is.fn / is.function (deprecated)
489 | * Test if `value` is a function.
490 | *
491 | * @param {Mixed} value value to test
492 | * @return {Boolean} true if `value` is a function, false otherwise
493 | * @api public
494 | */
495 |
496 | is.fn = is['function'] = function (value) {
497 | var isAlert = typeof window !== 'undefined' && value === window.alert;
498 | return isAlert || toStr.call(value) === '[object Function]';
499 | };
500 |
501 | /**
502 | * Test number.
503 | */
504 |
505 | /**
506 | * is.number
507 | * Test if `value` is a number.
508 | *
509 | * @param {Mixed} value value to test
510 | * @return {Boolean} true if `value` is a number, false otherwise
511 | * @api public
512 | */
513 |
514 | is.number = function (value) {
515 | return toStr.call(value) === '[object Number]';
516 | };
517 |
518 | /**
519 | * is.infinite
520 | * Test if `value` is positive or negative infinity.
521 | *
522 | * @param {Mixed} value value to test
523 | * @return {Boolean} true if `value` is positive or negative Infinity, false otherwise
524 | * @api public
525 | */
526 | is.infinite = function (value) {
527 | return value === Infinity || value === -Infinity;
528 | };
529 |
530 | /**
531 | * is.decimal
532 | * Test if `value` is a decimal number.
533 | *
534 | * @param {Mixed} value value to test
535 | * @return {Boolean} true if `value` is a decimal number, false otherwise
536 | * @api public
537 | */
538 |
539 | is.decimal = function (value) {
540 | return is.number(value) && !isActualNaN(value) && !is.infinite(value) && value % 1 !== 0;
541 | };
542 |
543 | /**
544 | * is.divisibleBy
545 | * Test if `value` is divisible by `n`.
546 | *
547 | * @param {Number} value value to test
548 | * @param {Number} n dividend
549 | * @return {Boolean} true if `value` is divisible by `n`, false otherwise
550 | * @api public
551 | */
552 |
553 | is.divisibleBy = function (value, n) {
554 | var isDividendInfinite = is.infinite(value);
555 | var isDivisorInfinite = is.infinite(n);
556 | var isNonZeroNumber = is.number(value) && !isActualNaN(value) && is.number(n) && !isActualNaN(n) && n !== 0;
557 | return isDividendInfinite || isDivisorInfinite || (isNonZeroNumber && value % n === 0);
558 | };
559 |
560 | /**
561 | * is.integer
562 | * Test if `value` is an integer.
563 | *
564 | * @param value to test
565 | * @return {Boolean} true if `value` is an integer, false otherwise
566 | * @api public
567 | */
568 |
569 | is.integer = is['int'] = function (value) {
570 | return is.number(value) && !isActualNaN(value) && value % 1 === 0;
571 | };
572 |
573 | /**
574 | * is.maximum
575 | * Test if `value` is greater than 'others' values.
576 | *
577 | * @param {Number} value value to test
578 | * @param {Array} others values to compare with
579 | * @return {Boolean} true if `value` is greater than `others` values
580 | * @api public
581 | */
582 |
583 | is.maximum = function (value, others) {
584 | if (isActualNaN(value)) {
585 | throw new TypeError('NaN is not a valid value');
586 | } else if (!is.arraylike(others)) {
587 | throw new TypeError('second argument must be array-like');
588 | }
589 | var len = others.length;
590 |
591 | while (--len >= 0) {
592 | if (value < others[len]) {
593 | return false;
594 | }
595 | }
596 |
597 | return true;
598 | };
599 |
600 | /**
601 | * is.minimum
602 | * Test if `value` is less than `others` values.
603 | *
604 | * @param {Number} value value to test
605 | * @param {Array} others values to compare with
606 | * @return {Boolean} true if `value` is less than `others` values
607 | * @api public
608 | */
609 |
610 | is.minimum = function (value, others) {
611 | if (isActualNaN(value)) {
612 | throw new TypeError('NaN is not a valid value');
613 | } else if (!is.arraylike(others)) {
614 | throw new TypeError('second argument must be array-like');
615 | }
616 | var len = others.length;
617 |
618 | while (--len >= 0) {
619 | if (value > others[len]) {
620 | return false;
621 | }
622 | }
623 |
624 | return true;
625 | };
626 |
627 | /**
628 | * is.nan
629 | * Test if `value` is not a number.
630 | *
631 | * @param {Mixed} value value to test
632 | * @return {Boolean} true if `value` is not a number, false otherwise
633 | * @api public
634 | */
635 |
636 | is.nan = function (value) {
637 | return !is.number(value) || value !== value;
638 | };
639 |
640 | /**
641 | * is.even
642 | * Test if `value` is an even number.
643 | *
644 | * @param {Number} value value to test
645 | * @return {Boolean} true if `value` is an even number, false otherwise
646 | * @api public
647 | */
648 |
649 | is.even = function (value) {
650 | return is.infinite(value) || (is.number(value) && value === value && value % 2 === 0);
651 | };
652 |
653 | /**
654 | * is.odd
655 | * Test if `value` is an odd number.
656 | *
657 | * @param {Number} value value to test
658 | * @return {Boolean} true if `value` is an odd number, false otherwise
659 | * @api public
660 | */
661 |
662 | is.odd = function (value) {
663 | return is.infinite(value) || (is.number(value) && value === value && value % 2 !== 0);
664 | };
665 |
666 | /**
667 | * is.ge
668 | * Test if `value` is greater than or equal to `other`.
669 | *
670 | * @param {Number} value value to test
671 | * @param {Number} other value to compare with
672 | * @return {Boolean}
673 | * @api public
674 | */
675 |
676 | is.ge = function (value, other) {
677 | if (isActualNaN(value) || isActualNaN(other)) {
678 | throw new TypeError('NaN is not a valid value');
679 | }
680 | return !is.infinite(value) && !is.infinite(other) && value >= other;
681 | };
682 |
683 | /**
684 | * is.gt
685 | * Test if `value` is greater than `other`.
686 | *
687 | * @param {Number} value value to test
688 | * @param {Number} other value to compare with
689 | * @return {Boolean}
690 | * @api public
691 | */
692 |
693 | is.gt = function (value, other) {
694 | if (isActualNaN(value) || isActualNaN(other)) {
695 | throw new TypeError('NaN is not a valid value');
696 | }
697 | return !is.infinite(value) && !is.infinite(other) && value > other;
698 | };
699 |
700 | /**
701 | * is.le
702 | * Test if `value` is less than or equal to `other`.
703 | *
704 | * @param {Number} value value to test
705 | * @param {Number} other value to compare with
706 | * @return {Boolean} if 'value' is less than or equal to 'other'
707 | * @api public
708 | */
709 |
710 | is.le = function (value, other) {
711 | if (isActualNaN(value) || isActualNaN(other)) {
712 | throw new TypeError('NaN is not a valid value');
713 | }
714 | return !is.infinite(value) && !is.infinite(other) && value <= other;
715 | };
716 |
717 | /**
718 | * is.lt
719 | * Test if `value` is less than `other`.
720 | *
721 | * @param {Number} value value to test
722 | * @param {Number} other value to compare with
723 | * @return {Boolean} if `value` is less than `other`
724 | * @api public
725 | */
726 |
727 | is.lt = function (value, other) {
728 | if (isActualNaN(value) || isActualNaN(other)) {
729 | throw new TypeError('NaN is not a valid value');
730 | }
731 | return !is.infinite(value) && !is.infinite(other) && value < other;
732 | };
733 |
734 | /**
735 | * is.within
736 | * Test if `value` is within `start` and `finish`.
737 | *
738 | * @param {Number} value value to test
739 | * @param {Number} start lower bound
740 | * @param {Number} finish upper bound
741 | * @return {Boolean} true if 'value' is is within 'start' and 'finish'
742 | * @api public
743 | */
744 | is.within = function (value, start, finish) {
745 | if (isActualNaN(value) || isActualNaN(start) || isActualNaN(finish)) {
746 | throw new TypeError('NaN is not a valid value');
747 | } else if (!is.number(value) || !is.number(start) || !is.number(finish)) {
748 | throw new TypeError('all arguments must be numbers');
749 | }
750 | var isAnyInfinite = is.infinite(value) || is.infinite(start) || is.infinite(finish);
751 | return isAnyInfinite || (value >= start && value <= finish);
752 | };
753 |
754 | /**
755 | * Test object.
756 | */
757 |
758 | /**
759 | * is.object
760 | * Test if `value` is an object.
761 | *
762 | * @param {Mixed} value value to test
763 | * @return {Boolean} true if `value` is an object, false otherwise
764 | * @api public
765 | */
766 |
767 | is.object = function (value) {
768 | return toStr.call(value) === '[object Object]';
769 | };
770 |
771 | /**
772 | * is.hash
773 | * Test if `value` is a hash - a plain object literal.
774 | *
775 | * @param {Mixed} value value to test
776 | * @return {Boolean} true if `value` is a hash, false otherwise
777 | * @api public
778 | */
779 |
780 | is.hash = function (value) {
781 | return is.object(value) && value.constructor === Object && !value.nodeType && !value.setInterval;
782 | };
783 |
784 | /**
785 | * Test regexp.
786 | */
787 |
788 | /**
789 | * is.regexp
790 | * Test if `value` is a regular expression.
791 | *
792 | * @param {Mixed} value value to test
793 | * @return {Boolean} true if `value` is a regexp, false otherwise
794 | * @api public
795 | */
796 |
797 | is.regexp = function (value) {
798 | return toStr.call(value) === '[object RegExp]';
799 | };
800 |
801 | /**
802 | * Test string.
803 | */
804 |
805 | /**
806 | * is.string
807 | * Test if `value` is a string.
808 | *
809 | * @param {Mixed} value value to test
810 | * @return {Boolean} true if 'value' is a string, false otherwise
811 | * @api public
812 | */
813 |
814 | is.string = function (value) {
815 | return toStr.call(value) === '[object String]';
816 | };
817 |
818 | /**
819 | * Test base64 string.
820 | */
821 |
822 | /**
823 | * is.base64
824 | * Test if `value` is a valid base64 encoded string.
825 | *
826 | * @param {Mixed} value value to test
827 | * @return {Boolean} true if 'value' is a base64 encoded string, false otherwise
828 | * @api public
829 | */
830 |
831 | is.base64 = function (value) {
832 | return is.string(value) && (!value.length || base64Regex.test(value));
833 | };
834 |
835 | /**
836 | * Test base64 string.
837 | */
838 |
839 | /**
840 | * is.hex
841 | * Test if `value` is a valid hex encoded string.
842 | *
843 | * @param {Mixed} value value to test
844 | * @return {Boolean} true if 'value' is a hex encoded string, false otherwise
845 | * @api public
846 | */
847 |
848 | is.hex = function (value) {
849 | return is.string(value) && (!value.length || hexRegex.test(value));
850 | };
851 |
852 | /**
853 | * is.symbol
854 | * Test if `value` is an ES6 Symbol
855 | *
856 | * @param {Mixed} value value to test
857 | * @return {Boolean} true if `value` is a Symbol, false otherise
858 | * @api public
859 | */
860 |
861 | is.symbol = function (value) {
862 | return typeof Symbol === 'function' && toStr.call(value) === '[object Symbol]' && typeof symbolValueOf.call(value) === 'symbol';
863 | };
864 |
865 | },{}],5:[function(require,module,exports){
866 | (function (global){
867 | 'use strict';
868 |
869 | Object.defineProperty(exports, '__esModule', {
870 | value: true
871 | });
872 |
873 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
874 |
875 | var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null);
876 |
877 | var _videoJs2 = _interopRequireDefault(_videoJs);
878 |
879 | var _videojsDailymotion = require('./videojs-dailymotion');
880 |
881 | var _videojsDailymotion2 = _interopRequireDefault(_videojsDailymotion);
882 |
883 | /**
884 | * The video.js Dailymotion plugin.
885 | *
886 | * @param {Object} options
887 | */
888 | var plugin = function plugin(options) {
889 | dailymotion(this, options);
890 | };
891 |
892 | _videoJs2['default'].plugin('dailymotion', plugin);
893 |
894 | exports['default'] = plugin;
895 | module.exports = exports['default'];
896 |
897 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
898 | },{"./videojs-dailymotion":6}],6:[function(require,module,exports){
899 | (function (global){
900 | /**
901 | * @file Dailymotion.js
902 | * Dailymotion Media Controller - Wrapper for HTML5 Media API
903 | */
904 | 'use strict';
905 |
906 | Object.defineProperty(exports, '__esModule', {
907 | value: true
908 | });
909 |
910 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
911 |
912 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
913 |
914 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
915 |
916 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
917 |
918 | function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
919 |
920 | var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null);
921 |
922 | var _videoJs2 = _interopRequireDefault(_videoJs);
923 |
924 | var Component = _videoJs2['default'].getComponent('Component');
925 | var Tech = _videoJs2['default'].getComponent('Tech');
926 |
927 | /**
928 | * Dailymotion Media Controller - Wrapper for HTML5 Media API
929 | *
930 | * @param {Object=} options Object of option names and values
931 | * @param {Function=} ready Ready callback function
932 | * @extends Tech
933 | * @class Dailymotion
934 | */
935 |
936 | var Dailymotion = (function (_Tech) {
937 | _inherits(Dailymotion, _Tech);
938 |
939 | function Dailymotion(options, ready) {
940 | var _this = this;
941 |
942 | _classCallCheck(this, Dailymotion);
943 |
944 | _get(Object.getPrototypeOf(Dailymotion.prototype), 'constructor', this).call(this, options, ready);
945 |
946 | this.params = {
947 | id: this.options_.techId,
948 | autoplay: this.player_.options_.autoplay ? 1 : 0,
949 | chromeless: this.player_.options_.dmControls ? 0 : 1,
950 | html: 1,
951 | info: 1,
952 | logo: 1,
953 | controls: 'html',
954 | wmode: 'opaque',
955 | format: 'json',
956 | url: options.source.src
957 | };
958 |
959 | // If we are not on a server, don't specify the origin (it will crash)
960 | if (window.location.protocol !== 'file:') {
961 | this.params.origin = window.location.protocol + '//' + window.location.hostname;
962 | }
963 |
964 | this.videoId = this.parseSrc(options.source.src);
965 |
966 | if (typeof this.videoId !== 'undefined') {
967 | this.setTimeout(function () {
968 | _this.setPoster('//api.dailymotion.com/video/' + _this.videoId + '?fields=poster_url&ads=false');
969 | }, 100);
970 | }
971 |
972 | if (Dailymotion.isApiReady) {
973 | this.loadApi();
974 | } else {
975 | // Add to the queue because the Dailymotion API is not ready
976 | Dailymotion.apiReadyQueue.push(this);
977 | }
978 | }
979 |
980 | _createClass(Dailymotion, [{
981 | key: 'createEl',
982 | value: function createEl() {
983 |
984 | var el = _videoJs2['default'].createEl('iframe', {
985 | id: this.options_.techId,
986 | className: 'vjs-tech vjs-tech-dailymotion'
987 | });
988 |
989 | var iframeContainer = _videoJs2['default'].createEl('iframe', {
990 | scrolling: 'no',
991 | marginWidth: 0,
992 | marginHeight: 0,
993 | frameBorder: 0,
994 | webkitAllowFullScreen: '',
995 | mozallowfullscreen: '',
996 | allowFullScreen: ''
997 | });
998 |
999 | el.appendChild(iframeContainer);
1000 |
1001 | if (/MSIE (\d+\.\d+);/.test(navigator.userAgent) || !/(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent)) {
1002 | var divBlocker = _videoJs2['default'].createEl('div', {
1003 | className: 'vjs-iframe-blocker',
1004 | style: 'position:absolute;top:0;left:0;width:100%;height:100%'
1005 | });
1006 |
1007 | // In case the blocker is still there and we want to pause
1008 | divBlocker.onclick = (function () {
1009 | this.pause();
1010 | }).bind(this);
1011 |
1012 | el.appendChild(divBlocker);
1013 | }
1014 |
1015 | return el;
1016 | }
1017 | }, {
1018 | key: 'loadApi',
1019 | value: function loadApi() {
1020 | this.dmPlayer = new DM.player(this.options_.techId, {
1021 | video: this.videoId,
1022 | width: this.options_.width,
1023 | height: this.options_.height,
1024 | params: this.params
1025 | });
1026 |
1027 | this.setupTriggers();
1028 |
1029 | this.dmPlayer.vjsTech = this;
1030 | }
1031 | }, {
1032 | key: 'parseSrc',
1033 | value: function parseSrc(src) {
1034 | if (src) {
1035 | // Regex that parse the video ID for any Dailymotion URL
1036 | var regExp = /^.+dailymotion.com\/((video|hub)\/([^_]+))?[^#]*(#video=([^_&]+))?/;
1037 | var match = src.match(regExp);
1038 |
1039 | return match ? match[5] || match[3] : null;
1040 | }
1041 | }
1042 | }, {
1043 | key: 'setupTriggers',
1044 | value: function setupTriggers() {
1045 | this.dmPlayer.listeners = [];
1046 | for (var i = Dailymotion.Events.length - 1; i >= 0; i--) {
1047 | //videojs.on(this.dmPlayer, Dailymotion.Events[i], videojs.bind(this, this.eventHandler));
1048 | var listener = _videoJs2['default'].bind(this, this.eventHandler);
1049 | this.dmPlayer.listeners.push({ event: Dailymotion.Events[i], func: listener });
1050 | this.dmPlayer.addEventListener(Dailymotion.Events[i], listener);
1051 | }
1052 | }
1053 | }, {
1054 | key: 'eventHandler',
1055 | value: function eventHandler(e) {
1056 | this.onStateChange(e);
1057 | this.trigger(e);
1058 | }
1059 | }, {
1060 | key: 'onStateChange',
1061 | value: function onStateChange(event) {
1062 | var state = event.type;
1063 | if (state !== this.lastState) {
1064 | switch (state) {
1065 | case -1:
1066 | break;
1067 |
1068 | case 'apiready':
1069 | this.triggerReady();
1070 | break;
1071 |
1072 | case 'video_end':
1073 | this.trigger('ended');
1074 | break;
1075 |
1076 | case 'ad_play':
1077 | this.trigger('play');
1078 | break;
1079 |
1080 | case 'video_start':
1081 | case 'ad_start':
1082 | this.trigger('playing');
1083 | this.trigger('play');
1084 | break;
1085 |
1086 | case 'play':
1087 | break;
1088 |
1089 | case 'playing':
1090 | break;
1091 |
1092 | case 'pause':
1093 | break;
1094 | case 'durationchange':
1095 | break;
1096 |
1097 | case 'timeupdate':
1098 | break;
1099 | case 'progress':
1100 | break;
1101 |
1102 | }
1103 |
1104 | this.lastState = state;
1105 | }
1106 | }
1107 | }, {
1108 | key: 'poster',
1109 | value: function poster() {
1110 | return this.poster_;
1111 | }
1112 | }, {
1113 | key: 'setPoster',
1114 | value: function setPoster(poster) {
1115 | this.poster_ = poster;
1116 | this.trigger('posterchange');
1117 | }
1118 |
1119 | /**
1120 | * Set video
1121 | *
1122 | * @param {Object=} src Source object
1123 | * @method setSrc
1124 | */
1125 | }, {
1126 | key: 'src',
1127 | value: function src(_src) {
1128 | if (typeof _src !== 'undefined') {
1129 | this.src_ = this.parseSrc(_src);
1130 | this.dmPlayer.load(this.src_);
1131 | }
1132 | return this.src_;
1133 | }
1134 | }, {
1135 | key: 'currentSrc',
1136 | value: function currentSrc() {
1137 | return this.src_;
1138 | }
1139 | }, {
1140 | key: 'play',
1141 | value: function play() {
1142 | if (this.isReady_) {
1143 | this.dmPlayer.play();
1144 | } else {
1145 | if (!this.player_.options_.dmControls) {
1146 | // Keep the big play button until it plays for real
1147 | this.player_.bigPlayButton.show();
1148 | }
1149 | }
1150 | }
1151 | }, {
1152 | key: 'ended',
1153 | value: function ended() {
1154 |
1155 | if (this.isReady_) {
1156 | var stateId = this.dmPlayer.getPlayerState();
1157 | return stateId === 0;
1158 | } else {
1159 | // We will play it when the API will be ready
1160 | return false;
1161 | }
1162 | }
1163 | }, {
1164 | key: 'pause',
1165 | value: function pause() {
1166 | this.dmPlayer.pause(!this.dmPlayer.paused);
1167 | }
1168 | }, {
1169 | key: 'paused',
1170 | value: function paused() {
1171 | return this.dmPlayer.paused;
1172 | }
1173 | }, {
1174 | key: 'currentTime',
1175 | value: function currentTime() {
1176 | return this.dmPlayer && this.dmPlayer.currentTime ? this.dmPlayer.currentTime : 0;
1177 | }
1178 | }, {
1179 | key: 'setCurrentTime',
1180 | value: function setCurrentTime(position) {
1181 | this.dmPlayer.seek(position);
1182 | }
1183 | }, {
1184 | key: 'duration',
1185 | value: function duration() {
1186 | return this.dmPlayer && this.dmPlayer.duration ? this.dmPlayer.duration : 0;
1187 | }
1188 | }, {
1189 | key: 'volume',
1190 | value: function volume() {
1191 | if (isNaN(this.volume_)) {
1192 | this.volume_ = this.dmPlayer.volume;
1193 | }
1194 |
1195 | return this.volume_;
1196 | }
1197 |
1198 | /**
1199 | * Request to enter fullscreen
1200 | *
1201 | * @method enterFullScreen
1202 | */
1203 | }, {
1204 | key: 'enterFullScreen',
1205 | value: function enterFullScreen() {
1206 | this.dmPlayer.setFullscreen(true);
1207 | }
1208 |
1209 | /**
1210 | * Request to exit fullscreen
1211 | *
1212 | * @method exitFullScreen
1213 | */
1214 | }, {
1215 | key: 'exitFullScreen',
1216 | value: function exitFullScreen() {
1217 | this.dmPlayer.setFullscreen(false);
1218 | }
1219 | }, {
1220 | key: 'setVolume',
1221 | value: function setVolume(percentAsDecimal) {
1222 | if (typeof percentAsDecimal !== 'undefined' && percentAsDecimal !== this.volume_) {
1223 | this.dmPlayer.setVolume(percentAsDecimal);
1224 | this.volume_ = percentAsDecimal;
1225 | this.player_.trigger('volumechange');
1226 | }
1227 | }
1228 | }, {
1229 | key: 'buffered',
1230 | value: function buffered() {
1231 | return [];
1232 | }
1233 | }, {
1234 | key: 'controls',
1235 | value: function controls() {
1236 | return false;
1237 | }
1238 | }, {
1239 | key: 'muted',
1240 | value: function muted() {
1241 | return this.dmPlayer.muted;
1242 | }
1243 | }, {
1244 | key: 'setMuted',
1245 | value: function setMuted(muted) {
1246 | this.dmPlayer.setMuted(muted);
1247 |
1248 | this.setTimeout(function () {
1249 | this.player_.trigger('volumechange');
1250 | });
1251 | }
1252 | }, {
1253 | key: 'supportsFullScreen',
1254 | value: function supportsFullScreen() {
1255 | return true;
1256 | }
1257 | }, {
1258 | key: 'resetSrc_',
1259 | value: function resetSrc_(callback) {
1260 | callback();
1261 | }
1262 | }, {
1263 | key: 'dispose',
1264 | value: function dispose() {
1265 | this.resetSrc_(Function.prototype);
1266 | _get(Object.getPrototypeOf(Dailymotion.prototype), 'dispose', this).call(this, this);
1267 | }
1268 | }]);
1269 |
1270 | return Dailymotion;
1271 | })(Tech);
1272 |
1273 | Dailymotion.prototype.options_ = {};
1274 |
1275 | Dailymotion.apiReadyQueue = [];
1276 |
1277 | Dailymotion.makeQueryString = function (args) {
1278 | var querys = [];
1279 | for (var key in args) {
1280 | if (args.hasOwnProperty(key)) {
1281 | querys.push(encodeURIComponent(key) + '=' + encodeURIComponent(args[key]));
1282 | }
1283 | }
1284 |
1285 | return querys.join('&');
1286 | };
1287 |
1288 | var injectJs = function injectJs() {
1289 | var tag = document.createElement('script');
1290 | tag.src = '//api.dmcdn.net/all.js';
1291 | var firstScriptTag = document.getElementsByTagName('script')[0];
1292 | firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
1293 | };
1294 |
1295 | /* Dailymotion Support Testing -------------------------------------------------------- */
1296 |
1297 | Dailymotion.isSupported = function () {
1298 | return true;
1299 | };
1300 |
1301 | // Add Source Handler pattern functions to this tech
1302 | Tech.withSourceHandlers(Dailymotion);
1303 |
1304 | /*
1305 | * The default native source handler.
1306 | * This simply passes the source to the video element. Nothing fancy.
1307 | *
1308 | * @param {Object} source The source object
1309 | * @param {Flash} tech The instance of the Flash tech
1310 | */
1311 | Dailymotion.nativeSourceHandler = {};
1312 |
1313 | /**
1314 | * Check if Flash can play the given videotype
1315 | * @param {String} type The mimetype to check
1316 | * @return {String} 'probably', 'maybe', or '' (empty string)
1317 | */
1318 | Dailymotion.nativeSourceHandler.canPlayType = function (source) {
1319 |
1320 | var dashExtRE = /^video\/(dailymotion)/i;
1321 |
1322 | if (dashExtRE.test(source)) {
1323 | return 'maybe';
1324 | } else {
1325 | return '';
1326 | }
1327 | };
1328 |
1329 | /*
1330 | * Check Flash can handle the source natively
1331 | *
1332 | * @param {Object} source The source object
1333 | * @return {String} 'probably', 'maybe', or '' (empty string)
1334 | */
1335 | Dailymotion.nativeSourceHandler.canHandleSource = function (source) {
1336 |
1337 | // If a type was provided we should rely on that
1338 | if (source.type) {
1339 | return Dailymotion.nativeSourceHandler.canPlayType(source.type);
1340 | } else if (source.src) {
1341 | return Dailymotion.nativeSourceHandler.canPlayType(source.src);
1342 | }
1343 |
1344 | return '';
1345 | };
1346 |
1347 | /*
1348 | * Pass the source to the flash object
1349 | * Adaptive source handlers will have more complicated workflows before passing
1350 | * video data to the video element
1351 | *
1352 | * @param {Object} source The source object
1353 | * @param {Flash} tech The instance of the Flash tech
1354 | */
1355 | Dailymotion.nativeSourceHandler.handleSource = function (source, tech) {
1356 | tech.src(source.src);
1357 | };
1358 |
1359 | /*
1360 | * Clean up the source handler when disposing the player or switching sources..
1361 | * (no cleanup is needed when supporting the format natively)
1362 | */
1363 | Dailymotion.nativeSourceHandler.dispose = function () {};
1364 |
1365 | // Register the native source handler
1366 | Dailymotion.registerSourceHandler(Dailymotion.nativeSourceHandler);
1367 |
1368 | /*
1369 | * Set the tech's volume control support status
1370 | *
1371 | * @type {Boolean}
1372 | */
1373 | Dailymotion.prototype['featuresVolumeControl'] = true;
1374 |
1375 | /*
1376 | * Set the tech's playbackRate support status
1377 | *
1378 | * @type {Boolean}
1379 | */
1380 | Dailymotion.prototype['featuresPlaybackRate'] = false;
1381 |
1382 | /*
1383 | * Set the tech's status on moving the video element.
1384 | * In iOS, if you move a video element in the DOM, it breaks video playback.
1385 | *
1386 | * @type {Boolean}
1387 | */
1388 | Dailymotion.prototype['movingMediaElementInDOM'] = false;
1389 |
1390 | /*
1391 | * Set the the tech's fullscreen resize support status.
1392 | * HTML video is able to automatically resize when going to fullscreen.
1393 | * (No longer appears to be used. Can probably be removed.)
1394 | */
1395 | Dailymotion.prototype['featuresFullscreenResize'] = false;
1396 |
1397 | /*
1398 | * Set the tech's timeupdate event support status
1399 | * (this disables the manual timeupdate events of the Tech)
1400 | */
1401 | Dailymotion.prototype['featuresTimeupdateEvents'] = false;
1402 |
1403 | /*
1404 | * Set the tech's progress event support status
1405 | * (this disables the manual progress events of the Tech)
1406 | */
1407 | Dailymotion.prototype['featuresProgressEvents'] = false;
1408 |
1409 | /*
1410 | * Sets the tech's status on native text track support
1411 | *
1412 | * @type {Boolean}
1413 | */
1414 | Dailymotion.prototype['featuresNativeTextTracks'] = true;
1415 |
1416 | /*
1417 | * Sets the tech's status on native audio track support
1418 | *
1419 | * @type {Boolean}
1420 | */
1421 | Dailymotion.prototype['featuresNativeAudioTracks'] = true;
1422 |
1423 | /*
1424 | * Sets the tech's status on native video track support
1425 | *
1426 | * @type {Boolean}
1427 | */
1428 | Dailymotion.prototype['featuresNativeVideoTracks'] = false;
1429 |
1430 | Dailymotion.Events = 'apiready,ad_play,ad_start,ad_timeupdate,ad_pause,ad_end,video_start,video_end,play,playing,pause,ended,canplay,canplaythrough,timeupdate,progress,seeking,seeked,volumechange,durationchange,fullscreenchange,error'.split(',');
1431 |
1432 | _videoJs2['default'].options.Dailymotion = {};
1433 |
1434 | Component.registerComponent('Dailymotion', Dailymotion);
1435 | Tech.registerTech('Dailymotion', Dailymotion);
1436 |
1437 | injectJs();
1438 |
1439 | // Called when Dailymotion API is ready to be used
1440 | window.dmAsyncInit = function () {
1441 | var dm;
1442 | while (dm = Dailymotion.apiReadyQueue.shift()) {
1443 | dm.loadApi();
1444 | }
1445 | Dailymotion.apiReadyQueue = [];
1446 | Dailymotion.isApiReady = true;
1447 | };
1448 |
1449 | exports['default'] = Dailymotion;
1450 | module.exports = exports['default'];
1451 |
1452 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1453 | },{}],7:[function(require,module,exports){
1454 | (function (global){
1455 | 'use strict';
1456 |
1457 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
1458 |
1459 | var _globalWindow = require('global/window');
1460 |
1461 | var _globalWindow2 = _interopRequireDefault(_globalWindow);
1462 |
1463 | var _qunit = (typeof window !== "undefined" ? window['QUnit'] : typeof global !== "undefined" ? global['QUnit'] : null);
1464 |
1465 | var _qunit2 = _interopRequireDefault(_qunit);
1466 |
1467 | var _srcVideojsDailymotion = require('../src/videojs-dailymotion');
1468 |
1469 | var _srcVideojsDailymotion2 = _interopRequireDefault(_srcVideojsDailymotion);
1470 |
1471 | var _playerProxy = require('./player-proxy');
1472 |
1473 | var _playerProxy2 = _interopRequireDefault(_playerProxy);
1474 |
1475 | _qunit2['default'].module('dailymotion', {
1476 |
1477 | beforeEach: function beforeEach() {
1478 | this.oldTimeout = _globalWindow2['default'].setTimeout;
1479 | _globalWindow2['default'].setTimeout = Function.prototype;
1480 | },
1481 |
1482 | afterEach: function afterEach() {
1483 | _globalWindow2['default'].setTimeout = this.oldTimeout;
1484 | }
1485 | });
1486 |
1487 | _qunit2['default'].test('chromecastMaker takes a player and returns a dailymotion plugin', function (assert) {
1488 | var chromecast = (0, _srcVideojsDailymotion2['default'])((0, _playerProxy2['default'])(), {});
1489 |
1490 | assert.equal(typeof chromecast, 'object', 'dailymotion is an object');
1491 | });
1492 |
1493 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1494 | },{"../src/videojs-dailymotion":6,"./player-proxy":8,"global/window":1}],8:[function(require,module,exports){
1495 | (function (global){
1496 | 'use strict';
1497 |
1498 | Object.defineProperty(exports, '__esModule', {
1499 | value: true
1500 | });
1501 |
1502 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
1503 |
1504 | var _nodeExtend = require('node.extend');
1505 |
1506 | var _nodeExtend2 = _interopRequireDefault(_nodeExtend);
1507 |
1508 | var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null);
1509 |
1510 | var _videoJs2 = _interopRequireDefault(_videoJs);
1511 |
1512 | var proxy = function proxy(props) {
1513 | var player = (0, _nodeExtend2['default'])(true, {}, _videoJs2['default'].EventTarget.prototype, {
1514 | play: Function.prototype,
1515 | paused: Function.prototype,
1516 | ended: Function.prototype,
1517 | poster: Function.prototype,
1518 | src: Function.prototype,
1519 | addRemoteTextTrack: Function.prototype,
1520 | removeRemoteTextTrack: Function.prototype,
1521 | remoteTextTracks: Function.prototype,
1522 | currentSrc: Function.prototype,
1523 | dailymotion: {}
1524 | }, props);
1525 |
1526 | player.constructor = _videoJs2['default'].getComponent('Player');
1527 | player.chromecast.player_ = player;
1528 |
1529 | return player;
1530 | };
1531 |
1532 | exports['default'] = proxy;
1533 | module.exports = exports['default'];
1534 |
1535 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1536 | },{"node.extend":2}],9:[function(require,module,exports){
1537 | (function (global){
1538 | 'use strict';
1539 |
1540 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
1541 |
1542 | var _qunit = (typeof window !== "undefined" ? window['QUnit'] : typeof global !== "undefined" ? global['QUnit'] : null);
1543 |
1544 | var _qunit2 = _interopRequireDefault(_qunit);
1545 |
1546 | var _sinon = (typeof window !== "undefined" ? window['sinon'] : typeof global !== "undefined" ? global['sinon'] : null);
1547 |
1548 | var _sinon2 = _interopRequireDefault(_sinon);
1549 |
1550 | var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null);
1551 |
1552 | var _videoJs2 = _interopRequireDefault(_videoJs);
1553 |
1554 | var _srcPlugin = require('../src/plugin');
1555 |
1556 | var _srcPlugin2 = _interopRequireDefault(_srcPlugin);
1557 |
1558 | _qunit2['default'].test('the environment is sane', function (assert) {
1559 | assert.strictEqual(typeof Array.isArray, 'function', 'es5 exists');
1560 | assert.strictEqual(typeof _sinon2['default'], 'object', 'sinon exists');
1561 | assert.strictEqual(typeof _videoJs2['default'], 'function', 'videojs exists');
1562 | assert.strictEqual(typeof _srcPlugin2['default'], 'function', 'plugin is a function');
1563 | });
1564 |
1565 | _qunit2['default'].test('registers itself with video.js', function (assert) {
1566 | assert.expect(1);
1567 | assert.strictEqual(_videoJs2['default'].getComponent('Player').prototype.dailymotion, _srcPlugin2['default'], 'videojs-dailymotion plugin was registered');
1568 | });
1569 |
1570 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1571 | },{"../src/plugin":5}]},{},[7,9]);
1572 |
--------------------------------------------------------------------------------