@oat-sa/tao-core-ui 1.5.4 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ckeditor/ckConfigurator.js +9 -1
- package/dist/mediaEditor/mediaEditorComponent.js +5 -3
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +46 -25
- package/dist/mediaplayer/css/player.css +104 -14
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +767 -0
- package/dist/mediaplayer/players/youtube.js +470 -0
- package/dist/mediaplayer/players.js +35 -0
- package/dist/mediaplayer/support.js +134 -0
- package/dist/mediaplayer/utils/reminder.js +198 -0
- package/dist/mediaplayer/utils/timeObserver.js +149 -0
- package/dist/mediaplayer/youtubeManager.js +177 -0
- package/dist/mediaplayer.js +1251 -1912
- package/dist/previewer.js +25 -19
- package/package.json +1 -1
- package/scss/basic.scss +1 -0
- package/scss/inc/_jquery.nouislider.scss +254 -0
- package/src/ckeditor/ckConfigurator.js +10 -1
- package/src/itemButtonList/css/item-button-list.css +225 -0
- package/src/itemButtonList/css/item-button-list.css.map +1 -0
- package/src/mediaEditor/mediaEditorComponent.js +25 -26
- package/src/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +83 -63
- package/src/mediaplayer/css/player.css +104 -14
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/mediaplayer/players/html5.js +564 -0
- package/src/mediaplayer/players/youtube.js +323 -0
- package/src/mediaplayer/players.js +29 -0
- package/src/mediaplayer/scss/player.scss +125 -16
- package/src/mediaplayer/support.js +126 -0
- package/src/mediaplayer/tpl/audio.tpl +6 -0
- package/src/mediaplayer/tpl/player.tpl +11 -32
- package/src/mediaplayer/tpl/source.tpl +1 -0
- package/src/mediaplayer/tpl/video.tpl +6 -0
- package/src/mediaplayer/tpl/youtube.tpl +1 -0
- package/src/mediaplayer/utils/reminder.js +184 -0
- package/src/mediaplayer/utils/timeObserver.js +143 -0
- package/src/mediaplayer/youtubeManager.js +161 -0
- package/src/mediaplayer.js +1217 -1901
- package/src/previewer.js +40 -33
- package/src/searchModal/css/advancedSearch.css +190 -0
- package/src/searchModal/css/advancedSearch.css.map +1 -0
- package/src/searchModal/css/searchModal.css +506 -0
- package/src/searchModal/css/searchModal.css.map +1 -0
package/dist/mediaplayer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/mimetype', 'core/store', 'handlebars', 'i18n', 'lib/dompurify/purify', 'css!ui/mediaplayer/css/player.css', 'nouislider'], function ($$1, _, async, UrlParser, eventifier, mimetype, store, Handlebars, __, DOMPurify, player_css, nouislider) { 'use strict';
|
|
1
|
+
define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/mimetype', 'core/store', 'ui/mediaplayer/support', 'ui/mediaplayer/players', 'handlebars', 'i18n', 'lib/dompurify/purify', 'css!ui/mediaplayer/css/player.css', 'nouislider'], function ($$1, _, async, UrlParser, eventifier, mimetype, store, support, players, Handlebars, __, DOMPurify, player_css, nouislider) { 'use strict';
|
|
2
2
|
|
|
3
3
|
$$1 = $$1 && $$1.hasOwnProperty('default') ? $$1['default'] : $$1;
|
|
4
4
|
_ = _ && _.hasOwnProperty('default') ? _['default'] : _;
|
|
@@ -7,6 +7,8 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
7
7
|
eventifier = eventifier && eventifier.hasOwnProperty('default') ? eventifier['default'] : eventifier;
|
|
8
8
|
mimetype = mimetype && mimetype.hasOwnProperty('default') ? mimetype['default'] : mimetype;
|
|
9
9
|
store = store && store.hasOwnProperty('default') ? store['default'] : store;
|
|
10
|
+
support = support && support.hasOwnProperty('default') ? support['default'] : support;
|
|
11
|
+
players = players && players.hasOwnProperty('default') ? players['default'] : players;
|
|
10
12
|
Handlebars = Handlebars && Handlebars.hasOwnProperty('default') ? Handlebars['default'] : Handlebars;
|
|
11
13
|
__ = __ && __.hasOwnProperty('default') ? __['default'] : __;
|
|
12
14
|
DOMPurify = DOMPurify && DOMPurify.hasOwnProperty('default') ? DOMPurify['default'] : DOMPurify;
|
|
@@ -125,146 +127,36 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
125
127
|
var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
126
128
|
this.compilerInfo = [4,'>= 1.0.0'];
|
|
127
129
|
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
128
|
-
var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression,
|
|
129
|
-
|
|
130
|
-
function program1(depth0,data) {
|
|
131
|
-
|
|
132
|
-
var buffer = "", stack1;
|
|
133
|
-
buffer += "\n ";
|
|
134
|
-
stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.is)),stack1 == null || stack1 === false ? stack1 : stack1.youtube), {hash:{},inverse:self.program(5, program5, data),fn:self.program(2, program2, data),data:data});
|
|
135
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
136
|
-
buffer += "\n ";
|
|
137
|
-
return buffer;
|
|
138
|
-
}
|
|
139
|
-
function program2(depth0,data) {
|
|
140
|
-
|
|
141
|
-
var buffer = "", stack1;
|
|
142
|
-
buffer += "\n ";
|
|
143
|
-
stack1 = helpers.each.call(depth0, (depth0 && depth0.sources), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
|
|
144
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
145
|
-
buffer += "\n ";
|
|
146
|
-
return buffer;
|
|
147
|
-
}
|
|
148
|
-
function program3(depth0,data) {
|
|
149
|
-
|
|
150
|
-
var buffer = "", stack1, helper;
|
|
151
|
-
buffer += "\n <div class=\"media video youtube\" data-video-src=\"";
|
|
152
|
-
if (helper = helpers.src) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
153
|
-
else { helper = (depth0 && depth0.src); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
154
|
-
buffer += escapeExpression(stack1)
|
|
155
|
-
+ "\" data-video-id=\"";
|
|
156
|
-
if (helper = helpers.id) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
157
|
-
else { helper = (depth0 && depth0.id); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
158
|
-
buffer += escapeExpression(stack1)
|
|
159
|
-
+ "\" data-type=\"youtube\"></div>\n ";
|
|
160
|
-
return buffer;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function program5(depth0,data) {
|
|
164
|
-
|
|
165
|
-
var buffer = "", stack1, helper, options;
|
|
166
|
-
buffer += "\n <video class=\"media video\" poster=\"";
|
|
167
|
-
if (helper = helpers.poster) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
168
|
-
else { helper = (depth0 && depth0.poster); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
169
|
-
buffer += escapeExpression(stack1)
|
|
170
|
-
+ "\" controls ";
|
|
171
|
-
stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.is)),stack1 == null || stack1 === false ? stack1 : stack1.cors), {hash:{},inverse:self.noop,fn:self.program(6, program6, data),data:data});
|
|
172
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
173
|
-
buffer += ">\n ";
|
|
174
|
-
stack1 = helpers.each.call(depth0, (depth0 && depth0.sources), {hash:{},inverse:self.noop,fn:self.program(8, program8, data),data:data});
|
|
175
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
176
|
-
buffer += "\n\n "
|
|
177
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Your browser doesn’t support the video player.", options) : helperMissing.call(depth0, "__", "Your browser doesn’t support the video player.", options)))
|
|
178
|
-
+ "\n ";
|
|
179
|
-
stack1 = helpers['if'].call(depth0, (depth0 && depth0.link), {hash:{},inverse:self.noop,fn:self.program(10, program10, data),data:data});
|
|
180
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
181
|
-
buffer += "\n </video>\n ";
|
|
182
|
-
return buffer;
|
|
183
|
-
}
|
|
184
|
-
function program6(depth0,data) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return "crossorigin";
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function program8(depth0,data) {
|
|
191
|
-
|
|
192
|
-
var buffer = "", stack1, helper;
|
|
193
|
-
buffer += "\n <source src=\"";
|
|
194
|
-
if (helper = helpers.src) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
195
|
-
else { helper = (depth0 && depth0.src); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
196
|
-
buffer += escapeExpression(stack1)
|
|
197
|
-
+ "\" type=\"";
|
|
198
|
-
if (helper = helpers.type) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
199
|
-
else { helper = (depth0 && depth0.type); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
200
|
-
buffer += escapeExpression(stack1)
|
|
201
|
-
+ "\">\n ";
|
|
202
|
-
return buffer;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function program10(depth0,data) {
|
|
206
|
-
|
|
207
|
-
var buffer = "", stack1, helper, options;
|
|
208
|
-
buffer += "\n <a href=\"";
|
|
209
|
-
if (helper = helpers.link) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
210
|
-
else { helper = (depth0 && depth0.link); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
211
|
-
buffer += escapeExpression(stack1)
|
|
212
|
-
+ "\">"
|
|
213
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Please download the video and view offline.", options) : helperMissing.call(depth0, "__", "Please download the video and view offline.", options)))
|
|
214
|
-
+ "</a>\n ";
|
|
215
|
-
return buffer;
|
|
216
|
-
}
|
|
130
|
+
var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing;
|
|
217
131
|
|
|
218
|
-
function program12(depth0,data) {
|
|
219
|
-
|
|
220
|
-
var buffer = "", stack1, helper, options;
|
|
221
|
-
buffer += "\n <audio class=\"media audio\" controls ";
|
|
222
|
-
stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.is)),stack1 == null || stack1 === false ? stack1 : stack1.cors), {hash:{},inverse:self.noop,fn:self.program(6, program6, data),data:data});
|
|
223
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
224
|
-
buffer += ">\n ";
|
|
225
|
-
stack1 = helpers.each.call(depth0, (depth0 && depth0.sources), {hash:{},inverse:self.noop,fn:self.program(8, program8, data),data:data});
|
|
226
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
227
|
-
buffer += "\n\n "
|
|
228
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Your browser doesn’t support the audio player.", options) : helperMissing.call(depth0, "__", "Your browser doesn’t support the audio player.", options)))
|
|
229
|
-
+ "\n ";
|
|
230
|
-
stack1 = helpers['if'].call(depth0, (depth0 && depth0.link), {hash:{},inverse:self.noop,fn:self.program(13, program13, data),data:data});
|
|
231
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
232
|
-
buffer += "\n </audio>\n ";
|
|
233
|
-
return buffer;
|
|
234
|
-
}
|
|
235
|
-
function program13(depth0,data) {
|
|
236
|
-
|
|
237
|
-
var buffer = "", stack1, helper, options;
|
|
238
|
-
buffer += "\n <a href=\"";
|
|
239
|
-
if (helper = helpers.link) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
240
|
-
else { helper = (depth0 && depth0.link); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
241
|
-
buffer += escapeExpression(stack1)
|
|
242
|
-
+ "\">"
|
|
243
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Please download the track and listen offline.", options) : helperMissing.call(depth0, "__", "Please download the track and listen offline.", options)))
|
|
244
|
-
+ "</a>\n ";
|
|
245
|
-
return buffer;
|
|
246
|
-
}
|
|
247
132
|
|
|
248
133
|
buffer += "<div class=\"mediaplayer ";
|
|
249
134
|
if (helper = helpers.type) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
250
135
|
else { helper = (depth0 && depth0.type); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
251
136
|
buffer += escapeExpression(stack1)
|
|
252
|
-
+ "\">\n <div class=\"player\">\n
|
|
253
|
-
stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.is)),stack1 == null || stack1 === false ? stack1 : stack1.video), {hash:{},inverse:self.program(12, program12, data),fn:self.program(1, program1, data),data:data});
|
|
254
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
255
|
-
buffer += "\n <div class=\"overlay\">\n <a class=\"action play\" data-control=\"play\"><span class=\"icon icon-play\" title=\""
|
|
137
|
+
+ "\">\n <div class=\"player\">\n <div class=\"player-overlay\">\n <a class=\"action play\" data-control=\"play\"><span class=\"icon icon-play\" title=\""
|
|
256
138
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Play", options) : helperMissing.call(depth0, "__", "Play", options)))
|
|
257
139
|
+ "\"></span></a>\n <a class=\"action play\" data-control=\"pause\"><span class=\"icon icon-pause\" title=\""
|
|
258
140
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Pause", options) : helperMissing.call(depth0, "__", "Pause", options)))
|
|
259
|
-
+ "\"></span></a>\n
|
|
141
|
+
+ "\"></span></a>\n <a class=\"action reload\" data-control=\"start\">\n <span class=\"icon icon-play\" title=\""
|
|
142
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Start", options) : helperMissing.call(depth0, "__", "Start", options)))
|
|
143
|
+
+ "\"></span>\n <div class=\"message\">"
|
|
144
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Click to start", options) : helperMissing.call(depth0, "__", "Click to start", options)))
|
|
145
|
+
+ "</div>\n </a>\n <a class=\"action reload\" data-control=\"reload\">\n <div class=\"icon icon-reload\" title=\""
|
|
146
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Reload", options) : helperMissing.call(depth0, "__", "Reload", options)))
|
|
147
|
+
+ "\"></div>\n <div class=\"message\">"
|
|
148
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "You are encountering a prolonged connectivity loss.", options) : helperMissing.call(depth0, "__", "You are encountering a prolonged connectivity loss.", options)))
|
|
149
|
+
+ " "
|
|
150
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Click to reload.", options) : helperMissing.call(depth0, "__", "Click to reload.", options)))
|
|
151
|
+
+ "</div>\n </a>\n </div>\n </div>\n <div class=\"controls\">\n <div class=\"bar\">\n <div class=\"control actions playback\">\n <a class=\"action play\" data-control=\"play\" title=\""
|
|
260
152
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Play", options) : helperMissing.call(depth0, "__", "Play", options)))
|
|
261
153
|
+ "\"><span class=\"icon icon-play\"></span></a>\n <a class=\"action play\" data-control=\"pause\" title=\""
|
|
262
154
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Pause", options) : helperMissing.call(depth0, "__", "Pause", options)))
|
|
263
155
|
+ "\"><span class=\"icon icon-pause\"></span></a>\n </div>\n <div class=\"control seek\"><div class=\"slider\"></div></div>\n <div class=\"control infos timer\">\n <span class=\"info time\" data-control=\"time-cur\" title=\""
|
|
264
156
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Current playback position", options) : helperMissing.call(depth0, "__", "Current playback position", options)))
|
|
265
|
-
+ "\"
|
|
157
|
+
+ "\">--:--</span>\n <span class=\"info time\" data-control=\"time-end\" title=\""
|
|
266
158
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Total duration", options) : helperMissing.call(depth0, "__", "Total duration", options)))
|
|
267
|
-
+ "\"
|
|
159
|
+
+ "\">--:--</span>\n </div>\n <div class=\"control actions sound\">\n <div class=\"volume\"><div class=\"slider\"></div></div>\n <a class=\"action mute\" data-control=\"mute\" title=\""
|
|
268
160
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Mute", options) : helperMissing.call(depth0, "__", "Mute", options)))
|
|
269
161
|
+ "\"><span class=\"icon icon-sound\"></span></a>\n <a class=\"action mute\" data-control=\"unmute\" title=\""
|
|
270
162
|
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Restore sound", options) : helperMissing.call(depth0, "__", "Restore sound", options)))
|
|
@@ -293,151 +185,88 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
293
185
|
* along with this program; if not, write to the Free Software
|
|
294
186
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
295
187
|
*
|
|
296
|
-
* Copyright (c) 2015 (original work) Open Assessment Technologies SA ;
|
|
188
|
+
* Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;
|
|
297
189
|
*/
|
|
298
190
|
/**
|
|
299
191
|
* CSS namespace
|
|
300
192
|
* @type {String}
|
|
301
|
-
* @private
|
|
302
|
-
*/
|
|
303
|
-
|
|
304
|
-
var _ns = '.mediaplayer';
|
|
305
|
-
/**
|
|
306
|
-
* A Regex to extract ID from Youtube URLs
|
|
307
|
-
* @type {RegExp}
|
|
308
|
-
* @private
|
|
309
193
|
*/
|
|
310
194
|
|
|
311
|
-
var
|
|
312
|
-
/**
|
|
313
|
-
* A Regex to detect Apple mobile browsers
|
|
314
|
-
* @type {RegExp}
|
|
315
|
-
* @private
|
|
316
|
-
*/
|
|
317
|
-
|
|
318
|
-
var _reAppleMobiles = /ip(hone|od)/i;
|
|
319
|
-
/**
|
|
320
|
-
* Array slice method needed to slice arguments
|
|
321
|
-
* @type {Function}
|
|
322
|
-
* @private
|
|
323
|
-
*/
|
|
324
|
-
|
|
325
|
-
var _slice = [].slice;
|
|
195
|
+
var ns = '.mediaplayer';
|
|
326
196
|
/**
|
|
327
197
|
* Minimum value of the volume
|
|
328
198
|
* @type {Number}
|
|
329
|
-
* @private
|
|
330
199
|
*/
|
|
331
200
|
|
|
332
|
-
var
|
|
201
|
+
var volumeMin = 0;
|
|
333
202
|
/**
|
|
334
203
|
* Maximum value of the volume
|
|
335
204
|
* @type {Number}
|
|
336
|
-
* @private
|
|
337
|
-
*/
|
|
338
|
-
|
|
339
|
-
var _volumeMax = 100;
|
|
340
|
-
/**
|
|
341
|
-
* Range value of the volume
|
|
342
|
-
* @type {Number}
|
|
343
|
-
* @private
|
|
344
205
|
*/
|
|
345
206
|
|
|
346
|
-
var
|
|
207
|
+
var volumeMax = 100;
|
|
347
208
|
/**
|
|
348
|
-
* Threshold (
|
|
209
|
+
* Threshold (minimum required space above the player) to display the volume
|
|
349
210
|
* above the bar.
|
|
350
211
|
* @type {Number}
|
|
351
212
|
*/
|
|
352
213
|
|
|
353
|
-
|
|
354
214
|
var volumePositionThreshold = 200;
|
|
355
215
|
/**
|
|
356
216
|
* Some default values
|
|
357
217
|
* @type {Object}
|
|
358
|
-
* @private
|
|
359
218
|
*/
|
|
360
219
|
|
|
361
|
-
var
|
|
220
|
+
var defaults = {
|
|
362
221
|
type: 'video/mp4',
|
|
363
222
|
video: {
|
|
364
|
-
width:
|
|
365
|
-
height:
|
|
366
|
-
minWidth: 200,
|
|
367
|
-
minHeight: 200
|
|
223
|
+
width: '100%',
|
|
224
|
+
height: 'auto'
|
|
368
225
|
},
|
|
369
226
|
audio: {
|
|
370
|
-
width:
|
|
371
|
-
height:
|
|
372
|
-
|
|
373
|
-
|
|
227
|
+
width: '100%',
|
|
228
|
+
height: 'auto'
|
|
229
|
+
},
|
|
230
|
+
youtube: {
|
|
231
|
+
width: 640,
|
|
232
|
+
height: 360
|
|
374
233
|
},
|
|
375
234
|
options: {
|
|
376
|
-
volume:
|
|
235
|
+
volume: 80,
|
|
377
236
|
startMuted: false,
|
|
378
237
|
maxPlays: 0,
|
|
379
238
|
replayTimeout: 0,
|
|
380
239
|
canPause: true,
|
|
381
240
|
canSeek: true,
|
|
382
241
|
loop: false,
|
|
383
|
-
autoStart: false
|
|
242
|
+
autoStart: false,
|
|
243
|
+
preview: true,
|
|
244
|
+
debug: false
|
|
384
245
|
}
|
|
385
246
|
};
|
|
386
|
-
/**
|
|
387
|
-
* A list of MIME types with codec declaration
|
|
388
|
-
* @type {Object}
|
|
389
|
-
* @private
|
|
390
|
-
*/
|
|
391
|
-
|
|
392
|
-
var _mimeTypes = {
|
|
393
|
-
// video
|
|
394
|
-
'video/webm': 'video/webm; codecs="vp8, vorbis"',
|
|
395
|
-
'video/mp4': 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
|
|
396
|
-
'video/ogg': 'video/ogg; codecs="theora, vorbis"',
|
|
397
|
-
// audio
|
|
398
|
-
'audio/mpeg': 'audio/mpeg;',
|
|
399
|
-
'audio/mp4': 'audio/mp4; codecs="mp4a.40.5"',
|
|
400
|
-
'audio/ogg': 'audio/ogg; codecs="vorbis"',
|
|
401
|
-
'audio/wav': 'audio/wav; codecs="1"'
|
|
402
|
-
};
|
|
403
|
-
/**
|
|
404
|
-
* Extracts the ID of a Youtube video from an URL
|
|
405
|
-
* @param {String} url
|
|
406
|
-
* @returns {String}
|
|
407
|
-
* @private
|
|
408
|
-
*/
|
|
409
|
-
|
|
410
|
-
var _extractYoutubeId = function _extractYoutubeId(url) {
|
|
411
|
-
var res = _reYoutube.exec(url);
|
|
412
|
-
|
|
413
|
-
return res && res[2] || url;
|
|
414
|
-
};
|
|
415
247
|
/**
|
|
416
248
|
* Ensures a value is a number
|
|
417
249
|
* @param {Number|String} value
|
|
418
250
|
* @returns {Number}
|
|
419
|
-
* @private
|
|
420
251
|
*/
|
|
421
252
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
return isFinite(value) ? value : 0;
|
|
253
|
+
var ensureNumber = function ensureNumber(value) {
|
|
254
|
+
var floatValue = parseFloat(value);
|
|
255
|
+
return isFinite(floatValue) ? floatValue : 0;
|
|
426
256
|
};
|
|
427
257
|
/**
|
|
428
258
|
* Format a number to string with leading zeros
|
|
429
259
|
* @param {Number} n
|
|
430
260
|
* @param {Number} len
|
|
431
261
|
* @returns {String}
|
|
432
|
-
* @private
|
|
433
262
|
*/
|
|
434
263
|
|
|
435
264
|
|
|
436
|
-
var
|
|
265
|
+
var leadingZero = function leadingZero(n, len) {
|
|
437
266
|
var value = n.toString();
|
|
438
267
|
|
|
439
268
|
while (value.length < len) {
|
|
440
|
-
value =
|
|
269
|
+
value = "0".concat(value);
|
|
441
270
|
}
|
|
442
271
|
|
|
443
272
|
return value;
|
|
@@ -446,11 +275,10 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
446
275
|
* Formats a time value to string
|
|
447
276
|
* @param {Number} time
|
|
448
277
|
* @returns {String}
|
|
449
|
-
* @private
|
|
450
278
|
*/
|
|
451
279
|
|
|
452
280
|
|
|
453
|
-
var
|
|
281
|
+
var timerFormat = function timerFormat(time) {
|
|
454
282
|
var seconds = Math.floor(time % 60);
|
|
455
283
|
var minutes = Math.floor(time / 60) % 60;
|
|
456
284
|
var hours = Math.floor(time / 3600);
|
|
@@ -460,30 +288,28 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
460
288
|
parts.push(hours);
|
|
461
289
|
}
|
|
462
290
|
|
|
463
|
-
parts.push(
|
|
464
|
-
parts.push(
|
|
291
|
+
parts.push(leadingZero(minutes, 2));
|
|
292
|
+
parts.push(leadingZero(seconds, 2));
|
|
465
293
|
return parts.join(':');
|
|
466
294
|
};
|
|
467
295
|
/**
|
|
468
296
|
* Checks if a type needs to be adjusted
|
|
469
297
|
* @param {String} type
|
|
470
298
|
* @returns {Boolean}
|
|
471
|
-
* @private
|
|
472
299
|
*/
|
|
473
300
|
|
|
474
301
|
|
|
475
|
-
var
|
|
302
|
+
var needTypeAdjust = function needTypeAdjust(type) {
|
|
476
303
|
return 'string' === typeof type && type.indexOf('application') === 0;
|
|
477
304
|
};
|
|
478
305
|
/**
|
|
479
306
|
* Adjust bad type by apllying heuristic on URI
|
|
480
307
|
* @param {Object|String} source
|
|
481
308
|
* @returns {String}
|
|
482
|
-
* @private
|
|
483
309
|
*/
|
|
484
310
|
|
|
485
311
|
|
|
486
|
-
var
|
|
312
|
+
var getAdjustedType = function getAdjustedType(source) {
|
|
487
313
|
var type = 'video/ogg';
|
|
488
314
|
var url = source && source.src || source;
|
|
489
315
|
var ext = url && url.substr(-4);
|
|
@@ -498,11 +324,10 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
498
324
|
* Extract a list of media sources from a config object
|
|
499
325
|
* @param {Object} config
|
|
500
326
|
* @returns {Array}
|
|
501
|
-
* @private
|
|
502
327
|
*/
|
|
503
328
|
|
|
504
329
|
|
|
505
|
-
var
|
|
330
|
+
var configToSources = function configToSources(config) {
|
|
506
331
|
var sources = config.sources || [];
|
|
507
332
|
var url = config.url;
|
|
508
333
|
|
|
@@ -522,1973 +347,1495 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
522
347
|
};
|
|
523
348
|
/**
|
|
524
349
|
* Checks if the browser can play media
|
|
525
|
-
* @param {
|
|
526
|
-
* @param {String} [mimeType] An optional MIME type to precise the support
|
|
350
|
+
* @param {String} sizeProps Width or Height
|
|
527
351
|
* @returns {Boolean}
|
|
528
|
-
* @private
|
|
529
352
|
*/
|
|
530
353
|
|
|
531
354
|
|
|
532
|
-
var
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
if (mimeType && support) {
|
|
536
|
-
support = !!media.canPlayType(_mimeTypes[mimeType] || mimeType).replace(/no/, '');
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
return support;
|
|
355
|
+
var isResponsiveSize = function isResponsiveSize(sizeProps) {
|
|
356
|
+
return /%/.test(sizeProps) || sizeProps === 'auto';
|
|
540
357
|
};
|
|
541
358
|
/**
|
|
542
|
-
*
|
|
543
|
-
* @
|
|
544
|
-
* @
|
|
359
|
+
* Builds a media player instance
|
|
360
|
+
* @param {Object} config
|
|
361
|
+
* @param {String} config.type - The type of media to play, say `audio`, `video`, or `youtube`. The default is `video`.
|
|
362
|
+
* It might also contain the MIME type of the media as a shorthand.
|
|
363
|
+
* @param {String|Array} [config.url] - The URL to the media. If several media are proposed as alternatives,
|
|
364
|
+
* please look at the `sources` option instead.
|
|
365
|
+
* @param {String} [config.mimeType] - The MIME type of the media. If omitted, the player will try to extract it
|
|
366
|
+
* from the `type` property, otherwise it will request the server to get the content-type.
|
|
367
|
+
* @param {Array} [config.sources] - A list of URL if several media can be proposed. Each entry may be either a
|
|
368
|
+
* string (single URL), or an object containing both the URL and the MIME type ({src: string, type: string}).
|
|
369
|
+
* @param {String|jQuery|HTMLElement} [config.renderTo] - An optional container in which renders the player
|
|
370
|
+
* @param {Boolean} [config.canSeek] - The player allows to reach an arbitrary position within the media using the duration bar
|
|
371
|
+
* @param {Boolean} [config.loop] - The media will be played continuously
|
|
372
|
+
* @param {Boolean} [config.canPause] - The player can be paused
|
|
373
|
+
* @param {Boolean} [config.startMuted] - The player should be initially muted
|
|
374
|
+
* @param {Boolean} [config.autoStart] - The player starts as soon as it is displayed
|
|
375
|
+
* @param {Number} [config.autoStartAt] - The time position at which the player should start
|
|
376
|
+
* @param {Number} [config.maxPlays] - Sets a few number of plays (default: infinite)
|
|
377
|
+
* @param {Number} [config.replayTimeout] - disable the possibility to replay a media after this timeout, in seconds (default: 0)
|
|
378
|
+
* @param {Number} [config.volume] - Sets the sound volume (default: 80)
|
|
379
|
+
* @param {Number} [config.width] - Sets the width of the player (default: depends on media type)
|
|
380
|
+
* @param {Number} [config.height] - Sets the height of the player (default: depends on media type)
|
|
381
|
+
* @param {Boolean} [config.preview] - Enables the media preview (load media metadata)
|
|
382
|
+
* @param {Boolean} [config.debug] - Enables the debug mode
|
|
383
|
+
* @param {number} [config.config.stalledDetectionDelay] - The delay before considering a media is stalled
|
|
384
|
+
* @event render - Event triggered when the player is rendering
|
|
385
|
+
* @event error - Event triggered when the player throws an unrecoverable error
|
|
386
|
+
* @event ready - Event triggered when the player is fully ready
|
|
387
|
+
* @event play - Event triggered when the playback is starting
|
|
388
|
+
* @event update - Event triggered while the player is playing
|
|
389
|
+
* @event pause - Event triggered when the playback is paused
|
|
390
|
+
* @event ended - Event triggered when the playback is ended
|
|
391
|
+
* @event limitreached - Event triggered when the play limit has been reached
|
|
392
|
+
* @event destroy - Event triggered when the player is destroying
|
|
393
|
+
* @returns {mediaplayer}
|
|
545
394
|
*/
|
|
546
395
|
|
|
547
396
|
|
|
548
|
-
|
|
397
|
+
function mediaplayerFactory(config) {
|
|
549
398
|
/**
|
|
550
|
-
*
|
|
551
|
-
* @
|
|
552
|
-
* @param {String} [mime] A media MIME type to check
|
|
553
|
-
* @returns {Boolean}
|
|
399
|
+
* Defines a media player object
|
|
400
|
+
* @type {Object}
|
|
554
401
|
*/
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
return this.canPlayVideo(mime);
|
|
564
|
-
|
|
565
|
-
default:
|
|
566
|
-
return false;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
402
|
+
var mediaplayer = {
|
|
403
|
+
/**
|
|
404
|
+
* Initializes the media player
|
|
405
|
+
* @param {Object} config
|
|
406
|
+
* @returns {mediaplayer}
|
|
407
|
+
*/
|
|
408
|
+
init: function init(config) {
|
|
409
|
+
var _this = this;
|
|
569
410
|
|
|
570
|
-
|
|
571
|
-
|
|
411
|
+
// load the config set, discard null values in order to allow defaults to be set
|
|
412
|
+
this.config = _.omit(config || {}, function (value) {
|
|
413
|
+
return typeof value === 'undefined' || value === null;
|
|
414
|
+
});
|
|
572
415
|
|
|
573
|
-
|
|
574
|
-
* Checks if the browser can play audio
|
|
575
|
-
* @param {String} [mime] A media MIME type to check
|
|
576
|
-
* @returns {Boolean}
|
|
577
|
-
*/
|
|
578
|
-
canPlayAudio: function canPlayAudio(mime) {
|
|
579
|
-
if (!this._mediaAudio) {
|
|
580
|
-
this._mediaAudio = document.createElement('audio');
|
|
581
|
-
}
|
|
416
|
+
_.defaults(this.config, defaults.options);
|
|
582
417
|
|
|
583
|
-
|
|
584
|
-
|
|
418
|
+
if (!this.config.mimeType && 'string' === typeof this.config.type && this.config.type.indexOf('/') > 0) {
|
|
419
|
+
this.config.mimeType = this.config.type;
|
|
420
|
+
}
|
|
585
421
|
|
|
586
|
-
|
|
587
|
-
* Checks if the browser can play video
|
|
588
|
-
* @param {String} [mime] A media MIME type to check
|
|
589
|
-
* @returns {Boolean}
|
|
590
|
-
*/
|
|
591
|
-
canPlayVideo: function canPlayVideo(mime) {
|
|
592
|
-
if (!this._mediaVideo) {
|
|
593
|
-
this._mediaVideo = document.createElement('video');
|
|
594
|
-
}
|
|
422
|
+
this._setType(this.config.type || defaults.type);
|
|
595
423
|
|
|
596
|
-
|
|
597
|
-
},
|
|
424
|
+
this._reset();
|
|
598
425
|
|
|
599
|
-
|
|
600
|
-
* Checks if the browser allows to control the media playback
|
|
601
|
-
* @returns {Boolean}
|
|
602
|
-
*/
|
|
603
|
-
canControl: function canControl() {
|
|
604
|
-
return !_reAppleMobiles.test(navigator.userAgent);
|
|
605
|
-
}
|
|
606
|
-
};
|
|
607
|
-
/**
|
|
608
|
-
* A local manager for Youtube players.
|
|
609
|
-
* Relies on https://developers.google.com/youtube/iframe_api_reference
|
|
610
|
-
* @type {Object}
|
|
611
|
-
* @private
|
|
612
|
-
*/
|
|
426
|
+
this._updateVolumeFromStore();
|
|
613
427
|
|
|
614
|
-
|
|
615
|
-
/**
|
|
616
|
-
* The Youtube API injection state
|
|
617
|
-
* @type {Boolean}
|
|
618
|
-
*/
|
|
619
|
-
injected: false,
|
|
428
|
+
this._initEvents();
|
|
620
429
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
430
|
+
this._initSources(function () {
|
|
431
|
+
if (!_this.is('youtube')) {
|
|
432
|
+
_.forEach(_this.config.sources, function (source) {
|
|
433
|
+
if (source && source.type && source.type.indexOf('audio') === 0) {
|
|
434
|
+
_this._setType(source.type);
|
|
626
435
|
|
|
627
|
-
|
|
628
|
-
* A list of pending players
|
|
629
|
-
* @type {Array}
|
|
630
|
-
*/
|
|
631
|
-
pending: [],
|
|
436
|
+
_this._initType();
|
|
632
437
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
* @param {Object} [options]
|
|
638
|
-
* @param {Boolean} [options.controls]
|
|
639
|
-
*/
|
|
640
|
-
add: function add(elem, player, options) {
|
|
641
|
-
if (this.ready) {
|
|
642
|
-
this.create(elem, player, options);
|
|
643
|
-
} else {
|
|
644
|
-
this.pending.push([elem, player, options]);
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
}
|
|
645
442
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
443
|
+
if (_this.config.renderTo) {
|
|
444
|
+
_.defer(function () {
|
|
445
|
+
return _this.render();
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
});
|
|
651
449
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
450
|
+
return this;
|
|
451
|
+
},
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Uninstalls the media player
|
|
455
|
+
* @returns {mediaplayer}
|
|
456
|
+
*/
|
|
457
|
+
destroy: function destroy() {
|
|
458
|
+
/**
|
|
459
|
+
* Triggers a destroy event
|
|
460
|
+
* @event mediaplayer#destroy
|
|
461
|
+
*/
|
|
462
|
+
this.trigger('destroy');
|
|
659
463
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
pending[idx] = null;
|
|
464
|
+
if (this.player) {
|
|
465
|
+
this.player.destroy();
|
|
663
466
|
}
|
|
664
|
-
});
|
|
665
|
-
},
|
|
666
467
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
* @param {String|jQuery|HTMLElement} elem
|
|
670
|
-
* @param {Object} player
|
|
671
|
-
* @param {Object} [options]
|
|
672
|
-
* @param {Boolean} [options.controls]
|
|
673
|
-
*/
|
|
674
|
-
create: function create(elem, player, options) {
|
|
675
|
-
var $elem;
|
|
468
|
+
if (this.$component) {
|
|
469
|
+
this._unbindEvents();
|
|
676
470
|
|
|
677
|
-
|
|
678
|
-
return this.add(elem, player, options);
|
|
679
|
-
}
|
|
471
|
+
this._destroySlider(this.$seekSlider);
|
|
680
472
|
|
|
681
|
-
|
|
682
|
-
options = {};
|
|
683
|
-
}
|
|
473
|
+
this._destroySlider(this.$volumeSlider);
|
|
684
474
|
|
|
685
|
-
|
|
686
|
-
new window.YT.Player($elem.get(0), {
|
|
687
|
-
height: $elem.width(),
|
|
688
|
-
width: $elem.height(),
|
|
689
|
-
videoId: $elem.data('videoId'),
|
|
690
|
-
playerVars: {
|
|
691
|
-
//hd: true,
|
|
692
|
-
autoplay: 0,
|
|
693
|
-
controls: options.controls ? 1 : 0,
|
|
694
|
-
rel: 0,
|
|
695
|
-
showinfo: 0,
|
|
696
|
-
wmode: 'transparent',
|
|
697
|
-
modestbranding: 1,
|
|
698
|
-
disablekb: 1,
|
|
699
|
-
playsinline: 1,
|
|
700
|
-
enablejsapi: 1,
|
|
701
|
-
origin: location.hostname
|
|
702
|
-
},
|
|
703
|
-
events: {
|
|
704
|
-
onReady: player.onReady.bind(player),
|
|
705
|
-
onStateChange: player.onStateChange.bind(player)
|
|
475
|
+
this.$component.remove();
|
|
706
476
|
}
|
|
707
|
-
});
|
|
708
|
-
},
|
|
709
477
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
478
|
+
this._reset();
|
|
479
|
+
|
|
480
|
+
return this;
|
|
481
|
+
},
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Renders the media player according to the media type
|
|
485
|
+
* @param {String|jQuery|HTMLElement} [to]
|
|
486
|
+
* @returns {mediaplayer}
|
|
487
|
+
*/
|
|
488
|
+
render: function render(to) {
|
|
489
|
+
var renderTo = to || this.config.renderTo || this.$container;
|
|
490
|
+
|
|
491
|
+
if (this.$component) {
|
|
492
|
+
this.destroy();
|
|
722
493
|
}
|
|
723
|
-
});
|
|
724
|
-
},
|
|
725
494
|
|
|
726
|
-
|
|
727
|
-
* Checks if the Youtube API is ready to use
|
|
728
|
-
* @returns {Boolean}
|
|
729
|
-
*/
|
|
730
|
-
isApiReady: function isApiReady() {
|
|
731
|
-
var apiReady = typeof window.YT !== 'undefined' && typeof window.YT.Player !== 'undefined';
|
|
495
|
+
this._initState();
|
|
732
496
|
|
|
733
|
-
|
|
734
|
-
_youtubeManager.apiReady();
|
|
735
|
-
}
|
|
497
|
+
this._buildDom();
|
|
736
498
|
|
|
737
|
-
|
|
738
|
-
|
|
499
|
+
if (this.config.preview) {
|
|
500
|
+
this._updateDuration(0);
|
|
739
501
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
*/
|
|
743
|
-
injectApi: function injectApi() {
|
|
744
|
-
var self = this;
|
|
745
|
-
|
|
746
|
-
if (!self.isApiReady()) {
|
|
747
|
-
window.require(['https://www.youtube.com/iframe_api'], function () {
|
|
748
|
-
var check = function check() {
|
|
749
|
-
if (!self.isApiReady()) {
|
|
750
|
-
setTimeout(check, 100);
|
|
751
|
-
}
|
|
752
|
-
};
|
|
502
|
+
this._updatePosition(0);
|
|
503
|
+
}
|
|
753
504
|
|
|
754
|
-
|
|
755
|
-
});
|
|
756
|
-
}
|
|
505
|
+
this._bindEvents();
|
|
757
506
|
|
|
758
|
-
|
|
759
|
-
}
|
|
760
|
-
};
|
|
761
|
-
/**
|
|
762
|
-
* Defines a player object dedicated to youtube media
|
|
763
|
-
* @param {mediaplayer} mediaplayer
|
|
764
|
-
* @private
|
|
765
|
-
*/
|
|
507
|
+
this._playingState(false, true);
|
|
766
508
|
|
|
767
|
-
|
|
768
|
-
var $media;
|
|
769
|
-
var media;
|
|
770
|
-
var player;
|
|
771
|
-
var interval;
|
|
772
|
-
var destroyed;
|
|
773
|
-
var initWidth, initHeight;
|
|
509
|
+
this._initPlayer();
|
|
774
510
|
|
|
775
|
-
|
|
776
|
-
_.forEach(['onStateChange', 'onPlaybackQualityChange', 'onPlaybackRateChange', 'onError', 'onApiChange'], callback);
|
|
777
|
-
}
|
|
511
|
+
this._initSize(); // Resize for old items with defined height to avoid big jump
|
|
778
512
|
|
|
779
|
-
if (mediaplayer) {
|
|
780
|
-
player = {
|
|
781
|
-
init: function _youtubePlayerInit() {
|
|
782
|
-
$media = mediaplayer.$media;
|
|
783
|
-
media = null;
|
|
784
|
-
destroyed = false;
|
|
785
513
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
514
|
+
if (this.config.height && this.config.height !== 'auto') {
|
|
515
|
+
this.resize('100%', 'auto');
|
|
516
|
+
} else {
|
|
517
|
+
this.resize(this.config.width, this.config.height);
|
|
518
|
+
}
|
|
791
519
|
|
|
792
|
-
|
|
793
|
-
},
|
|
794
|
-
onReady: function _youtubePlayerOnReady(event) {
|
|
795
|
-
var callbacks = this._callbacks;
|
|
796
|
-
media = event.target;
|
|
797
|
-
$media = $$1(media.getIframe());
|
|
798
|
-
this._callbacks = null;
|
|
520
|
+
this.config.is.rendered = true;
|
|
799
521
|
|
|
800
|
-
|
|
522
|
+
if (renderTo) {
|
|
523
|
+
this.$container = $$1(renderTo).append(this.$component);
|
|
524
|
+
} // add class if it is stalled
|
|
801
525
|
|
|
802
|
-
if (initWidth && initHeight) {
|
|
803
|
-
this.setSize(initWidth, initHeight);
|
|
804
|
-
}
|
|
805
526
|
|
|
806
|
-
|
|
527
|
+
if (this.is('stalled')) {
|
|
528
|
+
this._setState('stalled', true);
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Triggers a render event
|
|
532
|
+
* @event mediaplayer#render
|
|
533
|
+
* @param {jQuery} $component
|
|
534
|
+
*/
|
|
807
535
|
|
|
808
|
-
if (callbacks) {
|
|
809
|
-
_.forEach(callbacks, function (cb) {
|
|
810
|
-
cb();
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
} else {
|
|
814
|
-
this.destroy();
|
|
815
|
-
}
|
|
816
|
-
},
|
|
817
|
-
onStateChange: function _youtubePlayerOnStateChange(event) {
|
|
818
|
-
this.stopPolling();
|
|
819
536
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
case 0:
|
|
824
|
-
mediaplayer._onEnd();
|
|
537
|
+
this.trigger('render', this.$component);
|
|
538
|
+
return this;
|
|
539
|
+
},
|
|
825
540
|
|
|
826
|
-
|
|
827
|
-
|
|
541
|
+
/**
|
|
542
|
+
* Reloads media player after it was stalled
|
|
543
|
+
*/
|
|
544
|
+
reload: function reload() {
|
|
545
|
+
/**
|
|
546
|
+
* Triggers a reload event
|
|
547
|
+
* @event mediaplayer#reload
|
|
548
|
+
*/
|
|
549
|
+
this.trigger('reload');
|
|
828
550
|
|
|
829
|
-
|
|
830
|
-
|
|
551
|
+
if (this.player) {
|
|
552
|
+
this.player.recover();
|
|
553
|
+
}
|
|
831
554
|
|
|
832
|
-
|
|
833
|
-
break;
|
|
834
|
-
// paused
|
|
555
|
+
this._setState('stalled', false);
|
|
835
556
|
|
|
836
|
-
|
|
837
|
-
|
|
557
|
+
this.setInitialStates();
|
|
558
|
+
},
|
|
838
559
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
interval = null;
|
|
847
|
-
}
|
|
848
|
-
},
|
|
849
|
-
startPolling: function _youtubePlayerStartPolling() {
|
|
850
|
-
interval = setInterval(function () {
|
|
851
|
-
mediaplayer._onTimeUpdate();
|
|
852
|
-
}, mediaplayerFactory.youtubePolling);
|
|
853
|
-
},
|
|
854
|
-
destroy: function _youtubePlayerDestroy() {
|
|
855
|
-
destroyed = true;
|
|
856
|
-
|
|
857
|
-
if (media) {
|
|
858
|
-
loopEvents(function (ev) {
|
|
859
|
-
media.removeEventListener(ev);
|
|
860
|
-
});
|
|
861
|
-
media.destroy();
|
|
862
|
-
} else {
|
|
863
|
-
_youtubeManager.remove($media, this);
|
|
864
|
-
}
|
|
560
|
+
/**
|
|
561
|
+
* Set initial states
|
|
562
|
+
*/
|
|
563
|
+
setInitialStates: function setInitialStates() {
|
|
564
|
+
if (!this.is('stalled')) {
|
|
565
|
+
this._setState('ready', true);
|
|
566
|
+
}
|
|
865
567
|
|
|
866
|
-
|
|
867
|
-
$media = null;
|
|
868
|
-
media = null;
|
|
869
|
-
},
|
|
870
|
-
getPosition: function _youtubePlayerGetPosition() {
|
|
871
|
-
if (media) {
|
|
872
|
-
return media.getCurrentTime();
|
|
873
|
-
}
|
|
568
|
+
this._setState('canplay', true);
|
|
874
569
|
|
|
875
|
-
|
|
876
|
-
},
|
|
877
|
-
getDuration: function _youtubePlayerGetDuration() {
|
|
878
|
-
if (media) {
|
|
879
|
-
return media.getDuration();
|
|
880
|
-
}
|
|
570
|
+
this._setState('canpause', this.config.canPause);
|
|
881
571
|
|
|
882
|
-
|
|
883
|
-
},
|
|
884
|
-
getVolume: function _youtubePlayerGetVolume() {
|
|
885
|
-
var value = 0;
|
|
572
|
+
this._setState('canseek', this.config.canSeek);
|
|
886
573
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
}
|
|
574
|
+
this._setState('loading', false);
|
|
575
|
+
},
|
|
890
576
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
$media.width(width).height(height);
|
|
901
|
-
}
|
|
577
|
+
/**
|
|
578
|
+
* Sets the start position inside the media
|
|
579
|
+
* @param {Number} time - The start position in seconds
|
|
580
|
+
* @param {*} [internal] - Internal use
|
|
581
|
+
* @returns {mediaplayer}
|
|
582
|
+
*/
|
|
583
|
+
seek: function seek(time, internal) {
|
|
584
|
+
if (this._canPlay()) {
|
|
585
|
+
this._updatePosition(time, internal);
|
|
902
586
|
|
|
903
|
-
|
|
904
|
-
media.setSize(width, height);
|
|
905
|
-
} else {
|
|
906
|
-
initWidth = width;
|
|
907
|
-
initHeight = height;
|
|
908
|
-
}
|
|
909
|
-
},
|
|
910
|
-
seek: function _youtubePlayerSeek(value) {
|
|
911
|
-
if (media) {
|
|
912
|
-
media.seekTo(parseFloat(value), true);
|
|
913
|
-
}
|
|
914
|
-
},
|
|
915
|
-
play: function _youtubePlayerPlay() {
|
|
916
|
-
if (media) {
|
|
917
|
-
media.playVideo();
|
|
918
|
-
}
|
|
919
|
-
},
|
|
920
|
-
pause: function _youtubePlayerPause() {
|
|
921
|
-
if (media) {
|
|
922
|
-
media.pauseVideo();
|
|
923
|
-
}
|
|
924
|
-
},
|
|
925
|
-
stop: function _youtubePlayerStop() {
|
|
926
|
-
if (media) {
|
|
927
|
-
media.stopVideo();
|
|
587
|
+
this.execute('seek', this.position);
|
|
928
588
|
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
},
|
|
932
|
-
mute: function _youtubePlayerMute(state) {
|
|
933
|
-
if (media) {
|
|
934
|
-
media[state ? 'mute' : 'unMute']();
|
|
935
|
-
}
|
|
936
|
-
},
|
|
937
|
-
isMuted: function _youtubePlayerIsMuted() {
|
|
938
|
-
if (media) {
|
|
939
|
-
return media.isMuted();
|
|
589
|
+
if (!this.is('ready')) {
|
|
590
|
+
this.autoStartAt = this.position;
|
|
940
591
|
}
|
|
941
592
|
|
|
942
|
-
|
|
943
|
-
}
|
|
944
|
-
addMedia: function _youtubePlayerSetMedia(url) {
|
|
945
|
-
var id = _extractYoutubeId(url);
|
|
593
|
+
this.loop = !!this.config.loop;
|
|
594
|
+
}
|
|
946
595
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
};
|
|
596
|
+
return this;
|
|
597
|
+
},
|
|
950
598
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
599
|
+
/**
|
|
600
|
+
* Plays the media
|
|
601
|
+
* @param {Number} [time] - An optional start position in seconds
|
|
602
|
+
* @returns {mediaplayer}
|
|
603
|
+
*/
|
|
604
|
+
play: function play(time) {
|
|
605
|
+
if (this._canPlay()) {
|
|
606
|
+
if (typeof time !== 'undefined') {
|
|
607
|
+
this.seek(time);
|
|
608
|
+
}
|
|
956
609
|
|
|
957
|
-
|
|
958
|
-
}
|
|
610
|
+
this.execute('play');
|
|
959
611
|
|
|
960
|
-
|
|
612
|
+
if (!this.is('ready')) {
|
|
613
|
+
this.autoStart = true;
|
|
961
614
|
}
|
|
962
615
|
|
|
963
|
-
|
|
964
|
-
},
|
|
965
|
-
setMedia: function _youtubePlayerSetMedia(url) {
|
|
966
|
-
var id = _extractYoutubeId(url);
|
|
616
|
+
this.loop = !!this.config.loop;
|
|
967
617
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
}
|
|
618
|
+
if (this.timerId) {
|
|
619
|
+
cancelAnimationFrame(this.timerId);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
971
622
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
cb();
|
|
975
|
-
} else {
|
|
976
|
-
this._callbacks = [cb];
|
|
977
|
-
}
|
|
623
|
+
return this;
|
|
624
|
+
},
|
|
978
625
|
|
|
979
|
-
|
|
626
|
+
/**
|
|
627
|
+
* Pauses the media
|
|
628
|
+
* @param {Number} [time] - An optional time position in seconds
|
|
629
|
+
* @returns {mediaplayer}
|
|
630
|
+
*/
|
|
631
|
+
pause: function pause(time) {
|
|
632
|
+
if (this._canPause()) {
|
|
633
|
+
if (typeof time !== 'undefined') {
|
|
634
|
+
this.seek(time);
|
|
980
635
|
}
|
|
981
636
|
|
|
982
|
-
|
|
637
|
+
this.execute('pause');
|
|
638
|
+
|
|
639
|
+
if (!this.is('ready')) {
|
|
640
|
+
this.autoStart = false;
|
|
641
|
+
}
|
|
983
642
|
}
|
|
984
|
-
};
|
|
985
|
-
}
|
|
986
643
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
/**
|
|
990
|
-
* Defines a player object dedicated to native player
|
|
991
|
-
* @param {mediaplayer} mediaplayer
|
|
992
|
-
* @private
|
|
993
|
-
*/
|
|
644
|
+
return this;
|
|
645
|
+
},
|
|
994
646
|
|
|
647
|
+
/**
|
|
648
|
+
* Resumes the media
|
|
649
|
+
* @returns {mediaplayer}
|
|
650
|
+
*/
|
|
651
|
+
resume: function resume() {
|
|
652
|
+
if (this._canResume()) {
|
|
653
|
+
this.play();
|
|
654
|
+
}
|
|
995
655
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
var media;
|
|
999
|
-
var player;
|
|
1000
|
-
var played;
|
|
656
|
+
return this;
|
|
657
|
+
},
|
|
1001
658
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
played = false;
|
|
659
|
+
/**
|
|
660
|
+
* Stops the playback
|
|
661
|
+
* @returns {mediaplayer}
|
|
662
|
+
*/
|
|
663
|
+
stop: function stop() {
|
|
664
|
+
this.loop = false;
|
|
665
|
+
this.execute('stop');
|
|
1010
666
|
|
|
1011
|
-
|
|
1012
|
-
|
|
667
|
+
if (!this.is('ready')) {
|
|
668
|
+
this.autoStart = false;
|
|
669
|
+
}
|
|
1013
670
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
result = true;
|
|
1017
|
-
}
|
|
671
|
+
return this;
|
|
672
|
+
},
|
|
1018
673
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
674
|
+
/**
|
|
675
|
+
* Starts the media
|
|
676
|
+
* @returns {mediaplayer}
|
|
677
|
+
*/
|
|
678
|
+
start: function start() {
|
|
679
|
+
this._setState('preview', true);
|
|
1022
680
|
|
|
1023
|
-
|
|
1024
|
-
played = true;
|
|
1025
|
-
|
|
1026
|
-
mediaplayer._onPlay();
|
|
1027
|
-
}).on('pause' + _ns, function () {
|
|
1028
|
-
mediaplayer._onPause();
|
|
1029
|
-
}).on('ended' + _ns, function () {
|
|
1030
|
-
played = false;
|
|
1031
|
-
|
|
1032
|
-
mediaplayer._onEnd();
|
|
1033
|
-
}).on('timeupdate' + _ns, function () {
|
|
1034
|
-
mediaplayer._onTimeUpdate();
|
|
1035
|
-
}).on('loadstart', function () {
|
|
1036
|
-
if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE) {
|
|
1037
|
-
mediaplayer._onError();
|
|
1038
|
-
}
|
|
1039
|
-
}).on('error' + _ns, function () {
|
|
1040
|
-
if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE) {
|
|
1041
|
-
mediaplayer._onError();
|
|
1042
|
-
} else {
|
|
1043
|
-
mediaplayer._onRecoverError(); // recover from playing error
|
|
681
|
+
this._setState('loading', true);
|
|
1044
682
|
|
|
683
|
+
this.play();
|
|
684
|
+
},
|
|
1045
685
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
686
|
+
/**
|
|
687
|
+
* Restarts the media from the beginning
|
|
688
|
+
* @returns {mediaplayer}
|
|
689
|
+
*/
|
|
690
|
+
restart: function restart() {
|
|
691
|
+
this.play(0);
|
|
692
|
+
return this;
|
|
693
|
+
},
|
|
1054
694
|
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
695
|
+
/**
|
|
696
|
+
* Rewind the media to the beginning
|
|
697
|
+
* @returns {mediaplayer}
|
|
698
|
+
*/
|
|
699
|
+
rewind: function rewind() {
|
|
700
|
+
this.seek(0);
|
|
701
|
+
return this;
|
|
702
|
+
},
|
|
1058
703
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
704
|
+
/**
|
|
705
|
+
* Mutes the media
|
|
706
|
+
* @param {Boolean} [state] - A flag to set the mute state (default: true)
|
|
707
|
+
* @returns {mediaplayer}
|
|
708
|
+
*/
|
|
709
|
+
mute: function mute(state) {
|
|
710
|
+
if (typeof state === 'undefined') {
|
|
711
|
+
state = true;
|
|
712
|
+
}
|
|
1065
713
|
|
|
1066
|
-
|
|
1067
|
-
$media = null;
|
|
1068
|
-
media = null;
|
|
1069
|
-
played = false;
|
|
1070
|
-
},
|
|
1071
|
-
getPosition: function _nativePlayerGetPosition() {
|
|
1072
|
-
if (media) {
|
|
1073
|
-
return media.currentTime;
|
|
1074
|
-
}
|
|
714
|
+
this.execute('mute', state);
|
|
1075
715
|
|
|
1076
|
-
|
|
1077
|
-
},
|
|
1078
|
-
getDuration: function _nativePlayerGetDuration() {
|
|
1079
|
-
if (media) {
|
|
1080
|
-
return media.duration;
|
|
1081
|
-
}
|
|
716
|
+
this._setState('muted', state);
|
|
1082
717
|
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
var value = 0;
|
|
718
|
+
if (!this.is('ready')) {
|
|
719
|
+
this.startMuted = state;
|
|
720
|
+
}
|
|
1087
721
|
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
}
|
|
722
|
+
return this;
|
|
723
|
+
},
|
|
1091
724
|
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
if ($media) {
|
|
1101
|
-
$media.width(width).height(height);
|
|
1102
|
-
}
|
|
1103
|
-
},
|
|
1104
|
-
seek: function _nativePlayerSeek(value) {
|
|
1105
|
-
if (media) {
|
|
1106
|
-
media.currentTime = parseFloat(value);
|
|
1107
|
-
|
|
1108
|
-
if (!played) {
|
|
1109
|
-
this.play();
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
},
|
|
1113
|
-
play: function _nativePlayerPlay() {
|
|
1114
|
-
if (media) {
|
|
1115
|
-
media.play();
|
|
1116
|
-
}
|
|
1117
|
-
},
|
|
1118
|
-
pause: function _nativePlayerPause() {
|
|
1119
|
-
if (media) {
|
|
1120
|
-
media.pause();
|
|
1121
|
-
}
|
|
1122
|
-
},
|
|
1123
|
-
stop: function _nativePlayerStop() {
|
|
1124
|
-
if (media && played) {
|
|
1125
|
-
media.currentTime = media.duration;
|
|
1126
|
-
}
|
|
1127
|
-
},
|
|
1128
|
-
mute: function _nativePlayerMute(state) {
|
|
1129
|
-
if (media) {
|
|
1130
|
-
media.muted = !!state;
|
|
1131
|
-
}
|
|
1132
|
-
},
|
|
1133
|
-
isMuted: function _nativePlayerIsMuted() {
|
|
1134
|
-
if (media) {
|
|
1135
|
-
return !!media.muted;
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
return false;
|
|
1139
|
-
},
|
|
1140
|
-
addMedia: function _nativePlayerSetMedia(url, type) {
|
|
1141
|
-
type = type || _defaults.type;
|
|
1142
|
-
|
|
1143
|
-
if (media) {
|
|
1144
|
-
if (!_checkSupport(media, type)) {
|
|
1145
|
-
return false;
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
if (url && $media) {
|
|
1150
|
-
$media.append('<source src="' + url + '" type="' + (_mimeTypes[type] || type) + '" />');
|
|
1151
|
-
return true;
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
return false;
|
|
1155
|
-
},
|
|
1156
|
-
setMedia: function _nativePlayerSetMedia(url, type) {
|
|
1157
|
-
if ($media) {
|
|
1158
|
-
$media.empty();
|
|
1159
|
-
return this.addMedia(url, type);
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
return false;
|
|
1163
|
-
}
|
|
1164
|
-
};
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
return player;
|
|
1168
|
-
};
|
|
1169
|
-
/**
|
|
1170
|
-
* Defines the list of available players
|
|
1171
|
-
* @type {Object}
|
|
1172
|
-
* @private
|
|
1173
|
-
*/
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
var _players = {
|
|
1177
|
-
audio: _nativePlayer,
|
|
1178
|
-
video: _nativePlayer,
|
|
1179
|
-
youtube: _youtubePlayer
|
|
1180
|
-
};
|
|
1181
|
-
/**
|
|
1182
|
-
* Defines a media player object
|
|
1183
|
-
* @type {Object}
|
|
1184
|
-
*/
|
|
1185
|
-
|
|
1186
|
-
var mediaplayer = {
|
|
1187
|
-
/**
|
|
1188
|
-
* Initializes the media player
|
|
1189
|
-
* @param {Object} config
|
|
1190
|
-
* @param {String} config.type - The type of media to play
|
|
1191
|
-
* @param {String|Array} config.url - The URL to the media
|
|
1192
|
-
* @param {String|jQuery|HTMLElement} [config.renderTo] - An optional container in which renders the player
|
|
1193
|
-
* @param {Boolean} [config.loop] - The media will be played continuously
|
|
1194
|
-
* @param {Boolean} [config.canPause] - The play can be paused
|
|
1195
|
-
* @param {Boolean} [config.canSeek] - The player allows to reach an arbitrary position within the media using the duration bar
|
|
1196
|
-
* @param {Boolean} [config.startMuted] - The player should be initially muted
|
|
1197
|
-
* @param {Boolean} [config.autoStart] - The player starts as soon as it is displayed
|
|
1198
|
-
* @param {Number} [config.autoStartAt] - The time position at which the player should start
|
|
1199
|
-
* @param {Number} [config.maxPlays] - Sets a few number of plays (default: infinite)
|
|
1200
|
-
* @param {Number} [config.replayTimeout] - disable the possibility to replay a media after this timeout, in seconds (default: 0)
|
|
1201
|
-
* @param {Number} [config.volume] - Sets the sound volume (default: 80)
|
|
1202
|
-
* @param {Number} [config.width] - Sets the width of the player (default: depends on media type)
|
|
1203
|
-
* @param {Number} [config.height] - Sets the height of the player (default: depends on media type)
|
|
1204
|
-
* @returns {mediaplayer}
|
|
1205
|
-
*/
|
|
1206
|
-
init: function init(config) {
|
|
1207
|
-
var self = this; // load the config set, discard null values in order to allow defaults to be set
|
|
1208
|
-
|
|
1209
|
-
this.config = _.omit(config || {}, function (value) {
|
|
1210
|
-
return typeof value === 'undefined' || value === null;
|
|
1211
|
-
});
|
|
725
|
+
/**
|
|
726
|
+
* Restore the sound of the media after a mute
|
|
727
|
+
* @returns {mediaplayer}
|
|
728
|
+
*/
|
|
729
|
+
unmute: function unmute() {
|
|
730
|
+
this.mute(false);
|
|
731
|
+
return this;
|
|
732
|
+
},
|
|
1212
733
|
|
|
1213
|
-
|
|
734
|
+
/**
|
|
735
|
+
* Sets the sound volume of the media being played
|
|
736
|
+
* @param {Number} value - A value between 0 and 100
|
|
737
|
+
* @param {*} [internal] - Internal use
|
|
738
|
+
* @returns {mediaplayer}
|
|
739
|
+
*/
|
|
740
|
+
setVolume: function setVolume(value, internal) {
|
|
741
|
+
this._updateVolume(value, internal);
|
|
1214
742
|
|
|
1215
|
-
|
|
743
|
+
this.execute('setVolume', this.volume);
|
|
744
|
+
return this;
|
|
745
|
+
},
|
|
1216
746
|
|
|
1217
|
-
|
|
747
|
+
/**
|
|
748
|
+
* Gets the sound volume applied to the media being played
|
|
749
|
+
* @returns {Number} Returns a value between 0 and 100
|
|
750
|
+
*/
|
|
751
|
+
getVolume: function getVolume() {
|
|
752
|
+
return this.volume;
|
|
753
|
+
},
|
|
1218
754
|
|
|
1219
|
-
|
|
755
|
+
/**
|
|
756
|
+
* Gets the current displayed position inside the media
|
|
757
|
+
* @returns {Number}
|
|
758
|
+
*/
|
|
759
|
+
getPosition: function getPosition() {
|
|
760
|
+
return this.position;
|
|
761
|
+
},
|
|
1220
762
|
|
|
1221
|
-
|
|
763
|
+
/**
|
|
764
|
+
* Gets the duration of the media
|
|
765
|
+
* @returns {Number}
|
|
766
|
+
*/
|
|
767
|
+
getDuration: function getDuration() {
|
|
768
|
+
return this.duration;
|
|
769
|
+
},
|
|
1222
770
|
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
771
|
+
/**
|
|
772
|
+
* Gets the number of times the media has been played
|
|
773
|
+
* @returns {Number}
|
|
774
|
+
*/
|
|
775
|
+
getTimesPlayed: function getTimesPlayed() {
|
|
776
|
+
return this.timesPlayed;
|
|
777
|
+
},
|
|
1228
778
|
|
|
1229
|
-
|
|
779
|
+
/**
|
|
780
|
+
* Gets the type of player
|
|
781
|
+
* @returns {String}
|
|
782
|
+
*/
|
|
783
|
+
getType: function getType() {
|
|
784
|
+
return this.type;
|
|
785
|
+
},
|
|
1230
786
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
787
|
+
/**
|
|
788
|
+
* Gets the DOM container
|
|
789
|
+
* @returns {jQuery}
|
|
790
|
+
*/
|
|
791
|
+
getContainer: function getContainer() {
|
|
792
|
+
if (!this.$container && this.$component) {
|
|
793
|
+
var $container = this.$component.parent();
|
|
1235
794
|
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
});
|
|
795
|
+
if ($container.length) {
|
|
796
|
+
this.$container = $container;
|
|
797
|
+
}
|
|
1240
798
|
}
|
|
1241
|
-
});
|
|
1242
799
|
|
|
1243
|
-
|
|
1244
|
-
|
|
800
|
+
return this.$container;
|
|
801
|
+
},
|
|
1245
802
|
|
|
1246
|
-
/**
|
|
1247
|
-
* Uninstalls the media player
|
|
1248
|
-
* @returns {mediaplayer}
|
|
1249
|
-
*/
|
|
1250
|
-
destroy: function destroy() {
|
|
1251
803
|
/**
|
|
1252
|
-
*
|
|
1253
|
-
* @
|
|
804
|
+
* Gets the underlying DOM element
|
|
805
|
+
* @returns {jQuery}
|
|
1254
806
|
*/
|
|
1255
|
-
|
|
807
|
+
getElement: function getElement() {
|
|
808
|
+
return this.$component;
|
|
809
|
+
},
|
|
1256
810
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
811
|
+
/**
|
|
812
|
+
* Gets the list of media
|
|
813
|
+
* @returns {Array}
|
|
814
|
+
*/
|
|
815
|
+
getSources: function getSources() {
|
|
816
|
+
return this.config.sources.slice();
|
|
817
|
+
},
|
|
1260
818
|
|
|
1261
|
-
|
|
1262
|
-
|
|
819
|
+
/**
|
|
820
|
+
* Sets the media source. If a source has been already set, it will be replaced.
|
|
821
|
+
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
822
|
+
* @param {Function} [callback] - A function called to provide the added media source object
|
|
823
|
+
* @returns {mediaplayer}
|
|
824
|
+
*/
|
|
825
|
+
setSource: function setSource(src, callback) {
|
|
826
|
+
var _this2 = this;
|
|
1263
827
|
|
|
1264
|
-
this.
|
|
828
|
+
this._getSource(src, function (source) {
|
|
829
|
+
_this2.config.sources = [source];
|
|
1265
830
|
|
|
1266
|
-
|
|
831
|
+
if (_this2.is('rendered')) {
|
|
832
|
+
_this2.player.setMedia(source.src, source.type);
|
|
833
|
+
}
|
|
1267
834
|
|
|
1268
|
-
|
|
1269
|
-
|
|
835
|
+
if (callback) {
|
|
836
|
+
callback.call(_this2, source);
|
|
837
|
+
}
|
|
838
|
+
});
|
|
1270
839
|
|
|
1271
|
-
|
|
840
|
+
return this;
|
|
841
|
+
},
|
|
1272
842
|
|
|
1273
|
-
|
|
1274
|
-
|
|
843
|
+
/**
|
|
844
|
+
* Adds a media source.
|
|
845
|
+
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
846
|
+
* @param {Function} [callback] - A function called to provide the added media source object
|
|
847
|
+
* @returns {mediaplayer}
|
|
848
|
+
*/
|
|
849
|
+
addSource: function addSource(src, callback) {
|
|
850
|
+
var _this3 = this;
|
|
1275
851
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
* @param {String|jQuery|HTMLElement} [to]
|
|
1279
|
-
* @returns {mediaplayer}
|
|
1280
|
-
*/
|
|
1281
|
-
render: function render(to) {
|
|
1282
|
-
var renderTo = to || this.config.renderTo || this.$container;
|
|
852
|
+
this._getSource(src, function (source) {
|
|
853
|
+
_this3.config.sources.push(source);
|
|
1283
854
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
855
|
+
if (_this3.is('rendered')) {
|
|
856
|
+
_this3.player.addMedia(source.src, source.type);
|
|
857
|
+
}
|
|
1287
858
|
|
|
1288
|
-
|
|
859
|
+
if (callback) {
|
|
860
|
+
callback.call(_this3, source);
|
|
861
|
+
}
|
|
862
|
+
});
|
|
1289
863
|
|
|
1290
|
-
|
|
864
|
+
return this;
|
|
865
|
+
},
|
|
1291
866
|
|
|
1292
|
-
|
|
867
|
+
/**
|
|
868
|
+
* Tells if the media is in a particular state
|
|
869
|
+
* @param {String} state
|
|
870
|
+
* @returns {Boolean}
|
|
871
|
+
*/
|
|
872
|
+
is: function is(state) {
|
|
873
|
+
return !!this.config.is[state];
|
|
874
|
+
},
|
|
1293
875
|
|
|
1294
|
-
|
|
876
|
+
/**
|
|
877
|
+
* Changes the size of the player
|
|
878
|
+
* @param {Number} width
|
|
879
|
+
* @param {Number} height
|
|
880
|
+
* @returns {mediaplayer}
|
|
881
|
+
*/
|
|
882
|
+
resize: function resize(width, height) {
|
|
883
|
+
if (isResponsiveSize(width) && !isResponsiveSize(height) || this.is('youtube')) {
|
|
884
|
+
// responsive width height should be auto
|
|
885
|
+
// for youtube iframe height is limited by ration
|
|
886
|
+
height = 'auto';
|
|
887
|
+
}
|
|
1295
888
|
|
|
1296
|
-
|
|
889
|
+
this.execute('setSize', width, height);
|
|
890
|
+
return this;
|
|
891
|
+
},
|
|
1297
892
|
|
|
1298
|
-
|
|
893
|
+
/**
|
|
894
|
+
* Enables the media player
|
|
895
|
+
* @returns {mediaplayer}
|
|
896
|
+
*/
|
|
897
|
+
enable: function enable() {
|
|
898
|
+
this._fromState('disabled');
|
|
1299
899
|
|
|
1300
|
-
|
|
900
|
+
return this;
|
|
901
|
+
},
|
|
1301
902
|
|
|
1302
|
-
|
|
903
|
+
/**
|
|
904
|
+
* Disables the media player
|
|
905
|
+
* @returns {mediaplayer}
|
|
906
|
+
*/
|
|
907
|
+
disable: function disable() {
|
|
908
|
+
this._toState('disabled');
|
|
1303
909
|
|
|
1304
|
-
|
|
1305
|
-
|
|
910
|
+
this.trigger('disabled');
|
|
911
|
+
return this;
|
|
912
|
+
},
|
|
1306
913
|
|
|
1307
|
-
if (renderTo) {
|
|
1308
|
-
this.$container = $$1(renderTo).append(this.$component);
|
|
1309
|
-
}
|
|
1310
914
|
/**
|
|
1311
|
-
*
|
|
1312
|
-
* @
|
|
1313
|
-
* @param {jQuery} $component
|
|
915
|
+
* Shows the media player
|
|
916
|
+
* @returns {mediaplayer}
|
|
1314
917
|
*/
|
|
918
|
+
show: function show() {
|
|
919
|
+
this._fromState('hidden');
|
|
1315
920
|
|
|
921
|
+
return this;
|
|
922
|
+
},
|
|
1316
923
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
* @param {Number} time - The start position in seconds
|
|
1324
|
-
* @param {*} [internal] - Internal use
|
|
1325
|
-
* @returns {mediaplayer}
|
|
1326
|
-
*/
|
|
1327
|
-
seek: function seek(time, internal) {
|
|
1328
|
-
if (this._canPlay()) {
|
|
1329
|
-
this._updatePosition(time, internal);
|
|
924
|
+
/**
|
|
925
|
+
* hides the media player
|
|
926
|
+
* @returns {mediaplayer}
|
|
927
|
+
*/
|
|
928
|
+
hide: function hide() {
|
|
929
|
+
this._toState('hidden');
|
|
1330
930
|
|
|
1331
|
-
|
|
931
|
+
return this;
|
|
932
|
+
},
|
|
1332
933
|
|
|
1333
|
-
|
|
1334
|
-
|
|
934
|
+
/**
|
|
935
|
+
* get media original size
|
|
936
|
+
* @returns {Object}
|
|
937
|
+
*/
|
|
938
|
+
getMediaOriginalSize: function getMediaOriginalSize() {
|
|
939
|
+
if (this.is('youtube')) {
|
|
940
|
+
return defaults.youtube;
|
|
1335
941
|
}
|
|
1336
942
|
|
|
1337
|
-
this.
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
return this;
|
|
1341
|
-
},
|
|
1342
|
-
|
|
1343
|
-
/**
|
|
1344
|
-
* Plays the media
|
|
1345
|
-
* @param {Number} [time] - An optional start position in seconds
|
|
1346
|
-
* @returns {mediaplayer}
|
|
1347
|
-
*/
|
|
1348
|
-
play: function play(time) {
|
|
1349
|
-
if (this._canPlay()) {
|
|
1350
|
-
if (typeof time !== 'undefined') {
|
|
1351
|
-
this.seek(time);
|
|
943
|
+
if (this.is('video') && this.player) {
|
|
944
|
+
return this.player.getMediaSize();
|
|
1352
945
|
}
|
|
1353
946
|
|
|
1354
|
-
|
|
947
|
+
return {};
|
|
948
|
+
},
|
|
1355
949
|
|
|
1356
|
-
|
|
1357
|
-
|
|
950
|
+
/**
|
|
951
|
+
* Ensures the right media type is set
|
|
952
|
+
* @param {String} type
|
|
953
|
+
* @private
|
|
954
|
+
*/
|
|
955
|
+
_setType: function _setType(type) {
|
|
956
|
+
if (type.indexOf('youtube') !== -1) {
|
|
957
|
+
this.type = 'youtube';
|
|
958
|
+
} else if (type.indexOf('audio') === 0) {
|
|
959
|
+
this.type = 'audio';
|
|
960
|
+
} else {
|
|
961
|
+
this.type = 'video';
|
|
1358
962
|
}
|
|
963
|
+
},
|
|
1359
964
|
|
|
1360
|
-
|
|
965
|
+
/**
|
|
966
|
+
* Ensures the type is correctly applied
|
|
967
|
+
* @private
|
|
968
|
+
*/
|
|
969
|
+
_initType: function _initType() {
|
|
970
|
+
var is = this.config.is;
|
|
971
|
+
is.youtube = 'youtube' === this.type;
|
|
972
|
+
is.video = 'video' === this.type || 'youtube' === this.type;
|
|
973
|
+
is.audio = 'audio' === this.type;
|
|
974
|
+
},
|
|
1361
975
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
976
|
+
/**
|
|
977
|
+
* Gets a source descriptor.
|
|
978
|
+
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
979
|
+
* @param {Function} callback - A function called to provide the media source object
|
|
980
|
+
*/
|
|
981
|
+
_getSource: function _getSource(src, callback) {
|
|
982
|
+
var _this4 = this;
|
|
1366
983
|
|
|
1367
|
-
|
|
1368
|
-
},
|
|
984
|
+
var source;
|
|
1369
985
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
*/
|
|
1375
|
-
pause: function pause(time) {
|
|
1376
|
-
if (this._canPause()) {
|
|
1377
|
-
if (typeof time !== 'undefined') {
|
|
1378
|
-
this.seek(time);
|
|
1379
|
-
}
|
|
986
|
+
var done = function done() {
|
|
987
|
+
if (needTypeAdjust(source.type)) {
|
|
988
|
+
source.type = getAdjustedType(source);
|
|
989
|
+
}
|
|
1380
990
|
|
|
1381
|
-
|
|
991
|
+
callback.call(_this4, source);
|
|
992
|
+
};
|
|
1382
993
|
|
|
1383
|
-
if (
|
|
1384
|
-
|
|
994
|
+
if (_.isString(src)) {
|
|
995
|
+
source = {
|
|
996
|
+
src: src
|
|
997
|
+
};
|
|
998
|
+
} else {
|
|
999
|
+
source = _.clone(src);
|
|
1385
1000
|
}
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
return this;
|
|
1389
|
-
},
|
|
1390
|
-
|
|
1391
|
-
/**
|
|
1392
|
-
* Resumes the media
|
|
1393
|
-
* @returns {mediaplayer}
|
|
1394
|
-
*/
|
|
1395
|
-
resume: function resume() {
|
|
1396
|
-
if (this._canResume()) {
|
|
1397
|
-
this.play();
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
return this;
|
|
1401
|
-
},
|
|
1402
|
-
|
|
1403
|
-
/**
|
|
1404
|
-
* Stops the playback
|
|
1405
|
-
* @returns {mediaplayer}
|
|
1406
|
-
*/
|
|
1407
|
-
stop: function stop() {
|
|
1408
|
-
this.loop = false;
|
|
1409
|
-
this.execute('stop');
|
|
1410
|
-
|
|
1411
|
-
if (!this.is('ready')) {
|
|
1412
|
-
this.autoStart = false;
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
return this;
|
|
1416
|
-
},
|
|
1417
|
-
|
|
1418
|
-
/**
|
|
1419
|
-
* Restarts the media from the beginning
|
|
1420
|
-
* @returns {mediaplayer}
|
|
1421
|
-
*/
|
|
1422
|
-
restart: function restart() {
|
|
1423
|
-
this.play(0);
|
|
1424
|
-
return this;
|
|
1425
|
-
},
|
|
1426
|
-
|
|
1427
|
-
/**
|
|
1428
|
-
* Rewind the media to the beginning
|
|
1429
|
-
* @returns {mediaplayer}
|
|
1430
|
-
*/
|
|
1431
|
-
rewind: function rewind() {
|
|
1432
|
-
this.seek(0);
|
|
1433
|
-
return this;
|
|
1434
|
-
},
|
|
1435
|
-
|
|
1436
|
-
/**
|
|
1437
|
-
* Mutes the media
|
|
1438
|
-
* @param {Boolean} [state] - A flag to set the mute state (default: true)
|
|
1439
|
-
* @returns {mediaplayer}
|
|
1440
|
-
*/
|
|
1441
|
-
mute: function mute(state) {
|
|
1442
|
-
if (typeof state === 'undefined') {
|
|
1443
|
-
state = true;
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
this.execute('mute', state);
|
|
1447
|
-
|
|
1448
|
-
this._setState('muted', state);
|
|
1449
|
-
|
|
1450
|
-
if (!this.is('ready')) {
|
|
1451
|
-
this.startMuted = state;
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
return this;
|
|
1455
|
-
},
|
|
1456
|
-
|
|
1457
|
-
/**
|
|
1458
|
-
* Restore the sound of the media after a mute
|
|
1459
|
-
* @returns {mediaplayer}
|
|
1460
|
-
*/
|
|
1461
|
-
unmute: function unmute() {
|
|
1462
|
-
this.mute(false);
|
|
1463
|
-
return this;
|
|
1464
|
-
},
|
|
1465
|
-
|
|
1466
|
-
/**
|
|
1467
|
-
* Sets the sound volume of the media being played
|
|
1468
|
-
* @param {Number} value - A value between 0 and 100
|
|
1469
|
-
* @param {*} [internal] - Internal use
|
|
1470
|
-
* @returns {mediaplayer}
|
|
1471
|
-
*/
|
|
1472
|
-
setVolume: function setVolume(value, internal) {
|
|
1473
|
-
this._updateVolume(value, internal);
|
|
1474
|
-
|
|
1475
|
-
this.execute('setVolume', this.volume);
|
|
1476
|
-
return this;
|
|
1477
|
-
},
|
|
1478
|
-
|
|
1479
|
-
/**
|
|
1480
|
-
* Gets the sound volume applied to the media being played
|
|
1481
|
-
* @returns {Number} Returns a value between 0 and 100
|
|
1482
|
-
*/
|
|
1483
|
-
getVolume: function getVolume() {
|
|
1484
|
-
return this.volume;
|
|
1485
|
-
},
|
|
1486
|
-
|
|
1487
|
-
/**
|
|
1488
|
-
* Gets the current displayed position inside the media
|
|
1489
|
-
* @returns {Number}
|
|
1490
|
-
*/
|
|
1491
|
-
getPosition: function getPosition() {
|
|
1492
|
-
return this.position;
|
|
1493
|
-
},
|
|
1494
|
-
|
|
1495
|
-
/**
|
|
1496
|
-
* Gets the duration of the media
|
|
1497
|
-
* @returns {Number}
|
|
1498
|
-
*/
|
|
1499
|
-
getDuration: function getDuration() {
|
|
1500
|
-
return this.duration;
|
|
1501
|
-
},
|
|
1502
|
-
|
|
1503
|
-
/**
|
|
1504
|
-
* Gets the number of times the media has been played
|
|
1505
|
-
* @returns {Number}
|
|
1506
|
-
*/
|
|
1507
|
-
getTimesPlayed: function getTimesPlayed() {
|
|
1508
|
-
return this.timesPlayed;
|
|
1509
|
-
},
|
|
1510
1001
|
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
},
|
|
1518
|
-
|
|
1519
|
-
/**
|
|
1520
|
-
* Gets the DOM container
|
|
1521
|
-
* @returns {jQuery}
|
|
1522
|
-
*/
|
|
1523
|
-
getContainer: function getContainer() {
|
|
1524
|
-
var $container;
|
|
1525
|
-
|
|
1526
|
-
if (!this.$container && this.$component) {
|
|
1527
|
-
$container = this.$component.parent();
|
|
1528
|
-
|
|
1529
|
-
if ($container.length) {
|
|
1530
|
-
this.$container = $container;
|
|
1002
|
+
if (!source.type) {
|
|
1003
|
+
if (this.is('youtube')) {
|
|
1004
|
+
source.type = defaults.type;
|
|
1005
|
+
} else if (this.config.mimeType) {
|
|
1006
|
+
source.type = this.config.mimeType;
|
|
1007
|
+
}
|
|
1531
1008
|
}
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
return this.$container;
|
|
1535
|
-
},
|
|
1536
1009
|
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
return this.$component;
|
|
1543
|
-
},
|
|
1544
|
-
|
|
1545
|
-
/**
|
|
1546
|
-
* Gets the list of media
|
|
1547
|
-
* @returns {Array}
|
|
1548
|
-
*/
|
|
1549
|
-
getSources: function getSources() {
|
|
1550
|
-
return this.config.sources.slice();
|
|
1551
|
-
},
|
|
1552
|
-
|
|
1553
|
-
/**
|
|
1554
|
-
* Sets the media source. If a source has been already set, it will be replaced.
|
|
1555
|
-
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
1556
|
-
* @param {Function} [callback] - A function called to provide the added media source object
|
|
1557
|
-
* @returns {mediaplayer}
|
|
1558
|
-
*/
|
|
1559
|
-
setSource: function setSource(src, callback) {
|
|
1560
|
-
this._getSource(src, function (source) {
|
|
1561
|
-
this.config.sources = [source];
|
|
1562
|
-
|
|
1563
|
-
if (this.is('rendered')) {
|
|
1564
|
-
this.player.setMedia(source.src, source.type);
|
|
1565
|
-
}
|
|
1010
|
+
if (!source.type) {
|
|
1011
|
+
mimetype.getResourceType(source.src, function (err, type) {
|
|
1012
|
+
if (err) {
|
|
1013
|
+
type = defaults.type;
|
|
1014
|
+
}
|
|
1566
1015
|
|
|
1567
|
-
|
|
1568
|
-
|
|
1016
|
+
source.type = type;
|
|
1017
|
+
done();
|
|
1018
|
+
});
|
|
1019
|
+
} else {
|
|
1020
|
+
done();
|
|
1569
1021
|
}
|
|
1570
|
-
}
|
|
1022
|
+
},
|
|
1571
1023
|
|
|
1572
|
-
|
|
1573
|
-
|
|
1024
|
+
/**
|
|
1025
|
+
* Ensures the sources are correctly set
|
|
1026
|
+
* @param {Function} callback - A function called once all sources have been initialized
|
|
1027
|
+
* @private
|
|
1028
|
+
*/
|
|
1029
|
+
_initSources: function _initSources(callback) {
|
|
1030
|
+
var _this5 = this;
|
|
1031
|
+
|
|
1032
|
+
var sources = configToSources(this.config);
|
|
1033
|
+
this.config.sources = [];
|
|
1034
|
+
async.each(sources, function (source, cb) {
|
|
1035
|
+
_this5.addSource(source, function (src) {
|
|
1036
|
+
return cb(null, src);
|
|
1037
|
+
});
|
|
1038
|
+
}, callback);
|
|
1039
|
+
},
|
|
1574
1040
|
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
this._getSource(src, function (source) {
|
|
1583
|
-
this.config.sources.push(source);
|
|
1041
|
+
/**
|
|
1042
|
+
* Installs the events manager onto the instance
|
|
1043
|
+
* @private
|
|
1044
|
+
*/
|
|
1045
|
+
_initEvents: function _initEvents() {
|
|
1046
|
+
eventifier(this);
|
|
1047
|
+
var triggerEvent = this.trigger;
|
|
1584
1048
|
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1049
|
+
this.trigger = function trigger(eventName) {
|
|
1050
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
1051
|
+
args[_key - 1] = arguments[_key];
|
|
1052
|
+
}
|
|
1588
1053
|
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
}
|
|
1592
|
-
});
|
|
1054
|
+
if (this.$component) {
|
|
1055
|
+
var _this$$component;
|
|
1593
1056
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1057
|
+
(_this$$component = this.$component).trigger.apply(_this$$component, [eventName + ns].concat(args));
|
|
1058
|
+
}
|
|
1596
1059
|
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
* @returns {Boolean}
|
|
1601
|
-
*/
|
|
1602
|
-
is: function is(state) {
|
|
1603
|
-
return !!this.config.is[state];
|
|
1604
|
-
},
|
|
1060
|
+
return triggerEvent.call.apply(triggerEvent, [this, eventName].concat(args));
|
|
1061
|
+
};
|
|
1062
|
+
},
|
|
1605
1063
|
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
if (this.$component) {
|
|
1621
|
-
height -= this.$component.outerHeight() - this.$component.height();
|
|
1622
|
-
width -= this.$component.outerWidth() - this.$component.width();
|
|
1623
|
-
this.$component.width(width).height(height);
|
|
1624
|
-
|
|
1625
|
-
if (!this.is('nogui')) {
|
|
1626
|
-
height -= this.$controls.outerHeight();
|
|
1064
|
+
/**
|
|
1065
|
+
* Ensures the right size is set according to the media type
|
|
1066
|
+
* @private
|
|
1067
|
+
*/
|
|
1068
|
+
_initSize: function _initSize() {
|
|
1069
|
+
var type = this.is('video') ? 'video' : 'audio';
|
|
1070
|
+
var mediaConfig = defaults[type] || defaults.video;
|
|
1071
|
+
this.config.width = this.config.width || mediaConfig.width;
|
|
1072
|
+
this.config.height = this.config.height || mediaConfig.height;
|
|
1073
|
+
|
|
1074
|
+
if (isResponsiveSize(this.config.width) && !isResponsiveSize(this.config.height) || this.is('youtube')) {
|
|
1075
|
+
// responsive width height should be auto
|
|
1076
|
+
// for youtube iframe height is limited by ration
|
|
1077
|
+
this.config.height = 'auto';
|
|
1627
1078
|
}
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
this.execute('setSize', width, height);
|
|
1631
|
-
return this;
|
|
1632
|
-
},
|
|
1633
|
-
|
|
1634
|
-
/**
|
|
1635
|
-
* Enables the media player
|
|
1636
|
-
* @returns {mediaplayer}
|
|
1637
|
-
*/
|
|
1638
|
-
enable: function enable() {
|
|
1639
|
-
this._fromState('disabled');
|
|
1640
|
-
|
|
1641
|
-
return this;
|
|
1642
|
-
},
|
|
1079
|
+
},
|
|
1643
1080
|
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1081
|
+
/**
|
|
1082
|
+
* Initializes the right player instance
|
|
1083
|
+
* @private
|
|
1084
|
+
*/
|
|
1085
|
+
_initPlayer: function _initPlayer() {
|
|
1086
|
+
var _this6 = this;
|
|
1087
|
+
|
|
1088
|
+
var playerFactory = players[this.type];
|
|
1089
|
+
var error;
|
|
1090
|
+
|
|
1091
|
+
if (support.canPlay(this.type)) {
|
|
1092
|
+
if (_.isFunction(playerFactory)) {
|
|
1093
|
+
var playerConfig = {
|
|
1094
|
+
type: this.getType(),
|
|
1095
|
+
sources: this.getSources(),
|
|
1096
|
+
preview: this.config.preview,
|
|
1097
|
+
debug: this.config.debug,
|
|
1098
|
+
stalledDetectionDelay: this.config.stalledDetectionDelay
|
|
1099
|
+
};
|
|
1100
|
+
this.player = playerFactory(this.$player, playerConfig).on('resize', function (width, height) {
|
|
1101
|
+
if (_this6.$component) {
|
|
1102
|
+
_this6.$component.width(width).height(height);
|
|
1103
|
+
}
|
|
1104
|
+
}).on('ready', function () {
|
|
1105
|
+
return _this6._onReady();
|
|
1106
|
+
}).on('play', function () {
|
|
1107
|
+
return _this6._onPlay();
|
|
1108
|
+
}).on('pause', function () {
|
|
1109
|
+
return _this6._onPause();
|
|
1110
|
+
}).on('timeupdate', function () {
|
|
1111
|
+
return _this6._onTimeUpdate();
|
|
1112
|
+
}).on('stalled', function () {
|
|
1113
|
+
return _this6._onStalled();
|
|
1114
|
+
}).on('playing', function () {
|
|
1115
|
+
return _this6._onPlaying();
|
|
1116
|
+
}).on('end', function () {
|
|
1117
|
+
return _this6._onEnd();
|
|
1118
|
+
}).on('error', function () {
|
|
1119
|
+
return _this6._onError();
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1664
1122
|
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1123
|
+
if (this.player) {
|
|
1124
|
+
error = !this.player.init();
|
|
1125
|
+
} else {
|
|
1126
|
+
error = true;
|
|
1127
|
+
}
|
|
1128
|
+
} else {
|
|
1129
|
+
error = true;
|
|
1130
|
+
}
|
|
1671
1131
|
|
|
1672
|
-
|
|
1673
|
-
},
|
|
1132
|
+
this._setState('error', error);
|
|
1674
1133
|
|
|
1675
|
-
|
|
1676
|
-
* Ensures the right media type is set
|
|
1677
|
-
* @param {String} type
|
|
1678
|
-
* @private
|
|
1679
|
-
*/
|
|
1680
|
-
_setType: function _setType(type) {
|
|
1681
|
-
if (type.indexOf('youtube') !== -1) {
|
|
1682
|
-
this.type = 'youtube';
|
|
1683
|
-
} else if (type.indexOf('audio') === 0) {
|
|
1684
|
-
this.type = 'audio';
|
|
1685
|
-
} else {
|
|
1686
|
-
this.type = 'video';
|
|
1687
|
-
}
|
|
1688
|
-
},
|
|
1134
|
+
this._setState('nogui', !support.canControl());
|
|
1689
1135
|
|
|
1690
|
-
|
|
1691
|
-
* Ensures the type is correctly applied
|
|
1692
|
-
* @private
|
|
1693
|
-
*/
|
|
1694
|
-
_initType: function _initType() {
|
|
1695
|
-
var is = this.config.is;
|
|
1696
|
-
is.youtube = 'youtube' === this.type;
|
|
1697
|
-
is.video = 'video' === this.type || 'youtube' === this.type;
|
|
1698
|
-
is.audio = 'audio' === this.type;
|
|
1699
|
-
},
|
|
1136
|
+
this._setState('preview', this.config.preview);
|
|
1700
1137
|
|
|
1701
|
-
|
|
1702
|
-
* Gets a source descriptor.
|
|
1703
|
-
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
1704
|
-
* @param {Function} callback - A function called to provide the media source object
|
|
1705
|
-
*/
|
|
1706
|
-
_getSource: function _getSource(src, callback) {
|
|
1707
|
-
var self = this;
|
|
1708
|
-
var source;
|
|
1138
|
+
this._setState('loading', !error);
|
|
1709
1139
|
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
src: src
|
|
1713
|
-
};
|
|
1714
|
-
} else {
|
|
1715
|
-
source = _.clone(src);
|
|
1716
|
-
}
|
|
1140
|
+
if (error) {
|
|
1141
|
+
this._setState('ready', true);
|
|
1717
1142
|
|
|
1718
|
-
|
|
1719
|
-
source.type = _defaults.type;
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
if (!source.type) {
|
|
1723
|
-
mimetype.getResourceType(source.src, function (err, type) {
|
|
1724
|
-
if (err) {
|
|
1725
|
-
type = _defaults.type;
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
source.type = type;
|
|
1729
|
-
done();
|
|
1730
|
-
});
|
|
1731
|
-
} else {
|
|
1732
|
-
done();
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
function done() {
|
|
1736
|
-
if (_needTypeAdjust(source.type)) {
|
|
1737
|
-
source.type = _getAdjustedType(source);
|
|
1143
|
+
this.trigger('ready');
|
|
1738
1144
|
}
|
|
1145
|
+
},
|
|
1739
1146
|
|
|
1740
|
-
|
|
1741
|
-
|
|
1147
|
+
/**
|
|
1148
|
+
* Initializes the player state
|
|
1149
|
+
* @private
|
|
1150
|
+
*/
|
|
1151
|
+
_initState: function _initState() {
|
|
1152
|
+
var isCORS = false;
|
|
1153
|
+
var page;
|
|
1154
|
+
|
|
1155
|
+
if (!this.is('youtube')) {
|
|
1156
|
+
page = new UrlParser(window.location);
|
|
1157
|
+
isCORS = _.some(this.config.sources, function (source) {
|
|
1158
|
+
return !page.sameDomain(source.src);
|
|
1159
|
+
});
|
|
1742
1160
|
}
|
|
1743
1161
|
|
|
1744
|
-
|
|
1745
|
-
}
|
|
1746
|
-
},
|
|
1747
|
-
|
|
1748
|
-
/**
|
|
1749
|
-
* Ensures the sources are correctly set
|
|
1750
|
-
* @param {Function} callback - A function called once all sources have been initialized
|
|
1751
|
-
* @private
|
|
1752
|
-
*/
|
|
1753
|
-
_initSources: function _initSources(callback) {
|
|
1754
|
-
var self = this;
|
|
1755
|
-
|
|
1756
|
-
var sources = _configToSources(this.config);
|
|
1162
|
+
this._setState('cors', isCORS);
|
|
1757
1163
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
self.addSource(source, function (src) {
|
|
1761
|
-
cb(null, src);
|
|
1762
|
-
});
|
|
1763
|
-
}, callback);
|
|
1764
|
-
},
|
|
1765
|
-
|
|
1766
|
-
/**
|
|
1767
|
-
* Installs the events manager onto the instance
|
|
1768
|
-
* @private
|
|
1769
|
-
*/
|
|
1770
|
-
_initEvents: function _initEvents() {
|
|
1771
|
-
var triggerEvent;
|
|
1772
|
-
eventifier(this);
|
|
1773
|
-
triggerEvent = this.trigger;
|
|
1164
|
+
this._setState('ready', false);
|
|
1165
|
+
},
|
|
1774
1166
|
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1167
|
+
/**
|
|
1168
|
+
* Resets the internals attributes
|
|
1169
|
+
* @private
|
|
1170
|
+
*/
|
|
1171
|
+
_reset: function _reset() {
|
|
1172
|
+
this.config.is = {};
|
|
1779
1173
|
|
|
1780
|
-
|
|
1781
|
-
};
|
|
1782
|
-
},
|
|
1174
|
+
this._initType();
|
|
1783
1175
|
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1176
|
+
this.$component = null;
|
|
1177
|
+
this.$container = null;
|
|
1178
|
+
this.$player = null;
|
|
1179
|
+
this.$controls = null;
|
|
1180
|
+
this.$seek = null;
|
|
1181
|
+
this.$seekSlider = null;
|
|
1182
|
+
this.$sound = null;
|
|
1183
|
+
this.$volume = null;
|
|
1184
|
+
this.$volumeControl = null;
|
|
1185
|
+
this.$volumeSlider = null;
|
|
1186
|
+
this.$position = null;
|
|
1187
|
+
this.$duration = null;
|
|
1188
|
+
this.player = null;
|
|
1189
|
+
this.duration = 0;
|
|
1190
|
+
this.position = 0;
|
|
1191
|
+
this.timesPlayed = 0;
|
|
1192
|
+
this.volume = this.config.volume;
|
|
1193
|
+
this.autoStart = this.config.autoStart;
|
|
1194
|
+
this.autoStartAt = this.config.autoStartAt;
|
|
1195
|
+
this.startMuted = this.config.startMuted;
|
|
1196
|
+
},
|
|
1794
1197
|
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1198
|
+
/**
|
|
1199
|
+
* Builds the DOM content
|
|
1200
|
+
* @private
|
|
1201
|
+
*/
|
|
1202
|
+
_buildDom: function _buildDom() {
|
|
1203
|
+
var configForTemplate = _.clone(this.config);
|
|
1204
|
+
|
|
1205
|
+
configForTemplate.type = this.type;
|
|
1206
|
+
this.$component = $$1(playerTpl(configForTemplate));
|
|
1207
|
+
this.$player = this.$component.find('.player');
|
|
1208
|
+
this.$controls = this.$component.find('.controls');
|
|
1209
|
+
this.$seek = this.$controls.find('.seek .slider');
|
|
1210
|
+
this.$sound = this.$controls.find('.sound');
|
|
1211
|
+
this.$volumeControl = this.$controls.find('.volume');
|
|
1212
|
+
this.$volume = this.$controls.find('.volume .slider');
|
|
1213
|
+
this.$position = this.$controls.find('[data-control="time-cur"]');
|
|
1214
|
+
this.$duration = this.$controls.find('[data-control="time-end"]');
|
|
1215
|
+
this.$volumeSlider = this._renderSlider(this.$volume, this.volume, volumeMin, volumeMax, true);
|
|
1216
|
+
},
|
|
1802
1217
|
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1218
|
+
/**
|
|
1219
|
+
* Renders a slider onto an element
|
|
1220
|
+
* @param {jQuery} $elt - The element on which renders the slider
|
|
1221
|
+
* @param {Number} [value] - The current value of the slider
|
|
1222
|
+
* @param {Number} [min] - The min value of the slider
|
|
1223
|
+
* @param {Number} [max] - The max value of the slider
|
|
1224
|
+
* @param {Boolean} [vertical] - Tells if the slider must be vertical
|
|
1225
|
+
* @returns {jQuery} - Returns the element
|
|
1226
|
+
* @private
|
|
1227
|
+
*/
|
|
1228
|
+
_renderSlider: function _renderSlider($elt, value, min, max, vertical) {
|
|
1229
|
+
var orientation, direction;
|
|
1807
1230
|
|
|
1808
|
-
if (
|
|
1809
|
-
|
|
1231
|
+
if (vertical) {
|
|
1232
|
+
orientation = 'vertical';
|
|
1233
|
+
direction = 'rtl';
|
|
1810
1234
|
} else {
|
|
1811
|
-
|
|
1235
|
+
orientation = 'horizontal';
|
|
1236
|
+
direction = 'ltr';
|
|
1812
1237
|
}
|
|
1813
|
-
} else {
|
|
1814
|
-
error = true;
|
|
1815
|
-
}
|
|
1816
|
-
|
|
1817
|
-
this._setState('error', error);
|
|
1818
1238
|
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
var page;
|
|
1831
|
-
|
|
1832
|
-
if (!this.is('youtube')) {
|
|
1833
|
-
page = new UrlParser(window.location);
|
|
1834
|
-
isCORS = _.some(this.config.sources, function (source) {
|
|
1835
|
-
return !page.sameDomain(source.src);
|
|
1239
|
+
return $elt.noUiSlider({
|
|
1240
|
+
start: ensureNumber(value) || 0,
|
|
1241
|
+
step: 1,
|
|
1242
|
+
connect: 'lower',
|
|
1243
|
+
orientation: orientation,
|
|
1244
|
+
direction: direction,
|
|
1245
|
+
animate: true,
|
|
1246
|
+
range: {
|
|
1247
|
+
min: ensureNumber(min) || 0,
|
|
1248
|
+
max: ensureNumber(max) || 0
|
|
1249
|
+
}
|
|
1836
1250
|
});
|
|
1837
|
-
}
|
|
1838
|
-
|
|
1839
|
-
this._setState('cors', isCORS);
|
|
1840
|
-
|
|
1841
|
-
this._setState('ready', false);
|
|
1842
|
-
},
|
|
1843
|
-
|
|
1844
|
-
/**
|
|
1845
|
-
* Resets the internals attributes
|
|
1846
|
-
* @private
|
|
1847
|
-
*/
|
|
1848
|
-
_reset: function _reset() {
|
|
1849
|
-
this.config.is = {};
|
|
1850
|
-
|
|
1851
|
-
this._initType();
|
|
1852
|
-
|
|
1853
|
-
this.$component = null;
|
|
1854
|
-
this.$container = null;
|
|
1855
|
-
this.$player = null;
|
|
1856
|
-
this.$media = null;
|
|
1857
|
-
this.$controls = null;
|
|
1858
|
-
this.$seek = null;
|
|
1859
|
-
this.$seekSlider = null;
|
|
1860
|
-
this.$sound = null;
|
|
1861
|
-
this.$volume = null;
|
|
1862
|
-
this.$volumeControl = null;
|
|
1863
|
-
this.$volumeSlider = null;
|
|
1864
|
-
this.$position = null;
|
|
1865
|
-
this.$duration = null;
|
|
1866
|
-
this.player = null;
|
|
1867
|
-
this.duration = 0;
|
|
1868
|
-
this.position = 0;
|
|
1869
|
-
this.timesPlayed = 0;
|
|
1870
|
-
this.volume = this.config.volume;
|
|
1871
|
-
this.autoStart = this.config.autoStart;
|
|
1872
|
-
this.autoStartAt = this.config.autoStartAt;
|
|
1873
|
-
this.startMuted = this.config.startMuted;
|
|
1874
|
-
},
|
|
1251
|
+
},
|
|
1875
1252
|
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
this.$controls = this.$component.find('.controls');
|
|
1885
|
-
this.$seek = this.$controls.find('.seek .slider');
|
|
1886
|
-
this.$sound = this.$controls.find('.sound');
|
|
1887
|
-
this.$volumeControl = this.$controls.find('.volume');
|
|
1888
|
-
this.$volume = this.$controls.find('.volume .slider');
|
|
1889
|
-
this.$position = this.$controls.find('[data-control="time-cur"]');
|
|
1890
|
-
this.$duration = this.$controls.find('[data-control="time-end"]');
|
|
1891
|
-
this.$volumeSlider = this._renderSlider(this.$volume, this.volume, _volumeMin, _volumeMax, true);
|
|
1892
|
-
},
|
|
1893
|
-
|
|
1894
|
-
/**
|
|
1895
|
-
* Renders a slider onto an element
|
|
1896
|
-
* @param {jQuery} $elt - The element on which renders the slider
|
|
1897
|
-
* @param {Number} [value] - The current value of the slider
|
|
1898
|
-
* @param {Number} [min] - The min value of the slider
|
|
1899
|
-
* @param {Number} [max] - The max value of the slider
|
|
1900
|
-
* @param {Boolean} [vertical] - Tells if the slider must be vertical
|
|
1901
|
-
* @returns {jQuery} - Returns the element
|
|
1902
|
-
* @private
|
|
1903
|
-
*/
|
|
1904
|
-
_renderSlider: function _renderSlider($elt, value, min, max, vertical) {
|
|
1905
|
-
var orientation, direction;
|
|
1906
|
-
|
|
1907
|
-
if (vertical) {
|
|
1908
|
-
orientation = 'vertical';
|
|
1909
|
-
direction = 'rtl';
|
|
1910
|
-
} else {
|
|
1911
|
-
orientation = 'horizontal';
|
|
1912
|
-
direction = 'ltr';
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
return $elt.noUiSlider({
|
|
1916
|
-
start: _ensureNumber(value) || 0,
|
|
1917
|
-
step: 1,
|
|
1918
|
-
connect: 'lower',
|
|
1919
|
-
orientation: orientation,
|
|
1920
|
-
direction: direction,
|
|
1921
|
-
animate: true,
|
|
1922
|
-
range: {
|
|
1923
|
-
min: _ensureNumber(min) || 0,
|
|
1924
|
-
max: _ensureNumber(max) || 0
|
|
1253
|
+
/**
|
|
1254
|
+
* Destroys a slider bound to an element
|
|
1255
|
+
* @param {jQuery} $elt
|
|
1256
|
+
* @private
|
|
1257
|
+
*/
|
|
1258
|
+
_destroySlider: function _destroySlider($elt) {
|
|
1259
|
+
if ($elt) {
|
|
1260
|
+
$elt.get(0).destroy();
|
|
1925
1261
|
}
|
|
1926
|
-
}
|
|
1927
|
-
},
|
|
1262
|
+
},
|
|
1928
1263
|
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
if ($elt) {
|
|
1936
|
-
$elt.get(0).destroy();
|
|
1937
|
-
}
|
|
1938
|
-
},
|
|
1264
|
+
/**
|
|
1265
|
+
* Binds events onto the rendered player
|
|
1266
|
+
* @private
|
|
1267
|
+
*/
|
|
1268
|
+
_bindEvents: function _bindEvents() {
|
|
1269
|
+
var _this7 = this;
|
|
1939
1270
|
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
event.preventDefault();
|
|
1949
|
-
});
|
|
1950
|
-
this.$controls.on('click' + _ns, '.action', function (event) {
|
|
1951
|
-
var $target = $$1(event.target);
|
|
1952
|
-
var $action = $target.closest('.action');
|
|
1953
|
-
var id = $action.data('control');
|
|
1271
|
+
var overing = false;
|
|
1272
|
+
this.$component.on("contextmenu".concat(ns), function (event) {
|
|
1273
|
+
return event.preventDefault();
|
|
1274
|
+
});
|
|
1275
|
+
this.$controls.on("click".concat(ns), '.action', function (event) {
|
|
1276
|
+
var $target = $$1(event.target);
|
|
1277
|
+
var $action = $target.closest('.action');
|
|
1278
|
+
var id = $action.data('control');
|
|
1954
1279
|
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
} else {
|
|
1963
|
-
self.play();
|
|
1964
|
-
}
|
|
1965
|
-
});
|
|
1966
|
-
this.$seek.on('change' + _ns, function (event, value) {
|
|
1967
|
-
self.seek(value, true);
|
|
1968
|
-
});
|
|
1969
|
-
$$1(document).on('updateVolume' + _ns, function (event, value) {
|
|
1970
|
-
self.setVolume(value);
|
|
1971
|
-
});
|
|
1972
|
-
this.$volume.on('change' + _ns, function (event, value) {
|
|
1973
|
-
self.unmute();
|
|
1974
|
-
$$1(document).trigger('updateVolume' + _ns, value);
|
|
1975
|
-
self.setVolume(value, true);
|
|
1976
|
-
});
|
|
1977
|
-
this.$sound.on('mouseover' + _ns, 'a', function () {
|
|
1978
|
-
var position;
|
|
1280
|
+
if (_.isFunction(_this7[id])) {
|
|
1281
|
+
_this7[id]();
|
|
1282
|
+
}
|
|
1283
|
+
});
|
|
1284
|
+
this.$player.on("click".concat(ns), function (event) {
|
|
1285
|
+
var $target = $$1(event.target);
|
|
1286
|
+
var $action = $target.closest('.action'); // if action was clicked
|
|
1979
1287
|
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
position = self.$controls[0].getBoundingClientRect();
|
|
1288
|
+
if ($action.length) {
|
|
1289
|
+
var id = $action.data('control');
|
|
1983
1290
|
|
|
1984
|
-
|
|
1985
|
-
|
|
1291
|
+
if (_.isFunction(_this7[id])) {
|
|
1292
|
+
_this7[id]();
|
|
1293
|
+
}
|
|
1986
1294
|
} else {
|
|
1987
|
-
|
|
1988
|
-
|
|
1295
|
+
// default action is toggle play
|
|
1296
|
+
if (_this7.is('playing')) {
|
|
1297
|
+
_this7.pause();
|
|
1298
|
+
} else {
|
|
1299
|
+
_this7.play();
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1303
|
+
this.$seek.on("change".concat(ns), function (event, value) {
|
|
1304
|
+
_this7.seek(value, true);
|
|
1305
|
+
});
|
|
1306
|
+
$$1(document).on("updateVolume".concat(ns), function (event, value) {
|
|
1307
|
+
_this7.setVolume(value);
|
|
1308
|
+
});
|
|
1309
|
+
this.$volume.on("change".concat(ns), function (event, value) {
|
|
1310
|
+
_this7.unmute();
|
|
1989
1311
|
|
|
1312
|
+
$$1(document).trigger("updateVolume".concat(ns), value);
|
|
1990
1313
|
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1314
|
+
_this7.setVolume(value, true);
|
|
1315
|
+
});
|
|
1316
|
+
this.$sound.on("mouseover".concat(ns), 'a', function () {
|
|
1317
|
+
var position;
|
|
1995
1318
|
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
self.$volumeControl.removeClass('up down');
|
|
2000
|
-
overing = false;
|
|
2001
|
-
});
|
|
2002
|
-
}
|
|
2003
|
-
});
|
|
2004
|
-
},
|
|
1319
|
+
if (!overing && !_this7.$volumeControl.hasClass('up') && !_this7.$volumeControl.hasClass('down')) {
|
|
1320
|
+
overing = true;
|
|
1321
|
+
position = _this7.$controls[0].getBoundingClientRect();
|
|
2005
1322
|
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
this.$component.off(_ns);
|
|
2012
|
-
this.$player.off(_ns);
|
|
2013
|
-
this.$controls.off(_ns);
|
|
2014
|
-
this.$seek.off(_ns);
|
|
2015
|
-
this.$volume.off(_ns); //if the volume is opened and the player destroyed,
|
|
2016
|
-
//prevent the callback to run
|
|
2017
|
-
|
|
2018
|
-
if (this.overingTimer) {
|
|
2019
|
-
clearTimeout(this.overingTimer);
|
|
2020
|
-
}
|
|
1323
|
+
if (position && position.top && position.top < volumePositionThreshold) {
|
|
1324
|
+
_this7.$volumeControl.addClass('down');
|
|
1325
|
+
} else {
|
|
1326
|
+
_this7.$volumeControl.addClass('up');
|
|
1327
|
+
} //close the volume control after 15s
|
|
2021
1328
|
|
|
2022
|
-
$$1(document).off(_ns);
|
|
2023
|
-
},
|
|
2024
1329
|
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
*/
|
|
2030
|
-
_updateVolumeSlider: function _updateVolumeSlider(value) {
|
|
2031
|
-
if (this.$volumeSlider) {
|
|
2032
|
-
this.$volumeSlider.val(value);
|
|
2033
|
-
}
|
|
2034
|
-
},
|
|
1330
|
+
_this7.overingTimer = _.delay(function () {
|
|
1331
|
+
if (_this7.$volumeControl) {
|
|
1332
|
+
_this7.$volumeControl.removeClass('up down');
|
|
1333
|
+
}
|
|
2035
1334
|
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
* @param {Number} value
|
|
2039
|
-
* @param {*} [internal]
|
|
2040
|
-
* @private
|
|
2041
|
-
*/
|
|
2042
|
-
_updateVolume: function _updateVolume(value, internal) {
|
|
2043
|
-
this.volume = Math.max(_volumeMin, Math.min(_volumeMax, parseFloat(value)));
|
|
1335
|
+
overing = false;
|
|
1336
|
+
}, 15000);
|
|
2044
1337
|
|
|
2045
|
-
|
|
1338
|
+
_this7.$volumeControl.one("mouseleave".concat(ns), function () {
|
|
1339
|
+
_this7.$volumeControl.removeClass('up down');
|
|
2046
1340
|
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
1341
|
+
overing = false;
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
1344
|
+
});
|
|
1345
|
+
},
|
|
2051
1346
|
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
this.$
|
|
2060
|
-
|
|
2061
|
-
|
|
1347
|
+
/**
|
|
1348
|
+
* Unbinds events from the rendered player
|
|
1349
|
+
* @private
|
|
1350
|
+
*/
|
|
1351
|
+
_unbindEvents: function _unbindEvents() {
|
|
1352
|
+
this.$component.off(ns);
|
|
1353
|
+
this.$player.off(ns);
|
|
1354
|
+
this.$controls.off(ns);
|
|
1355
|
+
this.$seek.off(ns);
|
|
1356
|
+
this.$volume.off(ns); //if the volume is opened and the player destroyed,
|
|
1357
|
+
//prevent the callback to run
|
|
1358
|
+
|
|
1359
|
+
if (this.overingTimer) {
|
|
1360
|
+
clearTimeout(this.overingTimer);
|
|
1361
|
+
}
|
|
2062
1362
|
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
* @param {Number} value
|
|
2066
|
-
* @private
|
|
2067
|
-
*/
|
|
2068
|
-
_updatePositionLabel: function _updatePositionLabel(value) {
|
|
2069
|
-
if (this.$position) {
|
|
2070
|
-
this.$position.text(_timerFormat(value));
|
|
2071
|
-
}
|
|
2072
|
-
},
|
|
1363
|
+
$$1(document).off(ns);
|
|
1364
|
+
},
|
|
2073
1365
|
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
1366
|
+
/**
|
|
1367
|
+
* Updates the volume slider
|
|
1368
|
+
* @param {Number} value
|
|
1369
|
+
* @private
|
|
1370
|
+
*/
|
|
1371
|
+
_updateVolumeSlider: function _updateVolumeSlider(value) {
|
|
1372
|
+
if (this.$volumeSlider) {
|
|
1373
|
+
this.$volumeSlider.val(value);
|
|
1374
|
+
}
|
|
1375
|
+
},
|
|
2082
1376
|
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
1377
|
+
/**
|
|
1378
|
+
* Updates the displayed volume
|
|
1379
|
+
* @param {Number} value
|
|
1380
|
+
* @param {*} [internal]
|
|
1381
|
+
* @private
|
|
1382
|
+
*/
|
|
1383
|
+
_updateVolume: function _updateVolume(value, internal) {
|
|
1384
|
+
this.volume = Math.max(volumeMin, Math.min(volumeMax, parseFloat(value)));
|
|
2086
1385
|
|
|
2087
|
-
|
|
2088
|
-
},
|
|
1386
|
+
this._storeVolume(this.volume);
|
|
2089
1387
|
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
*/
|
|
2095
|
-
_updateDurationSlider: function _updateDurationSlider(value) {
|
|
2096
|
-
if (this.$seekSlider) {
|
|
2097
|
-
this._destroySlider(this.$seekSlider);
|
|
1388
|
+
if (!internal) {
|
|
1389
|
+
this._updateVolumeSlider(value);
|
|
1390
|
+
}
|
|
1391
|
+
},
|
|
2098
1392
|
|
|
2099
|
-
|
|
2100
|
-
|
|
1393
|
+
/**
|
|
1394
|
+
* Updates the time slider
|
|
1395
|
+
* @param {Number} value
|
|
1396
|
+
* @private
|
|
1397
|
+
*/
|
|
1398
|
+
_updatePositionSlider: function _updatePositionSlider(value) {
|
|
1399
|
+
if (this.$seekSlider) {
|
|
1400
|
+
this.$seekSlider.val(value);
|
|
1401
|
+
}
|
|
1402
|
+
},
|
|
2101
1403
|
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
1404
|
+
/**
|
|
1405
|
+
* Updates the time label
|
|
1406
|
+
* @param {Number} value
|
|
1407
|
+
* @private
|
|
1408
|
+
*/
|
|
1409
|
+
_updatePositionLabel: function _updatePositionLabel(value) {
|
|
1410
|
+
if (this.$position) {
|
|
1411
|
+
this.$position.text(timerFormat(value));
|
|
1412
|
+
}
|
|
1413
|
+
},
|
|
2107
1414
|
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
this
|
|
1415
|
+
/**
|
|
1416
|
+
* Updates the displayed time position
|
|
1417
|
+
* @param {Number} value
|
|
1418
|
+
* @param {*} [internal]
|
|
1419
|
+
* @private
|
|
1420
|
+
*/
|
|
1421
|
+
_updatePosition: function _updatePosition(value, internal) {
|
|
1422
|
+
this.position = Math.max(0, Math.min(this.duration || +Infinity, parseFloat(value)));
|
|
1423
|
+
|
|
1424
|
+
if (!internal && this.duration) {
|
|
1425
|
+
this._updatePositionSlider(this.position);
|
|
2119
1426
|
}
|
|
2120
|
-
}
|
|
2121
|
-
},
|
|
2122
1427
|
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
* @param {Number} value
|
|
2126
|
-
* @private
|
|
2127
|
-
*/
|
|
2128
|
-
_updateDuration: function _updateDuration(value) {
|
|
2129
|
-
this.duration = Math.abs(parseFloat(value));
|
|
1428
|
+
this._updatePositionLabel(this.position);
|
|
1429
|
+
},
|
|
2130
1430
|
|
|
2131
|
-
|
|
1431
|
+
/**
|
|
1432
|
+
* Updates the duration slider
|
|
1433
|
+
* @param {Number} value
|
|
1434
|
+
* @private
|
|
1435
|
+
*/
|
|
1436
|
+
_updateDurationSlider: function _updateDurationSlider(value) {
|
|
1437
|
+
if (this.$seekSlider) {
|
|
1438
|
+
this._destroySlider(this.$seekSlider);
|
|
2132
1439
|
|
|
2133
|
-
|
|
2134
|
-
|
|
1440
|
+
this.$seekSlider = null;
|
|
1441
|
+
}
|
|
2135
1442
|
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
1443
|
+
if (value && isFinite(value)) {
|
|
1444
|
+
this.$seekSlider = this._renderSlider(this.$seek, 0, 0, value);
|
|
1445
|
+
this.$seekSlider.attr('disabled', !this.config.canSeek);
|
|
1446
|
+
}
|
|
1447
|
+
},
|
|
1448
|
+
|
|
1449
|
+
/**
|
|
1450
|
+
* Updates the duration label
|
|
1451
|
+
* @param {Number} value
|
|
1452
|
+
* @private
|
|
1453
|
+
*/
|
|
1454
|
+
_updateDurationLabel: function _updateDurationLabel(value) {
|
|
1455
|
+
if (this.$duration) {
|
|
1456
|
+
if (value && isFinite(value)) {
|
|
1457
|
+
this.$duration.text(timerFormat(value)).show();
|
|
1458
|
+
} else {
|
|
1459
|
+
this.$duration.hide();
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
},
|
|
2142
1463
|
|
|
2143
|
-
|
|
1464
|
+
/**
|
|
1465
|
+
* Updates the displayed duration
|
|
1466
|
+
* @param {Number|String} value
|
|
1467
|
+
* @private
|
|
1468
|
+
*/
|
|
1469
|
+
_updateDuration: function _updateDuration(value) {
|
|
1470
|
+
var duration = Math.abs(parseFloat(value));
|
|
2144
1471
|
|
|
2145
|
-
|
|
1472
|
+
if (duration !== this.duration) {
|
|
1473
|
+
this.duration = duration;
|
|
2146
1474
|
|
|
2147
|
-
|
|
1475
|
+
this._updateDurationSlider(this.duration);
|
|
2148
1476
|
|
|
2149
|
-
|
|
1477
|
+
this._updateDurationLabel(this.duration);
|
|
1478
|
+
}
|
|
1479
|
+
},
|
|
2150
1480
|
|
|
2151
|
-
this._setState('loading', false);
|
|
2152
1481
|
/**
|
|
2153
|
-
*
|
|
2154
|
-
* @
|
|
1482
|
+
* Event called when the media is ready
|
|
1483
|
+
* @private
|
|
2155
1484
|
*/
|
|
1485
|
+
_onReady: function _onReady() {
|
|
1486
|
+
if (this.is('error')) {
|
|
1487
|
+
this._setState('error', false);
|
|
1488
|
+
}
|
|
2156
1489
|
|
|
1490
|
+
var duration = this.player.getDuration();
|
|
1491
|
+
var timePreview = this.config.preview || duration;
|
|
2157
1492
|
|
|
2158
|
-
|
|
1493
|
+
if (timePreview) {
|
|
1494
|
+
this._updateDuration(duration);
|
|
1495
|
+
}
|
|
2159
1496
|
|
|
2160
|
-
|
|
2161
|
-
|
|
1497
|
+
this.setInitialStates();
|
|
1498
|
+
/**
|
|
1499
|
+
* Triggers a media ready event
|
|
1500
|
+
* @event mediaplayer#ready
|
|
1501
|
+
*/
|
|
2162
1502
|
|
|
2163
|
-
|
|
2164
|
-
this.seek(this.autoStartAt);
|
|
2165
|
-
} else if (this.autoStart) {
|
|
2166
|
-
this.play();
|
|
2167
|
-
}
|
|
2168
|
-
},
|
|
1503
|
+
this.trigger('ready'); // set the initial state
|
|
2169
1504
|
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
* @param {Number} volume
|
|
2173
|
-
* @private
|
|
2174
|
-
*/
|
|
2175
|
-
_storeVolume: function _storeVolume(volume) {
|
|
2176
|
-
return store('mediaVolume').then(function (volumeStore) {
|
|
2177
|
-
volumeStore.setItem('volume', volume);
|
|
2178
|
-
});
|
|
2179
|
-
},
|
|
1505
|
+
this.setVolume(this.volume);
|
|
1506
|
+
this.mute(!!this.startMuted);
|
|
2180
1507
|
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
_updateVolumeFromStore: function _updateVolumeFromStore() {
|
|
2186
|
-
var self = this;
|
|
2187
|
-
return store('mediaVolume').then(function (volumeStore) {
|
|
2188
|
-
return volumeStore.getItem('volume');
|
|
2189
|
-
}).then(function (volume) {
|
|
2190
|
-
if (_.isNumber(volume)) {
|
|
2191
|
-
self.volume = Math.max(_volumeMin, Math.min(_volumeMax, parseFloat(volume)));
|
|
2192
|
-
self.setVolume(self.volume);
|
|
1508
|
+
if (this.autoStartAt) {
|
|
1509
|
+
this.seek(this.autoStartAt);
|
|
1510
|
+
} else if (this.autoStart) {
|
|
1511
|
+
this.play();
|
|
2193
1512
|
}
|
|
2194
|
-
});
|
|
2195
|
-
},
|
|
2196
1513
|
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
1514
|
+
if (this.config.preview && this.$container && this.config.height && this.config.height !== 'auto') {
|
|
1515
|
+
this._setMaxHeight();
|
|
1516
|
+
}
|
|
1517
|
+
},
|
|
1518
|
+
|
|
1519
|
+
/**
|
|
1520
|
+
* Set max height limit for container
|
|
1521
|
+
* using by old media items with defined height.
|
|
1522
|
+
* @private
|
|
1523
|
+
*/
|
|
1524
|
+
_setMaxHeight: function _setMaxHeight() {
|
|
1525
|
+
var $video = this.$container.find('video.video');
|
|
1526
|
+
var controlsHeight = parseInt(window.getComputedStyle(this.$controls[0]).height);
|
|
1527
|
+
var scale = $video.height() / this.config.height;
|
|
1528
|
+
var playerWidth = this.$container.find('.player').width();
|
|
1529
|
+
var videoWidth = $video.width() / scale;
|
|
1530
|
+
|
|
1531
|
+
if (videoWidth > playerWidth) {
|
|
1532
|
+
this.execute('setSize', '100%', 'auto');
|
|
1533
|
+
} else {
|
|
1534
|
+
this.$component.css({
|
|
1535
|
+
maxHeight: "".concat(this.config.height + controlsHeight, "px")
|
|
1536
|
+
});
|
|
1537
|
+
this.execute('setSize', Math.floor(videoWidth), 'auto');
|
|
1538
|
+
}
|
|
1539
|
+
},
|
|
2203
1540
|
|
|
2204
|
-
this._setState('loading', false);
|
|
2205
1541
|
/**
|
|
2206
|
-
*
|
|
2207
|
-
* @
|
|
1542
|
+
* Update volume in DBIndex store
|
|
1543
|
+
* @param {Number} volume
|
|
1544
|
+
* @returns {Promise}
|
|
1545
|
+
* @private
|
|
2208
1546
|
*/
|
|
1547
|
+
_storeVolume: function _storeVolume(volume) {
|
|
1548
|
+
return store('mediaVolume').then(function (volumeStore) {
|
|
1549
|
+
return volumeStore.setItem('volume', volume);
|
|
1550
|
+
});
|
|
1551
|
+
},
|
|
2209
1552
|
|
|
1553
|
+
/**
|
|
1554
|
+
* Get volume from DBIndex store
|
|
1555
|
+
* @returns {Promise}
|
|
1556
|
+
* @private
|
|
1557
|
+
*/
|
|
1558
|
+
_updateVolumeFromStore: function _updateVolumeFromStore() {
|
|
1559
|
+
var _this8 = this;
|
|
2210
1560
|
|
|
2211
|
-
|
|
2212
|
-
|
|
1561
|
+
return store('mediaVolume').then(function (volumeStore) {
|
|
1562
|
+
return volumeStore.getItem('volume');
|
|
1563
|
+
}).then(function (volume) {
|
|
1564
|
+
if (_.isNumber(volume)) {
|
|
1565
|
+
_this8.volume = Math.max(volumeMin, Math.min(volumeMax, parseFloat(volume)));
|
|
1566
|
+
|
|
1567
|
+
_this8.setVolume(_this8.volume);
|
|
1568
|
+
}
|
|
1569
|
+
});
|
|
1570
|
+
},
|
|
2213
1571
|
|
|
2214
|
-
/**
|
|
2215
|
-
* Event called when the media throws recoverable error
|
|
2216
|
-
* @private
|
|
2217
|
-
*/
|
|
2218
|
-
_onRecoverError: function _onRecoverError() {
|
|
2219
|
-
this._setState('error', false);
|
|
2220
1572
|
/**
|
|
2221
|
-
*
|
|
2222
|
-
* @
|
|
1573
|
+
* Event called when the media throws unrecoverable error
|
|
1574
|
+
* @private
|
|
2223
1575
|
*/
|
|
1576
|
+
_onError: function _onError() {
|
|
1577
|
+
this._setState('error', true);
|
|
2224
1578
|
|
|
1579
|
+
this._setState('loading', false);
|
|
1580
|
+
/**
|
|
1581
|
+
* Triggers an unrecoverable media error event
|
|
1582
|
+
* @event mediaplayer#error
|
|
1583
|
+
*/
|
|
2225
1584
|
|
|
2226
|
-
this.trigger('recovererror');
|
|
2227
|
-
},
|
|
2228
1585
|
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
*/
|
|
2233
|
-
_onPlay: function _onPlay() {
|
|
2234
|
-
this._playingState(true);
|
|
1586
|
+
this.trigger('error');
|
|
1587
|
+
},
|
|
1588
|
+
|
|
2235
1589
|
/**
|
|
2236
|
-
*
|
|
2237
|
-
* @
|
|
1590
|
+
* Event called when the media is played
|
|
1591
|
+
* @private
|
|
2238
1592
|
*/
|
|
1593
|
+
_onPlay: function _onPlay() {
|
|
1594
|
+
this._playingState(true);
|
|
1595
|
+
|
|
1596
|
+
this._setState('preview', true);
|
|
1597
|
+
/**
|
|
1598
|
+
* Triggers a media playback event
|
|
1599
|
+
* @event mediaplayer#play
|
|
1600
|
+
*/
|
|
2239
1601
|
|
|
2240
1602
|
|
|
2241
|
-
|
|
2242
|
-
|
|
1603
|
+
this.trigger('play', this.player && this.player.getMedia());
|
|
1604
|
+
},
|
|
2243
1605
|
|
|
2244
|
-
/**
|
|
2245
|
-
* Event called when the media is paused
|
|
2246
|
-
* @private
|
|
2247
|
-
*/
|
|
2248
|
-
_onPause: function _onPause() {
|
|
2249
|
-
this._playingState(false);
|
|
2250
1606
|
/**
|
|
2251
|
-
*
|
|
2252
|
-
* @
|
|
1607
|
+
* Event called when the media is paused
|
|
1608
|
+
* @private
|
|
2253
1609
|
*/
|
|
1610
|
+
_onPause: function _onPause() {
|
|
1611
|
+
this._playingState(false);
|
|
1612
|
+
/**
|
|
1613
|
+
* Triggers a media paused event
|
|
1614
|
+
* @event mediaplayer#pause
|
|
1615
|
+
*/
|
|
2254
1616
|
|
|
2255
1617
|
|
|
2256
|
-
|
|
2257
|
-
|
|
1618
|
+
this.trigger('pause');
|
|
1619
|
+
},
|
|
2258
1620
|
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
1621
|
+
/**
|
|
1622
|
+
* Event called when the media is ended
|
|
1623
|
+
* @private
|
|
1624
|
+
*/
|
|
1625
|
+
_onEnd: function _onEnd() {
|
|
1626
|
+
this.timesPlayed++;
|
|
1627
|
+
|
|
1628
|
+
this._playingState(false, true);
|
|
2265
1629
|
|
|
2266
|
-
|
|
1630
|
+
this._updatePosition(0); // disable when the play limit is reached
|
|
2267
1631
|
|
|
2268
|
-
|
|
1632
|
+
|
|
1633
|
+
if (this._playLimitReached()) {
|
|
1634
|
+
if (!this.is('disabled')) {
|
|
1635
|
+
this.disable();
|
|
1636
|
+
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Triggers a play limit reached event
|
|
1639
|
+
* @event mediaplayer#limitreached
|
|
1640
|
+
*/
|
|
2269
1641
|
|
|
2270
1642
|
|
|
2271
|
-
|
|
2272
|
-
this.
|
|
1643
|
+
this.trigger('limitreached');
|
|
1644
|
+
} else if (this.loop) {
|
|
1645
|
+
this.restart();
|
|
1646
|
+
} else if (parseInt(this.config.replayTimeout, 10) > 0) {
|
|
1647
|
+
this.replayTimeoutStartMs = new window.Date().getTime();
|
|
1648
|
+
|
|
1649
|
+
this._replayTimeout();
|
|
1650
|
+
}
|
|
2273
1651
|
/**
|
|
2274
|
-
* Triggers a
|
|
2275
|
-
* @event mediaplayer#
|
|
1652
|
+
* Triggers a media ended event
|
|
1653
|
+
* @event mediaplayer#ended
|
|
2276
1654
|
*/
|
|
2277
1655
|
|
|
2278
1656
|
|
|
2279
|
-
this.trigger('
|
|
2280
|
-
}
|
|
2281
|
-
this.restart();
|
|
2282
|
-
} else if (parseInt(this.config.replayTimeout, 10) > 0) {
|
|
2283
|
-
this.replayTimeoutStartMs = new window.Date().getTime();
|
|
1657
|
+
this.trigger('ended');
|
|
1658
|
+
},
|
|
2284
1659
|
|
|
2285
|
-
this._replayTimeout();
|
|
2286
|
-
}
|
|
2287
1660
|
/**
|
|
2288
|
-
*
|
|
2289
|
-
* @
|
|
1661
|
+
* Event called when the playback is playing
|
|
1662
|
+
* @private
|
|
2290
1663
|
*/
|
|
1664
|
+
_onPlaying: function _onPlaying() {
|
|
1665
|
+
this._setState('preview', true);
|
|
2291
1666
|
|
|
1667
|
+
this._setState('stalled', false);
|
|
2292
1668
|
|
|
2293
|
-
|
|
2294
|
-
|
|
1669
|
+
this._setState('ready', true);
|
|
1670
|
+
},
|
|
2295
1671
|
|
|
2296
|
-
/**
|
|
2297
|
-
* Event called when the time position has changed
|
|
2298
|
-
* @private
|
|
2299
|
-
*/
|
|
2300
|
-
_onTimeUpdate: function _onTimeUpdate() {
|
|
2301
|
-
this._updatePosition(this.player.getPosition());
|
|
2302
1672
|
/**
|
|
2303
|
-
*
|
|
2304
|
-
* @
|
|
1673
|
+
* Event called when the playback is stalled
|
|
1674
|
+
* @private
|
|
2305
1675
|
*/
|
|
1676
|
+
_onStalled: function _onStalled() {
|
|
1677
|
+
this._setState('stalled', true);
|
|
2306
1678
|
|
|
1679
|
+
this._setState('ready', false);
|
|
1680
|
+
},
|
|
2307
1681
|
|
|
2308
|
-
|
|
2309
|
-
|
|
1682
|
+
/**
|
|
1683
|
+
* Event called when the time position has changed
|
|
1684
|
+
* @private
|
|
1685
|
+
*/
|
|
1686
|
+
_onTimeUpdate: function _onTimeUpdate() {
|
|
1687
|
+
this._updatePosition(this.player.getPosition());
|
|
1688
|
+
/**
|
|
1689
|
+
* Triggers a media time update event
|
|
1690
|
+
* @event mediaplayer#update
|
|
1691
|
+
*/
|
|
2310
1692
|
|
|
2311
|
-
/**
|
|
2312
|
-
* Run a timer to disable the possibility of replaying a media
|
|
2313
|
-
* @private
|
|
2314
|
-
*/
|
|
2315
|
-
_replayTimeout: function _replayTimeout() {
|
|
2316
|
-
var nowMs = new window.Date().getTime(),
|
|
2317
|
-
elapsedSeconds = Math.floor((nowMs - this.replayTimeoutStartMs) / 1000);
|
|
2318
|
-
this.timerId = requestAnimationFrame(this._replayTimeout.bind(this));
|
|
2319
1693
|
|
|
2320
|
-
|
|
2321
|
-
|
|
1694
|
+
this.trigger('update');
|
|
1695
|
+
},
|
|
2322
1696
|
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
1697
|
+
/**
|
|
1698
|
+
* Run a timer to disable the possibility of replaying a media
|
|
1699
|
+
* @private
|
|
1700
|
+
*/
|
|
1701
|
+
_replayTimeout: function _replayTimeout() {
|
|
1702
|
+
var nowMs = new window.Date().getTime(),
|
|
1703
|
+
elapsedSeconds = Math.floor((nowMs - this.replayTimeoutStartMs) / 1000);
|
|
1704
|
+
this.timerId = requestAnimationFrame(this._replayTimeout.bind(this));
|
|
2327
1705
|
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
this._setState('ready', false);
|
|
1706
|
+
if (elapsedSeconds >= parseInt(this.config.replayTimeout, 10)) {
|
|
1707
|
+
this.disable();
|
|
1708
|
+
cancelAnimationFrame(this.timerId);
|
|
1709
|
+
}
|
|
1710
|
+
},
|
|
2334
1711
|
|
|
2335
|
-
|
|
2336
|
-
|
|
1712
|
+
/**
|
|
1713
|
+
* Checks if the play limit has been reached
|
|
1714
|
+
* @returns {Boolean}
|
|
1715
|
+
* @private
|
|
1716
|
+
*/
|
|
1717
|
+
_playLimitReached: function _playLimitReached() {
|
|
1718
|
+
return this.config.maxPlays && this.timesPlayed >= this.config.maxPlays;
|
|
1719
|
+
},
|
|
2337
1720
|
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
1721
|
+
/**
|
|
1722
|
+
* Checks if the media can be played
|
|
1723
|
+
* @returns {Boolean}
|
|
1724
|
+
* @private
|
|
1725
|
+
*/
|
|
1726
|
+
_canPlay: function _canPlay() {
|
|
1727
|
+
return (this.is('ready') || this.is('stalled')) && !this.is('disabled') && !this.is('hidden') && !this._playLimitReached();
|
|
1728
|
+
},
|
|
2346
1729
|
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
1730
|
+
/**
|
|
1731
|
+
* Checks if the media can be paused
|
|
1732
|
+
* @returns {Boolean}
|
|
1733
|
+
* @private
|
|
1734
|
+
*/
|
|
1735
|
+
_canPause: function _canPause() {
|
|
1736
|
+
return !!this.config.canPause;
|
|
1737
|
+
},
|
|
2355
1738
|
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
1739
|
+
/**
|
|
1740
|
+
* Checks if the media can be sought
|
|
1741
|
+
* @returns {Boolean}
|
|
1742
|
+
* @private
|
|
1743
|
+
*/
|
|
1744
|
+
_canSeek: function _canSeek() {
|
|
1745
|
+
return !!this.config.canSeek;
|
|
1746
|
+
},
|
|
2364
1747
|
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
1748
|
+
/**
|
|
1749
|
+
* Checks if the playback can be resumed
|
|
1750
|
+
* @returns {Boolean}
|
|
1751
|
+
* @private
|
|
1752
|
+
*/
|
|
1753
|
+
_canResume: function _canResume() {
|
|
1754
|
+
return this.is('paused') && this._canPlay();
|
|
1755
|
+
},
|
|
2373
1756
|
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
1757
|
+
/**
|
|
1758
|
+
* Sets the media is in a particular state
|
|
1759
|
+
* @param {String} name
|
|
1760
|
+
* @param {Boolean} value
|
|
1761
|
+
* @returns {mediaplayer}
|
|
1762
|
+
*/
|
|
1763
|
+
_setState: function _setState(name, value) {
|
|
1764
|
+
value = !!value;
|
|
1765
|
+
this.config.is[name] = value;
|
|
2382
1766
|
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
* @param {Boolean} value
|
|
2387
|
-
* @returns {mediaplayer}
|
|
2388
|
-
*/
|
|
2389
|
-
_setState: function _setState(name, value) {
|
|
2390
|
-
value = !!value;
|
|
2391
|
-
this.config.is[name] = value;
|
|
1767
|
+
if (this.$component) {
|
|
1768
|
+
this.$component.toggleClass(name, value);
|
|
1769
|
+
}
|
|
2392
1770
|
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
}
|
|
1771
|
+
return this;
|
|
1772
|
+
},
|
|
2396
1773
|
|
|
2397
|
-
|
|
2398
|
-
|
|
1774
|
+
/**
|
|
1775
|
+
* Restores the media player from a particular state and resumes the playback
|
|
1776
|
+
* @param {String} stateName
|
|
1777
|
+
* @returns {mediaplayer}
|
|
1778
|
+
* @private
|
|
1779
|
+
*/
|
|
1780
|
+
_fromState: function _fromState(stateName) {
|
|
1781
|
+
this._setState(stateName, false);
|
|
2399
1782
|
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
* @returns {mediaplayer}
|
|
2404
|
-
* @private
|
|
2405
|
-
*/
|
|
2406
|
-
_fromState: function _fromState(stateName) {
|
|
2407
|
-
this._setState(stateName, false);
|
|
1783
|
+
this.resume();
|
|
1784
|
+
return this;
|
|
1785
|
+
},
|
|
2408
1786
|
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
1787
|
+
/**
|
|
1788
|
+
* Sets the media player to a particular state and pauses the playback
|
|
1789
|
+
* @param {String} stateName
|
|
1790
|
+
* @returns {mediaplayer}
|
|
1791
|
+
* @private
|
|
1792
|
+
*/
|
|
1793
|
+
_toState: function _toState(stateName) {
|
|
1794
|
+
this.pause();
|
|
2412
1795
|
|
|
2413
|
-
|
|
2414
|
-
* Sets the media player to a particular state and pauses the playback
|
|
2415
|
-
* @param {String} stateName
|
|
2416
|
-
* @returns {mediaplayer}
|
|
2417
|
-
* @private
|
|
2418
|
-
*/
|
|
2419
|
-
_toState: function _toState(stateName) {
|
|
2420
|
-
this.pause();
|
|
1796
|
+
this._setState(stateName, true);
|
|
2421
1797
|
|
|
2422
|
-
|
|
1798
|
+
return this;
|
|
1799
|
+
},
|
|
2423
1800
|
|
|
2424
|
-
|
|
2425
|
-
|
|
1801
|
+
/**
|
|
1802
|
+
* Sets the playing state
|
|
1803
|
+
* @param {Boolean} state
|
|
1804
|
+
* @param {Boolean} [ended]
|
|
1805
|
+
* @returns {mediaplayer}
|
|
1806
|
+
* @private
|
|
1807
|
+
*/
|
|
1808
|
+
_playingState: function _playingState(state, ended) {
|
|
1809
|
+
this._setState('playing', !!state);
|
|
2426
1810
|
|
|
2427
|
-
|
|
2428
|
-
* Sets the playing state
|
|
2429
|
-
* @param {Boolean} state
|
|
2430
|
-
* @param {Boolean} [ended]
|
|
2431
|
-
* @returns {mediaplayer}
|
|
2432
|
-
* @private
|
|
2433
|
-
*/
|
|
2434
|
-
_playingState: function _playingState(state, ended) {
|
|
2435
|
-
this._setState('playing', !!state);
|
|
1811
|
+
this._setState('paused', !state);
|
|
2436
1812
|
|
|
2437
|
-
|
|
1813
|
+
this._setState('ended', !!ended);
|
|
2438
1814
|
|
|
2439
|
-
|
|
1815
|
+
return this;
|
|
1816
|
+
},
|
|
2440
1817
|
|
|
2441
|
-
|
|
2442
|
-
|
|
1818
|
+
/**
|
|
1819
|
+
* Executes a command onto the media
|
|
1820
|
+
* @param {String} command - The name of the command to execute
|
|
1821
|
+
* @param {*} args - additional arguments
|
|
1822
|
+
* @returns {*}
|
|
1823
|
+
* @private
|
|
1824
|
+
*/
|
|
1825
|
+
execute: function execute(command) {
|
|
1826
|
+
if (this.player && 'function' === typeof this.player[command]) {
|
|
1827
|
+
var _this$player;
|
|
2443
1828
|
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
* @returns {*}
|
|
2448
|
-
* @private
|
|
2449
|
-
*/
|
|
2450
|
-
execute: function execute(command) {
|
|
2451
|
-
var ctx = this.player;
|
|
2452
|
-
var method = ctx && ctx[command];
|
|
1829
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
1830
|
+
args[_key2 - 1] = arguments[_key2];
|
|
1831
|
+
}
|
|
2453
1832
|
|
|
2454
|
-
|
|
2455
|
-
|
|
1833
|
+
return (_this$player = this.player)[command].apply(_this$player, args);
|
|
1834
|
+
}
|
|
2456
1835
|
}
|
|
2457
|
-
}
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
* Builds a media player instance
|
|
2461
|
-
* @param {Object} config
|
|
2462
|
-
* @param {String} config.type - The type of media to play
|
|
2463
|
-
* @param {String|Array} config.url - The URL to the media
|
|
2464
|
-
* @param {String|jQuery|HTMLElement} [config.renderTo] - An optional container in which renders the player
|
|
2465
|
-
* @param {Boolean} [config.loop] - The media will be played continuously
|
|
2466
|
-
* @param {Boolean} [config.canPause] - The play can be paused
|
|
2467
|
-
* @param {Boolean} [config.startMuted] - The player should be initially muted
|
|
2468
|
-
* @param {Boolean} [config.autoStart] - The player starts as soon as it is displayed
|
|
2469
|
-
* @param {Number} [config.autoStartAt] - The time position at which the player should start
|
|
2470
|
-
* @param {Number} [config.maxPlays] - Sets a few number of plays (default: infinite)
|
|
2471
|
-
* @param {Number} [config.volume] - Sets the sound volume (default: 80)
|
|
2472
|
-
* @param {Number} [config.width] - Sets the width of the player (default: depends on media type)
|
|
2473
|
-
* @param {Number} [config.height] - Sets the height of the player (default: depends on media type)
|
|
2474
|
-
* @event render - Event triggered when the player is rendering
|
|
2475
|
-
* @event error - Event triggered when the player throws an unrecoverable error
|
|
2476
|
-
* @event recovererror - Event triggered when the player throws a recoverable error
|
|
2477
|
-
* @event ready - Event triggered when the player is fully ready
|
|
2478
|
-
* @event play - Event triggered when the playback is starting
|
|
2479
|
-
* @event update - Event triggered while the player is playing
|
|
2480
|
-
* @event pause - Event triggered when the playback is paused
|
|
2481
|
-
* @event ended - Event triggered when the playback is ended
|
|
2482
|
-
* @event limitreached - Event triggered when the play limit has been reached
|
|
2483
|
-
* @event destroy - Event triggered when the player is destroying
|
|
2484
|
-
* @returns {mediaplayer}
|
|
2485
|
-
*/
|
|
2486
|
-
|
|
2487
|
-
var mediaplayerFactory = function mediaplayerFactory(config) {
|
|
2488
|
-
var player = _.clone(mediaplayer);
|
|
2489
|
-
|
|
2490
|
-
return player.init(config);
|
|
2491
|
-
};
|
|
1836
|
+
};
|
|
1837
|
+
return mediaplayer.init(config);
|
|
1838
|
+
}
|
|
2492
1839
|
/**
|
|
2493
1840
|
* Tells if the browser can play audio and video
|
|
2494
1841
|
* @param {String} [type] The type of media (audio or video)
|
|
@@ -2498,7 +1845,7 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
2498
1845
|
|
|
2499
1846
|
|
|
2500
1847
|
mediaplayerFactory.canPlay = function canPlay(type, mime) {
|
|
2501
|
-
return
|
|
1848
|
+
return support.canPlay(type, mime);
|
|
2502
1849
|
};
|
|
2503
1850
|
/**
|
|
2504
1851
|
* Tells if the browser can play audio
|
|
@@ -2508,7 +1855,7 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
2508
1855
|
|
|
2509
1856
|
|
|
2510
1857
|
mediaplayerFactory.canPlayAudio = function canPlayAudio(mime) {
|
|
2511
|
-
return
|
|
1858
|
+
return support.canPlayAudio(mime);
|
|
2512
1859
|
};
|
|
2513
1860
|
/**
|
|
2514
1861
|
* Tells if the browser can play video
|
|
@@ -2518,7 +1865,7 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
2518
1865
|
|
|
2519
1866
|
|
|
2520
1867
|
mediaplayerFactory.canPlayVideo = function canPlayVideo(mime) {
|
|
2521
|
-
return
|
|
1868
|
+
return support.canPlayVideo(mime);
|
|
2522
1869
|
};
|
|
2523
1870
|
/**
|
|
2524
1871
|
* Checks if the browser allows to control the media playback
|
|
@@ -2527,16 +1874,8 @@ define(['jquery', 'lodash', 'async', 'util/urlParser', 'core/eventifier', 'core/
|
|
|
2527
1874
|
|
|
2528
1875
|
|
|
2529
1876
|
mediaplayerFactory.canControl = function canControl() {
|
|
2530
|
-
return
|
|
1877
|
+
return support.canControl();
|
|
2531
1878
|
};
|
|
2532
|
-
/**
|
|
2533
|
-
* The polling interval used to update the progress bar while playing a YouTube video.
|
|
2534
|
-
* Note : the YouTube API does not provide events to update this progress bar...
|
|
2535
|
-
* @type {Number}
|
|
2536
|
-
*/
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
mediaplayerFactory.youtubePolling = 100;
|
|
2540
1879
|
|
|
2541
1880
|
return mediaplayerFactory;
|
|
2542
1881
|
|