@oat-sa/tao-core-ui 1.6.2 → 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/mediaplayer/css/player.css +34 -2
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +236 -59
- package/dist/mediaplayer/support.js +17 -3
- package/dist/mediaplayer/utils/reminder.js +198 -0
- package/dist/mediaplayer/utils/timeObserver.js +149 -0
- package/dist/mediaplayer.js +44 -97
- package/package.json +1 -1
- package/src/itemButtonList/css/item-button-list.css +225 -0
- package/src/itemButtonList/css/item-button-list.css.map +1 -0
- package/src/mediaplayer/css/player.css +34 -2
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/mediaplayer/players/html5.js +247 -67
- package/src/mediaplayer/scss/player.scss +47 -6
- package/src/mediaplayer/support.js +17 -4
- package/src/mediaplayer/tpl/player.tpl +1 -2
- package/src/mediaplayer/utils/reminder.js +184 -0
- package/src/mediaplayer/utils/timeObserver.js +143 -0
- package/src/mediaplayer.js +38 -88
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support', 'handlebars', 'i18n', 'lodash', 'lib/dompurify/purify'], function ($$1, UrlParser, eventifier, support, Handlebars, __, _, DOMPurify) { 'use strict';
|
|
1
|
+
define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support', 'handlebars', 'i18n', 'lodash', 'lib/dompurify/purify', 'ui/mediaplayer/utils/reminder', 'ui/mediaplayer/utils/timeObserver'], function ($$1, UrlParser, eventifier, support, Handlebars, __, _, DOMPurify, reminderManagerFactory, timeObserverFactory) { 'use strict';
|
|
2
2
|
|
|
3
3
|
$$1 = $$1 && $$1.hasOwnProperty('default') ? $$1['default'] : $$1;
|
|
4
4
|
UrlParser = UrlParser && UrlParser.hasOwnProperty('default') ? UrlParser['default'] : UrlParser;
|
|
@@ -8,6 +8,8 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
8
8
|
__ = __ && __.hasOwnProperty('default') ? __['default'] : __;
|
|
9
9
|
_ = _ && _.hasOwnProperty('default') ? _['default'] : _;
|
|
10
10
|
DOMPurify = DOMPurify && DOMPurify.hasOwnProperty('default') ? DOMPurify['default'] : DOMPurify;
|
|
11
|
+
reminderManagerFactory = reminderManagerFactory && reminderManagerFactory.hasOwnProperty('default') ? reminderManagerFactory['default'] : reminderManagerFactory;
|
|
12
|
+
timeObserverFactory = timeObserverFactory && timeObserverFactory.hasOwnProperty('default') ? timeObserverFactory['default'] : timeObserverFactory;
|
|
11
13
|
|
|
12
14
|
function _typeof(obj) {
|
|
13
15
|
"@babel/helpers - typeof";
|
|
@@ -261,47 +263,56 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
261
263
|
*/
|
|
262
264
|
/**
|
|
263
265
|
* CSS namespace
|
|
264
|
-
* @type {
|
|
266
|
+
* @type {string}
|
|
265
267
|
*/
|
|
266
268
|
|
|
267
269
|
var ns = '.mediaplayer';
|
|
268
270
|
/**
|
|
269
271
|
* Range value of the volume
|
|
270
|
-
* @type {
|
|
272
|
+
* @type {number}
|
|
271
273
|
*/
|
|
272
274
|
|
|
273
275
|
var volumeRange = 100;
|
|
276
|
+
/**
|
|
277
|
+
* Delay before considering a media stalled
|
|
278
|
+
* @type {number}
|
|
279
|
+
*/
|
|
280
|
+
|
|
281
|
+
var stalledDetectionDelay = 2000;
|
|
274
282
|
/**
|
|
275
283
|
* List of media events that can be listened to for debugging
|
|
276
|
-
* @type {
|
|
284
|
+
* @type {string[]}
|
|
277
285
|
*/
|
|
278
286
|
|
|
279
287
|
var mediaEvents = ['abort', 'canplay', 'canplaythrough', 'canshowcurrentframe', 'dataunavailable', 'durationchange', 'emptied', 'empty', 'ended', 'error', 'loadeddata', 'loadedfirstframe', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting'];
|
|
280
288
|
/**
|
|
281
289
|
* List of player events that can be listened to for debugging
|
|
282
|
-
* @type {
|
|
290
|
+
* @type {string[]}
|
|
283
291
|
*/
|
|
284
292
|
|
|
285
|
-
var playerEvents = ['end', 'error', 'pause', 'play', 'playing', 'ready', '
|
|
293
|
+
var playerEvents = ['end', 'error', 'pause', 'play', 'playing', 'ready', 'resize', 'stalled', 'timeupdate'];
|
|
286
294
|
/**
|
|
287
295
|
* Defines a player object dedicated to the native HTML5 player
|
|
288
296
|
* @param {jQuery} $container - Where to render the player
|
|
289
|
-
* @param {
|
|
297
|
+
* @param {object} config - The list of config entries
|
|
290
298
|
* @param {Array} config.sources - The list of media sources
|
|
291
|
-
* @param {
|
|
292
|
-
* @param {
|
|
293
|
-
* @param {
|
|
294
|
-
* @
|
|
299
|
+
* @param {string} [config.type] - The type of player (video or audio) (default: video)
|
|
300
|
+
* @param {boolean} [config.preview] - Enables the media preview (load media metadata)
|
|
301
|
+
* @param {boolean} [config.debug] - Enables the debug mode
|
|
302
|
+
* @param {number} [config.config.stalledDetectionDelay] - The delay before considering a media is stalled
|
|
303
|
+
* @returns {object} player
|
|
295
304
|
*/
|
|
296
305
|
|
|
297
306
|
function html5PlayerFactory($container) {
|
|
298
307
|
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
299
308
|
var type = config.type || 'video';
|
|
300
309
|
var sources = config.sources || [];
|
|
310
|
+
var updateObserver = reminderManagerFactory();
|
|
311
|
+
var timeObserver = timeObserverFactory();
|
|
312
|
+
config.stalledDetectionDelay = config.stalledDetectionDelay || stalledDetectionDelay;
|
|
301
313
|
var $media;
|
|
302
314
|
var media;
|
|
303
|
-
var
|
|
304
|
-
var stalled = false;
|
|
315
|
+
var state = {};
|
|
305
316
|
|
|
306
317
|
var getDebugContext = function getDebugContext(action) {
|
|
307
318
|
var networkState = media && media.networkState;
|
|
@@ -317,10 +328,10 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
317
328
|
args[_key - 1] = arguments[_key];
|
|
318
329
|
}
|
|
319
330
|
|
|
320
|
-
return config.debug && (_window$console = window.console).log.apply(_window$console, [getDebugContext(action)].concat(args));
|
|
331
|
+
return (config.debug === true || config.debug === action) && (_window$console = window.console).log.apply(_window$console, [getDebugContext(action)].concat(args));
|
|
321
332
|
};
|
|
322
333
|
|
|
323
|
-
|
|
334
|
+
return eventifier({
|
|
324
335
|
init: function init() {
|
|
325
336
|
var _this = this;
|
|
326
337
|
|
|
@@ -331,6 +342,7 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
331
342
|
var poster = '';
|
|
332
343
|
var link = '';
|
|
333
344
|
var result = false;
|
|
345
|
+
state = {};
|
|
334
346
|
sources.forEach(function (source) {
|
|
335
347
|
if (!page.sameDomain(source.src)) {
|
|
336
348
|
cors = true;
|
|
@@ -351,54 +363,105 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
351
363
|
link: link
|
|
352
364
|
}));
|
|
353
365
|
$container.append($media);
|
|
354
|
-
playback = false;
|
|
355
|
-
stalled = false;
|
|
356
366
|
media = $media.get(0);
|
|
357
|
-
result = !!(media && support.checkSupport(media)); //
|
|
367
|
+
result = !!(media && support.checkSupport(media)); // Remove the browser native controls if we can use the API instead
|
|
358
368
|
|
|
359
369
|
if (support.canControl()) {
|
|
360
370
|
$media.removeAttr('controls');
|
|
361
|
-
}
|
|
371
|
+
} // Detect stalled video when the timer suddenly jump to the end
|
|
372
|
+
|
|
362
373
|
|
|
374
|
+
timeObserver.removeAllListeners().on('irregularity', function (position) {
|
|
375
|
+
if (state.playback && state.stallDetection) {
|
|
376
|
+
_this.stalled(position);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
363
379
|
$media.on("play".concat(ns), function () {
|
|
364
|
-
playback = true;
|
|
380
|
+
state.playback = true;
|
|
381
|
+
state.playedViaApi = false;
|
|
382
|
+
timeObserver.init(media.currentTime, media.duration);
|
|
365
383
|
|
|
366
384
|
_this.trigger('play');
|
|
367
385
|
}).on("pause".concat(ns), function () {
|
|
386
|
+
if (state.stallDetection && !state.pausedViaApi && updateObserver.running && updateObserver.elapsed < 100) {
|
|
387
|
+
// The pause event may be triggered after a connectivity issue as the player is out of data
|
|
388
|
+
_this.stalled();
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
state.pausedViaApi = false;
|
|
392
|
+
state.playing = false;
|
|
393
|
+
updateObserver.stop();
|
|
394
|
+
|
|
368
395
|
_this.trigger('pause');
|
|
396
|
+
}).on("seeked".concat(ns), function () {
|
|
397
|
+
// When the user try changing the current playing position while the network is down,
|
|
398
|
+
// the player will end the playback by moving straight to the end.
|
|
399
|
+
if (state.seekedViaApi && Math.floor(state.seekAt) !== Math.floor(media.currentTime)) {
|
|
400
|
+
state.stallDetection = true;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
state.seekedViaApi = false;
|
|
369
404
|
}).on("ended".concat(ns), function () {
|
|
370
|
-
|
|
405
|
+
updateObserver.forget().stop();
|
|
406
|
+
timeObserver.update(media.currentTime);
|
|
407
|
+
state.playback = false;
|
|
408
|
+
state.playing = false;
|
|
371
409
|
|
|
372
410
|
_this.trigger('end');
|
|
373
411
|
}).on("timeupdate".concat(ns), function () {
|
|
412
|
+
state.playing = true;
|
|
413
|
+
updateObserver.start();
|
|
414
|
+
timeObserver.update(media.currentTime);
|
|
415
|
+
|
|
374
416
|
_this.trigger('timeupdate');
|
|
375
417
|
}).on('loadstart', function () {
|
|
376
|
-
if (stalled) {
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
418
|
if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE) {
|
|
381
419
|
_this.trigger('error');
|
|
382
420
|
}
|
|
383
421
|
|
|
384
422
|
if (!config.preview && media.networkState === HTMLMediaElement.NETWORK_IDLE) {
|
|
385
423
|
_this.trigger('ready');
|
|
386
|
-
}
|
|
424
|
+
} // The media may be unreachable straight from the beginning
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
_this.detectStalledNetwork();
|
|
428
|
+
}).on("waiting".concat(ns), function () {
|
|
429
|
+
// The "waiting" event means the player is pending data,
|
|
430
|
+
// it may be the symptom of a connectivity issue
|
|
431
|
+
_this.detectStalledNetwork();
|
|
387
432
|
}).on("error".concat(ns), function () {
|
|
388
|
-
if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE) {
|
|
433
|
+
if (media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE || media.error instanceof MediaError && media.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {
|
|
434
|
+
// No source means the player does not support the supplied media.
|
|
435
|
+
// Or it can be more explicit with the not supported error.
|
|
436
|
+
// There is nothing that we can do from this stage.
|
|
389
437
|
_this.trigger('error');
|
|
390
438
|
} else {
|
|
391
|
-
|
|
439
|
+
// Other errors need special attention as they can be recoverable
|
|
440
|
+
_this.handleError(media.error);
|
|
392
441
|
}
|
|
393
|
-
}).on(
|
|
442
|
+
}).on('loadedmetadata', function () {
|
|
443
|
+
timeObserver.init(media.currentTime, media.duration);
|
|
394
444
|
|
|
395
|
-
_this.
|
|
445
|
+
_this.ready();
|
|
446
|
+
}).on("canplay".concat(ns), function () {
|
|
447
|
+
if (!state.stalled) {
|
|
448
|
+
_this.ready();
|
|
449
|
+
}
|
|
396
450
|
}).on("stalled".concat(ns), function () {
|
|
397
|
-
stalled
|
|
398
|
-
|
|
399
|
-
|
|
451
|
+
// The "stalled" event may be triggered once the player is halted after initialisation,
|
|
452
|
+
// but this does not mean the playback is actually stalled, hence we only take care of the playing state
|
|
453
|
+
if (state.playing && !media.paused) {
|
|
454
|
+
_this.handleError(media.error);
|
|
455
|
+
}
|
|
400
456
|
}).on("playing".concat(ns), function () {
|
|
401
|
-
|
|
457
|
+
if (state.stallDetection) {
|
|
458
|
+
// The "playing" event may occur after a connectivity issue.
|
|
459
|
+
// For the sake of the stall detection, we need to discard this event
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
updateObserver.forget().start();
|
|
464
|
+
state.playing = true;
|
|
402
465
|
|
|
403
466
|
_this.trigger('playing');
|
|
404
467
|
}); // install debug logger
|
|
@@ -421,18 +484,120 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
421
484
|
});
|
|
422
485
|
}
|
|
423
486
|
|
|
424
|
-
sources.
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
_this.addMedia(src, type);
|
|
429
|
-
});
|
|
487
|
+
result = result && sources.reduce(function (supported, source) {
|
|
488
|
+
return _this.addMedia(source.src, source.type) || supported;
|
|
489
|
+
}, false);
|
|
430
490
|
return result;
|
|
431
491
|
},
|
|
492
|
+
handleError: function handleError(error) {
|
|
493
|
+
var _this2 = this;
|
|
494
|
+
|
|
495
|
+
// Discard legitimate and non-blocking errors
|
|
496
|
+
switch (error && error.name) {
|
|
497
|
+
case 'NotAllowedError':
|
|
498
|
+
debug('api call', 'handleError', 'the autoplay is not allowed without a user interaction', error);
|
|
499
|
+
return;
|
|
500
|
+
|
|
501
|
+
case 'AbortError':
|
|
502
|
+
debug('api call', 'handleError', 'the action has been aborted for some reason', error);
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
debug('api call', 'handleError', error); // Detect if the playback can continue a bit
|
|
507
|
+
|
|
508
|
+
var canContinueTemporarily = media && (media.readyState === HTMLMediaElement.HAVE_ENOUGH_DATA || media.readyState === HTMLMediaElement.HAVE_FUTURE_DATA || media.readyState === HTMLMediaElement.HAVE_CURRENT_DATA); // If a connectivity error occurs we may need to enter in stalled mode unless we can wait a bit
|
|
509
|
+
|
|
510
|
+
if (error instanceof MediaError && (error.code === MediaError.MEDIA_ERR_NETWORK || error.code === MediaError.MEDIA_ERR_DECODE) && !canContinueTemporarily) {
|
|
511
|
+
this.stalled();
|
|
512
|
+
return;
|
|
513
|
+
} // To this point, there is a big chance the media is stalled.
|
|
514
|
+
// We start an observer to remind as soon as an irregularity occurs on the time update
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
state.stallDetection = true;
|
|
518
|
+
updateObserver.remind(function () {
|
|
519
|
+
// The last time update is a bit old, the media is most probably stalled now
|
|
520
|
+
if (updateObserver.elapsed >= config.stalledDetectionDelay) {
|
|
521
|
+
_this2.stalled();
|
|
522
|
+
}
|
|
523
|
+
}, config.stalledDetectionDelay);
|
|
524
|
+
updateObserver.start();
|
|
525
|
+
},
|
|
526
|
+
ready: function ready() {
|
|
527
|
+
if (!state.ready) {
|
|
528
|
+
state.ready = true;
|
|
529
|
+
this.trigger('ready');
|
|
530
|
+
}
|
|
531
|
+
},
|
|
532
|
+
detectStalledNetwork: function detectStalledNetwork() {
|
|
533
|
+
var _this3 = this;
|
|
534
|
+
|
|
535
|
+
// Install an observer that will watch the network state after a small delay.
|
|
536
|
+
// It is needed since the network state may need time to settle.
|
|
537
|
+
setTimeout(function () {
|
|
538
|
+
if (media && media.networkState === HTMLMediaElement.NETWORK_NO_SOURCE && media.readyState === HTMLMediaElement.HAVE_NOTHING) {
|
|
539
|
+
if (!state.ready) {
|
|
540
|
+
_this3.trigger('ready');
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
_this3.stalled();
|
|
544
|
+
}
|
|
545
|
+
}, config.stalledDetectionDelay);
|
|
546
|
+
},
|
|
547
|
+
stalled: function stalled(position) {
|
|
548
|
+
debug('api call', 'stalled');
|
|
549
|
+
|
|
550
|
+
if (media) {
|
|
551
|
+
if ('undefined' !== typeof position) {
|
|
552
|
+
state.stalledAt = position;
|
|
553
|
+
} else {
|
|
554
|
+
state.stalledAt = timeObserver.position;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
state.stalled = true;
|
|
559
|
+
state.stallDetection = false;
|
|
560
|
+
updateObserver.forget().stop();
|
|
561
|
+
this.pause();
|
|
562
|
+
this.trigger('stalled');
|
|
563
|
+
},
|
|
564
|
+
recover: function recover() {
|
|
565
|
+
debug('api call', 'recover');
|
|
566
|
+
state.stalled = false;
|
|
567
|
+
state.stallDetection = false;
|
|
568
|
+
|
|
569
|
+
if (media) {
|
|
570
|
+
// Special processing of video player to prevent visual glitch while reloading
|
|
571
|
+
if (media.tagName === 'VIDEO') {
|
|
572
|
+
// Temporarily set the size of the media to prevent a shrink while reloading it
|
|
573
|
+
$media.width($media.width());
|
|
574
|
+
$media.height($media.height());
|
|
575
|
+
$media.on('loadedmetadata.recover', function () {
|
|
576
|
+
$media.off('loadedmetadata.recover');
|
|
577
|
+
$media.css({
|
|
578
|
+
width: '',
|
|
579
|
+
height: ''
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
media.load();
|
|
585
|
+
|
|
586
|
+
if (state.stalledAt) {
|
|
587
|
+
this.seek(state.stalledAt);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
if (state.playback && !state.playing || state.playedViaApi) {
|
|
591
|
+
this.play();
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
},
|
|
432
595
|
destroy: function destroy() {
|
|
433
596
|
debug('api call', 'destroy');
|
|
434
597
|
this.stop();
|
|
435
598
|
this.removeAllListeners();
|
|
599
|
+
updateObserver.forget();
|
|
600
|
+
timeObserver.removeAllListeners();
|
|
436
601
|
|
|
437
602
|
if ($media) {
|
|
438
603
|
$media.off(ns).remove();
|
|
@@ -440,8 +605,7 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
440
605
|
|
|
441
606
|
$media = void 0;
|
|
442
607
|
media = void 0;
|
|
443
|
-
|
|
444
|
-
stalled = false;
|
|
608
|
+
state = {};
|
|
445
609
|
},
|
|
446
610
|
getMedia: function getMedia() {
|
|
447
611
|
debug('api call', 'getMedia', media);
|
|
@@ -506,40 +670,54 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
506
670
|
|
|
507
671
|
if (media) {
|
|
508
672
|
media.currentTime = parseFloat(time);
|
|
673
|
+
state.seekedViaApi = true;
|
|
674
|
+
state.seekAt = media.currentTime;
|
|
675
|
+
timeObserver.seek(media.currentTime);
|
|
509
676
|
|
|
510
|
-
if (!playback) {
|
|
677
|
+
if (!state.playback) {
|
|
511
678
|
this.play();
|
|
512
679
|
}
|
|
513
680
|
}
|
|
514
681
|
},
|
|
515
682
|
play: function play() {
|
|
683
|
+
var _this4 = this;
|
|
684
|
+
|
|
516
685
|
debug('api call', 'play');
|
|
517
686
|
|
|
518
687
|
if (media) {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
688
|
+
state.playedViaApi = true;
|
|
689
|
+
var startPlayPromise = media.play();
|
|
690
|
+
|
|
691
|
+
if ('undefined' !== typeof startPlayPromise) {
|
|
692
|
+
startPlayPromise.catch(function (error) {
|
|
693
|
+
return _this4.handleError(error);
|
|
694
|
+
});
|
|
695
|
+
}
|
|
522
696
|
}
|
|
523
697
|
},
|
|
524
698
|
pause: function pause() {
|
|
525
699
|
debug('api call', 'pause');
|
|
526
700
|
|
|
527
701
|
if (media) {
|
|
702
|
+
if (!media.paused) {
|
|
703
|
+
state.pausedViaApi = true;
|
|
704
|
+
}
|
|
705
|
+
|
|
528
706
|
media.pause();
|
|
529
707
|
}
|
|
530
708
|
},
|
|
531
709
|
stop: function stop() {
|
|
532
710
|
debug('api call', 'stop');
|
|
533
711
|
|
|
534
|
-
if (media && playback) {
|
|
712
|
+
if (media && media.duration && state.playback && !state.stalled) {
|
|
535
713
|
media.currentTime = media.duration;
|
|
536
714
|
}
|
|
537
715
|
},
|
|
538
|
-
mute: function mute(
|
|
539
|
-
debug('api call', 'mute',
|
|
716
|
+
mute: function mute(muted) {
|
|
717
|
+
debug('api call', 'mute', muted);
|
|
540
718
|
|
|
541
719
|
if (media) {
|
|
542
|
-
media.muted = !!
|
|
720
|
+
media.muted = !!muted;
|
|
543
721
|
}
|
|
544
722
|
},
|
|
545
723
|
isMuted: function isMuted() {
|
|
@@ -552,11 +730,11 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
552
730
|
debug('api call', 'isMuted', mute);
|
|
553
731
|
return mute;
|
|
554
732
|
},
|
|
555
|
-
addMedia: function addMedia(src,
|
|
556
|
-
debug('api call', 'addMedia', src,
|
|
733
|
+
addMedia: function addMedia(src, srcType) {
|
|
734
|
+
debug('api call', 'addMedia', src, srcType);
|
|
557
735
|
|
|
558
736
|
if (media) {
|
|
559
|
-
if (!support.checkSupport(media,
|
|
737
|
+
if (!support.checkSupport(media, srcType)) {
|
|
560
738
|
return false;
|
|
561
739
|
}
|
|
562
740
|
}
|
|
@@ -564,25 +742,24 @@ define(['jquery', 'util/urlParser', 'core/eventifier', 'ui/mediaplayer/support',
|
|
|
564
742
|
if (src && $media) {
|
|
565
743
|
$media.append(sourceTpl({
|
|
566
744
|
src: src,
|
|
567
|
-
type:
|
|
745
|
+
type: srcType
|
|
568
746
|
}));
|
|
569
747
|
return true;
|
|
570
748
|
}
|
|
571
749
|
|
|
572
750
|
return false;
|
|
573
751
|
},
|
|
574
|
-
setMedia: function setMedia(src,
|
|
575
|
-
debug('api call', 'setMedia', src,
|
|
752
|
+
setMedia: function setMedia(src, srcType) {
|
|
753
|
+
debug('api call', 'setMedia', src, srcType);
|
|
576
754
|
|
|
577
755
|
if ($media) {
|
|
578
756
|
$media.empty();
|
|
579
|
-
return this.addMedia(src,
|
|
757
|
+
return this.addMedia(src, srcType);
|
|
580
758
|
}
|
|
581
759
|
|
|
582
760
|
return false;
|
|
583
761
|
}
|
|
584
|
-
};
|
|
585
|
-
return eventifier(player);
|
|
762
|
+
});
|
|
586
763
|
}
|
|
587
764
|
|
|
588
765
|
return html5PlayerFactory;
|
|
@@ -21,11 +21,13 @@ define(function () { 'use strict';
|
|
|
21
21
|
/**
|
|
22
22
|
* A Regex to detect Apple mobile browsers
|
|
23
23
|
* @type {RegExp}
|
|
24
|
+
* @private
|
|
24
25
|
*/
|
|
25
26
|
var reAppleMobiles = /ip(hone|od)/i;
|
|
26
27
|
/**
|
|
27
28
|
* A list of MIME types with codec declaration
|
|
28
29
|
* @type {Object}
|
|
30
|
+
* @private
|
|
29
31
|
*/
|
|
30
32
|
|
|
31
33
|
var supportedMimeTypes = {
|
|
@@ -39,11 +41,23 @@ define(function () { 'use strict';
|
|
|
39
41
|
'audio/ogg': 'audio/ogg; codecs="vorbis"',
|
|
40
42
|
'audio/wav': 'audio/wav; codecs="1"'
|
|
41
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Checks support for a MIME type.
|
|
46
|
+
* @param {HTMLMediaElement} media The media element on which check support
|
|
47
|
+
* @param {String} mimeType A MIME type to check the support for
|
|
48
|
+
* @returns {string}
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
var findSupport = function findSupport(media, mimeType) {
|
|
53
|
+
return media.canPlayType(mimeType).replace(/no/, '');
|
|
54
|
+
};
|
|
42
55
|
/**
|
|
43
56
|
* Support detection
|
|
44
57
|
* @type {Object}
|
|
45
58
|
*/
|
|
46
59
|
|
|
60
|
+
|
|
47
61
|
var support = {
|
|
48
62
|
/**
|
|
49
63
|
* Checks if the browser can play media
|
|
@@ -53,13 +67,13 @@ define(function () { 'use strict';
|
|
|
53
67
|
* @private
|
|
54
68
|
*/
|
|
55
69
|
checkSupport: function checkSupport(media, mimeType) {
|
|
56
|
-
var support =
|
|
70
|
+
var support = media.canPlayType;
|
|
57
71
|
|
|
58
72
|
if (support && mimeType) {
|
|
59
|
-
return !!
|
|
73
|
+
return !!(supportedMimeTypes[mimeType] && findSupport(media, supportedMimeTypes[mimeType]) || findSupport(media, mimeType));
|
|
60
74
|
}
|
|
61
75
|
|
|
62
|
-
return support;
|
|
76
|
+
return !!support;
|
|
63
77
|
},
|
|
64
78
|
|
|
65
79
|
/**
|