@oat-sa/tao-core-ui 1.58.1 → 1.58.2
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/actionbar.js +386 -395
- package/dist/adder.js +21 -19
- package/dist/animable/absorbable/absorbable.js +204 -213
- package/dist/animable/absorbable/css/absorb.css +1 -0
- package/dist/animable/absorbable/css/absorb.css.map +1 -1
- package/dist/animable/pulsable/pulsable.js +168 -177
- package/dist/autocomplete/css/autocomplete.css +1 -0
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/autocomplete.js +68 -66
- package/dist/badge/badge.js +188 -197
- package/dist/badge/css/badge.css +1 -0
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs.js +275 -284
- package/dist/btngrouper.js +5 -5
- package/dist/bulkActionPopup.js +490 -495
- package/dist/button.js +283 -291
- package/dist/cascadingComboBox.js +249 -258
- package/dist/ckeditor/ckConfigurator.js +26 -19
- package/dist/ckeditor/dtdHandler.js +11 -9
- package/dist/class/selector.js +441 -450
- package/dist/component/resizable.js +1 -1
- package/dist/component/windowed.js +285 -294
- package/dist/component.js +419 -428
- package/dist/contextualPopup.js +417 -426
- package/dist/dashboard.js +300 -309
- package/dist/datalist.js +753 -762
- package/dist/datatable/filterStrategy/multiple.js +1 -1
- package/dist/datatable/filterStrategy/single.js +1 -1
- package/dist/datatable.js +1527 -1550
- package/dist/dateRange/dateRange.js +393 -402
- package/dist/datetime/picker.js +665 -672
- package/dist/deleter.js +368 -377
- package/dist/destination/selector.js +286 -295
- package/dist/dialog/alert.js +3 -3
- package/dist/dialog/confirm.js +1 -1
- package/dist/dialog/confirmDelete.js +216 -225
- package/dist/dialog.js +650 -654
- package/dist/disabler.js +8 -8
- package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +166 -175
- package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +518 -527
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +380 -389
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +539 -548
- package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +369 -378
- package/dist/documentViewer/providers/pdfViewer.js +184 -193
- package/dist/documentViewer.js +292 -301
- package/dist/dropdown.js +383 -392
- package/dist/durationer.js +5 -5
- package/dist/dynamicComponent.js +597 -598
- package/dist/feedback.js +356 -362
- package/dist/figure/FigureStateActive.js +117 -108
- package/dist/filesender.js +2 -2
- package/dist/filter.js +230 -239
- package/dist/form/dropdownForm.js +355 -357
- package/dist/form/form.js +919 -690
- package/dist/form/simpleForm.js +1 -1
- package/dist/form/validator/renderer.js +233 -235
- package/dist/form/validator/validator.js +257 -189
- package/dist/form/widget/definitions.js +1 -1
- package/dist/form/widget/providers/checkBox.js +254 -259
- package/dist/form/widget/providers/comboBox.js +187 -192
- package/dist/form/widget/providers/default.js +8 -9
- package/dist/form/widget/providers/hidden.js +170 -179
- package/dist/form/widget/providers/hiddenBox.js +262 -267
- package/dist/form/widget/providers/radioBox.js +216 -225
- package/dist/form/widget/providers/textArea.js +187 -196
- package/dist/form/widget/providers/textBox.js +2 -3
- package/dist/form/widget/widget.js +473 -475
- package/dist/formValidator/formValidator.js +1 -1
- package/dist/formValidator/highlighters/message.js +1 -1
- package/dist/generis/form/form.js +314 -323
- package/dist/generis/validator/validator.js +209 -218
- package/dist/generis/widget/checkBox/checkBox.js +218 -227
- package/dist/generis/widget/comboBox/comboBox.js +179 -188
- package/dist/generis/widget/hiddenBox/hiddenBox.js +220 -229
- package/dist/generis/widget/textBox/textBox.js +169 -178
- package/dist/generis/widget/widget.js +246 -255
- package/dist/groupedComboBox.js +222 -231
- package/dist/groupvalidator.js +2 -2
- package/dist/highlighter.js +967 -958
- package/dist/image/ImgStateActive/helper.js +7 -5
- package/dist/image/ImgStateActive/initHelper.js +49 -43
- package/dist/image/ImgStateActive/initMediaEditor.js +24 -20
- package/dist/image/ImgStateActive/mediaSizer.js +14 -12
- package/dist/image/ImgStateActive.js +72 -70
- package/dist/incrementer.js +6 -6
- package/dist/inplacer.js +6 -6
- package/dist/itemButtonList/css/item-button-list.css +1 -0
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +439 -435
- package/dist/keyNavigation/navigableDomElement.js +51 -38
- package/dist/keyNavigation/navigator.js +85 -70
- package/dist/listbox.js +460 -469
- package/dist/liststyler.js +8 -8
- package/dist/loadingButton/loadingButton.js +209 -218
- package/dist/lock.js +476 -485
- package/dist/login/login.js +475 -484
- package/dist/maths/calculator/basicCalculator.js +235 -244
- package/dist/maths/calculator/calculatorComponent.js +3 -3
- package/dist/maths/calculator/core/board.js +772 -781
- package/dist/maths/calculator/core/expression.js +476 -485
- package/dist/maths/calculator/core/labels.js +228 -237
- package/dist/maths/calculator/core/tokenizer.js +1 -1
- package/dist/maths/calculator/core/tokens.js +163 -170
- package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +244 -253
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +279 -288
- package/dist/maths/calculator/scientificCalculator.js +327 -336
- package/dist/mediaEditor/mediaEditorComponent.js +238 -245
- package/dist/mediaEditor/plugins/mediaAlignment/helper.js +7 -7
- package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +229 -235
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +580 -589
- package/dist/mediaplayer/players/html5.js +666 -675
- package/dist/mediaplayer/players/youtube.js +419 -424
- package/dist/mediaplayer/support.js +11 -10
- package/dist/mediaplayer/utils/reminder.js +14 -13
- package/dist/mediaplayer/utils/timeObserver.js +10 -11
- package/dist/mediaplayer/youtubeManager.js +164 -145
- package/dist/mediaplayer.js +1565 -1520
- package/dist/mediasizer.js +669 -678
- package/dist/modal.js +10 -17
- package/dist/pageSizeSelector.js +219 -228
- package/dist/pagination/providers/pages.js +280 -289
- package/dist/pagination/providers/simple.js +192 -201
- package/dist/previewer.js +30 -30
- package/dist/progressbar.js +4 -4
- package/dist/report.js +347 -356
- package/dist/resource/filters.js +271 -280
- package/dist/resource/list.js +1264 -1273
- package/dist/resource/selector.js +865 -874
- package/dist/resource/tree.js +1483 -1492
- package/dist/resourcemgr/fileBrowser.js +564 -569
- package/dist/resourcemgr/filePreview.js +16 -16
- package/dist/resourcemgr/fileSelector.js +515 -524
- package/dist/resourcemgr/util/updatePermissions.js +2 -2
- package/dist/resourcemgr.js +306 -315
- package/dist/searchModal/advancedSearch.js +796 -767
- package/dist/searchModal.js +114 -91
- package/dist/switch/switch.js +298 -307
- package/dist/tabs.js +598 -575
- package/dist/taskQueue/status.js +312 -321
- package/dist/taskQueue/table.js +375 -384
- package/dist/taskQueue/taskQueueModel.js +488 -472
- package/dist/taskQueueButton/taskable.js +264 -273
- package/dist/taskQueueButton/treeButton.js +189 -198
- package/dist/themeLoader.js +24 -23
- package/dist/themes.js +1 -1
- package/dist/toggler.js +3 -3
- package/dist/tooltip.js +295 -304
- package/dist/transformer.js +2 -2
- package/dist/tristateCheckboxGroup.js +311 -320
- package/dist/uploader.js +687 -696
- package/dist/validator/Report.js +1 -1
- package/dist/validator/Validator.js +3 -3
- package/dist/validator/validators.js +9 -9
- package/dist/validator.js +240 -230
- package/dist/waitForMedia.js +1 -1
- package/package.json +3 -3
- package/src/animable/absorbable/css/absorb.css +1 -0
- package/src/animable/absorbable/css/absorb.css.map +1 -1
- package/src/autocomplete/css/autocomplete.css +1 -0
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/badge/css/badge.css +1 -0
- package/src/badge/css/badge.css.map +1 -1
- package/src/ckeditor/ckConfigurator.js +4 -0
- package/src/itemButtonList/css/item-button-list.css +1 -0
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/.DS_Store +0 -0
- package/src/css/basic.css +0 -7826
- package/src/css/basic.css.map +0 -1
- package/src/css/ckeditor/skins/tao/css/dialog.css +0 -950
- package/src/css/ckeditor/skins/tao/css/dialog.css.map +0 -1
- package/src/css/ckeditor/skins/tao/css/editor.css +0 -1850
- package/src/css/ckeditor/skins/tao/css/editor.css.map +0 -1
- package/src/scss/.DS_Store +0 -0
- package/src/scss/basic.scss +0 -16
- package/src/scss/ckeditor/skins/tao/scss/dialog.scss +0 -763
- package/src/scss/ckeditor/skins/tao/scss/editor.scss +0 -111
- package/src/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +0 -59
- package/src/scss/ckeditor/skins/tao/scss/inc/_colorpanel.scss +0 -118
- package/src/scss/ckeditor/skins/tao/scss/inc/_elementspath.scss +0 -69
- package/src/scss/ckeditor/skins/tao/scss/inc/_mainui.scss +0 -194
- package/src/scss/ckeditor/skins/tao/scss/inc/_menu.scss +0 -181
- package/src/scss/ckeditor/skins/tao/scss/inc/_panel.scss +0 -200
- package/src/scss/ckeditor/skins/tao/scss/inc/_presets.scss +0 -32
- package/src/scss/ckeditor/skins/tao/scss/inc/_reset.scss +0 -101
- package/src/scss/ckeditor/skins/tao/scss/inc/_richcombo.scss +0 -213
- package/src/scss/ckeditor/skins/tao/scss/inc/_tao.scss +0 -59
- package/src/scss/ckeditor/skins/tao/scss/inc/_toolbar.scss +0 -301
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot.b64 +0 -1
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff +0 -0
- package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff.b64 +0 -1
- package/src/scss/font/tao/tao.eot +0 -0
- package/src/scss/font/tao/tao.svg +0 -235
- package/src/scss/font/tao/tao.ttf +0 -0
- package/src/scss/font/tao/tao.woff +0 -0
- package/src/scss/inc/_base.scss +0 -496
- package/src/scss/inc/_bootstrap.scss +0 -6
- package/src/scss/inc/_buttons.scss +0 -114
- package/src/scss/inc/_colors.scss +0 -88
- package/src/scss/inc/_feedback.scss +0 -150
- package/src/scss/inc/_flex-grid.scss +0 -15
- package/src/scss/inc/_fonts.scss +0 -4
- package/src/scss/inc/_forms.scss +0 -827
- package/src/scss/inc/_functions.scss +0 -283
- package/src/scss/inc/_grid.scss +0 -66
- package/src/scss/inc/_jquery.nouislider.scss +0 -254
- package/src/scss/inc/_normalize.scss +0 -528
- package/src/scss/inc/_report.scss +0 -68
- package/src/scss/inc/_secondary-properties.scss +0 -89
- package/src/scss/inc/_select2.scss +0 -634
- package/src/scss/inc/_toolbars.scss +0 -155
- package/src/scss/inc/_tooltip.scss +0 -312
- package/src/scss/inc/_variables.scss +0 -21
- package/src/scss/inc/base/_highlight.scss +0 -5
- package/src/scss/inc/base/_list-style.scss +0 -59
- package/src/scss/inc/base/_svg.scss +0 -3
- package/src/scss/inc/base/_table.scss +0 -63
- package/src/scss/inc/fonts/_source-sans-pro.scss +0 -29
- package/src/scss/inc/fonts/_tao-icon-classes.scss +0 -226
- package/src/scss/inc/fonts/_tao-icon-def.scss +0 -12
- package/src/scss/inc/fonts/_tao-icon-vars.scss +0 -240
package/dist/mediaplayer.js
CHANGED
|
@@ -1,1831 +1,1876 @@
|
|
|
1
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
$$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
|
|
4
|
+
_ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
|
|
5
|
+
async = async && Object.prototype.hasOwnProperty.call(async, 'default') ? async['default'] : async;
|
|
6
|
+
UrlParser = UrlParser && Object.prototype.hasOwnProperty.call(UrlParser, 'default') ? UrlParser['default'] : UrlParser;
|
|
7
|
+
eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;
|
|
8
|
+
mimetype = mimetype && Object.prototype.hasOwnProperty.call(mimetype, 'default') ? mimetype['default'] : mimetype;
|
|
9
|
+
store = store && Object.prototype.hasOwnProperty.call(store, 'default') ? store['default'] : store;
|
|
10
|
+
support = support && Object.prototype.hasOwnProperty.call(support, 'default') ? support['default'] : support;
|
|
11
|
+
players = players && Object.prototype.hasOwnProperty.call(players, 'default') ? players['default'] : players;
|
|
12
|
+
Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
|
|
13
|
+
__ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
|
|
14
|
+
DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
|
|
15
|
+
|
|
16
|
+
function _typeof(obj) {
|
|
17
|
+
"@babel/helpers - typeof";
|
|
18
|
+
|
|
19
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
|
|
20
|
+
return typeof obj;
|
|
21
|
+
} : function (obj) {
|
|
22
|
+
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
23
|
+
}, _typeof(obj);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function Helpers0 (hb) {
|
|
27
|
+
//register a i18n helper
|
|
28
|
+
hb.registerHelper('__', function (key) {
|
|
29
|
+
return __(key);
|
|
30
|
+
});
|
|
16
31
|
/**
|
|
17
|
-
*
|
|
18
|
-
* modify it under the terms of the GNU General Public License
|
|
19
|
-
* as published by the Free Software Foundation; under version 2
|
|
20
|
-
* of the License (non-upgradable).
|
|
21
|
-
*
|
|
22
|
-
* This program is distributed in the hope that it will be useful,
|
|
23
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
24
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
25
|
-
* GNU General Public License for more details.
|
|
26
|
-
*
|
|
27
|
-
* You should have received a copy of the GNU General Public License
|
|
28
|
-
* along with this program; if not, write to the Free Software
|
|
29
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
30
|
-
*
|
|
31
|
-
* Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
|
|
32
|
-
*
|
|
32
|
+
* Register dompurify helper
|
|
33
33
|
*
|
|
34
|
+
* https://github.com/cure53/DOMPurify
|
|
35
|
+
* with config SAFE_FOR_TEMPLATES: true
|
|
36
|
+
* to make output safe for template systems
|
|
34
37
|
*/
|
|
35
|
-
function Helpers0 (hb) {
|
|
36
|
-
//register a i18n helper
|
|
37
|
-
hb.registerHelper('__', function (key) {
|
|
38
|
-
return __(key);
|
|
39
|
-
});
|
|
40
|
-
/**
|
|
41
|
-
* Register dompurify helper
|
|
42
|
-
*
|
|
43
|
-
* https://github.com/cure53/DOMPurify
|
|
44
|
-
* with config SAFE_FOR_TEMPLATES: true
|
|
45
|
-
* to make output safe for template systems
|
|
46
|
-
*/
|
|
47
38
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
|
|
61
|
-
var fragments = [];
|
|
62
|
-
keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
|
|
63
|
-
fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
|
|
64
|
-
wrapper = typeof wrapper === 'string' ? wrapper : '"';
|
|
39
|
+
hb.registerHelper('dompurify', function (context) {
|
|
40
|
+
return DOMPurify.sanitize(context);
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Register join helper
|
|
44
|
+
*
|
|
45
|
+
* Example :
|
|
46
|
+
* var values = {a:v1, b:v2, c:v3};
|
|
47
|
+
* Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
|
|
48
|
+
* Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
|
|
49
|
+
*/
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
|
|
51
|
+
hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
|
|
52
|
+
var fragments = [];
|
|
53
|
+
keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
|
|
54
|
+
fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
|
|
55
|
+
wrapper = typeof wrapper === 'string' ? wrapper : '"';
|
|
68
56
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
value = value ? 'true' : 'false';
|
|
72
|
-
} else if (typeof value === 'object') {
|
|
73
|
-
value = _.values(value).join(' ');
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
value = '';
|
|
77
|
-
}
|
|
57
|
+
_.forIn(arr, function (value, key) {
|
|
58
|
+
var fragment = '';
|
|
78
59
|
|
|
79
|
-
|
|
80
|
-
|
|
60
|
+
if (value !== null || value !== undefined) {
|
|
61
|
+
if (typeof value === 'boolean') {
|
|
62
|
+
value = value ? 'true' : 'false';
|
|
63
|
+
} else if (_typeof(value) === 'object') {
|
|
64
|
+
value = _.values(value).join(' ');
|
|
81
65
|
}
|
|
82
|
-
|
|
83
|
-
fragment += wrapper + value + wrapper;
|
|
84
|
-
fragments.push(fragment);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
return fragments.join(fragmentGlue);
|
|
88
|
-
}); //register a classic "for loop" helper
|
|
89
|
-
//it also adds a local variable "i" as the index in each iteration loop
|
|
90
|
-
|
|
91
|
-
hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
|
|
92
|
-
var ret = '';
|
|
93
|
-
startIndex = parseInt(startIndex);
|
|
94
|
-
stopIndex = parseInt(stopIndex);
|
|
95
|
-
increment = parseInt(increment);
|
|
96
|
-
|
|
97
|
-
for (var i = startIndex; i < stopIndex; i += increment) {
|
|
98
|
-
ret += options.fn(_.extend({}, this, {
|
|
99
|
-
i: i
|
|
100
|
-
}));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return ret;
|
|
104
|
-
});
|
|
105
|
-
hb.registerHelper('equal', function (var1, var2, options) {
|
|
106
|
-
if (var1 == var2) {
|
|
107
|
-
return options.fn(this);
|
|
108
66
|
} else {
|
|
109
|
-
|
|
67
|
+
value = '';
|
|
110
68
|
}
|
|
111
|
-
}); // register a "get property" helper
|
|
112
|
-
// it gets the named property from the provided context
|
|
113
69
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}); // register an 'includes' helper
|
|
117
|
-
// it checks if value is in array
|
|
118
|
-
|
|
119
|
-
hb.registerHelper('includes', function (haystack, needle, options) {
|
|
120
|
-
if (_.contains(haystack, needle)) {
|
|
121
|
-
return options.fn(this);
|
|
70
|
+
if (keyValueGlue !== undefined) {
|
|
71
|
+
fragment += key + keyValueGlue;
|
|
122
72
|
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
73
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
Helpers0.__initialized = true;
|
|
129
|
-
}
|
|
130
|
-
var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
131
|
-
this.compilerInfo = [4,'>= 1.0.0'];
|
|
132
|
-
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
133
|
-
var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
buffer += "<div class=\"mediaplayer ";
|
|
137
|
-
if (helper = helpers.type) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
138
|
-
else { helper = (depth0 && depth0.type); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
139
|
-
buffer += escapeExpression(stack1)
|
|
140
|
-
+ "\">\n <div class=\"player\">\n <div class=\"player-overlay\">\n <a class=\"action play\" data-control=\"play\"><span class=\"icon icon-play\" title=\""
|
|
141
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Play", options) : helperMissing.call(depth0, "__", "Play", options)))
|
|
142
|
-
+ "\"></span></a>\n <a class=\"action play\" data-control=\"pause\"><span class=\"icon icon-pause\" title=\""
|
|
143
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Pause", options) : helperMissing.call(depth0, "__", "Pause", options)))
|
|
144
|
-
+ "\"></span></a>\n <a class=\"action reload\" data-control=\"start\">\n <span class=\"icon icon-play\" title=\""
|
|
145
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Start", options) : helperMissing.call(depth0, "__", "Start", options)))
|
|
146
|
-
+ "\"></span>\n <div class=\"message\">"
|
|
147
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Click to start", options) : helperMissing.call(depth0, "__", "Click to start", options)))
|
|
148
|
-
+ "</div>\n </a>\n <a class=\"action reload\" data-control=\"reload\">\n <div class=\"icon icon-reload\" title=\""
|
|
149
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Reload", options) : helperMissing.call(depth0, "__", "Reload", options)))
|
|
150
|
-
+ "\"></div>\n <div class=\"message\">"
|
|
151
|
-
+ 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)))
|
|
152
|
-
+ " "
|
|
153
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Click to reload.", options) : helperMissing.call(depth0, "__", "Click to reload.", options)))
|
|
154
|
-
+ "</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=\""
|
|
155
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Play", options) : helperMissing.call(depth0, "__", "Play", options)))
|
|
156
|
-
+ "\"><span class=\"icon icon-play\"></span></a>\n <a class=\"action play\" data-control=\"pause\" title=\""
|
|
157
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Pause", options) : helperMissing.call(depth0, "__", "Pause", options)))
|
|
158
|
-
+ "\"><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=\""
|
|
159
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Current playback position", options) : helperMissing.call(depth0, "__", "Current playback position", options)))
|
|
160
|
-
+ "\">--:--</span>\n <span class=\"info time\" data-control=\"time-end\" title=\""
|
|
161
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Total duration", options) : helperMissing.call(depth0, "__", "Total duration", options)))
|
|
162
|
-
+ "\">--:--</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=\""
|
|
163
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Mute", options) : helperMissing.call(depth0, "__", "Mute", options)))
|
|
164
|
-
+ "\"><span class=\"icon icon-sound\"></span></a>\n <a class=\"action mute\" data-control=\"unmute\" title=\""
|
|
165
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Restore sound", options) : helperMissing.call(depth0, "__", "Restore sound", options)))
|
|
166
|
-
+ "\"><span class=\"icon icon-mute\"></span></a>\n </div>\n </div>\n </div>\n <div class=\"error\">\n <div class=\"message\">"
|
|
167
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "This media cannot be played!", options) : helperMissing.call(depth0, "__", "This media cannot be played!", options)))
|
|
168
|
-
+ "</div>\n </div>\n</div>\n";
|
|
169
|
-
return buffer;
|
|
74
|
+
fragment += wrapper + value + wrapper;
|
|
75
|
+
fragments.push(fragment);
|
|
170
76
|
});
|
|
171
|
-
function playerTpl(data, options, asString) {
|
|
172
|
-
var html = Template(data, options);
|
|
173
|
-
return (asString || true) ? html : $(html);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* This program is free software; you can redistribute it and/or
|
|
178
|
-
* modify it under the terms of the GNU General Public License
|
|
179
|
-
* as published by the Free Software Foundation; under version 2
|
|
180
|
-
* of the License (non-upgradable).
|
|
181
|
-
*
|
|
182
|
-
* This program is distributed in the hope that it will be useful,
|
|
183
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
184
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
185
|
-
* GNU General Public License for more details.
|
|
186
|
-
*
|
|
187
|
-
* You should have received a copy of the GNU General Public License
|
|
188
|
-
* along with this program; if not, write to the Free Software
|
|
189
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
190
|
-
*
|
|
191
|
-
* Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;
|
|
192
|
-
*/
|
|
193
|
-
/**
|
|
194
|
-
* CSS namespace
|
|
195
|
-
* @type {String}
|
|
196
|
-
*/
|
|
197
|
-
|
|
198
|
-
const ns = '.mediaplayer';
|
|
199
|
-
/**
|
|
200
|
-
* Minimum value of the volume
|
|
201
|
-
* @type {Number}
|
|
202
|
-
*/
|
|
203
|
-
|
|
204
|
-
const volumeMin = 0;
|
|
205
|
-
/**
|
|
206
|
-
* Maximum value of the volume
|
|
207
|
-
* @type {Number}
|
|
208
|
-
*/
|
|
209
77
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
* above the bar.
|
|
214
|
-
* @type {Number}
|
|
215
|
-
*/
|
|
78
|
+
return fragments.join(fragmentGlue);
|
|
79
|
+
}); //register a classic "for loop" helper
|
|
80
|
+
//it also adds a local variable "i" as the index in each iteration loop
|
|
216
81
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
82
|
+
hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
|
|
83
|
+
var ret = '';
|
|
84
|
+
startIndex = parseInt(startIndex);
|
|
85
|
+
stopIndex = parseInt(stopIndex);
|
|
86
|
+
increment = parseInt(increment);
|
|
222
87
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
height: 'auto'
|
|
228
|
-
},
|
|
229
|
-
audio: {
|
|
230
|
-
width: '100%',
|
|
231
|
-
height: 'auto'
|
|
232
|
-
},
|
|
233
|
-
youtube: {
|
|
234
|
-
width: 640,
|
|
235
|
-
height: 360
|
|
236
|
-
},
|
|
237
|
-
options: {
|
|
238
|
-
volume: 80,
|
|
239
|
-
startMuted: false,
|
|
240
|
-
maxPlays: 0,
|
|
241
|
-
replayTimeout: 0,
|
|
242
|
-
canPause: true,
|
|
243
|
-
canSeek: true,
|
|
244
|
-
loop: false,
|
|
245
|
-
autoStart: false,
|
|
246
|
-
preview: true,
|
|
247
|
-
debug: false
|
|
88
|
+
for (var i = startIndex; i < stopIndex; i += increment) {
|
|
89
|
+
ret += options.fn(_.extend({}, this, {
|
|
90
|
+
i: i
|
|
91
|
+
}));
|
|
248
92
|
}
|
|
249
|
-
};
|
|
250
|
-
/**
|
|
251
|
-
* Ensures a value is a number
|
|
252
|
-
* @param {Number|String} value
|
|
253
|
-
* @returns {Number}
|
|
254
|
-
*/
|
|
255
|
-
|
|
256
|
-
const ensureNumber = value => {
|
|
257
|
-
const floatValue = parseFloat(value);
|
|
258
|
-
return isFinite(floatValue) ? floatValue : 0;
|
|
259
|
-
};
|
|
260
|
-
/**
|
|
261
|
-
* Format a number to string with leading zeros
|
|
262
|
-
* @param {Number} n
|
|
263
|
-
* @param {Number} len
|
|
264
|
-
* @returns {String}
|
|
265
|
-
*/
|
|
266
|
-
|
|
267
93
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
94
|
+
return ret;
|
|
95
|
+
});
|
|
96
|
+
hb.registerHelper('equal', function (var1, var2, options) {
|
|
97
|
+
if (var1 == var2) {
|
|
98
|
+
return options.fn(this);
|
|
99
|
+
} else {
|
|
100
|
+
return options.inverse(this);
|
|
273
101
|
}
|
|
102
|
+
}); // register a "get property" helper
|
|
103
|
+
// it gets the named property from the provided context
|
|
274
104
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
* @param {Number} time
|
|
280
|
-
* @returns {String}
|
|
281
|
-
*/
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const timerFormat = time => {
|
|
285
|
-
const seconds = Math.floor(time % 60);
|
|
286
|
-
const minutes = Math.floor(time / 60) % 60;
|
|
287
|
-
const hours = Math.floor(time / 3600);
|
|
288
|
-
const parts = [];
|
|
105
|
+
hb.registerHelper('property', function (name, context) {
|
|
106
|
+
return context[name] || '';
|
|
107
|
+
}); // register an 'includes' helper
|
|
108
|
+
// it checks if value is in array
|
|
289
109
|
|
|
290
|
-
|
|
291
|
-
|
|
110
|
+
hb.registerHelper('includes', function (haystack, needle, options) {
|
|
111
|
+
if (_.contains(haystack, needle)) {
|
|
112
|
+
return options.fn(this);
|
|
292
113
|
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!Helpers0.__initialized) {
|
|
118
|
+
Helpers0(Handlebars);
|
|
119
|
+
Helpers0.__initialized = true;
|
|
120
|
+
}
|
|
121
|
+
var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
122
|
+
this.compilerInfo = [4,'>= 1.0.0'];
|
|
123
|
+
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
124
|
+
var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing;
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
buffer += "<div class=\"mediaplayer ";
|
|
128
|
+
if (helper = helpers.type) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
129
|
+
else { helper = (depth0 && depth0.type); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
130
|
+
buffer += escapeExpression(stack1)
|
|
131
|
+
+ "\">\n <div class=\"player\">\n <div class=\"player-overlay\">\n <a class=\"action play\" data-control=\"play\"><span class=\"icon icon-play\" title=\""
|
|
132
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Play", options) : helperMissing.call(depth0, "__", "Play", options)))
|
|
133
|
+
+ "\"></span></a>\n <a class=\"action play\" data-control=\"pause\"><span class=\"icon icon-pause\" title=\""
|
|
134
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Pause", options) : helperMissing.call(depth0, "__", "Pause", options)))
|
|
135
|
+
+ "\"></span></a>\n <a class=\"action reload\" data-control=\"start\">\n <span class=\"icon icon-play\" title=\""
|
|
136
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Start", options) : helperMissing.call(depth0, "__", "Start", options)))
|
|
137
|
+
+ "\"></span>\n <div class=\"message\">"
|
|
138
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Click to start", options) : helperMissing.call(depth0, "__", "Click to start", options)))
|
|
139
|
+
+ "</div>\n </a>\n <a class=\"action reload\" data-control=\"reload\">\n <div class=\"icon icon-reload\" title=\""
|
|
140
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Reload", options) : helperMissing.call(depth0, "__", "Reload", options)))
|
|
141
|
+
+ "\"></div>\n <div class=\"message\">"
|
|
142
|
+
+ 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)))
|
|
143
|
+
+ " "
|
|
144
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Click to reload.", options) : helperMissing.call(depth0, "__", "Click to reload.", options)))
|
|
145
|
+
+ "</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=\""
|
|
146
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Play", options) : helperMissing.call(depth0, "__", "Play", options)))
|
|
147
|
+
+ "\"><span class=\"icon icon-play\"></span></a>\n <a class=\"action play\" data-control=\"pause\" title=\""
|
|
148
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Pause", options) : helperMissing.call(depth0, "__", "Pause", options)))
|
|
149
|
+
+ "\"><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=\""
|
|
150
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Current playback position", options) : helperMissing.call(depth0, "__", "Current playback position", options)))
|
|
151
|
+
+ "\">--:--</span>\n <span class=\"info time\" data-control=\"time-end\" title=\""
|
|
152
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Total duration", options) : helperMissing.call(depth0, "__", "Total duration", options)))
|
|
153
|
+
+ "\">--:--</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=\""
|
|
154
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Mute", options) : helperMissing.call(depth0, "__", "Mute", options)))
|
|
155
|
+
+ "\"><span class=\"icon icon-sound\"></span></a>\n <a class=\"action mute\" data-control=\"unmute\" title=\""
|
|
156
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Restore sound", options) : helperMissing.call(depth0, "__", "Restore sound", options)))
|
|
157
|
+
+ "\"><span class=\"icon icon-mute\"></span></a>\n </div>\n </div>\n </div>\n <div class=\"error\">\n <div class=\"message\">"
|
|
158
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "This media cannot be played!", options) : helperMissing.call(depth0, "__", "This media cannot be played!", options)))
|
|
159
|
+
+ "</div>\n </div>\n</div>\n";
|
|
160
|
+
return buffer;
|
|
161
|
+
});
|
|
162
|
+
function playerTpl(data, options, asString) {
|
|
163
|
+
var html = Template(data, options);
|
|
164
|
+
return (asString || true) ? html : $(html);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* This program is free software; you can redistribute it and/or
|
|
169
|
+
* modify it under the terms of the GNU General Public License
|
|
170
|
+
* as published by the Free Software Foundation; under version 2
|
|
171
|
+
* of the License (non-upgradable).
|
|
172
|
+
*
|
|
173
|
+
* This program is distributed in the hope that it will be useful,
|
|
174
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
175
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
176
|
+
* GNU General Public License for more details.
|
|
177
|
+
*
|
|
178
|
+
* You should have received a copy of the GNU General Public License
|
|
179
|
+
* along with this program; if not, write to the Free Software
|
|
180
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
181
|
+
*
|
|
182
|
+
* Copyright (c) 2015-2021 (original work) Open Assessment Technologies SA ;
|
|
183
|
+
*/
|
|
184
|
+
/**
|
|
185
|
+
* CSS namespace
|
|
186
|
+
* @type {String}
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
var ns = '.mediaplayer';
|
|
190
|
+
/**
|
|
191
|
+
* Minimum value of the volume
|
|
192
|
+
* @type {Number}
|
|
193
|
+
*/
|
|
194
|
+
|
|
195
|
+
var volumeMin = 0;
|
|
196
|
+
/**
|
|
197
|
+
* Maximum value of the volume
|
|
198
|
+
* @type {Number}
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
var volumeMax = 100;
|
|
202
|
+
/**
|
|
203
|
+
* Threshold (minimum required space above the player) to display the volume
|
|
204
|
+
* above the bar.
|
|
205
|
+
* @type {Number}
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
var volumePositionThreshold = 200;
|
|
209
|
+
/**
|
|
210
|
+
* Some default values
|
|
211
|
+
* @type {Object}
|
|
212
|
+
*/
|
|
213
|
+
|
|
214
|
+
var defaults = {
|
|
215
|
+
type: 'video/mp4',
|
|
216
|
+
video: {
|
|
217
|
+
width: '100%',
|
|
218
|
+
height: 'auto'
|
|
219
|
+
},
|
|
220
|
+
audio: {
|
|
221
|
+
width: '100%',
|
|
222
|
+
height: 'auto'
|
|
223
|
+
},
|
|
224
|
+
youtube: {
|
|
225
|
+
width: 640,
|
|
226
|
+
height: 360
|
|
227
|
+
},
|
|
228
|
+
options: {
|
|
229
|
+
volume: 80,
|
|
230
|
+
startMuted: false,
|
|
231
|
+
maxPlays: 0,
|
|
232
|
+
replayTimeout: 0,
|
|
233
|
+
canPause: true,
|
|
234
|
+
canSeek: true,
|
|
235
|
+
loop: false,
|
|
236
|
+
autoStart: false,
|
|
237
|
+
preview: true,
|
|
238
|
+
debug: false
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Ensures a value is a number
|
|
243
|
+
* @param {Number|String} value
|
|
244
|
+
* @returns {Number}
|
|
245
|
+
*/
|
|
246
|
+
|
|
247
|
+
var ensureNumber = function ensureNumber(value) {
|
|
248
|
+
var floatValue = parseFloat(value);
|
|
249
|
+
return isFinite(floatValue) ? floatValue : 0;
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* Format a number to string with leading zeros
|
|
253
|
+
* @param {Number} n
|
|
254
|
+
* @param {Number} len
|
|
255
|
+
* @returns {String}
|
|
256
|
+
*/
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
var leadingZero = function leadingZero(n, len) {
|
|
260
|
+
var value = n.toString();
|
|
261
|
+
|
|
262
|
+
while (value.length < len) {
|
|
263
|
+
value = "0".concat(value);
|
|
264
|
+
}
|
|
293
265
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
* @returns {Boolean}
|
|
302
|
-
*/
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const needTypeAdjust = type => {
|
|
306
|
-
return 'string' === typeof type && type.indexOf('application') === 0;
|
|
307
|
-
};
|
|
308
|
-
/**
|
|
309
|
-
* Adjust bad type by apllying heuristic on URI
|
|
310
|
-
* @param {Object|String} source
|
|
311
|
-
* @returns {String}
|
|
312
|
-
*/
|
|
266
|
+
return value;
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Formats a time value to string
|
|
270
|
+
* @param {Number} time
|
|
271
|
+
* @returns {String}
|
|
272
|
+
*/
|
|
313
273
|
|
|
314
274
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
275
|
+
var timerFormat = function timerFormat(time) {
|
|
276
|
+
var seconds = Math.floor(time % 60);
|
|
277
|
+
var minutes = Math.floor(time / 60) % 60;
|
|
278
|
+
var hours = Math.floor(time / 3600);
|
|
279
|
+
var parts = [];
|
|
319
280
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
281
|
+
if (hours) {
|
|
282
|
+
parts.push(hours);
|
|
283
|
+
}
|
|
323
284
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
285
|
+
parts.push(leadingZero(minutes, 2));
|
|
286
|
+
parts.push(leadingZero(seconds, 2));
|
|
287
|
+
return parts.join(':');
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
* Checks if a type needs to be adjusted
|
|
291
|
+
* @param {String} type
|
|
292
|
+
* @returns {Boolean}
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
var needTypeAdjust = function needTypeAdjust(type) {
|
|
297
|
+
return 'string' === typeof type && type.indexOf('application') === 0;
|
|
298
|
+
};
|
|
299
|
+
/**
|
|
300
|
+
* Adjust bad type by apllying heuristic on URI
|
|
301
|
+
* @param {Object|String} source
|
|
302
|
+
* @returns {String}
|
|
303
|
+
*/
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
var getAdjustedType = function getAdjustedType(source) {
|
|
307
|
+
var type = 'video/ogg';
|
|
308
|
+
var url = source && source.src || source;
|
|
309
|
+
var ext = url && url.substr(-4);
|
|
310
|
+
|
|
311
|
+
if (ext === '.ogg' || ext === '.oga') {
|
|
312
|
+
type = 'audio/ogg';
|
|
313
|
+
}
|
|
331
314
|
|
|
315
|
+
return type;
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* Extract a list of media sources from a config object
|
|
319
|
+
* @param {Object} config
|
|
320
|
+
* @returns {Array}
|
|
321
|
+
*/
|
|
332
322
|
|
|
333
|
-
const configToSources = config => {
|
|
334
|
-
let sources = config.sources || [];
|
|
335
|
-
let url = config.url;
|
|
336
323
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
324
|
+
var configToSources = function configToSources(config) {
|
|
325
|
+
var sources = config.sources || [];
|
|
326
|
+
var url = config.url;
|
|
340
327
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
328
|
+
if (!_.isArray(sources)) {
|
|
329
|
+
sources = [sources];
|
|
330
|
+
}
|
|
345
331
|
|
|
346
|
-
|
|
332
|
+
if (url) {
|
|
333
|
+
if (!_.isArray(config.url)) {
|
|
334
|
+
url = [url];
|
|
347
335
|
}
|
|
348
336
|
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Checks if the browser can play media
|
|
353
|
-
* @param {String} sizeProps Width or Height
|
|
354
|
-
* @returns {Boolean}
|
|
355
|
-
*/
|
|
356
|
-
|
|
337
|
+
sources = sources.concat(url);
|
|
338
|
+
}
|
|
357
339
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
340
|
+
return sources;
|
|
341
|
+
};
|
|
342
|
+
/**
|
|
343
|
+
* Checks if the browser can play media
|
|
344
|
+
* @param {String} sizeProps Width or Height
|
|
345
|
+
* @returns {Boolean}
|
|
346
|
+
*/
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
var isResponsiveSize = function isResponsiveSize(sizeProps) {
|
|
350
|
+
return /%/.test(sizeProps) || sizeProps === 'auto';
|
|
351
|
+
};
|
|
352
|
+
/**
|
|
353
|
+
* Builds a media player instance
|
|
354
|
+
* @param {Object} config
|
|
355
|
+
* @param {String} config.type - The type of media to play, say `audio`, `video`, or `youtube`. The default is `video`.
|
|
356
|
+
* It might also contain the MIME type of the media as a shorthand.
|
|
357
|
+
* @param {String|Array} [config.url] - The URL to the media. If several media are proposed as alternatives,
|
|
358
|
+
* please look at the `sources` option instead.
|
|
359
|
+
* @param {String} [config.mimeType] - The MIME type of the media. If omitted, the player will try to extract it
|
|
360
|
+
* from the `type` property, otherwise it will request the server to get the content-type.
|
|
361
|
+
* @param {Array} [config.sources] - A list of URL if several media can be proposed. Each entry may be either a
|
|
362
|
+
* string (single URL), or an object containing both the URL and the MIME type ({src: string, type: string}).
|
|
363
|
+
* @param {String|jQuery|HTMLElement} [config.renderTo] - An optional container in which renders the player
|
|
364
|
+
* @param {Boolean} [config.canSeek] - The player allows to reach an arbitrary position within the media using the duration bar
|
|
365
|
+
* @param {Boolean} [config.loop] - The media will be played continuously
|
|
366
|
+
* @param {Boolean} [config.canPause] - The player can be paused
|
|
367
|
+
* @param {Boolean} [config.startMuted] - The player should be initially muted
|
|
368
|
+
* @param {Boolean} [config.autoStart] - The player starts as soon as it is displayed
|
|
369
|
+
* @param {Number} [config.autoStartAt] - The time position at which the player should start
|
|
370
|
+
* @param {Number} [config.maxPlays] - Sets a few number of plays (default: infinite)
|
|
371
|
+
* @param {Number} [config.replayTimeout] - disable the possibility to replay a media after this timeout, in seconds (default: 0)
|
|
372
|
+
* @param {Number} [config.volume] - Sets the sound volume (default: 80)
|
|
373
|
+
* @param {Number} [config.width] - Sets the width of the player (default: depends on media type)
|
|
374
|
+
* @param {Number} [config.height] - Sets the height of the player (default: depends on media type)
|
|
375
|
+
* @param {Boolean} [config.preview] - Enables the media preview (load media metadata)
|
|
376
|
+
* @param {Boolean} [config.debug] - Enables the debug mode
|
|
377
|
+
* @param {number} [config.config.stalledDetectionDelay] - The delay before considering a media is stalled
|
|
378
|
+
* @event render - Event triggered when the player is rendering
|
|
379
|
+
* @event error - Event triggered when the player throws an unrecoverable error
|
|
380
|
+
* @event ready - Event triggered when the player is fully ready
|
|
381
|
+
* @event play - Event triggered when the playback is starting
|
|
382
|
+
* @event update - Event triggered while the player is playing
|
|
383
|
+
* @event pause - Event triggered when the playback is paused
|
|
384
|
+
* @event ended - Event triggered when the playback is ended
|
|
385
|
+
* @event limitreached - Event triggered when the play limit has been reached
|
|
386
|
+
* @event destroy - Event triggered when the player is destroying
|
|
387
|
+
* @returns {mediaplayer}
|
|
388
|
+
*/
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
function mediaplayerFactory(config) {
|
|
361
392
|
/**
|
|
362
|
-
*
|
|
363
|
-
* @
|
|
364
|
-
* @param {String} config.type - The type of media to play, say `audio`, `video`, or `youtube`. The default is `video`.
|
|
365
|
-
* It might also contain the MIME type of the media as a shorthand.
|
|
366
|
-
* @param {String|Array} [config.url] - The URL to the media. If several media are proposed as alternatives,
|
|
367
|
-
* please look at the `sources` option instead.
|
|
368
|
-
* @param {String} [config.mimeType] - The MIME type of the media. If omitted, the player will try to extract it
|
|
369
|
-
* from the `type` property, otherwise it will request the server to get the content-type.
|
|
370
|
-
* @param {Array} [config.sources] - A list of URL if several media can be proposed. Each entry may be either a
|
|
371
|
-
* string (single URL), or an object containing both the URL and the MIME type ({src: string, type: string}).
|
|
372
|
-
* @param {String|jQuery|HTMLElement} [config.renderTo] - An optional container in which renders the player
|
|
373
|
-
* @param {Boolean} [config.canSeek] - The player allows to reach an arbitrary position within the media using the duration bar
|
|
374
|
-
* @param {Boolean} [config.loop] - The media will be played continuously
|
|
375
|
-
* @param {Boolean} [config.canPause] - The player can be paused
|
|
376
|
-
* @param {Boolean} [config.startMuted] - The player should be initially muted
|
|
377
|
-
* @param {Boolean} [config.autoStart] - The player starts as soon as it is displayed
|
|
378
|
-
* @param {Number} [config.autoStartAt] - The time position at which the player should start
|
|
379
|
-
* @param {Number} [config.maxPlays] - Sets a few number of plays (default: infinite)
|
|
380
|
-
* @param {Number} [config.replayTimeout] - disable the possibility to replay a media after this timeout, in seconds (default: 0)
|
|
381
|
-
* @param {Number} [config.volume] - Sets the sound volume (default: 80)
|
|
382
|
-
* @param {Number} [config.width] - Sets the width of the player (default: depends on media type)
|
|
383
|
-
* @param {Number} [config.height] - Sets the height of the player (default: depends on media type)
|
|
384
|
-
* @param {Boolean} [config.preview] - Enables the media preview (load media metadata)
|
|
385
|
-
* @param {Boolean} [config.debug] - Enables the debug mode
|
|
386
|
-
* @param {number} [config.config.stalledDetectionDelay] - The delay before considering a media is stalled
|
|
387
|
-
* @event render - Event triggered when the player is rendering
|
|
388
|
-
* @event error - Event triggered when the player throws an unrecoverable error
|
|
389
|
-
* @event ready - Event triggered when the player is fully ready
|
|
390
|
-
* @event play - Event triggered when the playback is starting
|
|
391
|
-
* @event update - Event triggered while the player is playing
|
|
392
|
-
* @event pause - Event triggered when the playback is paused
|
|
393
|
-
* @event ended - Event triggered when the playback is ended
|
|
394
|
-
* @event limitreached - Event triggered when the play limit has been reached
|
|
395
|
-
* @event destroy - Event triggered when the player is destroying
|
|
396
|
-
* @returns {mediaplayer}
|
|
393
|
+
* Defines a media player object
|
|
394
|
+
* @type {Object}
|
|
397
395
|
*/
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
function mediaplayerFactory(config) {
|
|
396
|
+
var mediaplayer = {
|
|
401
397
|
/**
|
|
402
|
-
*
|
|
403
|
-
* @
|
|
398
|
+
* Initializes the media player
|
|
399
|
+
* @param {Object} config
|
|
400
|
+
* @returns {mediaplayer}
|
|
404
401
|
*/
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
* Initializes the media player
|
|
408
|
-
* @param {Object} config
|
|
409
|
-
* @returns {mediaplayer}
|
|
410
|
-
*/
|
|
411
|
-
init(config) {
|
|
412
|
-
// load the config set, discard null values in order to allow defaults to be set
|
|
413
|
-
this.config = _.omit(config || {}, value => typeof value === 'undefined' || value === null);
|
|
414
|
-
|
|
415
|
-
_.defaults(this.config, defaults.options);
|
|
416
|
-
|
|
417
|
-
if (!this.config.mimeType && 'string' === typeof this.config.type && this.config.type.indexOf('/') > 0) {
|
|
418
|
-
this.config.mimeType = this.config.type;
|
|
419
|
-
}
|
|
402
|
+
init: function init(config) {
|
|
403
|
+
var _this = this;
|
|
420
404
|
|
|
421
|
-
|
|
405
|
+
// load the config set, discard null values in order to allow defaults to be set
|
|
406
|
+
this.config = _.omit(config || {}, function (value) {
|
|
407
|
+
return typeof value === 'undefined' || value === null;
|
|
408
|
+
});
|
|
422
409
|
|
|
423
|
-
|
|
410
|
+
_.defaults(this.config, defaults.options);
|
|
424
411
|
|
|
425
|
-
|
|
412
|
+
if (!this.config.mimeType && 'string' === typeof this.config.type && this.config.type.indexOf('/') > 0) {
|
|
413
|
+
this.config.mimeType = this.config.type;
|
|
414
|
+
}
|
|
426
415
|
|
|
427
|
-
|
|
416
|
+
this._setType(this.config.type || defaults.type);
|
|
428
417
|
|
|
429
|
-
|
|
430
|
-
if (!this.is('youtube')) {
|
|
431
|
-
_.forEach(this.config.sources, source => {
|
|
432
|
-
if (source && source.type && source.type.indexOf('audio') === 0) {
|
|
433
|
-
this._setType(source.type);
|
|
418
|
+
this._reset();
|
|
434
419
|
|
|
435
|
-
|
|
420
|
+
this._updateVolumeFromStore();
|
|
436
421
|
|
|
437
|
-
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
}
|
|
422
|
+
this._initEvents();
|
|
441
423
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
424
|
+
this._initSources(function () {
|
|
425
|
+
if (!_this.is('youtube')) {
|
|
426
|
+
_.forEach(_this.config.sources, function (source) {
|
|
427
|
+
if (source && source.type && source.type.indexOf('audio') === 0) {
|
|
428
|
+
_this._setType(source.type);
|
|
446
429
|
|
|
447
|
-
|
|
448
|
-
},
|
|
430
|
+
_this._initType();
|
|
449
431
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
destroy() {
|
|
455
|
-
/**
|
|
456
|
-
* Triggers a destroy event
|
|
457
|
-
* @event mediaplayer#destroy
|
|
458
|
-
*/
|
|
459
|
-
this.trigger('destroy');
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
460
436
|
|
|
461
|
-
if (
|
|
462
|
-
|
|
437
|
+
if (_this.config.renderTo) {
|
|
438
|
+
_.defer(function () {
|
|
439
|
+
return _this.render();
|
|
440
|
+
});
|
|
463
441
|
}
|
|
442
|
+
});
|
|
464
443
|
|
|
465
|
-
|
|
466
|
-
|
|
444
|
+
return this;
|
|
445
|
+
},
|
|
467
446
|
|
|
468
|
-
|
|
447
|
+
/**
|
|
448
|
+
* Uninstalls the media player
|
|
449
|
+
* @returns {mediaplayer}
|
|
450
|
+
*/
|
|
451
|
+
destroy: function destroy() {
|
|
452
|
+
/**
|
|
453
|
+
* Triggers a destroy event
|
|
454
|
+
* @event mediaplayer#destroy
|
|
455
|
+
*/
|
|
456
|
+
this.trigger('destroy');
|
|
469
457
|
|
|
470
|
-
|
|
458
|
+
if (this.player) {
|
|
459
|
+
this.player.destroy();
|
|
460
|
+
}
|
|
471
461
|
|
|
472
|
-
|
|
473
|
-
|
|
462
|
+
if (this.$component) {
|
|
463
|
+
this._unbindEvents();
|
|
474
464
|
|
|
475
|
-
this.
|
|
465
|
+
this._destroySlider(this.$seekSlider);
|
|
476
466
|
|
|
477
|
-
|
|
478
|
-
},
|
|
467
|
+
this._destroySlider(this.$volumeSlider);
|
|
479
468
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
* @param {String|jQuery|HTMLElement} [to]
|
|
483
|
-
* @returns {mediaplayer}
|
|
484
|
-
*/
|
|
485
|
-
render(to) {
|
|
486
|
-
const renderTo = to || this.config.renderTo || this.$container;
|
|
469
|
+
this.$component.remove();
|
|
470
|
+
}
|
|
487
471
|
|
|
488
|
-
|
|
489
|
-
this.destroy();
|
|
490
|
-
}
|
|
472
|
+
this._reset();
|
|
491
473
|
|
|
492
|
-
|
|
474
|
+
return this;
|
|
475
|
+
},
|
|
493
476
|
|
|
494
|
-
|
|
477
|
+
/**
|
|
478
|
+
* Renders the media player according to the media type
|
|
479
|
+
* @param {String|jQuery|HTMLElement} [to]
|
|
480
|
+
* @returns {mediaplayer}
|
|
481
|
+
*/
|
|
482
|
+
render: function render(to) {
|
|
483
|
+
var renderTo = to || this.config.renderTo || this.$container;
|
|
495
484
|
|
|
496
|
-
|
|
497
|
-
|
|
485
|
+
if (this.$component) {
|
|
486
|
+
this.destroy();
|
|
487
|
+
}
|
|
498
488
|
|
|
499
|
-
|
|
500
|
-
}
|
|
489
|
+
this._initState();
|
|
501
490
|
|
|
502
|
-
|
|
491
|
+
this._buildDom();
|
|
503
492
|
|
|
504
|
-
|
|
493
|
+
if (this.config.preview) {
|
|
494
|
+
this._updateDuration(0);
|
|
505
495
|
|
|
506
|
-
this.
|
|
496
|
+
this._updatePosition(0);
|
|
497
|
+
}
|
|
507
498
|
|
|
508
|
-
|
|
499
|
+
this._bindEvents();
|
|
509
500
|
|
|
501
|
+
this._playingState(false, true);
|
|
510
502
|
|
|
511
|
-
|
|
512
|
-
this.resize('100%', 'auto');
|
|
513
|
-
} else {
|
|
514
|
-
this.resize(this.config.width, this.config.height);
|
|
515
|
-
}
|
|
503
|
+
this._initPlayer();
|
|
516
504
|
|
|
517
|
-
|
|
505
|
+
this._initSize(); // Resize for old items with defined height to avoid big jump
|
|
518
506
|
|
|
519
|
-
if (renderTo) {
|
|
520
|
-
this.$container = $$1(renderTo).append(this.$component);
|
|
521
|
-
} // add class if it is stalled
|
|
522
507
|
|
|
508
|
+
if (this.config.height && this.config.height !== 'auto') {
|
|
509
|
+
this.resize('100%', 'auto');
|
|
510
|
+
} else {
|
|
511
|
+
this.resize(this.config.width, this.config.height);
|
|
512
|
+
}
|
|
523
513
|
|
|
524
|
-
|
|
525
|
-
this._setState('stalled', true);
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Triggers a render event
|
|
529
|
-
* @event mediaplayer#render
|
|
530
|
-
* @param {jQuery} $component
|
|
531
|
-
*/
|
|
514
|
+
this.config.is.rendered = true;
|
|
532
515
|
|
|
516
|
+
if (renderTo) {
|
|
517
|
+
this.$container = $$1(renderTo).append(this.$component);
|
|
518
|
+
} // add class if it is stalled
|
|
533
519
|
|
|
534
|
-
this.trigger('render', this.$component);
|
|
535
|
-
return this;
|
|
536
|
-
},
|
|
537
520
|
|
|
521
|
+
if (this.is('stalled')) {
|
|
522
|
+
this._setState('stalled', true);
|
|
523
|
+
}
|
|
538
524
|
/**
|
|
539
|
-
*
|
|
525
|
+
* Triggers a render event
|
|
526
|
+
* @event mediaplayer#render
|
|
527
|
+
* @param {jQuery} $component
|
|
540
528
|
*/
|
|
541
|
-
reload() {
|
|
542
|
-
/**
|
|
543
|
-
* Triggers a reload event
|
|
544
|
-
* @event mediaplayer#reload
|
|
545
|
-
*/
|
|
546
|
-
this.trigger('reload');
|
|
547
|
-
|
|
548
|
-
if (this.player) {
|
|
549
|
-
this.player.recover();
|
|
550
|
-
}
|
|
551
529
|
|
|
552
|
-
this._setState('stalled', false);
|
|
553
530
|
|
|
554
|
-
|
|
555
|
-
|
|
531
|
+
this.trigger('render', this.$component);
|
|
532
|
+
return this;
|
|
533
|
+
},
|
|
556
534
|
|
|
535
|
+
/**
|
|
536
|
+
* Reloads media player after it was stalled
|
|
537
|
+
*/
|
|
538
|
+
reload: function reload() {
|
|
557
539
|
/**
|
|
558
|
-
*
|
|
540
|
+
* Triggers a reload event
|
|
541
|
+
* @event mediaplayer#reload
|
|
559
542
|
*/
|
|
560
|
-
|
|
561
|
-
if (!this.is('stalled')) {
|
|
562
|
-
this._setState('ready', true);
|
|
563
|
-
}
|
|
543
|
+
this.trigger('reload');
|
|
564
544
|
|
|
565
|
-
|
|
545
|
+
if (this.player) {
|
|
546
|
+
this.player.recover();
|
|
547
|
+
}
|
|
566
548
|
|
|
567
|
-
|
|
549
|
+
this._setState('stalled', false);
|
|
568
550
|
|
|
569
|
-
|
|
551
|
+
this.setInitialStates();
|
|
552
|
+
},
|
|
570
553
|
|
|
571
|
-
|
|
572
|
-
|
|
554
|
+
/**
|
|
555
|
+
* Set initial states
|
|
556
|
+
*/
|
|
557
|
+
setInitialStates: function setInitialStates() {
|
|
558
|
+
if (!this.is('stalled')) {
|
|
559
|
+
this._setState('ready', true);
|
|
560
|
+
}
|
|
573
561
|
|
|
574
|
-
|
|
575
|
-
* Sets the start position inside the media
|
|
576
|
-
* @param {Number} time - The start position in seconds
|
|
577
|
-
* @param {*} [internal] - Internal use
|
|
578
|
-
* @returns {mediaplayer}
|
|
579
|
-
*/
|
|
580
|
-
seek(time, internal) {
|
|
581
|
-
if (this._canPlay()) {
|
|
582
|
-
this._updatePosition(time, internal);
|
|
562
|
+
this._setState('canplay', true);
|
|
583
563
|
|
|
584
|
-
|
|
564
|
+
this._setState('canpause', this.config.canPause);
|
|
585
565
|
|
|
586
|
-
|
|
587
|
-
this.autoStartAt = this.position;
|
|
588
|
-
}
|
|
566
|
+
this._setState('canseek', this.config.canSeek);
|
|
589
567
|
|
|
590
|
-
|
|
591
|
-
|
|
568
|
+
this._setState('loading', false);
|
|
569
|
+
},
|
|
592
570
|
|
|
593
|
-
|
|
594
|
-
|
|
571
|
+
/**
|
|
572
|
+
* Sets the start position inside the media
|
|
573
|
+
* @param {Number} time - The start position in seconds
|
|
574
|
+
* @param {*} [internal] - Internal use
|
|
575
|
+
* @returns {mediaplayer}
|
|
576
|
+
*/
|
|
577
|
+
seek: function seek(time, internal) {
|
|
578
|
+
if (this._canPlay()) {
|
|
579
|
+
this._updatePosition(time, internal);
|
|
595
580
|
|
|
596
|
-
|
|
597
|
-
* Plays the media
|
|
598
|
-
* @param {Number} [time] - An optional start position in seconds
|
|
599
|
-
* @returns {mediaplayer}
|
|
600
|
-
*/
|
|
601
|
-
play(time) {
|
|
602
|
-
if (this._canPlay()) {
|
|
603
|
-
if (typeof time !== 'undefined') {
|
|
604
|
-
this.seek(time);
|
|
605
|
-
}
|
|
581
|
+
this.execute('seek', this.position);
|
|
606
582
|
|
|
607
|
-
|
|
583
|
+
if (!this.is('ready')) {
|
|
584
|
+
this.autoStartAt = this.position;
|
|
585
|
+
}
|
|
608
586
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
}
|
|
587
|
+
this.loop = !!this.config.loop;
|
|
588
|
+
}
|
|
612
589
|
|
|
613
|
-
|
|
590
|
+
return this;
|
|
591
|
+
},
|
|
614
592
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
593
|
+
/**
|
|
594
|
+
* Plays the media
|
|
595
|
+
* @param {Number} [time] - An optional start position in seconds
|
|
596
|
+
* @returns {mediaplayer}
|
|
597
|
+
*/
|
|
598
|
+
play: function play(time) {
|
|
599
|
+
if (this._canPlay()) {
|
|
600
|
+
if (typeof time !== 'undefined') {
|
|
601
|
+
this.seek(time);
|
|
618
602
|
}
|
|
619
603
|
|
|
620
|
-
|
|
621
|
-
},
|
|
604
|
+
this.execute('play');
|
|
622
605
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
* @returns {mediaplayer}
|
|
627
|
-
*/
|
|
628
|
-
pause(time) {
|
|
629
|
-
if (this._canPause()) {
|
|
630
|
-
if (typeof time !== 'undefined') {
|
|
631
|
-
this.seek(time);
|
|
632
|
-
}
|
|
606
|
+
if (!this.is('ready')) {
|
|
607
|
+
this.autoStart = true;
|
|
608
|
+
}
|
|
633
609
|
|
|
634
|
-
|
|
610
|
+
this.loop = !!this.config.loop;
|
|
635
611
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
}
|
|
612
|
+
if (this.timerId) {
|
|
613
|
+
cancelAnimationFrame(this.timerId);
|
|
639
614
|
}
|
|
615
|
+
}
|
|
640
616
|
|
|
641
|
-
|
|
642
|
-
|
|
617
|
+
return this;
|
|
618
|
+
},
|
|
643
619
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
620
|
+
/**
|
|
621
|
+
* Pauses the media
|
|
622
|
+
* @param {Number} [time] - An optional time position in seconds
|
|
623
|
+
* @returns {mediaplayer}
|
|
624
|
+
*/
|
|
625
|
+
pause: function pause(time) {
|
|
626
|
+
if (this._canPause()) {
|
|
627
|
+
if (typeof time !== 'undefined') {
|
|
628
|
+
this.seek(time);
|
|
651
629
|
}
|
|
652
630
|
|
|
653
|
-
|
|
654
|
-
},
|
|
655
|
-
|
|
656
|
-
/**
|
|
657
|
-
* Stops the playback
|
|
658
|
-
* @returns {mediaplayer}
|
|
659
|
-
*/
|
|
660
|
-
stop() {
|
|
661
|
-
this.loop = false;
|
|
662
|
-
this.execute('stop');
|
|
631
|
+
this.execute('pause');
|
|
663
632
|
|
|
664
633
|
if (!this.is('ready')) {
|
|
665
634
|
this.autoStart = false;
|
|
666
635
|
}
|
|
636
|
+
}
|
|
667
637
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* Starts the media
|
|
673
|
-
* @returns {mediaplayer}
|
|
674
|
-
*/
|
|
675
|
-
start() {
|
|
676
|
-
this._setState('preview', true);
|
|
677
|
-
|
|
678
|
-
this._setState('loading', true);
|
|
638
|
+
return this;
|
|
639
|
+
},
|
|
679
640
|
|
|
641
|
+
/**
|
|
642
|
+
* Resumes the media
|
|
643
|
+
* @returns {mediaplayer}
|
|
644
|
+
*/
|
|
645
|
+
resume: function resume() {
|
|
646
|
+
if (this._canResume()) {
|
|
680
647
|
this.play();
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* Restarts the media from the beginning
|
|
685
|
-
* @returns {mediaplayer}
|
|
686
|
-
*/
|
|
687
|
-
restart() {
|
|
688
|
-
this.play(0);
|
|
689
|
-
return this;
|
|
690
|
-
},
|
|
648
|
+
}
|
|
691
649
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
* @returns {mediaplayer}
|
|
695
|
-
*/
|
|
696
|
-
rewind() {
|
|
697
|
-
this.seek(0);
|
|
698
|
-
return this;
|
|
699
|
-
},
|
|
650
|
+
return this;
|
|
651
|
+
},
|
|
700
652
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
state = true;
|
|
709
|
-
}
|
|
653
|
+
/**
|
|
654
|
+
* Stops the playback
|
|
655
|
+
* @returns {mediaplayer}
|
|
656
|
+
*/
|
|
657
|
+
stop: function stop() {
|
|
658
|
+
this.loop = false;
|
|
659
|
+
this.execute('stop');
|
|
710
660
|
|
|
711
|
-
|
|
661
|
+
if (!this.is('ready')) {
|
|
662
|
+
this.autoStart = false;
|
|
663
|
+
}
|
|
712
664
|
|
|
713
|
-
|
|
665
|
+
return this;
|
|
666
|
+
},
|
|
714
667
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
668
|
+
/**
|
|
669
|
+
* Starts the media
|
|
670
|
+
* @returns {mediaplayer}
|
|
671
|
+
*/
|
|
672
|
+
start: function start() {
|
|
673
|
+
this._setState('preview', true);
|
|
718
674
|
|
|
719
|
-
|
|
720
|
-
},
|
|
675
|
+
this._setState('loading', true);
|
|
721
676
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
* @returns {mediaplayer}
|
|
725
|
-
*/
|
|
726
|
-
unmute() {
|
|
727
|
-
this.mute(false);
|
|
728
|
-
return this;
|
|
729
|
-
},
|
|
677
|
+
this.play();
|
|
678
|
+
},
|
|
730
679
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
680
|
+
/**
|
|
681
|
+
* Restarts the media from the beginning
|
|
682
|
+
* @returns {mediaplayer}
|
|
683
|
+
*/
|
|
684
|
+
restart: function restart() {
|
|
685
|
+
this.play(0);
|
|
686
|
+
return this;
|
|
687
|
+
},
|
|
739
688
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
689
|
+
/**
|
|
690
|
+
* Rewind the media to the beginning
|
|
691
|
+
* @returns {mediaplayer}
|
|
692
|
+
*/
|
|
693
|
+
rewind: function rewind() {
|
|
694
|
+
this.seek(0);
|
|
695
|
+
return this;
|
|
696
|
+
},
|
|
743
697
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
698
|
+
/**
|
|
699
|
+
* Mutes the media
|
|
700
|
+
* @param {Boolean} [state] - A flag to set the mute state (default: true)
|
|
701
|
+
* @returns {mediaplayer}
|
|
702
|
+
*/
|
|
703
|
+
mute: function mute(state) {
|
|
704
|
+
if (typeof state === 'undefined') {
|
|
705
|
+
state = true;
|
|
706
|
+
}
|
|
751
707
|
|
|
752
|
-
|
|
753
|
-
* Gets the current displayed position inside the media
|
|
754
|
-
* @returns {Number}
|
|
755
|
-
*/
|
|
756
|
-
getPosition() {
|
|
757
|
-
return this.position;
|
|
758
|
-
},
|
|
708
|
+
this.execute('mute', state);
|
|
759
709
|
|
|
760
|
-
|
|
761
|
-
* Gets the duration of the media
|
|
762
|
-
* @returns {Number}
|
|
763
|
-
*/
|
|
764
|
-
getDuration() {
|
|
765
|
-
return this.duration;
|
|
766
|
-
},
|
|
710
|
+
this._setState('muted', state);
|
|
767
711
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
*/
|
|
772
|
-
getTimesPlayed() {
|
|
773
|
-
return this.timesPlayed;
|
|
774
|
-
},
|
|
712
|
+
if (!this.is('ready')) {
|
|
713
|
+
this.startMuted = state;
|
|
714
|
+
}
|
|
775
715
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
* @returns {String}
|
|
779
|
-
*/
|
|
780
|
-
getType() {
|
|
781
|
-
return this.type;
|
|
782
|
-
},
|
|
716
|
+
return this;
|
|
717
|
+
},
|
|
783
718
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
719
|
+
/**
|
|
720
|
+
* Restore the sound of the media after a mute
|
|
721
|
+
* @returns {mediaplayer}
|
|
722
|
+
*/
|
|
723
|
+
unmute: function unmute() {
|
|
724
|
+
this.mute(false);
|
|
725
|
+
return this;
|
|
726
|
+
},
|
|
791
727
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
728
|
+
/**
|
|
729
|
+
* Sets the sound volume of the media being played
|
|
730
|
+
* @param {Number} value - A value between 0 and 100
|
|
731
|
+
* @param {*} [internal] - Internal use
|
|
732
|
+
* @returns {mediaplayer}
|
|
733
|
+
*/
|
|
734
|
+
setVolume: function setVolume(value, internal) {
|
|
735
|
+
this._updateVolume(value, internal);
|
|
796
736
|
|
|
797
|
-
|
|
798
|
-
|
|
737
|
+
this.execute('setVolume', this.volume);
|
|
738
|
+
return this;
|
|
739
|
+
},
|
|
799
740
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
741
|
+
/**
|
|
742
|
+
* Gets the sound volume applied to the media being played
|
|
743
|
+
* @returns {Number} Returns a value between 0 and 100
|
|
744
|
+
*/
|
|
745
|
+
getVolume: function getVolume() {
|
|
746
|
+
return this.volume;
|
|
747
|
+
},
|
|
807
748
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
749
|
+
/**
|
|
750
|
+
* Gets the current displayed position inside the media
|
|
751
|
+
* @returns {Number}
|
|
752
|
+
*/
|
|
753
|
+
getPosition: function getPosition() {
|
|
754
|
+
return this.position;
|
|
755
|
+
},
|
|
815
756
|
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
this._getSource(src, source => {
|
|
824
|
-
this.config.sources = [source];
|
|
757
|
+
/**
|
|
758
|
+
* Gets the duration of the media
|
|
759
|
+
* @returns {Number}
|
|
760
|
+
*/
|
|
761
|
+
getDuration: function getDuration() {
|
|
762
|
+
return this.duration;
|
|
763
|
+
},
|
|
825
764
|
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
765
|
+
/**
|
|
766
|
+
* Gets the number of times the media has been played
|
|
767
|
+
* @returns {Number}
|
|
768
|
+
*/
|
|
769
|
+
getTimesPlayed: function getTimesPlayed() {
|
|
770
|
+
return this.timesPlayed;
|
|
771
|
+
},
|
|
829
772
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
773
|
+
/**
|
|
774
|
+
* Gets the type of player
|
|
775
|
+
* @returns {String}
|
|
776
|
+
*/
|
|
777
|
+
getType: function getType() {
|
|
778
|
+
return this.type;
|
|
779
|
+
},
|
|
834
780
|
|
|
835
|
-
|
|
836
|
-
|
|
781
|
+
/**
|
|
782
|
+
* Gets the DOM container
|
|
783
|
+
* @returns {jQuery}
|
|
784
|
+
*/
|
|
785
|
+
getContainer: function getContainer() {
|
|
786
|
+
if (!this.$container && this.$component) {
|
|
787
|
+
var $container = this.$component.parent();
|
|
837
788
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
* @returns {mediaplayer}
|
|
843
|
-
*/
|
|
844
|
-
addSource(src, callback) {
|
|
845
|
-
this._getSource(src, source => {
|
|
846
|
-
this.config.sources.push(source);
|
|
789
|
+
if ($container.length) {
|
|
790
|
+
this.$container = $container;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
847
793
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
}
|
|
794
|
+
return this.$container;
|
|
795
|
+
},
|
|
851
796
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
797
|
+
/**
|
|
798
|
+
* Gets the underlying DOM element
|
|
799
|
+
* @returns {jQuery}
|
|
800
|
+
*/
|
|
801
|
+
getElement: function getElement() {
|
|
802
|
+
return this.$component;
|
|
803
|
+
},
|
|
856
804
|
|
|
857
|
-
|
|
858
|
-
|
|
805
|
+
/**
|
|
806
|
+
* Gets the list of media
|
|
807
|
+
* @returns {Array}
|
|
808
|
+
*/
|
|
809
|
+
getSources: function getSources() {
|
|
810
|
+
return this.config.sources.slice();
|
|
811
|
+
},
|
|
859
812
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
813
|
+
/**
|
|
814
|
+
* Sets the media source. If a source has been already set, it will be replaced.
|
|
815
|
+
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
816
|
+
* @param {Function} [callback] - A function called to provide the added media source object
|
|
817
|
+
* @returns {mediaplayer}
|
|
818
|
+
*/
|
|
819
|
+
setSource: function setSource(src, callback) {
|
|
820
|
+
var _this2 = this;
|
|
868
821
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
*/
|
|
875
|
-
resize(width, height) {
|
|
876
|
-
if (isResponsiveSize(width) && !isResponsiveSize(height) || this.is('youtube')) {
|
|
877
|
-
// responsive width height should be auto
|
|
878
|
-
// for youtube iframe height is limited by ration
|
|
879
|
-
height = 'auto';
|
|
822
|
+
this._getSource(src, function (source) {
|
|
823
|
+
_this2.config.sources = [source];
|
|
824
|
+
|
|
825
|
+
if (_this2.is('rendered')) {
|
|
826
|
+
_this2.player.setMedia(source.src, source.type);
|
|
880
827
|
}
|
|
881
828
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
829
|
+
if (callback) {
|
|
830
|
+
callback.call(_this2, source);
|
|
831
|
+
}
|
|
832
|
+
});
|
|
885
833
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
* @returns {mediaplayer}
|
|
889
|
-
*/
|
|
890
|
-
enable() {
|
|
891
|
-
this._fromState('disabled');
|
|
834
|
+
return this;
|
|
835
|
+
},
|
|
892
836
|
|
|
893
|
-
|
|
894
|
-
|
|
837
|
+
/**
|
|
838
|
+
* Adds a media source.
|
|
839
|
+
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
840
|
+
* @param {Function} [callback] - A function called to provide the added media source object
|
|
841
|
+
* @returns {mediaplayer}
|
|
842
|
+
*/
|
|
843
|
+
addSource: function addSource(src, callback) {
|
|
844
|
+
var _this3 = this;
|
|
895
845
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
* @returns {mediaplayer}
|
|
899
|
-
*/
|
|
900
|
-
disable() {
|
|
901
|
-
this._toState('disabled');
|
|
846
|
+
this._getSource(src, function (source) {
|
|
847
|
+
_this3.config.sources.push(source);
|
|
902
848
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
849
|
+
if (_this3.is('rendered')) {
|
|
850
|
+
_this3.player.addMedia(source.src, source.type);
|
|
851
|
+
}
|
|
906
852
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
show() {
|
|
912
|
-
this._fromState('hidden');
|
|
853
|
+
if (callback) {
|
|
854
|
+
callback.call(_this3, source);
|
|
855
|
+
}
|
|
856
|
+
});
|
|
913
857
|
|
|
914
|
-
|
|
915
|
-
|
|
858
|
+
return this;
|
|
859
|
+
},
|
|
916
860
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
861
|
+
/**
|
|
862
|
+
* Tells if the media is in a particular state
|
|
863
|
+
* @param {String} state
|
|
864
|
+
* @returns {Boolean}
|
|
865
|
+
*/
|
|
866
|
+
is: function is(state) {
|
|
867
|
+
return !!this.config.is[state];
|
|
868
|
+
},
|
|
923
869
|
|
|
924
|
-
|
|
925
|
-
|
|
870
|
+
/**
|
|
871
|
+
* Changes the size of the player
|
|
872
|
+
* @param {Number} width
|
|
873
|
+
* @param {Number} height
|
|
874
|
+
* @returns {mediaplayer}
|
|
875
|
+
*/
|
|
876
|
+
resize: function resize(width, height) {
|
|
877
|
+
if (isResponsiveSize(width) && !isResponsiveSize(height) || this.is('youtube')) {
|
|
878
|
+
// responsive width height should be auto
|
|
879
|
+
// for youtube iframe height is limited by ration
|
|
880
|
+
height = 'auto';
|
|
881
|
+
}
|
|
926
882
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
*/
|
|
931
|
-
getMediaOriginalSize() {
|
|
932
|
-
if (this.is('youtube')) {
|
|
933
|
-
return defaults.youtube;
|
|
934
|
-
}
|
|
883
|
+
this.execute('setSize', width, height);
|
|
884
|
+
return this;
|
|
885
|
+
},
|
|
935
886
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
887
|
+
/**
|
|
888
|
+
* Enables the media player
|
|
889
|
+
* @returns {mediaplayer}
|
|
890
|
+
*/
|
|
891
|
+
enable: function enable() {
|
|
892
|
+
this._fromState('disabled');
|
|
939
893
|
|
|
940
|
-
|
|
941
|
-
|
|
894
|
+
return this;
|
|
895
|
+
},
|
|
942
896
|
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
if (type.indexOf('youtube') !== -1) {
|
|
950
|
-
this.type = 'youtube';
|
|
951
|
-
} else if (type.indexOf('audio') === 0) {
|
|
952
|
-
this.type = 'audio';
|
|
953
|
-
} else {
|
|
954
|
-
this.type = 'video';
|
|
955
|
-
}
|
|
956
|
-
},
|
|
897
|
+
/**
|
|
898
|
+
* Disables the media player
|
|
899
|
+
* @returns {mediaplayer}
|
|
900
|
+
*/
|
|
901
|
+
disable: function disable() {
|
|
902
|
+
this._toState('disabled');
|
|
957
903
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
*/
|
|
962
|
-
_initType() {
|
|
963
|
-
const is = this.config.is;
|
|
964
|
-
is.youtube = 'youtube' === this.type;
|
|
965
|
-
is.video = 'video' === this.type || 'youtube' === this.type;
|
|
966
|
-
is.audio = 'audio' === this.type;
|
|
967
|
-
},
|
|
904
|
+
this.trigger('disabled');
|
|
905
|
+
return this;
|
|
906
|
+
},
|
|
968
907
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
let source;
|
|
908
|
+
/**
|
|
909
|
+
* Shows the media player
|
|
910
|
+
* @returns {mediaplayer}
|
|
911
|
+
*/
|
|
912
|
+
show: function show() {
|
|
913
|
+
this._fromState('hidden');
|
|
976
914
|
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
source.type = getAdjustedType(source);
|
|
980
|
-
}
|
|
915
|
+
return this;
|
|
916
|
+
},
|
|
981
917
|
|
|
982
|
-
|
|
983
|
-
|
|
918
|
+
/**
|
|
919
|
+
* hides the media player
|
|
920
|
+
* @returns {mediaplayer}
|
|
921
|
+
*/
|
|
922
|
+
hide: function hide() {
|
|
923
|
+
this._toState('hidden');
|
|
984
924
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
src: src
|
|
988
|
-
};
|
|
989
|
-
} else {
|
|
990
|
-
source = _.clone(src);
|
|
991
|
-
}
|
|
925
|
+
return this;
|
|
926
|
+
},
|
|
992
927
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
928
|
+
/**
|
|
929
|
+
* get media original size
|
|
930
|
+
* @returns {Object}
|
|
931
|
+
*/
|
|
932
|
+
getMediaOriginalSize: function getMediaOriginalSize() {
|
|
933
|
+
if (this.is('youtube')) {
|
|
934
|
+
return defaults.youtube;
|
|
935
|
+
}
|
|
1000
936
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
type = defaults.type;
|
|
1005
|
-
}
|
|
937
|
+
if (this.is('video') && this.player) {
|
|
938
|
+
return this.player.getMediaSize();
|
|
939
|
+
}
|
|
1006
940
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
});
|
|
1010
|
-
} else {
|
|
1011
|
-
done();
|
|
1012
|
-
}
|
|
1013
|
-
},
|
|
941
|
+
return {};
|
|
942
|
+
},
|
|
1014
943
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
this.
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
944
|
+
/**
|
|
945
|
+
* Ensures the right media type is set
|
|
946
|
+
* @param {String} type
|
|
947
|
+
* @private
|
|
948
|
+
*/
|
|
949
|
+
_setType: function _setType(type) {
|
|
950
|
+
if (type.indexOf('youtube') !== -1) {
|
|
951
|
+
this.type = 'youtube';
|
|
952
|
+
} else if (type.indexOf('audio') === 0) {
|
|
953
|
+
this.type = 'audio';
|
|
954
|
+
} else {
|
|
955
|
+
this.type = 'video';
|
|
956
|
+
}
|
|
957
|
+
},
|
|
1027
958
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
959
|
+
/**
|
|
960
|
+
* Ensures the type is correctly applied
|
|
961
|
+
* @private
|
|
962
|
+
*/
|
|
963
|
+
_initType: function _initType() {
|
|
964
|
+
var is = this.config.is;
|
|
965
|
+
is.youtube = 'youtube' === this.type;
|
|
966
|
+
is.video = 'video' === this.type || 'youtube' === this.type;
|
|
967
|
+
is.audio = 'audio' === this.type;
|
|
968
|
+
},
|
|
1035
969
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
970
|
+
/**
|
|
971
|
+
* Gets a source descriptor.
|
|
972
|
+
* @param {String|Object} src - The media URL, or an object containing the source and the type
|
|
973
|
+
* @param {Function} callback - A function called to provide the media source object
|
|
974
|
+
*/
|
|
975
|
+
_getSource: function _getSource(src, callback) {
|
|
976
|
+
var _this4 = this;
|
|
1040
977
|
|
|
1041
|
-
|
|
1042
|
-
this.$component.trigger(eventName + ns, ...args);
|
|
1043
|
-
}
|
|
978
|
+
var source;
|
|
1044
979
|
|
|
1045
|
-
|
|
980
|
+
var done = function done() {
|
|
981
|
+
if (needTypeAdjust(source.type)) {
|
|
982
|
+
source.type = getAdjustedType(source);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
callback.call(_this4, source);
|
|
986
|
+
};
|
|
987
|
+
|
|
988
|
+
if (_.isString(src)) {
|
|
989
|
+
source = {
|
|
990
|
+
src: src
|
|
1046
991
|
};
|
|
1047
|
-
}
|
|
992
|
+
} else {
|
|
993
|
+
source = _.clone(src);
|
|
994
|
+
}
|
|
1048
995
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
const type = this.is('video') ? 'video' : 'audio';
|
|
1055
|
-
const mediaConfig = defaults[type] || defaults.video;
|
|
1056
|
-
this.config.width = this.config.width || mediaConfig.width;
|
|
1057
|
-
this.config.height = this.config.height || mediaConfig.height;
|
|
1058
|
-
|
|
1059
|
-
if (isResponsiveSize(this.config.width) && !isResponsiveSize(this.config.height) || this.is('youtube')) {
|
|
1060
|
-
// responsive width height should be auto
|
|
1061
|
-
// for youtube iframe height is limited by ration
|
|
1062
|
-
this.config.height = 'auto';
|
|
996
|
+
if (!source.type) {
|
|
997
|
+
if (this.is('youtube')) {
|
|
998
|
+
source.type = defaults.type;
|
|
999
|
+
} else if (this.config.mimeType) {
|
|
1000
|
+
source.type = this.config.mimeType;
|
|
1063
1001
|
}
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
/**
|
|
1067
|
-
* Initializes the right player instance
|
|
1068
|
-
* @private
|
|
1069
|
-
*/
|
|
1070
|
-
_initPlayer() {
|
|
1071
|
-
const playerFactory = players[this.type];
|
|
1072
|
-
let error;
|
|
1073
|
-
|
|
1074
|
-
if (support.canPlay(this.type)) {
|
|
1075
|
-
if (_.isFunction(playerFactory)) {
|
|
1076
|
-
const playerConfig = {
|
|
1077
|
-
type: this.getType(),
|
|
1078
|
-
sources: this.getSources(),
|
|
1079
|
-
preview: this.config.preview,
|
|
1080
|
-
debug: this.config.debug,
|
|
1081
|
-
stalledDetectionDelay: this.config.stalledDetectionDelay
|
|
1082
|
-
};
|
|
1083
|
-
this.player = playerFactory(this.$player, playerConfig).on('resize', (width, height) => {
|
|
1084
|
-
if (this.$component) {
|
|
1085
|
-
this.$component.width(width).height(height);
|
|
1086
|
-
}
|
|
1087
|
-
}).on('ready', () => this._onReady()).on('play', () => this._onPlay()).on('pause', () => this._onPause()).on('timeupdate', () => this._onTimeUpdate()).on('stalled', () => this._onStalled()).on('playing', () => this._onPlaying()).on('end', () => this._onEnd()).on('error', () => this._onError());
|
|
1088
|
-
}
|
|
1002
|
+
}
|
|
1089
1003
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1004
|
+
if (!source.type) {
|
|
1005
|
+
mimetype.getResourceType(source.src, function (err, type) {
|
|
1006
|
+
if (err) {
|
|
1007
|
+
type = defaults.type;
|
|
1094
1008
|
}
|
|
1095
|
-
} else {
|
|
1096
|
-
error = true;
|
|
1097
|
-
}
|
|
1098
1009
|
|
|
1099
|
-
|
|
1010
|
+
source.type = type;
|
|
1011
|
+
done();
|
|
1012
|
+
});
|
|
1013
|
+
} else {
|
|
1014
|
+
done();
|
|
1015
|
+
}
|
|
1016
|
+
},
|
|
1100
1017
|
|
|
1101
|
-
|
|
1018
|
+
/**
|
|
1019
|
+
* Ensures the sources are correctly set
|
|
1020
|
+
* @param {Function} callback - A function called once all sources have been initialized
|
|
1021
|
+
* @private
|
|
1022
|
+
*/
|
|
1023
|
+
_initSources: function _initSources(callback) {
|
|
1024
|
+
var _this5 = this;
|
|
1025
|
+
|
|
1026
|
+
var sources = configToSources(this.config);
|
|
1027
|
+
this.config.sources = [];
|
|
1028
|
+
async.each(sources, function (source, cb) {
|
|
1029
|
+
_this5.addSource(source, function (src) {
|
|
1030
|
+
return cb(null, src);
|
|
1031
|
+
});
|
|
1032
|
+
}, callback);
|
|
1033
|
+
},
|
|
1102
1034
|
|
|
1103
|
-
|
|
1035
|
+
/**
|
|
1036
|
+
* Installs the events manager onto the instance
|
|
1037
|
+
* @private
|
|
1038
|
+
*/
|
|
1039
|
+
_initEvents: function _initEvents() {
|
|
1040
|
+
eventifier(this);
|
|
1041
|
+
var triggerEvent = this.trigger;
|
|
1104
1042
|
|
|
1105
|
-
|
|
1043
|
+
this.trigger = function trigger(eventName) {
|
|
1044
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
1045
|
+
args[_key - 1] = arguments[_key];
|
|
1046
|
+
}
|
|
1106
1047
|
|
|
1107
|
-
if (
|
|
1108
|
-
|
|
1048
|
+
if (this.$component) {
|
|
1049
|
+
var _this$$component;
|
|
1109
1050
|
|
|
1110
|
-
this.trigger(
|
|
1051
|
+
(_this$$component = this.$component).trigger.apply(_this$$component, [eventName + ns].concat(args));
|
|
1111
1052
|
}
|
|
1112
|
-
},
|
|
1113
1053
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
*/
|
|
1118
|
-
_initState() {
|
|
1119
|
-
let isCORS = false;
|
|
1120
|
-
let page;
|
|
1054
|
+
return triggerEvent.call.apply(triggerEvent, [this, eventName].concat(args));
|
|
1055
|
+
};
|
|
1056
|
+
},
|
|
1121
1057
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1058
|
+
/**
|
|
1059
|
+
* Ensures the right size is set according to the media type
|
|
1060
|
+
* @private
|
|
1061
|
+
*/
|
|
1062
|
+
_initSize: function _initSize() {
|
|
1063
|
+
var type = this.is('video') ? 'video' : 'audio';
|
|
1064
|
+
var mediaConfig = defaults[type] || defaults.video;
|
|
1065
|
+
this.config.width = this.config.width || mediaConfig.width;
|
|
1066
|
+
this.config.height = this.config.height || mediaConfig.height;
|
|
1067
|
+
|
|
1068
|
+
if (isResponsiveSize(this.config.width) && !isResponsiveSize(this.config.height) || this.is('youtube')) {
|
|
1069
|
+
// responsive width height should be auto
|
|
1070
|
+
// for youtube iframe height is limited by ration
|
|
1071
|
+
this.config.height = 'auto';
|
|
1072
|
+
}
|
|
1073
|
+
},
|
|
1126
1074
|
|
|
1127
|
-
|
|
1075
|
+
/**
|
|
1076
|
+
* Initializes the right player instance
|
|
1077
|
+
* @private
|
|
1078
|
+
*/
|
|
1079
|
+
_initPlayer: function _initPlayer() {
|
|
1080
|
+
var _this6 = this;
|
|
1081
|
+
|
|
1082
|
+
var playerFactory = players[this.type];
|
|
1083
|
+
var error;
|
|
1084
|
+
|
|
1085
|
+
if (support.canPlay(this.type)) {
|
|
1086
|
+
if (_.isFunction(playerFactory)) {
|
|
1087
|
+
var playerConfig = {
|
|
1088
|
+
type: this.getType(),
|
|
1089
|
+
sources: this.getSources(),
|
|
1090
|
+
preview: this.config.preview,
|
|
1091
|
+
debug: this.config.debug,
|
|
1092
|
+
stalledDetectionDelay: this.config.stalledDetectionDelay
|
|
1093
|
+
};
|
|
1094
|
+
this.player = playerFactory(this.$player, playerConfig).on('resize', function (width, height) {
|
|
1095
|
+
if (_this6.$component) {
|
|
1096
|
+
_this6.$component.width(width).height(height);
|
|
1097
|
+
}
|
|
1098
|
+
}).on('ready', function () {
|
|
1099
|
+
return _this6._onReady();
|
|
1100
|
+
}).on('play', function () {
|
|
1101
|
+
return _this6._onPlay();
|
|
1102
|
+
}).on('pause', function () {
|
|
1103
|
+
return _this6._onPause();
|
|
1104
|
+
}).on('timeupdate', function () {
|
|
1105
|
+
return _this6._onTimeUpdate();
|
|
1106
|
+
}).on('stalled', function () {
|
|
1107
|
+
return _this6._onStalled();
|
|
1108
|
+
}).on('playing', function () {
|
|
1109
|
+
return _this6._onPlaying();
|
|
1110
|
+
}).on('end', function () {
|
|
1111
|
+
return _this6._onEnd();
|
|
1112
|
+
}).on('error', function () {
|
|
1113
|
+
return _this6._onError();
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1128
1116
|
|
|
1129
|
-
this.
|
|
1130
|
-
|
|
1117
|
+
if (this.player) {
|
|
1118
|
+
error = !this.player.init();
|
|
1119
|
+
} else {
|
|
1120
|
+
error = true;
|
|
1121
|
+
}
|
|
1122
|
+
} else {
|
|
1123
|
+
error = true;
|
|
1124
|
+
}
|
|
1131
1125
|
|
|
1132
|
-
|
|
1133
|
-
* Resets the internals attributes
|
|
1134
|
-
* @private
|
|
1135
|
-
*/
|
|
1136
|
-
_reset() {
|
|
1137
|
-
this.config.is = {};
|
|
1126
|
+
this._setState('error', error);
|
|
1138
1127
|
|
|
1139
|
-
|
|
1128
|
+
this._setState('nogui', !support.canControl());
|
|
1140
1129
|
|
|
1141
|
-
|
|
1142
|
-
this.$container = null;
|
|
1143
|
-
this.$player = null;
|
|
1144
|
-
this.$controls = null;
|
|
1145
|
-
this.$seek = null;
|
|
1146
|
-
this.$seekSlider = null;
|
|
1147
|
-
this.$sound = null;
|
|
1148
|
-
this.$volume = null;
|
|
1149
|
-
this.$volumeControl = null;
|
|
1150
|
-
this.$volumeSlider = null;
|
|
1151
|
-
this.$position = null;
|
|
1152
|
-
this.$duration = null;
|
|
1153
|
-
this.player = null;
|
|
1154
|
-
this.duration = 0;
|
|
1155
|
-
this.position = 0;
|
|
1156
|
-
this.timesPlayed = 0;
|
|
1157
|
-
this.volume = this.config.volume;
|
|
1158
|
-
this.autoStart = this.config.autoStart;
|
|
1159
|
-
this.autoStartAt = this.config.autoStartAt;
|
|
1160
|
-
this.startMuted = this.config.startMuted;
|
|
1161
|
-
},
|
|
1130
|
+
this._setState('preview', this.config.preview);
|
|
1162
1131
|
|
|
1163
|
-
|
|
1164
|
-
* Builds the DOM content
|
|
1165
|
-
* @private
|
|
1166
|
-
*/
|
|
1167
|
-
_buildDom() {
|
|
1168
|
-
const configForTemplate = _.clone(this.config);
|
|
1169
|
-
|
|
1170
|
-
configForTemplate.type = this.type;
|
|
1171
|
-
this.$component = $$1(playerTpl(configForTemplate));
|
|
1172
|
-
this.$player = this.$component.find('.player');
|
|
1173
|
-
this.$controls = this.$component.find('.controls');
|
|
1174
|
-
this.$seek = this.$controls.find('.seek .slider');
|
|
1175
|
-
this.$sound = this.$controls.find('.sound');
|
|
1176
|
-
this.$volumeControl = this.$controls.find('.volume');
|
|
1177
|
-
this.$volume = this.$controls.find('.volume .slider');
|
|
1178
|
-
this.$position = this.$controls.find('[data-control="time-cur"]');
|
|
1179
|
-
this.$duration = this.$controls.find('[data-control="time-end"]');
|
|
1180
|
-
this.$volumeSlider = this._renderSlider(this.$volume, this.volume, volumeMin, volumeMax, true);
|
|
1181
|
-
},
|
|
1132
|
+
this._setState('loading', !error);
|
|
1182
1133
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
* @param {jQuery} $elt - The element on which renders the slider
|
|
1186
|
-
* @param {Number} [value] - The current value of the slider
|
|
1187
|
-
* @param {Number} [min] - The min value of the slider
|
|
1188
|
-
* @param {Number} [max] - The max value of the slider
|
|
1189
|
-
* @param {Boolean} [vertical] - Tells if the slider must be vertical
|
|
1190
|
-
* @returns {jQuery} - Returns the element
|
|
1191
|
-
* @private
|
|
1192
|
-
*/
|
|
1193
|
-
_renderSlider($elt, value, min, max, vertical) {
|
|
1194
|
-
let orientation, direction;
|
|
1134
|
+
if (error) {
|
|
1135
|
+
this._setState('ready', true);
|
|
1195
1136
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
} else {
|
|
1200
|
-
orientation = 'horizontal';
|
|
1201
|
-
direction = 'ltr';
|
|
1202
|
-
}
|
|
1137
|
+
this.trigger('ready');
|
|
1138
|
+
}
|
|
1139
|
+
},
|
|
1203
1140
|
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1141
|
+
/**
|
|
1142
|
+
* Initializes the player state
|
|
1143
|
+
* @private
|
|
1144
|
+
*/
|
|
1145
|
+
_initState: function _initState() {
|
|
1146
|
+
var isCORS = false;
|
|
1147
|
+
var page;
|
|
1148
|
+
|
|
1149
|
+
if (!this.is('youtube')) {
|
|
1150
|
+
page = new UrlParser(window.location);
|
|
1151
|
+
isCORS = _.some(this.config.sources, function (source) {
|
|
1152
|
+
return !page.sameDomain(source.src);
|
|
1215
1153
|
});
|
|
1216
|
-
}
|
|
1154
|
+
}
|
|
1217
1155
|
|
|
1218
|
-
|
|
1219
|
-
* Destroys a slider bound to an element
|
|
1220
|
-
* @param {jQuery} $elt
|
|
1221
|
-
* @private
|
|
1222
|
-
*/
|
|
1223
|
-
_destroySlider($elt) {
|
|
1224
|
-
if ($elt) {
|
|
1225
|
-
$elt.get(0).destroy();
|
|
1226
|
-
}
|
|
1227
|
-
},
|
|
1156
|
+
this._setState('cors', isCORS);
|
|
1228
1157
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
* @private
|
|
1232
|
-
*/
|
|
1233
|
-
_bindEvents() {
|
|
1234
|
-
let overing = false;
|
|
1235
|
-
this.$component.on(`contextmenu${ns}`, event => event.preventDefault());
|
|
1236
|
-
this.$controls.on(`click${ns}`, '.action', event => {
|
|
1237
|
-
const $target = $$1(event.target);
|
|
1238
|
-
const $action = $target.closest('.action');
|
|
1239
|
-
const id = $action.data('control');
|
|
1240
|
-
|
|
1241
|
-
if (_.isFunction(this[id])) {
|
|
1242
|
-
this[id]();
|
|
1243
|
-
}
|
|
1244
|
-
});
|
|
1245
|
-
this.$player.on(`click${ns}`, event => {
|
|
1246
|
-
const $target = $$1(event.target);
|
|
1247
|
-
const $action = $target.closest('.action'); // if action was clicked
|
|
1158
|
+
this._setState('ready', false);
|
|
1159
|
+
},
|
|
1248
1160
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1161
|
+
/**
|
|
1162
|
+
* Resets the internals attributes
|
|
1163
|
+
* @private
|
|
1164
|
+
*/
|
|
1165
|
+
_reset: function _reset() {
|
|
1166
|
+
this.config.is = {};
|
|
1167
|
+
|
|
1168
|
+
this._initType();
|
|
1169
|
+
|
|
1170
|
+
this.$component = null;
|
|
1171
|
+
this.$container = null;
|
|
1172
|
+
this.$player = null;
|
|
1173
|
+
this.$controls = null;
|
|
1174
|
+
this.$seek = null;
|
|
1175
|
+
this.$seekSlider = null;
|
|
1176
|
+
this.$sound = null;
|
|
1177
|
+
this.$volume = null;
|
|
1178
|
+
this.$volumeControl = null;
|
|
1179
|
+
this.$volumeSlider = null;
|
|
1180
|
+
this.$position = null;
|
|
1181
|
+
this.$duration = null;
|
|
1182
|
+
this.player = null;
|
|
1183
|
+
this.duration = 0;
|
|
1184
|
+
this.position = 0;
|
|
1185
|
+
this.timesPlayed = 0;
|
|
1186
|
+
this.volume = this.config.volume;
|
|
1187
|
+
this.autoStart = this.config.autoStart;
|
|
1188
|
+
this.autoStartAt = this.config.autoStartAt;
|
|
1189
|
+
this.startMuted = this.config.startMuted;
|
|
1190
|
+
},
|
|
1251
1191
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
this.unmute();
|
|
1272
|
-
$$1(document).trigger(`updateVolume${ns}`, value);
|
|
1273
|
-
this.setVolume(value, true);
|
|
1274
|
-
});
|
|
1275
|
-
this.$sound.on(`mouseover${ns}`, 'a', () => {
|
|
1276
|
-
let position;
|
|
1277
|
-
|
|
1278
|
-
if (!overing && !this.$volumeControl.hasClass('up') && !this.$volumeControl.hasClass('down')) {
|
|
1279
|
-
overing = true;
|
|
1280
|
-
position = this.$controls[0].getBoundingClientRect();
|
|
1281
|
-
|
|
1282
|
-
if (position && position.top && position.top < volumePositionThreshold) {
|
|
1283
|
-
this.$volumeControl.addClass('down');
|
|
1284
|
-
} else {
|
|
1285
|
-
this.$volumeControl.addClass('up');
|
|
1286
|
-
} //close the volume control after 15s
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
this.overingTimer = _.delay(() => {
|
|
1290
|
-
if (this.$volumeControl) {
|
|
1291
|
-
this.$volumeControl.removeClass('up down');
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
|
-
overing = false;
|
|
1295
|
-
}, 15000);
|
|
1296
|
-
this.$volumeControl.one(`mouseleave${ns}`, () => {
|
|
1297
|
-
this.$volumeControl.removeClass('up down');
|
|
1298
|
-
overing = false;
|
|
1299
|
-
});
|
|
1300
|
-
}
|
|
1301
|
-
});
|
|
1302
|
-
},
|
|
1192
|
+
/**
|
|
1193
|
+
* Builds the DOM content
|
|
1194
|
+
* @private
|
|
1195
|
+
*/
|
|
1196
|
+
_buildDom: function _buildDom() {
|
|
1197
|
+
var configForTemplate = _.clone(this.config);
|
|
1198
|
+
|
|
1199
|
+
configForTemplate.type = this.type;
|
|
1200
|
+
this.$component = $$1(playerTpl(configForTemplate));
|
|
1201
|
+
this.$player = this.$component.find('.player');
|
|
1202
|
+
this.$controls = this.$component.find('.controls');
|
|
1203
|
+
this.$seek = this.$controls.find('.seek .slider');
|
|
1204
|
+
this.$sound = this.$controls.find('.sound');
|
|
1205
|
+
this.$volumeControl = this.$controls.find('.volume');
|
|
1206
|
+
this.$volume = this.$controls.find('.volume .slider');
|
|
1207
|
+
this.$position = this.$controls.find('[data-control="time-cur"]');
|
|
1208
|
+
this.$duration = this.$controls.find('[data-control="time-end"]');
|
|
1209
|
+
this.$volumeSlider = this._renderSlider(this.$volume, this.volume, volumeMin, volumeMax, true);
|
|
1210
|
+
},
|
|
1303
1211
|
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
if (this.overingTimer) {
|
|
1317
|
-
clearTimeout(this.overingTimer);
|
|
1318
|
-
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Renders a slider onto an element
|
|
1214
|
+
* @param {jQuery} $elt - The element on which renders the slider
|
|
1215
|
+
* @param {Number} [value] - The current value of the slider
|
|
1216
|
+
* @param {Number} [min] - The min value of the slider
|
|
1217
|
+
* @param {Number} [max] - The max value of the slider
|
|
1218
|
+
* @param {Boolean} [vertical] - Tells if the slider must be vertical
|
|
1219
|
+
* @returns {jQuery} - Returns the element
|
|
1220
|
+
* @private
|
|
1221
|
+
*/
|
|
1222
|
+
_renderSlider: function _renderSlider($elt, value, min, max, vertical) {
|
|
1223
|
+
var orientation, direction;
|
|
1319
1224
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1225
|
+
if (vertical) {
|
|
1226
|
+
orientation = 'vertical';
|
|
1227
|
+
direction = 'rtl';
|
|
1228
|
+
} else {
|
|
1229
|
+
orientation = 'horizontal';
|
|
1230
|
+
direction = 'ltr';
|
|
1231
|
+
}
|
|
1322
1232
|
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1233
|
+
return $elt.noUiSlider({
|
|
1234
|
+
start: ensureNumber(value) || 0,
|
|
1235
|
+
step: 1,
|
|
1236
|
+
connect: 'lower',
|
|
1237
|
+
orientation: orientation,
|
|
1238
|
+
direction: direction,
|
|
1239
|
+
animate: true,
|
|
1240
|
+
range: {
|
|
1241
|
+
min: ensureNumber(min) || 0,
|
|
1242
|
+
max: ensureNumber(max) || 0
|
|
1331
1243
|
}
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
/**
|
|
1335
|
-
* Updates the displayed volume
|
|
1336
|
-
* @param {Number} value
|
|
1337
|
-
* @param {*} [internal]
|
|
1338
|
-
* @private
|
|
1339
|
-
*/
|
|
1340
|
-
_updateVolume(value, internal) {
|
|
1341
|
-
this.volume = Math.max(volumeMin, Math.min(volumeMax, parseFloat(value)));
|
|
1244
|
+
});
|
|
1245
|
+
},
|
|
1342
1246
|
|
|
1343
|
-
|
|
1247
|
+
/**
|
|
1248
|
+
* Destroys a slider bound to an element
|
|
1249
|
+
* @param {jQuery} $elt
|
|
1250
|
+
* @private
|
|
1251
|
+
*/
|
|
1252
|
+
_destroySlider: function _destroySlider($elt) {
|
|
1253
|
+
if ($elt) {
|
|
1254
|
+
$elt.get(0).destroy();
|
|
1255
|
+
}
|
|
1256
|
+
},
|
|
1344
1257
|
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1258
|
+
/**
|
|
1259
|
+
* Binds events onto the rendered player
|
|
1260
|
+
* @private
|
|
1261
|
+
*/
|
|
1262
|
+
_bindEvents: function _bindEvents() {
|
|
1263
|
+
var _this7 = this;
|
|
1349
1264
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
}
|
|
1359
|
-
},
|
|
1265
|
+
var overing = false;
|
|
1266
|
+
this.$component.on("contextmenu".concat(ns), function (event) {
|
|
1267
|
+
return event.preventDefault();
|
|
1268
|
+
});
|
|
1269
|
+
this.$controls.on("click".concat(ns), '.action', function (event) {
|
|
1270
|
+
var $target = $$1(event.target);
|
|
1271
|
+
var $action = $target.closest('.action');
|
|
1272
|
+
var id = $action.data('control');
|
|
1360
1273
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
* @param {Number} value
|
|
1364
|
-
* @private
|
|
1365
|
-
*/
|
|
1366
|
-
_updatePositionLabel(value) {
|
|
1367
|
-
if (this.$position) {
|
|
1368
|
-
this.$position.text(timerFormat(value));
|
|
1274
|
+
if (_.isFunction(_this7[id])) {
|
|
1275
|
+
_this7[id]();
|
|
1369
1276
|
}
|
|
1370
|
-
}
|
|
1277
|
+
});
|
|
1278
|
+
this.$player.on("click".concat(ns), function (event) {
|
|
1279
|
+
var $target = $$1(event.target);
|
|
1280
|
+
var $action = $target.closest('.action'); // if action was clicked
|
|
1371
1281
|
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
* @param {Number} value
|
|
1375
|
-
* @param {*} [internal]
|
|
1376
|
-
* @private
|
|
1377
|
-
*/
|
|
1378
|
-
_updatePosition(value, internal) {
|
|
1379
|
-
this.position = Math.max(0, Math.min(this.duration || +Infinity, parseFloat(value)));
|
|
1282
|
+
if ($action.length) {
|
|
1283
|
+
var id = $action.data('control');
|
|
1380
1284
|
|
|
1381
|
-
|
|
1382
|
-
|
|
1285
|
+
if (_.isFunction(_this7[id])) {
|
|
1286
|
+
_this7[id]();
|
|
1287
|
+
}
|
|
1288
|
+
} else {
|
|
1289
|
+
// default action is toggle play
|
|
1290
|
+
if (_this7.is('playing')) {
|
|
1291
|
+
_this7.pause();
|
|
1292
|
+
} else {
|
|
1293
|
+
_this7.play();
|
|
1294
|
+
}
|
|
1383
1295
|
}
|
|
1296
|
+
});
|
|
1297
|
+
this.$seek.on("change".concat(ns), function (event, value) {
|
|
1298
|
+
_this7.seek(value, true);
|
|
1299
|
+
});
|
|
1300
|
+
$$1(document).on("updateVolume".concat(ns), function (event, value) {
|
|
1301
|
+
_this7.setVolume(value);
|
|
1302
|
+
});
|
|
1303
|
+
this.$volume.on("change".concat(ns), function (event, value) {
|
|
1304
|
+
_this7.unmute();
|
|
1384
1305
|
|
|
1385
|
-
|
|
1386
|
-
},
|
|
1306
|
+
$$1(document).trigger("updateVolume".concat(ns), value);
|
|
1387
1307
|
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
*/
|
|
1393
|
-
_updateDurationSlider(value) {
|
|
1394
|
-
if (this.$seekSlider) {
|
|
1395
|
-
this._destroySlider(this.$seekSlider);
|
|
1396
|
-
|
|
1397
|
-
this.$seekSlider = null;
|
|
1398
|
-
}
|
|
1308
|
+
_this7.setVolume(value, true);
|
|
1309
|
+
});
|
|
1310
|
+
this.$sound.on("mouseover".concat(ns), 'a', function () {
|
|
1311
|
+
var position;
|
|
1399
1312
|
|
|
1400
|
-
if (
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1404
|
-
},
|
|
1313
|
+
if (!overing && !_this7.$volumeControl.hasClass('up') && !_this7.$volumeControl.hasClass('down')) {
|
|
1314
|
+
overing = true;
|
|
1315
|
+
position = _this7.$controls[0].getBoundingClientRect();
|
|
1405
1316
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
* @param {Number} value
|
|
1409
|
-
* @private
|
|
1410
|
-
*/
|
|
1411
|
-
_updateDurationLabel(value) {
|
|
1412
|
-
if (this.$duration) {
|
|
1413
|
-
if (value && isFinite(value)) {
|
|
1414
|
-
this.$duration.text(timerFormat(value)).show();
|
|
1317
|
+
if (position && position.top && position.top < volumePositionThreshold) {
|
|
1318
|
+
_this7.$volumeControl.addClass('down');
|
|
1415
1319
|
} else {
|
|
1416
|
-
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
},
|
|
1320
|
+
_this7.$volumeControl.addClass('up');
|
|
1321
|
+
} //close the volume control after 15s
|
|
1420
1322
|
|
|
1421
|
-
/**
|
|
1422
|
-
* Updates the displayed duration
|
|
1423
|
-
* @param {Number|String} value
|
|
1424
|
-
* @private
|
|
1425
|
-
*/
|
|
1426
|
-
_updateDuration(value) {
|
|
1427
|
-
const duration = Math.abs(parseFloat(value));
|
|
1428
1323
|
|
|
1429
|
-
|
|
1430
|
-
|
|
1324
|
+
_this7.overingTimer = _.delay(function () {
|
|
1325
|
+
if (_this7.$volumeControl) {
|
|
1326
|
+
_this7.$volumeControl.removeClass('up down');
|
|
1327
|
+
}
|
|
1431
1328
|
|
|
1432
|
-
|
|
1329
|
+
overing = false;
|
|
1330
|
+
}, 15000);
|
|
1433
1331
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
},
|
|
1332
|
+
_this7.$volumeControl.one("mouseleave".concat(ns), function () {
|
|
1333
|
+
_this7.$volumeControl.removeClass('up down');
|
|
1437
1334
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
* @private
|
|
1441
|
-
*/
|
|
1442
|
-
_onReady() {
|
|
1443
|
-
if (this.is('error')) {
|
|
1444
|
-
this._setState('error', false);
|
|
1335
|
+
overing = false;
|
|
1336
|
+
});
|
|
1445
1337
|
}
|
|
1338
|
+
});
|
|
1339
|
+
},
|
|
1446
1340
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1341
|
+
/**
|
|
1342
|
+
* Unbinds events from the rendered player
|
|
1343
|
+
* @private
|
|
1344
|
+
*/
|
|
1345
|
+
_unbindEvents: function _unbindEvents() {
|
|
1346
|
+
this.$component.off(ns);
|
|
1347
|
+
this.$player.off(ns);
|
|
1348
|
+
this.$controls.off(ns);
|
|
1349
|
+
this.$seek.off(ns);
|
|
1350
|
+
this.$volume.off(ns); //if the volume is opened and the player destroyed,
|
|
1351
|
+
//prevent the callback to run
|
|
1352
|
+
|
|
1353
|
+
if (this.overingTimer) {
|
|
1354
|
+
clearTimeout(this.overingTimer);
|
|
1355
|
+
}
|
|
1449
1356
|
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
}
|
|
1357
|
+
$$1(document).off(ns);
|
|
1358
|
+
},
|
|
1453
1359
|
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1360
|
+
/**
|
|
1361
|
+
* Updates the volume slider
|
|
1362
|
+
* @param {Number} value
|
|
1363
|
+
* @private
|
|
1364
|
+
*/
|
|
1365
|
+
_updateVolumeSlider: function _updateVolumeSlider(value) {
|
|
1366
|
+
if (this.$volumeSlider) {
|
|
1367
|
+
this.$volumeSlider.val(value);
|
|
1368
|
+
}
|
|
1369
|
+
},
|
|
1459
1370
|
|
|
1460
|
-
|
|
1371
|
+
/**
|
|
1372
|
+
* Updates the displayed volume
|
|
1373
|
+
* @param {Number} value
|
|
1374
|
+
* @param {*} [internal]
|
|
1375
|
+
* @private
|
|
1376
|
+
*/
|
|
1377
|
+
_updateVolume: function _updateVolume(value, internal) {
|
|
1378
|
+
this.volume = Math.max(volumeMin, Math.min(volumeMax, parseFloat(value)));
|
|
1461
1379
|
|
|
1462
|
-
|
|
1463
|
-
this.mute(!!this.startMuted);
|
|
1380
|
+
this._storeVolume(this.volume);
|
|
1464
1381
|
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
}
|
|
1382
|
+
if (!internal) {
|
|
1383
|
+
this._updateVolumeSlider(value);
|
|
1384
|
+
}
|
|
1385
|
+
},
|
|
1470
1386
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1387
|
+
/**
|
|
1388
|
+
* Updates the time slider
|
|
1389
|
+
* @param {Number} value
|
|
1390
|
+
* @private
|
|
1391
|
+
*/
|
|
1392
|
+
_updatePositionSlider: function _updatePositionSlider(value) {
|
|
1393
|
+
if (this.$seekSlider) {
|
|
1394
|
+
this.$seekSlider.val(value);
|
|
1395
|
+
}
|
|
1396
|
+
},
|
|
1475
1397
|
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
const videoWidth = $video.width() / scale;
|
|
1487
|
-
|
|
1488
|
-
if (videoWidth > playerWidth) {
|
|
1489
|
-
this.execute('setSize', '100%', 'auto');
|
|
1490
|
-
} else {
|
|
1491
|
-
this.$component.css({
|
|
1492
|
-
maxHeight: `${this.config.height + controlsHeight}px`
|
|
1493
|
-
});
|
|
1494
|
-
this.execute('setSize', Math.floor(videoWidth), 'auto');
|
|
1495
|
-
}
|
|
1496
|
-
},
|
|
1398
|
+
/**
|
|
1399
|
+
* Updates the time label
|
|
1400
|
+
* @param {Number} value
|
|
1401
|
+
* @private
|
|
1402
|
+
*/
|
|
1403
|
+
_updatePositionLabel: function _updatePositionLabel(value) {
|
|
1404
|
+
if (this.$position) {
|
|
1405
|
+
this.$position.text(timerFormat(value));
|
|
1406
|
+
}
|
|
1407
|
+
},
|
|
1497
1408
|
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
},
|
|
1409
|
+
/**
|
|
1410
|
+
* Updates the displayed time position
|
|
1411
|
+
* @param {Number} value
|
|
1412
|
+
* @param {*} [internal]
|
|
1413
|
+
* @private
|
|
1414
|
+
*/
|
|
1415
|
+
_updatePosition: function _updatePosition(value, internal) {
|
|
1416
|
+
this.position = Math.max(0, Math.min(this.duration || +Infinity, parseFloat(value)));
|
|
1507
1417
|
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
* @private
|
|
1512
|
-
*/
|
|
1513
|
-
_updateVolumeFromStore() {
|
|
1514
|
-
return store('mediaVolume').then(volumeStore => volumeStore.getItem('volume')).then(volume => {
|
|
1515
|
-
if (_.isNumber(volume)) {
|
|
1516
|
-
this.volume = Math.max(volumeMin, Math.min(volumeMax, parseFloat(volume)));
|
|
1517
|
-
this.setVolume(this.volume);
|
|
1518
|
-
}
|
|
1519
|
-
});
|
|
1520
|
-
},
|
|
1418
|
+
if (!internal && this.duration) {
|
|
1419
|
+
this._updatePositionSlider(this.position);
|
|
1420
|
+
}
|
|
1521
1421
|
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
* @private
|
|
1525
|
-
*/
|
|
1526
|
-
_onError() {
|
|
1527
|
-
this._setState('error', true);
|
|
1422
|
+
this._updatePositionLabel(this.position);
|
|
1423
|
+
},
|
|
1528
1424
|
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1425
|
+
/**
|
|
1426
|
+
* Updates the duration slider
|
|
1427
|
+
* @param {Number} value
|
|
1428
|
+
* @private
|
|
1429
|
+
*/
|
|
1430
|
+
_updateDurationSlider: function _updateDurationSlider(value) {
|
|
1431
|
+
if (this.$seekSlider) {
|
|
1432
|
+
this._destroySlider(this.$seekSlider);
|
|
1534
1433
|
|
|
1434
|
+
this.$seekSlider = null;
|
|
1435
|
+
}
|
|
1535
1436
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1437
|
+
if (value && isFinite(value)) {
|
|
1438
|
+
this.$seekSlider = this._renderSlider(this.$seek, 0, 0, value);
|
|
1439
|
+
this.$seekSlider.attr('disabled', !this.config.canSeek);
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1538
1442
|
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1443
|
+
/**
|
|
1444
|
+
* Updates the duration label
|
|
1445
|
+
* @param {Number} value
|
|
1446
|
+
* @private
|
|
1447
|
+
*/
|
|
1448
|
+
_updateDurationLabel: function _updateDurationLabel(value) {
|
|
1449
|
+
if (this.$duration) {
|
|
1450
|
+
if (value && isFinite(value)) {
|
|
1451
|
+
this.$duration.text(timerFormat(value)).show();
|
|
1452
|
+
} else {
|
|
1453
|
+
this.$duration.hide();
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
},
|
|
1545
1457
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1458
|
+
/**
|
|
1459
|
+
* Updates the displayed duration
|
|
1460
|
+
* @param {Number|String} value
|
|
1461
|
+
* @private
|
|
1462
|
+
*/
|
|
1463
|
+
_updateDuration: function _updateDuration(value) {
|
|
1464
|
+
var duration = Math.abs(parseFloat(value));
|
|
1551
1465
|
|
|
1466
|
+
if (duration !== this.duration) {
|
|
1467
|
+
this.duration = duration;
|
|
1552
1468
|
|
|
1553
|
-
this.
|
|
1554
|
-
},
|
|
1469
|
+
this._updateDurationSlider(this.duration);
|
|
1555
1470
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
*/
|
|
1560
|
-
_onPause() {
|
|
1561
|
-
this._playingState(false);
|
|
1562
|
-
/**
|
|
1563
|
-
* Triggers a media paused event
|
|
1564
|
-
* @event mediaplayer#pause
|
|
1565
|
-
*/
|
|
1471
|
+
this._updateDurationLabel(this.duration);
|
|
1472
|
+
}
|
|
1473
|
+
},
|
|
1566
1474
|
|
|
1475
|
+
/**
|
|
1476
|
+
* Event called when the media is ready
|
|
1477
|
+
* @private
|
|
1478
|
+
*/
|
|
1479
|
+
_onReady: function _onReady() {
|
|
1480
|
+
if (this.is('error')) {
|
|
1481
|
+
this._setState('error', false);
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
var duration = this.player.getDuration();
|
|
1485
|
+
var timePreview = this.config.preview || duration;
|
|
1567
1486
|
|
|
1568
|
-
|
|
1569
|
-
|
|
1487
|
+
if (timePreview) {
|
|
1488
|
+
this._updateDuration(duration);
|
|
1489
|
+
}
|
|
1570
1490
|
|
|
1491
|
+
this.setInitialStates();
|
|
1571
1492
|
/**
|
|
1572
|
-
*
|
|
1573
|
-
* @
|
|
1493
|
+
* Triggers a media ready event
|
|
1494
|
+
* @event mediaplayer#ready
|
|
1574
1495
|
*/
|
|
1575
|
-
_onEnd() {
|
|
1576
|
-
this.timesPlayed++;
|
|
1577
1496
|
|
|
1578
|
-
|
|
1497
|
+
this.trigger('ready'); // set the initial state
|
|
1579
1498
|
|
|
1580
|
-
|
|
1499
|
+
this.setVolume(this.volume);
|
|
1500
|
+
this.mute(!!this.startMuted);
|
|
1581
1501
|
|
|
1502
|
+
if (this.autoStartAt) {
|
|
1503
|
+
this.seek(this.autoStartAt);
|
|
1504
|
+
} else if (this.autoStart) {
|
|
1505
|
+
this.play();
|
|
1506
|
+
}
|
|
1582
1507
|
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1508
|
+
if (this.config.preview && this.$container && this.config.height && this.config.height !== 'auto') {
|
|
1509
|
+
this._setMaxHeight();
|
|
1510
|
+
}
|
|
1511
|
+
},
|
|
1512
|
+
|
|
1513
|
+
/**
|
|
1514
|
+
* Set max height limit for container
|
|
1515
|
+
* using by old media items with defined height.
|
|
1516
|
+
* @private
|
|
1517
|
+
*/
|
|
1518
|
+
_setMaxHeight: function _setMaxHeight() {
|
|
1519
|
+
var $video = this.$container.find('video.video');
|
|
1520
|
+
var controlsHeight = parseInt(window.getComputedStyle(this.$controls[0]).height);
|
|
1521
|
+
var scale = $video.height() / this.config.height;
|
|
1522
|
+
var playerWidth = this.$container.find('.player').width();
|
|
1523
|
+
var videoWidth = $video.width() / scale;
|
|
1524
|
+
|
|
1525
|
+
if (videoWidth > playerWidth) {
|
|
1526
|
+
this.execute('setSize', '100%', 'auto');
|
|
1527
|
+
} else {
|
|
1528
|
+
this.$component.css({
|
|
1529
|
+
maxHeight: "".concat(this.config.height + controlsHeight, "px")
|
|
1530
|
+
});
|
|
1531
|
+
this.execute('setSize', Math.floor(videoWidth), 'auto');
|
|
1532
|
+
}
|
|
1533
|
+
},
|
|
1534
|
+
|
|
1535
|
+
/**
|
|
1536
|
+
* Update volume in DBIndex store
|
|
1537
|
+
* @param {Number} volume
|
|
1538
|
+
* @returns {Promise}
|
|
1539
|
+
* @private
|
|
1540
|
+
*/
|
|
1541
|
+
_storeVolume: function _storeVolume(volume) {
|
|
1542
|
+
return store('mediaVolume').then(function (volumeStore) {
|
|
1543
|
+
return volumeStore.setItem('volume', volume);
|
|
1544
|
+
});
|
|
1545
|
+
},
|
|
1591
1546
|
|
|
1547
|
+
/**
|
|
1548
|
+
* Get volume from DBIndex store
|
|
1549
|
+
* @returns {Promise}
|
|
1550
|
+
* @private
|
|
1551
|
+
*/
|
|
1552
|
+
_updateVolumeFromStore: function _updateVolumeFromStore() {
|
|
1553
|
+
var _this8 = this;
|
|
1592
1554
|
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1555
|
+
return store('mediaVolume').then(function (volumeStore) {
|
|
1556
|
+
return volumeStore.getItem('volume');
|
|
1557
|
+
}).then(function (volume) {
|
|
1558
|
+
if (_.isNumber(volume)) {
|
|
1559
|
+
_this8.volume = Math.max(volumeMin, Math.min(volumeMax, parseFloat(volume)));
|
|
1598
1560
|
|
|
1599
|
-
|
|
1561
|
+
_this8.setVolume(_this8.volume);
|
|
1600
1562
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
* @event mediaplayer#ended
|
|
1604
|
-
*/
|
|
1605
|
-
|
|
1563
|
+
});
|
|
1564
|
+
},
|
|
1606
1565
|
|
|
1607
|
-
|
|
1608
|
-
|
|
1566
|
+
/**
|
|
1567
|
+
* Event called when the media throws unrecoverable error
|
|
1568
|
+
* @private
|
|
1569
|
+
*/
|
|
1570
|
+
_onError: function _onError() {
|
|
1571
|
+
this._setState('error', true);
|
|
1609
1572
|
|
|
1573
|
+
this._setState('loading', false);
|
|
1610
1574
|
/**
|
|
1611
|
-
*
|
|
1612
|
-
* @
|
|
1575
|
+
* Triggers an unrecoverable media error event
|
|
1576
|
+
* @event mediaplayer#error
|
|
1613
1577
|
*/
|
|
1614
|
-
_onPlaying() {
|
|
1615
|
-
this._setState('preview', true);
|
|
1616
1578
|
|
|
1617
|
-
this._setState('stalled', false);
|
|
1618
1579
|
|
|
1619
|
-
|
|
1620
|
-
|
|
1580
|
+
this.trigger('error');
|
|
1581
|
+
},
|
|
1582
|
+
|
|
1583
|
+
/**
|
|
1584
|
+
* Event called when the media is played
|
|
1585
|
+
* @private
|
|
1586
|
+
*/
|
|
1587
|
+
_onPlay: function _onPlay() {
|
|
1588
|
+
this._playingState(true);
|
|
1621
1589
|
|
|
1590
|
+
this._setState('preview', true);
|
|
1622
1591
|
/**
|
|
1623
|
-
*
|
|
1624
|
-
* @
|
|
1592
|
+
* Triggers a media playback event
|
|
1593
|
+
* @event mediaplayer#play
|
|
1625
1594
|
*/
|
|
1626
|
-
_onStalled() {
|
|
1627
|
-
this._setState('stalled', true);
|
|
1628
1595
|
|
|
1629
|
-
this._setState('ready', false);
|
|
1630
|
-
},
|
|
1631
1596
|
|
|
1597
|
+
this.trigger('play', this.player && this.player.getMedia());
|
|
1598
|
+
},
|
|
1599
|
+
|
|
1600
|
+
/**
|
|
1601
|
+
* Event called when the media is paused
|
|
1602
|
+
* @private
|
|
1603
|
+
*/
|
|
1604
|
+
_onPause: function _onPause() {
|
|
1605
|
+
this._playingState(false);
|
|
1632
1606
|
/**
|
|
1633
|
-
*
|
|
1634
|
-
* @
|
|
1607
|
+
* Triggers a media paused event
|
|
1608
|
+
* @event mediaplayer#pause
|
|
1635
1609
|
*/
|
|
1636
|
-
_onTimeUpdate() {
|
|
1637
|
-
this._updatePosition(this.player.getPosition());
|
|
1638
|
-
/**
|
|
1639
|
-
* Triggers a media time update event
|
|
1640
|
-
* @event mediaplayer#update
|
|
1641
|
-
*/
|
|
1642
1610
|
|
|
1643
1611
|
|
|
1644
|
-
|
|
1645
|
-
|
|
1612
|
+
this.trigger('pause');
|
|
1613
|
+
},
|
|
1646
1614
|
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1615
|
+
/**
|
|
1616
|
+
* Event called when the media is ended
|
|
1617
|
+
* @private
|
|
1618
|
+
*/
|
|
1619
|
+
_onEnd: function _onEnd() {
|
|
1620
|
+
this.timesPlayed++;
|
|
1621
|
+
|
|
1622
|
+
this._playingState(false, true);
|
|
1623
|
+
|
|
1624
|
+
this._updatePosition(0); // disable when the play limit is reached
|
|
1655
1625
|
|
|
1656
|
-
|
|
1626
|
+
|
|
1627
|
+
if (this._playLimitReached()) {
|
|
1628
|
+
if (!this.is('disabled')) {
|
|
1657
1629
|
this.disable();
|
|
1658
|
-
cancelAnimationFrame(this.timerId);
|
|
1659
1630
|
}
|
|
1660
|
-
|
|
1631
|
+
/**
|
|
1632
|
+
* Triggers a play limit reached event
|
|
1633
|
+
* @event mediaplayer#limitreached
|
|
1634
|
+
*/
|
|
1661
1635
|
|
|
1662
|
-
/**
|
|
1663
|
-
* Checks if the play limit has been reached
|
|
1664
|
-
* @returns {Boolean}
|
|
1665
|
-
* @private
|
|
1666
|
-
*/
|
|
1667
|
-
_playLimitReached() {
|
|
1668
|
-
return this.config.maxPlays && this.timesPlayed >= this.config.maxPlays;
|
|
1669
|
-
},
|
|
1670
1636
|
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
_canPlay() {
|
|
1677
|
-
return (this.is('ready') || this.is('stalled')) && !this.is('disabled') && !this.is('hidden') && !this._playLimitReached();
|
|
1678
|
-
},
|
|
1637
|
+
this.trigger('limitreached');
|
|
1638
|
+
} else if (this.loop) {
|
|
1639
|
+
this.restart();
|
|
1640
|
+
} else if (parseInt(this.config.replayTimeout, 10) > 0) {
|
|
1641
|
+
this.replayTimeoutStartMs = new window.Date().getTime();
|
|
1679
1642
|
|
|
1643
|
+
this._replayTimeout();
|
|
1644
|
+
}
|
|
1680
1645
|
/**
|
|
1681
|
-
*
|
|
1682
|
-
* @
|
|
1683
|
-
* @private
|
|
1646
|
+
* Triggers a media ended event
|
|
1647
|
+
* @event mediaplayer#ended
|
|
1684
1648
|
*/
|
|
1685
|
-
_canPause() {
|
|
1686
|
-
return !!this.config.canPause;
|
|
1687
|
-
},
|
|
1688
1649
|
|
|
1689
|
-
/**
|
|
1690
|
-
* Checks if the media can be sought
|
|
1691
|
-
* @returns {Boolean}
|
|
1692
|
-
* @private
|
|
1693
|
-
*/
|
|
1694
|
-
_canSeek() {
|
|
1695
|
-
return !!this.config.canSeek;
|
|
1696
|
-
},
|
|
1697
1650
|
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
* @returns {Boolean}
|
|
1701
|
-
* @private
|
|
1702
|
-
*/
|
|
1703
|
-
_canResume() {
|
|
1704
|
-
return this.is('paused') && this._canPlay();
|
|
1705
|
-
},
|
|
1651
|
+
this.trigger('ended');
|
|
1652
|
+
},
|
|
1706
1653
|
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
_setState(name, value) {
|
|
1714
|
-
value = !!value;
|
|
1715
|
-
this.config.is[name] = value;
|
|
1654
|
+
/**
|
|
1655
|
+
* Event called when the playback is playing
|
|
1656
|
+
* @private
|
|
1657
|
+
*/
|
|
1658
|
+
_onPlaying: function _onPlaying() {
|
|
1659
|
+
this._setState('preview', true);
|
|
1716
1660
|
|
|
1717
|
-
|
|
1718
|
-
this.$component.toggleClass(name, value);
|
|
1719
|
-
}
|
|
1661
|
+
this._setState('stalled', false);
|
|
1720
1662
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1663
|
+
this._setState('ready', true);
|
|
1664
|
+
},
|
|
1723
1665
|
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
_fromState(stateName) {
|
|
1731
|
-
this._setState(stateName, false);
|
|
1666
|
+
/**
|
|
1667
|
+
* Event called when the playback is stalled
|
|
1668
|
+
* @private
|
|
1669
|
+
*/
|
|
1670
|
+
_onStalled: function _onStalled() {
|
|
1671
|
+
this._setState('stalled', true);
|
|
1732
1672
|
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
},
|
|
1673
|
+
this._setState('ready', false);
|
|
1674
|
+
},
|
|
1736
1675
|
|
|
1676
|
+
/**
|
|
1677
|
+
* Event called when the time position has changed
|
|
1678
|
+
* @private
|
|
1679
|
+
*/
|
|
1680
|
+
_onTimeUpdate: function _onTimeUpdate() {
|
|
1681
|
+
this._updatePosition(this.player.getPosition());
|
|
1737
1682
|
/**
|
|
1738
|
-
*
|
|
1739
|
-
* @
|
|
1740
|
-
* @returns {mediaplayer}
|
|
1741
|
-
* @private
|
|
1683
|
+
* Triggers a media time update event
|
|
1684
|
+
* @event mediaplayer#update
|
|
1742
1685
|
*/
|
|
1743
|
-
_toState(stateName) {
|
|
1744
|
-
this.pause();
|
|
1745
1686
|
|
|
1746
|
-
this._setState(stateName, true);
|
|
1747
1687
|
|
|
1748
|
-
|
|
1749
|
-
|
|
1688
|
+
this.trigger('update');
|
|
1689
|
+
},
|
|
1750
1690
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1691
|
+
/**
|
|
1692
|
+
* Run a timer to disable the possibility of replaying a media
|
|
1693
|
+
* @private
|
|
1694
|
+
*/
|
|
1695
|
+
_replayTimeout: function _replayTimeout() {
|
|
1696
|
+
var nowMs = new window.Date().getTime(),
|
|
1697
|
+
elapsedSeconds = Math.floor((nowMs - this.replayTimeoutStartMs) / 1000);
|
|
1698
|
+
this.timerId = requestAnimationFrame(this._replayTimeout.bind(this));
|
|
1699
|
+
|
|
1700
|
+
if (elapsedSeconds >= parseInt(this.config.replayTimeout, 10)) {
|
|
1701
|
+
this.disable();
|
|
1702
|
+
cancelAnimationFrame(this.timerId);
|
|
1703
|
+
}
|
|
1704
|
+
},
|
|
1760
1705
|
|
|
1761
|
-
|
|
1706
|
+
/**
|
|
1707
|
+
* Checks if the play limit has been reached
|
|
1708
|
+
* @returns {Boolean}
|
|
1709
|
+
* @private
|
|
1710
|
+
*/
|
|
1711
|
+
_playLimitReached: function _playLimitReached() {
|
|
1712
|
+
return this.config.maxPlays && this.timesPlayed >= this.config.maxPlays;
|
|
1713
|
+
},
|
|
1762
1714
|
|
|
1763
|
-
|
|
1715
|
+
/**
|
|
1716
|
+
* Checks if the media can be played
|
|
1717
|
+
* @returns {Boolean}
|
|
1718
|
+
* @private
|
|
1719
|
+
*/
|
|
1720
|
+
_canPlay: function _canPlay() {
|
|
1721
|
+
return (this.is('ready') || this.is('stalled')) && !this.is('disabled') && !this.is('hidden') && !this._playLimitReached();
|
|
1722
|
+
},
|
|
1764
1723
|
|
|
1765
|
-
|
|
1766
|
-
|
|
1724
|
+
/**
|
|
1725
|
+
* Checks if the media can be paused
|
|
1726
|
+
* @returns {Boolean}
|
|
1727
|
+
* @private
|
|
1728
|
+
*/
|
|
1729
|
+
_canPause: function _canPause() {
|
|
1730
|
+
return !!this.config.canPause;
|
|
1731
|
+
},
|
|
1767
1732
|
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
if (this.player && 'function' === typeof this.player[command]) {
|
|
1777
|
-
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
1778
|
-
args[_key2 - 1] = arguments[_key2];
|
|
1779
|
-
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Checks if the media can be sought
|
|
1735
|
+
* @returns {Boolean}
|
|
1736
|
+
* @private
|
|
1737
|
+
*/
|
|
1738
|
+
_canSeek: function _canSeek() {
|
|
1739
|
+
return !!this.config.canSeek;
|
|
1740
|
+
},
|
|
1780
1741
|
|
|
1781
|
-
|
|
1782
|
-
|
|
1742
|
+
/**
|
|
1743
|
+
* Checks if the playback can be resumed
|
|
1744
|
+
* @returns {Boolean}
|
|
1745
|
+
* @private
|
|
1746
|
+
*/
|
|
1747
|
+
_canResume: function _canResume() {
|
|
1748
|
+
return this.is('paused') && this._canPlay();
|
|
1749
|
+
},
|
|
1750
|
+
|
|
1751
|
+
/**
|
|
1752
|
+
* Sets the media is in a particular state
|
|
1753
|
+
* @param {String} name
|
|
1754
|
+
* @param {Boolean} value
|
|
1755
|
+
* @returns {mediaplayer}
|
|
1756
|
+
*/
|
|
1757
|
+
_setState: function _setState(name, value) {
|
|
1758
|
+
value = !!value;
|
|
1759
|
+
this.config.is[name] = value;
|
|
1760
|
+
|
|
1761
|
+
if (this.$component) {
|
|
1762
|
+
this.$component.toggleClass(name, value);
|
|
1783
1763
|
}
|
|
1784
1764
|
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
}
|
|
1788
|
-
/**
|
|
1789
|
-
* Tells if the browser can play audio and video
|
|
1790
|
-
* @param {String} [type] The type of media (audio or video)
|
|
1791
|
-
* @param {String} [mime] A media MIME type to check
|
|
1792
|
-
* @type {Boolean}
|
|
1793
|
-
*/
|
|
1765
|
+
return this;
|
|
1766
|
+
},
|
|
1794
1767
|
|
|
1768
|
+
/**
|
|
1769
|
+
* Restores the media player from a particular state and resumes the playback
|
|
1770
|
+
* @param {String} stateName
|
|
1771
|
+
* @returns {mediaplayer}
|
|
1772
|
+
* @private
|
|
1773
|
+
*/
|
|
1774
|
+
_fromState: function _fromState(stateName) {
|
|
1775
|
+
this._setState(stateName, false);
|
|
1795
1776
|
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
/**
|
|
1800
|
-
* Tells if the browser can play audio
|
|
1801
|
-
* @param {String} [mime] A media MIME type to check
|
|
1802
|
-
* @type {Boolean}
|
|
1803
|
-
*/
|
|
1777
|
+
this.resume();
|
|
1778
|
+
return this;
|
|
1779
|
+
},
|
|
1804
1780
|
|
|
1781
|
+
/**
|
|
1782
|
+
* Sets the media player to a particular state and pauses the playback
|
|
1783
|
+
* @param {String} stateName
|
|
1784
|
+
* @returns {mediaplayer}
|
|
1785
|
+
* @private
|
|
1786
|
+
*/
|
|
1787
|
+
_toState: function _toState(stateName) {
|
|
1788
|
+
this.pause();
|
|
1805
1789
|
|
|
1806
|
-
|
|
1807
|
-
return support.canPlayAudio(mime);
|
|
1808
|
-
};
|
|
1809
|
-
/**
|
|
1810
|
-
* Tells if the browser can play video
|
|
1811
|
-
* @param {String} [mime] A media MIME type to check
|
|
1812
|
-
* @type {Boolean}
|
|
1813
|
-
*/
|
|
1790
|
+
this._setState(stateName, true);
|
|
1814
1791
|
|
|
1792
|
+
return this;
|
|
1793
|
+
},
|
|
1815
1794
|
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1795
|
+
/**
|
|
1796
|
+
* Sets the playing state
|
|
1797
|
+
* @param {Boolean} state
|
|
1798
|
+
* @param {Boolean} [ended]
|
|
1799
|
+
* @returns {mediaplayer}
|
|
1800
|
+
* @private
|
|
1801
|
+
*/
|
|
1802
|
+
_playingState: function _playingState(state, ended) {
|
|
1803
|
+
this._setState('playing', !!state);
|
|
1823
1804
|
|
|
1805
|
+
this._setState('paused', !state);
|
|
1824
1806
|
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1807
|
+
this._setState('ended', !!ended);
|
|
1808
|
+
|
|
1809
|
+
return this;
|
|
1810
|
+
},
|
|
1828
1811
|
|
|
1829
|
-
|
|
1812
|
+
/**
|
|
1813
|
+
* Executes a command onto the media
|
|
1814
|
+
* @param {String} command - The name of the command to execute
|
|
1815
|
+
* @param {*} args - additional arguments
|
|
1816
|
+
* @returns {*}
|
|
1817
|
+
* @private
|
|
1818
|
+
*/
|
|
1819
|
+
execute: function execute(command) {
|
|
1820
|
+
if (this.player && 'function' === typeof this.player[command]) {
|
|
1821
|
+
var _this$player;
|
|
1822
|
+
|
|
1823
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
1824
|
+
args[_key2 - 1] = arguments[_key2];
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
return (_this$player = this.player)[command].apply(_this$player, args);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1831
|
+
return mediaplayer.init(config);
|
|
1832
|
+
}
|
|
1833
|
+
/**
|
|
1834
|
+
* Tells if the browser can play audio and video
|
|
1835
|
+
* @param {String} [type] The type of media (audio or video)
|
|
1836
|
+
* @param {String} [mime] A media MIME type to check
|
|
1837
|
+
* @type {Boolean}
|
|
1838
|
+
*/
|
|
1839
|
+
|
|
1840
|
+
|
|
1841
|
+
mediaplayerFactory.canPlay = function canPlay(type, mime) {
|
|
1842
|
+
return support.canPlay(type, mime);
|
|
1843
|
+
};
|
|
1844
|
+
/**
|
|
1845
|
+
* Tells if the browser can play audio
|
|
1846
|
+
* @param {String} [mime] A media MIME type to check
|
|
1847
|
+
* @type {Boolean}
|
|
1848
|
+
*/
|
|
1849
|
+
|
|
1850
|
+
|
|
1851
|
+
mediaplayerFactory.canPlayAudio = function canPlayAudio(mime) {
|
|
1852
|
+
return support.canPlayAudio(mime);
|
|
1853
|
+
};
|
|
1854
|
+
/**
|
|
1855
|
+
* Tells if the browser can play video
|
|
1856
|
+
* @param {String} [mime] A media MIME type to check
|
|
1857
|
+
* @type {Boolean}
|
|
1858
|
+
*/
|
|
1859
|
+
|
|
1860
|
+
|
|
1861
|
+
mediaplayerFactory.canPlayVideo = function canPlayVideo(mime) {
|
|
1862
|
+
return support.canPlayVideo(mime);
|
|
1863
|
+
};
|
|
1864
|
+
/**
|
|
1865
|
+
* Checks if the browser allows to control the media playback
|
|
1866
|
+
* @returns {Boolean}
|
|
1867
|
+
*/
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
mediaplayerFactory.canControl = function canControl() {
|
|
1871
|
+
return support.canControl();
|
|
1872
|
+
};
|
|
1873
|
+
|
|
1874
|
+
return mediaplayerFactory;
|
|
1830
1875
|
|
|
1831
1876
|
});
|