@gcorevideo/player 2.22.3 → 2.22.5
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/assets/audio-selector/style.scss +4 -2
- package/assets/audio-selector/track-selector.ejs +2 -2
- package/assets/level-selector/button.ejs +1 -1
- package/assets/level-selector/list.ejs +10 -4
- package/assets/level-selector/style.scss +8 -3
- package/dist/core.js +1 -1
- package/dist/index.css +1435 -1429
- package/dist/index.js +402 -419
- package/dist/plugins/index.css +1192 -1186
- package/dist/plugins/index.js +428 -438
- package/lib/index.plugins.d.ts +3 -1
- package/lib/index.plugins.d.ts.map +1 -1
- package/lib/index.plugins.js +3 -1
- package/lib/plugins/audio-selector/AudioSelector.d.ts +3 -9
- package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
- package/lib/plugins/audio-selector/AudioSelector.js +34 -57
- package/lib/plugins/level-selector/LevelSelector.d.ts +6 -5
- package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
- package/lib/plugins/level-selector/LevelSelector.js +11 -8
- package/lib/plugins/level-selector/QualityLevels.d.ts +112 -0
- package/lib/plugins/level-selector/QualityLevels.d.ts.map +1 -0
- package/lib/plugins/level-selector/QualityLevels.js +280 -0
- package/lib/plugins/vast-ads/VastAds.d.ts +1 -0
- package/lib/plugins/vast-ads/VastAds.d.ts.map +1 -1
- package/lib/plugins/vast-ads/VastAds.js +6 -3
- package/lib/testUtils.d.ts +2 -0
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +2 -0
- package/package.json +1 -1
- package/src/index.plugins.ts +3 -1
- package/src/plugins/audio-selector/AudioSelector.ts +36 -72
- package/src/plugins/audio-selector/__tests__/AudioSelector.test.ts +176 -0
- package/src/plugins/audio-selector/__tests__/__snapshots__/AudioSelector.test.ts.snap +67 -0
- package/src/plugins/level-selector/{LevelSelector.ts → QualityLevels.ts} +19 -13
- package/src/plugins/level-selector/__tests__/{LevelSelector.test.ts → QualityLevels.test.ts} +20 -6
- package/src/plugins/level-selector/__tests__/__snapshots__/{LevelSelector.test.ts.snap → QualityLevels.test.ts.snap} +58 -25
- package/src/plugins/vast-ads/VastAds.ts +8 -4
- package/src/testUtils.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { Events, template, UICorePlugin } from '@clappr/core';
|
|
2
|
+
import { trace } from '@gcorevideo/utils';
|
|
3
|
+
import assert from 'assert';
|
|
4
|
+
import { CLAPPR_VERSION } from '../../build.js';
|
|
5
|
+
import { GearEvents } from '../bottom-gear/BottomGear.js';
|
|
6
|
+
import buttonHtml from '../../../assets/level-selector/button.ejs';
|
|
7
|
+
import listHtml from '../../../assets/level-selector/list.ejs';
|
|
8
|
+
import hdIcon from '../../../assets/icons/new/hd.svg';
|
|
9
|
+
import arrowRightIcon from '../../../assets/icons/new/arrow-right.svg';
|
|
10
|
+
import arrowLeftIcon from '../../../assets/icons/new/arrow-left.svg';
|
|
11
|
+
import checkIcon from '../../../assets/icons/new/check.svg';
|
|
12
|
+
import '../../../assets/level-selector/style.scss';
|
|
13
|
+
const T = 'plugins.quality_levels';
|
|
14
|
+
const VERSION = 'v2.22.5';
|
|
15
|
+
/**
|
|
16
|
+
* `PLUGIN` that provides a UI to select the desired quality level of the playback.
|
|
17
|
+
* @beta
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Depends on:
|
|
21
|
+
*
|
|
22
|
+
* - {@link MediaControl}
|
|
23
|
+
*
|
|
24
|
+
* - {@link BottomGear}
|
|
25
|
+
*
|
|
26
|
+
* The plugin is rendered as an item in the gear menu, which, when clicked, shows a list of quality levels to choose from.
|
|
27
|
+
*
|
|
28
|
+
* Configuration options - {@link QualityLevelsPluginSettings}
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* new Player({
|
|
33
|
+
* qualityLevels: {
|
|
34
|
+
* restrictResolution: 360,
|
|
35
|
+
* labels: { 360: 'SD', 720: 'HD' },
|
|
36
|
+
* },
|
|
37
|
+
* })
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export class QualityLevels extends UICorePlugin {
|
|
41
|
+
levels = [];
|
|
42
|
+
levelLabels = [];
|
|
43
|
+
removeAuto = false;
|
|
44
|
+
isHd = false;
|
|
45
|
+
currentText = '';
|
|
46
|
+
selectedLevelId = -1;
|
|
47
|
+
static buttonTemplate = template(buttonHtml);
|
|
48
|
+
static listTemplate = template(listHtml);
|
|
49
|
+
/**
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
get name() {
|
|
53
|
+
return 'level_selector';
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
get supportedVersion() {
|
|
59
|
+
return { min: CLAPPR_VERSION };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
static get version() {
|
|
65
|
+
return VERSION;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
get attributes() {
|
|
71
|
+
return {
|
|
72
|
+
class: 'level-selector',
|
|
73
|
+
'data-level-selector': '',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
get events() {
|
|
77
|
+
return {
|
|
78
|
+
'click .gear-sub-menu_btn': 'onSelect',
|
|
79
|
+
'click .go-back': 'goBack',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
bindEvents() {
|
|
86
|
+
this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
|
|
87
|
+
this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChange);
|
|
88
|
+
}
|
|
89
|
+
onCoreReady() {
|
|
90
|
+
trace(`${T} onCoreReady`);
|
|
91
|
+
const gear = this.core.getPlugin('bottom_gear');
|
|
92
|
+
assert(gear, 'bottom_gear plugin is required');
|
|
93
|
+
this.currentText = this.core.i18n.t('auto');
|
|
94
|
+
this.listenTo(gear, GearEvents.RENDERED, this.onGearRendered);
|
|
95
|
+
}
|
|
96
|
+
onGearRendered() {
|
|
97
|
+
trace(`${T} onGearRendered`);
|
|
98
|
+
this.render();
|
|
99
|
+
}
|
|
100
|
+
onActiveContainerChange() {
|
|
101
|
+
this.removeAuto = false;
|
|
102
|
+
this.isHd = false;
|
|
103
|
+
const activePlayback = this.core.activePlayback;
|
|
104
|
+
this.listenTo(activePlayback, Events.PLAYBACK_LEVELS_AVAILABLE, this.onLevelsAvailable);
|
|
105
|
+
this.listenTo(activePlayback, Events.PLAYBACK_LEVEL_SWITCH_START, this.onLevelSwitchStart);
|
|
106
|
+
this.listenTo(activePlayback, Events.PLAYBACK_LEVEL_SWITCH_END, this.onLevelSwitchEnd);
|
|
107
|
+
this.listenTo(activePlayback, Events.PLAYBACK_BITRATE, this.onBitrate);
|
|
108
|
+
this.listenTo(activePlayback, Events.PLAYBACK_STOP, this.onStop);
|
|
109
|
+
this.listenTo(activePlayback, Events.PLAYBACK_HIGHDEFINITIONUPDATE, (isHd) => {
|
|
110
|
+
this.isHd = isHd;
|
|
111
|
+
this.updateHd();
|
|
112
|
+
});
|
|
113
|
+
if (activePlayback.levels?.length > 0) {
|
|
114
|
+
this.onLevelsAvailable(activePlayback.levels);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
updateHd() {
|
|
118
|
+
if (this.isHd) {
|
|
119
|
+
this.$el.find('.gear-option_hd-icon').removeClass('hidden');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
this.$el.find('.gear-option_hd-icon').addClass('hidden');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
onStop() {
|
|
126
|
+
trace(`${T} onStop`);
|
|
127
|
+
this.listenToOnce(this.core.activePlayback, Events.PLAYBACK_PLAY, () => {
|
|
128
|
+
if (this.core.activePlayback.getPlaybackType() === 'live') {
|
|
129
|
+
if (this.selectedLevelId !== -1) {
|
|
130
|
+
this.core.activePlayback.currentLevel = this.selectedLevelId;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
shouldRender() {
|
|
136
|
+
const activePlayback = this.core.activePlayback;
|
|
137
|
+
if (!activePlayback) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
const supportsCurrentLevel = 'currentLevel' in activePlayback;
|
|
141
|
+
if (!supportsCurrentLevel) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
// Only care if we have at least 2 to choose from
|
|
145
|
+
return !!(this.levels && this.levels.length > 1);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
render() {
|
|
151
|
+
if (!this.shouldRender()) {
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
this.renderDropdown();
|
|
155
|
+
this.updateButton();
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
renderDropdown() {
|
|
159
|
+
this.$el.html(QualityLevels.listTemplate({
|
|
160
|
+
arrowLeftIcon,
|
|
161
|
+
checkIcon,
|
|
162
|
+
current: this.selectedLevelId,
|
|
163
|
+
labels: this.levelLabels,
|
|
164
|
+
levels: this.levels,
|
|
165
|
+
maxLevel: this.maxLevel,
|
|
166
|
+
removeAuto: this.removeAuto,
|
|
167
|
+
i18n: this.core.i18n,
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
updateButton() {
|
|
171
|
+
;
|
|
172
|
+
this.core.getPlugin('bottom_gear')
|
|
173
|
+
?.addItem('quality', this.$el)
|
|
174
|
+
.html(QualityLevels.buttonTemplate({
|
|
175
|
+
arrowRightIcon,
|
|
176
|
+
currentText: this.currentText,
|
|
177
|
+
isHd: this.isHd,
|
|
178
|
+
hdIcon,
|
|
179
|
+
i18n: this.core.i18n,
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
get pluginOptions() {
|
|
183
|
+
return (this.core.options.qualityLevels || this.core.options.levelSelector || {});
|
|
184
|
+
}
|
|
185
|
+
get maxLevel() {
|
|
186
|
+
const maxRes = this.pluginOptions.restrictResolution;
|
|
187
|
+
return maxRes
|
|
188
|
+
? this.levels.find((level) => (level.height > level.width ? level.width : level.height) ===
|
|
189
|
+
maxRes)?.level ?? -1
|
|
190
|
+
: -1;
|
|
191
|
+
}
|
|
192
|
+
onLevelsAvailable(levels) {
|
|
193
|
+
const maxResolution = this.pluginOptions.restrictResolution;
|
|
194
|
+
this.levels = levels;
|
|
195
|
+
this.makeLevelsLabels();
|
|
196
|
+
if (maxResolution) {
|
|
197
|
+
this.removeAuto = true;
|
|
198
|
+
const initialLevel = levels
|
|
199
|
+
.filter((level) => (level.width > level.height ? level.height : level.width) <=
|
|
200
|
+
maxResolution)
|
|
201
|
+
.pop();
|
|
202
|
+
this.setLevel(initialLevel?.level ?? 0);
|
|
203
|
+
}
|
|
204
|
+
this.render();
|
|
205
|
+
}
|
|
206
|
+
makeLevelsLabels() {
|
|
207
|
+
const labels = this.pluginOptions.labels ?? {};
|
|
208
|
+
this.levelLabels = [];
|
|
209
|
+
for (const level of this.levels) {
|
|
210
|
+
const ll = level.width > level.height ? level.height : level.width;
|
|
211
|
+
const label = labels[ll] || `${ll}p`;
|
|
212
|
+
this.levelLabels.push(label);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
onSelect(event) {
|
|
216
|
+
const selectedLevel = parseInt(event.currentTarget?.dataset?.id ?? '-1', 10);
|
|
217
|
+
this.setLevel(selectedLevel);
|
|
218
|
+
event.stopPropagation();
|
|
219
|
+
event.preventDefault();
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
goBack() {
|
|
223
|
+
trace(`${T} goBack`);
|
|
224
|
+
this.core.getPlugin('bottom_gear').refresh();
|
|
225
|
+
}
|
|
226
|
+
setLevel(index) {
|
|
227
|
+
this.selectedLevelId = index;
|
|
228
|
+
this.core.activePlayback.currentLevel = this.selectedLevelId;
|
|
229
|
+
this.highlightCurrentLevel();
|
|
230
|
+
}
|
|
231
|
+
allLevelElements() {
|
|
232
|
+
return this.$('#level-selector-menu li');
|
|
233
|
+
}
|
|
234
|
+
levelElement(id = -1) {
|
|
235
|
+
return this.$(`#level-selector-menu a[data-id="${id}"]`).parent();
|
|
236
|
+
}
|
|
237
|
+
onLevelSwitchStart() {
|
|
238
|
+
this.levelElement(this.selectedLevelId).addClass('changing');
|
|
239
|
+
}
|
|
240
|
+
onLevelSwitchEnd() {
|
|
241
|
+
this.levelElement(this.selectedLevelId).removeClass('changing');
|
|
242
|
+
}
|
|
243
|
+
updateText(level) {
|
|
244
|
+
this.currentText = this.getLevelLabel(level);
|
|
245
|
+
this.updateButton();
|
|
246
|
+
}
|
|
247
|
+
getLevelLabel(id) {
|
|
248
|
+
if (id < 0) {
|
|
249
|
+
return this.core.i18n.t('auto');
|
|
250
|
+
}
|
|
251
|
+
const index = this.levels.findIndex((l) => l.level === id);
|
|
252
|
+
if (index < 0) {
|
|
253
|
+
return this.core.i18n.t('auto');
|
|
254
|
+
}
|
|
255
|
+
return this.levelLabels[index] ?? formatLevelLabel(this.levels[index]);
|
|
256
|
+
}
|
|
257
|
+
onBitrate(info) {
|
|
258
|
+
trace(`${T} updateCurrentLevel`, { info });
|
|
259
|
+
this.highlightCurrentLevel();
|
|
260
|
+
}
|
|
261
|
+
highlightCurrentLevel() {
|
|
262
|
+
trace(`${T} highlightCurrentLevel`, {
|
|
263
|
+
selectedLevelId: this.selectedLevelId,
|
|
264
|
+
});
|
|
265
|
+
this.allLevelElements()
|
|
266
|
+
.removeClass('current')
|
|
267
|
+
.find('a')
|
|
268
|
+
.removeClass('gcore-skin-active');
|
|
269
|
+
const currentLevelElement = this.levelElement(this.selectedLevelId);
|
|
270
|
+
currentLevelElement
|
|
271
|
+
.addClass('current')
|
|
272
|
+
.find('a')
|
|
273
|
+
.addClass('gcore-skin-active');
|
|
274
|
+
this.updateText(this.selectedLevelId);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function formatLevelLabel(level) {
|
|
278
|
+
const h = level.width > level.height ? level.height : level.width;
|
|
279
|
+
return `${h}p`;
|
|
280
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VastAds.d.ts","sourceRoot":"","sources":["../../../src/plugins/vast-ads/VastAds.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,IAAI,EAIJ,QAAQ,EAER,YAAY,EAEb,MAAM,cAAc,CAAA;AAarB,OAAO,qCAAqC,CAAA;AAQ5C,qBAAa,OAAQ,SAAQ,YAAY;IACvC,OAAO,CAAC,mBAAmB,CAAiC;IAE5D,OAAO,CAAC,qBAAqB,CAAwC;IAErE,OAAO,CAAC,oBAAoB,CAAwC;IAEpE,OAAO,CAAC,eAAe,CAAI;IAE3B,OAAO,CAAC,mBAAmB,CAAI;IAE/B,OAAO,CAAC,UAAU,CAAyB;IAE3C,OAAO,CAAC,SAAS,CAAyB;IAE1C,OAAO,CAAC,eAAe,CAA2B;IAElD,OAAO,CAAC,gBAAgB,CAAI;IAE5B,OAAO,CAAC,YAAY,CAAY;IAEhC,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,aAAa,CAAuB;IAE5C,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,mBAAmB,CAA2B;IAEtD,OAAO,CAAC,aAAa,CAAiC;IAEtD,OAAO,CAAC,gBAAgB,CAAI;IAE5B,OAAO,CAAC,IAAI,CAA2B;IAEvC,OAAO,CAAC,OAAO,CAAK;IAEpB,OAAO,CAAC,uBAAuB,CAAI;IAEnC,OAAO,CAAC,0BAA0B,CAAI;IAEtC,OAAO,CAAC,YAAY,CAAoB;IAExC,OAAO,CAAC,OAAO,CAA2B;IAE1C,OAAO,CAAC,SAAS,CAA2B;IAE5C,OAAO,CAAC,UAAU,CAA2B;IAE7C,OAAO,CAAC,aAAa,CAA2B;IAEhD,OAAO,CAAC,YAAY,CAA2B;IAE/C,IAAI,IAAI,WAEP;IAED,IAAI,gBAAgB;;MAEnB;IAED,MAAM,KAAK,OAAO,WAEjB;IAED,IAAI,YAAY,QAEf;IAED,IAAa,UAAU;;;MAKtB;gBAEW,IAAI,EAAE,IAAI;IAqEb,UAAU;IA8FnB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,oBAAoB;IAkE5B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,qBAAqB;IAwD7B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,uBAAuB;IAuC/B,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,mBAAmB;IAiD3B,YAAY;IASZ,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IA6BpB,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAG3B;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,OAAO,CAAC,kBAAkB;IAU1B,gBAAgB,CAAC,CAAC,EAAE,MAAM;IAQ1B,cAAc;IAsBd,eAAe;IAkBf,WAAW;IAiBX,OAAO,CAAC,UAAU;IA+ClB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,iBAAiB;IAiHhB,MAAM;IAqBf,OAAO,CAAC,QAAQ;CAGjB"}
|
|
1
|
+
{"version":3,"file":"VastAds.d.ts","sourceRoot":"","sources":["../../../src/plugins/vast-ads/VastAds.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,IAAI,EAIJ,QAAQ,EAER,YAAY,EAEb,MAAM,cAAc,CAAA;AAarB,OAAO,qCAAqC,CAAA;AAQ5C,qBAAa,OAAQ,SAAQ,YAAY;IACvC,OAAO,CAAC,mBAAmB,CAAiC;IAE5D,OAAO,CAAC,qBAAqB,CAAwC;IAErE,OAAO,CAAC,oBAAoB,CAAwC;IAEpE,OAAO,CAAC,eAAe,CAAI;IAE3B,OAAO,CAAC,mBAAmB,CAAI;IAE/B,OAAO,CAAC,UAAU,CAAyB;IAE3C,OAAO,CAAC,SAAS,CAAyB;IAE1C,OAAO,CAAC,eAAe,CAA2B;IAElD,OAAO,CAAC,gBAAgB,CAAI;IAE5B,OAAO,CAAC,YAAY,CAAY;IAEhC,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,aAAa,CAAuB;IAE5C,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,mBAAmB,CAA2B;IAEtD,OAAO,CAAC,aAAa,CAAiC;IAEtD,OAAO,CAAC,gBAAgB,CAAI;IAE5B,OAAO,CAAC,IAAI,CAA2B;IAEvC,OAAO,CAAC,OAAO,CAAK;IAEpB,OAAO,CAAC,uBAAuB,CAAI;IAEnC,OAAO,CAAC,0BAA0B,CAAI;IAEtC,OAAO,CAAC,YAAY,CAAoB;IAExC,OAAO,CAAC,OAAO,CAA2B;IAE1C,OAAO,CAAC,SAAS,CAA2B;IAE5C,OAAO,CAAC,UAAU,CAA2B;IAE7C,OAAO,CAAC,aAAa,CAA2B;IAEhD,OAAO,CAAC,YAAY,CAA2B;IAE/C,IAAI,IAAI,WAEP;IAED,IAAI,gBAAgB;;MAEnB;IAED,MAAM,KAAK,OAAO,WAEjB;IAED,IAAI,YAAY,QAEf;IAED,IAAa,UAAU;;;MAKtB;gBAEW,IAAI,EAAE,IAAI;IAqEb,UAAU;IA8FnB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,oBAAoB;IAkE5B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,qBAAqB;IAwD7B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,uBAAuB;IAuC/B,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,uBAAuB;IAO/B,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,CAAC,mBAAmB;IAiD3B,YAAY;IASZ,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IA6BpB,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAG3B;IAED,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAE9B;IAED,OAAO,CAAC,kBAAkB;IAU1B,gBAAgB,CAAC,CAAC,EAAE,MAAM;IAQ1B,cAAc;IAsBd,eAAe;IAkBf,WAAW;IAiBX,OAAO,CAAC,UAAU;IA+ClB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,iBAAiB;IAiHhB,MAAM;IAqBf,OAAO,CAAC,QAAQ;CAGjB"}
|
|
@@ -345,8 +345,11 @@ export class VastAds extends UICorePlugin {
|
|
|
345
345
|
// @ts-ignore
|
|
346
346
|
this.stopListening(this.playback, Events.PLAYBACK_PAUSE);
|
|
347
347
|
}
|
|
348
|
+
get pluginOptions() {
|
|
349
|
+
return this.options.vastAds;
|
|
350
|
+
}
|
|
348
351
|
_pauserollListeners() {
|
|
349
|
-
if (!this._validateData(this.
|
|
352
|
+
if (!this._validateData(this.pluginOptions.pauseroll)) {
|
|
350
353
|
return;
|
|
351
354
|
}
|
|
352
355
|
this._stopPauserollListeners();
|
|
@@ -571,11 +574,11 @@ export class VastAds extends UICorePlugin {
|
|
|
571
574
|
// const currentRoll = type;
|
|
572
575
|
this.destroyRoll();
|
|
573
576
|
if (currentRoll === 'preroll') {
|
|
574
|
-
this.
|
|
577
|
+
this.pluginOptions[currentRoll] = [];
|
|
575
578
|
}
|
|
576
579
|
this.currentState = '';
|
|
577
580
|
this.$el.hide();
|
|
578
|
-
if (!this.options.disableClickOnPause) {
|
|
581
|
+
if (!this.options.disableClickOnPause) { // TODO sort out
|
|
579
582
|
this._clickToPausePlugin?.enable();
|
|
580
583
|
}
|
|
581
584
|
try {
|
package/lib/testUtils.d.ts
CHANGED
|
@@ -91,6 +91,7 @@ export declare function createMockPlayback(name?: string): Events<string | symbo
|
|
|
91
91
|
canAutoPlay: import("vitest").Mock<(...args: any[]) => any>;
|
|
92
92
|
onResize: import("vitest").Mock<(...args: any[]) => any>;
|
|
93
93
|
setPlaybackRate: import("vitest").Mock<(...args: any[]) => any>;
|
|
94
|
+
switchAudioTrack: import("vitest").Mock<(...args: any[]) => any>;
|
|
94
95
|
trigger: <T extends string | symbol>(event: T, ...args: any[]) => boolean;
|
|
95
96
|
};
|
|
96
97
|
export declare function createMockContainer(playback?: any): Events<string | symbol, any> & {
|
|
@@ -105,6 +106,7 @@ export declare function createMockContainer(playback?: any): Events<string | sym
|
|
|
105
106
|
isPlaying: import("vitest").Mock<(...args: any[]) => any>;
|
|
106
107
|
play: import("vitest").Mock<(...args: any[]) => any>;
|
|
107
108
|
seek: import("vitest").Mock<(...args: any[]) => any>;
|
|
109
|
+
switchAudioTrack: import("vitest").Mock<(...args: any[]) => any>;
|
|
108
110
|
trigger: <T extends string | symbol>(event: T, ...args: any[]) => boolean;
|
|
109
111
|
};
|
|
110
112
|
export declare function createMockMediaControl(core: any): UICorePlugin;
|
package/lib/testUtils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,YAAY,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,MAAM,MAAM,eAAe,CAAA;AAElC;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,MAAM;IAErC,SAAS,CAAC,OAAO,EAAE,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,GAAG;IAClB,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;gBAFjB,OAAO,EAAE,GAAG,EACb,IAAI,EAAE,GAAG,EACR,WAAW,CAAC,EAAE,GAAG,YAAA;IAK7B,IAAI,IAAI,WAEP;IAED,OAAO;IAEP,IAAI;IAEJ,KAAK;IAEL,IAAI;IAEJ,OAAO;IAEP,IAAI;IAEJ,cAAc;IAEd,WAAW;IAIX,QAAQ;IAER,OAAO;IAEP,eAAe;IAIf,kBAAkB;IAIlB,cAAc;IAId,qBAAqB;IAIrB,IAAI;IAEJ,MAAM;IAEN,MAAM;IAEN,SAAS;IAET,eAAe;IAIf,WAAW;IAIX,QAAQ;IAIR,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;CAGtC;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAA2B;;;;;;;;;;;;;;;;EAqBvC;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS
|
|
1
|
+
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,YAAY,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,MAAM,MAAM,eAAe,CAAA;AAElC;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,MAAM;IAErC,SAAS,CAAC,OAAO,EAAE,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,GAAG;IAClB,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;gBAFjB,OAAO,EAAE,GAAG,EACb,IAAI,EAAE,GAAG,EACR,WAAW,CAAC,EAAE,GAAG,YAAA;IAK7B,IAAI,IAAI,WAEP;IAED,OAAO;IAEP,IAAI;IAEJ,KAAK;IAEL,IAAI;IAEJ,OAAO;IAEP,IAAI;IAEJ,cAAc;IAEd,WAAW;IAIX,QAAQ;IAER,OAAO;IAEP,eAAe;IAIf,kBAAkB;IAIlB,cAAc;IAId,qBAAqB;IAIrB,IAAI;IAEJ,MAAM;IAEN,MAAM;IAEN,SAAS;IAET,eAAe;IAIf,WAAW;IAIX,QAAQ;IAIR,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;CAGtC;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAA2B;;;;;;;;;;;;;;;;EAqBvC;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC/C;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,GAAE,GAA0B;;;;;;;;;;;;;;EAkBvE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAiB/C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAY7C"}
|
package/lib/testUtils.js
CHANGED
|
@@ -124,6 +124,7 @@ export function createMockPlayback(name = 'mock') {
|
|
|
124
124
|
canAutoPlay: vi.fn().mockImplementation(() => true),
|
|
125
125
|
onResize: vi.fn().mockImplementation(() => true),
|
|
126
126
|
setPlaybackRate: vi.fn(),
|
|
127
|
+
switchAudioTrack: vi.fn(),
|
|
127
128
|
trigger: emitter.emit,
|
|
128
129
|
});
|
|
129
130
|
}
|
|
@@ -142,6 +143,7 @@ export function createMockContainer(playback = createMockPlayback()) {
|
|
|
142
143
|
isPlaying: vi.fn().mockReturnValue(false),
|
|
143
144
|
play: vi.fn(),
|
|
144
145
|
seek: vi.fn(),
|
|
146
|
+
switchAudioTrack: vi.fn(),
|
|
145
147
|
trigger: emitter.emit,
|
|
146
148
|
});
|
|
147
149
|
}
|
package/package.json
CHANGED
package/src/index.plugins.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '../assets/style/main.scss';
|
|
2
2
|
|
|
3
3
|
export * from "./plugins/audio-selector/AudioSelector.js";
|
|
4
|
+
export { AudioTracks as AudioSelector } from "./plugins/audio-selector/AudioSelector.js";
|
|
4
5
|
export * from "./plugins/big-mute-button/BigMuteButton.js";
|
|
5
6
|
export * from "./plugins/bottom-gear/BottomGear.js";
|
|
6
7
|
export * from "./plugins/clappr-nerd-stats/ClapprNerdStats.js";
|
|
@@ -13,13 +14,14 @@ export * from "./plugins/error-screen/ErrorScreen.js";
|
|
|
13
14
|
export * from "./plugins/favicon/Favicon.js";
|
|
14
15
|
// _ ga-events
|
|
15
16
|
export * from "./plugins/google-analytics/GoogleAnalytics.js";
|
|
16
|
-
export * from "./plugins/level-selector/LevelSelector.js";
|
|
17
17
|
export * from "./plugins/logo/Logo.js";
|
|
18
18
|
export * from "./plugins/media-control/MediaControl.js";
|
|
19
19
|
export * from "./plugins/multi-camera/MultiCamera.js";
|
|
20
20
|
export * from "./plugins/picture-in-picture/PictureInPicture.js";
|
|
21
21
|
export * from "./plugins/playback-rate/PlaybackRate.js";
|
|
22
22
|
export * from "./plugins/poster/Poster.js";
|
|
23
|
+
export * from "./plugins/level-selector/QualityLevels.js";
|
|
24
|
+
export { QualityLevels as LevelSelector } from "./plugins/level-selector/QualityLevels.js";
|
|
23
25
|
export * from "./plugins/seek-time/SeekTime.js";
|
|
24
26
|
export * from "./plugins/share/Share.js";
|
|
25
27
|
export * from "./plugins/skip-time/SkipTime.js";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Events, UICorePlugin, template } from '@clappr/core'
|
|
2
2
|
import { AudioTrack } from '@clappr/core/types/base/playback/playback.js'
|
|
3
|
-
import { trace } from '@gcorevideo/utils'
|
|
4
3
|
import assert from 'assert'
|
|
5
4
|
|
|
6
5
|
import { CLAPPR_VERSION } from '../../build.js'
|
|
@@ -11,9 +10,9 @@ import audioArrow from '../../../assets/icons/old/quality-arrow.svg'
|
|
|
11
10
|
import { ZeptoResult } from '../../types.js'
|
|
12
11
|
import { MediaControl } from '../media-control/MediaControl.js'
|
|
13
12
|
|
|
14
|
-
const VERSION: string = '
|
|
13
|
+
const VERSION: string = '2.22.4'
|
|
15
14
|
|
|
16
|
-
const T = 'plugins.
|
|
15
|
+
// const T = 'plugins.audiotracks'
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* `PLUGIN` that makes possible to switch audio tracks via the media control UI.
|
|
@@ -25,7 +24,7 @@ const T = 'plugins.audio_selector'
|
|
|
25
24
|
*
|
|
26
25
|
* - {@link MediaControl}
|
|
27
26
|
*/
|
|
28
|
-
export class
|
|
27
|
+
export class AudioTracks extends UICorePlugin {
|
|
29
28
|
private currentTrack: AudioTrack | null = null
|
|
30
29
|
|
|
31
30
|
private tracks: AudioTrack[] = []
|
|
@@ -34,7 +33,7 @@ export class AudioSelector extends UICorePlugin {
|
|
|
34
33
|
* @internal
|
|
35
34
|
*/
|
|
36
35
|
get name() {
|
|
37
|
-
return 'audio_selector'
|
|
36
|
+
return 'audio_selector' // TODO rename to audiotracks
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
/**
|
|
@@ -59,7 +58,6 @@ export class AudioSelector extends UICorePlugin {
|
|
|
59
58
|
override get attributes() {
|
|
60
59
|
return {
|
|
61
60
|
class: 'media-control-audiotracks',
|
|
62
|
-
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
|
|
@@ -69,7 +67,7 @@ export class AudioSelector extends UICorePlugin {
|
|
|
69
67
|
override get events() {
|
|
70
68
|
return {
|
|
71
69
|
'click [data-audiotracks-select]': 'onTrackSelect',
|
|
72
|
-
'click
|
|
70
|
+
'click #audiotracks-button': 'toggleContextMenu',
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
73
|
|
|
@@ -77,7 +75,7 @@ export class AudioSelector extends UICorePlugin {
|
|
|
77
75
|
* @internal
|
|
78
76
|
*/
|
|
79
77
|
override bindEvents() {
|
|
80
|
-
this.
|
|
78
|
+
this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady)
|
|
81
79
|
this.listenTo(
|
|
82
80
|
this.core,
|
|
83
81
|
Events.CORE_ACTIVE_CONTAINER_CHANGED,
|
|
@@ -86,41 +84,30 @@ export class AudioSelector extends UICorePlugin {
|
|
|
86
84
|
}
|
|
87
85
|
|
|
88
86
|
private onCoreReady() {
|
|
89
|
-
trace(`${T} onCoreReady`)
|
|
90
87
|
const mediaControl = this.core.getPlugin('media_control')
|
|
91
88
|
assert(mediaControl, 'media_control plugin is required')
|
|
92
|
-
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
this.hideSelectTrackMenu,
|
|
97
|
-
)
|
|
89
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, () => {
|
|
90
|
+
mediaControl.putElement('audiotracks', this.$el)
|
|
91
|
+
})
|
|
92
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, this.hideMenu)
|
|
98
93
|
}
|
|
99
94
|
|
|
100
|
-
private
|
|
101
|
-
trace(`${T} bindPlaybackEvents`)
|
|
95
|
+
private onActiveContainerChanged() {
|
|
102
96
|
this.currentTrack = null
|
|
103
|
-
this.listenTo(this.core.activePlayback, Events.PLAYBACK_STOP, this.onStop)
|
|
104
|
-
this.setupAudioTrackListeners()
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private setupAudioTrackListeners() {
|
|
108
97
|
this.listenTo(
|
|
109
|
-
this.core.
|
|
110
|
-
Events.
|
|
98
|
+
this.core.activeContainer,
|
|
99
|
+
Events.CONTAINER_AUDIO_AVAILABLE,
|
|
111
100
|
(tracks: AudioTrack[]) => {
|
|
112
|
-
trace(`${T} on PLAYBACK_AUDIO_AVAILABLE`, { audioTracks: tracks })
|
|
113
101
|
this.currentTrack =
|
|
114
|
-
tracks.find((track) => track.kind === 'main') ?? null
|
|
115
|
-
this.
|
|
102
|
+
tracks.find((track) => track.kind === 'main') ?? null // TODO test
|
|
103
|
+
this.tracks = tracks
|
|
104
|
+
this.render()
|
|
116
105
|
},
|
|
117
106
|
)
|
|
118
|
-
|
|
119
107
|
this.listenTo(
|
|
120
|
-
this.core.
|
|
121
|
-
Events.
|
|
108
|
+
this.core.activeContainer,
|
|
109
|
+
Events.CONTAINER_AUDIO_CHANGED,
|
|
122
110
|
(track: AudioTrack) => {
|
|
123
|
-
trace(`${T} PLAYBACK_AUDIO_CHANGED`, { audioTrack: track })
|
|
124
111
|
this.currentTrack = track
|
|
125
112
|
this.highlightCurrentTrack()
|
|
126
113
|
this.buttonElement().removeClass('changing')
|
|
@@ -129,24 +116,10 @@ export class AudioSelector extends UICorePlugin {
|
|
|
129
116
|
)
|
|
130
117
|
}
|
|
131
118
|
|
|
132
|
-
private onStop() {
|
|
133
|
-
trace(`${T} onStop`)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
private onActiveContainerChanged() {
|
|
137
|
-
trace(`${T} onActiveContainerChanged`)
|
|
138
|
-
this.bindPlaybackEvents()
|
|
139
|
-
}
|
|
140
|
-
|
|
141
119
|
private shouldRender() {
|
|
142
|
-
|
|
143
|
-
return false
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
this.tracks = this.core.activePlayback.audioTracks
|
|
147
|
-
|
|
120
|
+
// Render is called from the parent class constructor so tracks aren't available
|
|
148
121
|
// Only care if we have at least 2 to choose from
|
|
149
|
-
return this.tracks
|
|
122
|
+
return this.tracks?.length > 1
|
|
150
123
|
}
|
|
151
124
|
|
|
152
125
|
/**
|
|
@@ -159,52 +132,40 @@ export class AudioSelector extends UICorePlugin {
|
|
|
159
132
|
|
|
160
133
|
const mediaControl = this.core.getPlugin('media_control') as MediaControl
|
|
161
134
|
this.$el.html(
|
|
162
|
-
|
|
135
|
+
AudioTracks.template({
|
|
136
|
+
tracks: this.tracks,
|
|
137
|
+
title: this.getTitle(),
|
|
138
|
+
icon: audioArrow,
|
|
139
|
+
}),
|
|
163
140
|
)
|
|
164
|
-
this.$('.audio-arrow').append(audioArrow)
|
|
165
|
-
mediaControl.putElement('audiotracks', this.el)
|
|
166
|
-
|
|
167
141
|
this.updateText()
|
|
168
142
|
this.highlightCurrentTrack()
|
|
169
143
|
|
|
170
144
|
return this
|
|
171
145
|
}
|
|
172
146
|
|
|
173
|
-
private fillTracks(tracks: AudioTrack[]) {
|
|
174
|
-
this.tracks = tracks
|
|
175
|
-
this.render()
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private findTrackBy(id: string) {
|
|
179
|
-
return this.tracks.find((track) => track.id === id)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
147
|
private onTrackSelect(event: MouseEvent) {
|
|
183
148
|
const id = (event.target as HTMLElement)?.dataset?.audiotracksSelect
|
|
184
149
|
if (id) {
|
|
185
150
|
this.selectAudioTrack(id)
|
|
186
151
|
}
|
|
187
|
-
this.
|
|
152
|
+
this.hideMenu()
|
|
188
153
|
event.stopPropagation()
|
|
189
154
|
return false
|
|
190
155
|
}
|
|
191
156
|
|
|
192
157
|
private selectAudioTrack(id: string) {
|
|
193
158
|
this.startTrackSwitch()
|
|
194
|
-
this.core.
|
|
159
|
+
this.core.activeContainer.switchAudioTrack(id)
|
|
195
160
|
this.updateText()
|
|
196
161
|
}
|
|
197
162
|
|
|
198
|
-
private
|
|
199
|
-
this.
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private hideSelectTrackMenu() {
|
|
203
|
-
;(this.$('ul') as ZeptoResult).hide()
|
|
163
|
+
private hideMenu() {
|
|
164
|
+
this.$el.find('#audiotracks-select').addClass('hidden')
|
|
204
165
|
}
|
|
205
166
|
|
|
206
167
|
private toggleContextMenu() {
|
|
207
|
-
|
|
168
|
+
this.$el.find('#audiotracks-select').toggleClass('hidden')
|
|
208
169
|
}
|
|
209
170
|
|
|
210
171
|
private buttonElement(): ZeptoResult {
|
|
@@ -218,14 +179,17 @@ export class AudioSelector extends UICorePlugin {
|
|
|
218
179
|
private trackElement(id?: string): ZeptoResult {
|
|
219
180
|
return (
|
|
220
181
|
this.$(
|
|
221
|
-
'
|
|
222
|
-
(id !== undefined ?
|
|
182
|
+
'#audiotracks-select a' +
|
|
183
|
+
(id !== undefined ? `[data-audiotracks-select="${id}"]` : ''),
|
|
223
184
|
) as ZeptoResult
|
|
224
185
|
).parent()
|
|
225
186
|
}
|
|
226
187
|
|
|
227
188
|
private getTitle(): string {
|
|
228
|
-
|
|
189
|
+
if (!this.currentTrack) {
|
|
190
|
+
return ''
|
|
191
|
+
}
|
|
192
|
+
return this.currentTrack.label || this.currentTrack.language
|
|
229
193
|
}
|
|
230
194
|
|
|
231
195
|
private startTrackSwitch() {
|