@gcorevideo/player 2.22.22 → 2.22.23
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/clappr-nerd-stats/clappr-nerd-stats.scss +0 -3
- package/dist/core.js +1 -1
- package/dist/index.css +1388 -1388
- package/dist/index.js +4294 -4276
- package/dist/plugins/index.css +905 -905
- package/dist/plugins/index.js +5364 -5350
- package/lib/index.plugins.d.ts +2 -2
- package/lib/index.plugins.d.ts.map +1 -1
- package/lib/index.plugins.js +2 -2
- package/lib/plugins/audio-selector/AudioTracks.d.ts +67 -0
- package/lib/plugins/audio-selector/AudioTracks.d.ts.map +1 -0
- package/lib/plugins/audio-selector/AudioTracks.js +176 -0
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +6 -0
- package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts +1 -1
- package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/NerdStats.js +11 -5
- package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.js +0 -1
- package/lib/plugins/clappr-nerd-stats/utils.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/utils.js +0 -3
- package/lib/plugins/media-control/MediaControl.d.ts +2 -1
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +1 -0
- package/lib/plugins/skip-time/SkipTime.d.ts +2 -2
- package/lib/plugins/skip-time/SkipTime.d.ts.map +1 -1
- package/lib/plugins/skip-time/SkipTime.js +6 -5
- package/lib/plugins/subtitles/ClosedCaptions.d.ts.map +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.js +10 -3
- package/package.json +1 -1
- package/src/index.plugins.ts +2 -2
- package/src/plugins/audio-selector/{AudioSelector.ts → AudioTracks.ts} +6 -3
- package/src/plugins/audio-selector/__tests__/{AudioSelector.test.ts → AudioTracks.test.ts} +24 -24
- package/src/plugins/audio-selector/__tests__/__snapshots__/AudioSelector.test.ts.snap +66 -0
- package/src/plugins/audio-selector/__tests__/__snapshots__/AudioTracks.test.ts.snap +67 -0
- package/src/plugins/bottom-gear/BottomGear.ts +10 -0
- package/src/plugins/clappr-nerd-stats/NerdStats.ts +12 -6
- package/src/plugins/clappr-nerd-stats/speedtest/Speedtest.ts +0 -1
- package/src/plugins/clappr-nerd-stats/utils.ts +0 -3
- package/src/plugins/media-control/MediaControl.ts +1 -0
- package/src/plugins/skip-time/SkipTime.ts +45 -38
- package/src/plugins/subtitles/ClosedCaptions.ts +17 -7
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
2
|
import { Events } from '@clappr/core'
|
|
3
3
|
|
|
4
|
-
import { AudioTracks } from '../
|
|
4
|
+
import { AudioTracks } from '../AudioTracks'
|
|
5
5
|
|
|
6
6
|
import { createMockCore, createMockMediaControl } from '../../../testUtils'
|
|
7
7
|
// import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
|
|
8
8
|
|
|
9
9
|
// Logger.enable('*')
|
|
10
|
-
// setTracer(new LogTracer('
|
|
10
|
+
// setTracer(new LogTracer('AudioTracks.test'))
|
|
11
11
|
|
|
12
12
|
const TRACKS = [
|
|
13
13
|
{ id: '1', label: 'English', language: 'en', track: {} },
|
|
14
14
|
{ id: '2', label: 'Spanish', language: 'es', track: {} },
|
|
15
15
|
]
|
|
16
16
|
|
|
17
|
-
describe('
|
|
17
|
+
describe('AudioTracks', () => {
|
|
18
18
|
let core: any
|
|
19
19
|
let mediaControl: any
|
|
20
|
-
let
|
|
20
|
+
let audioTracks: AudioTracks
|
|
21
21
|
beforeEach(() => {
|
|
22
22
|
core = createMockCore()
|
|
23
23
|
mediaControl = createMockMediaControl(core)
|
|
@@ -25,7 +25,7 @@ describe('AudioSelector', () => {
|
|
|
25
25
|
if (name === 'media_control') return mediaControl
|
|
26
26
|
return null
|
|
27
27
|
})
|
|
28
|
-
|
|
28
|
+
audioTracks = new AudioTracks(core)
|
|
29
29
|
core.emit(Events.CORE_READY)
|
|
30
30
|
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
31
31
|
})
|
|
@@ -47,7 +47,7 @@ describe('AudioSelector', () => {
|
|
|
47
47
|
it('should attach to the media control', () => {
|
|
48
48
|
expect(mediaControl.mount).toHaveBeenCalledWith(
|
|
49
49
|
'audiotracks',
|
|
50
|
-
|
|
50
|
+
audioTracks.$el,
|
|
51
51
|
)
|
|
52
52
|
})
|
|
53
53
|
})
|
|
@@ -56,31 +56,31 @@ describe('AudioSelector', () => {
|
|
|
56
56
|
emitTracksAvailable(core, TRACKS)
|
|
57
57
|
})
|
|
58
58
|
it('should render button', () => {
|
|
59
|
-
expect(
|
|
59
|
+
expect(audioTracks.$el.find('#audiotracks-button').length).toBe(1)
|
|
60
60
|
})
|
|
61
61
|
it('should render menu hidden', () => {
|
|
62
|
-
expect(
|
|
62
|
+
expect(audioTracks.el.innerHTML).toMatchSnapshot()
|
|
63
63
|
expect(
|
|
64
|
-
|
|
64
|
+
audioTracks.$el.find('#audiotracks-select').hasClass('hidden'),
|
|
65
65
|
).toBe(true)
|
|
66
|
-
const trackItems =
|
|
66
|
+
const trackItems = audioTracks.$el.find('#audiotracks-select li')
|
|
67
67
|
expect(trackItems.length).toBe(2)
|
|
68
68
|
expect(trackItems.eq(0).text().trim()).toBe('English')
|
|
69
69
|
expect(trackItems.eq(1).text().trim()).toBe('Spanish')
|
|
70
70
|
})
|
|
71
71
|
describe('when button is clicked', () => {
|
|
72
72
|
beforeEach(() => {
|
|
73
|
-
|
|
73
|
+
audioTracks.$el.find('#audiotracks-button').click()
|
|
74
74
|
})
|
|
75
75
|
it('should show menu', () => {
|
|
76
|
-
expect(
|
|
76
|
+
expect(audioTracks.$el.html()).toMatchSnapshot()
|
|
77
77
|
expect(
|
|
78
|
-
|
|
78
|
+
audioTracks.$el.find('#audiotracks-select').hasClass('hidden'),
|
|
79
79
|
).toBe(false)
|
|
80
80
|
})
|
|
81
81
|
describe('when audio track is selected', () => {
|
|
82
82
|
beforeEach(() => {
|
|
83
|
-
|
|
83
|
+
audioTracks.$el
|
|
84
84
|
.find('#audiotracks-select [data-audiotracks-select="2"]')
|
|
85
85
|
.click()
|
|
86
86
|
})
|
|
@@ -90,14 +90,14 @@ describe('AudioSelector', () => {
|
|
|
90
90
|
)
|
|
91
91
|
})
|
|
92
92
|
it('should hide the menu', () => {
|
|
93
|
-
expect(
|
|
93
|
+
expect(audioTracks.$el.html()).toMatchSnapshot()
|
|
94
94
|
expect(
|
|
95
|
-
|
|
95
|
+
audioTracks.$el.find('#audiotracks-select').hasClass('hidden'),
|
|
96
96
|
).toBe(true)
|
|
97
97
|
})
|
|
98
98
|
it('should add changing class to the button', () => {
|
|
99
99
|
expect(
|
|
100
|
-
|
|
100
|
+
audioTracks.$el.find('#audiotracks-button').hasClass('changing'),
|
|
101
101
|
).toBe(true)
|
|
102
102
|
})
|
|
103
103
|
describe('when current audio track changes', () => {
|
|
@@ -115,14 +115,14 @@ describe('AudioSelector', () => {
|
|
|
115
115
|
})
|
|
116
116
|
it('should update button class', () => {
|
|
117
117
|
expect(
|
|
118
|
-
|
|
118
|
+
audioTracks.$el
|
|
119
119
|
.find('#audiotracks-button')
|
|
120
120
|
.hasClass('changing'),
|
|
121
121
|
).toBe(false)
|
|
122
122
|
})
|
|
123
123
|
it('should update button label', () => {
|
|
124
124
|
expect(
|
|
125
|
-
|
|
125
|
+
audioTracks.$el
|
|
126
126
|
.find('#audiotracks-button')
|
|
127
127
|
.text()
|
|
128
128
|
.replace(/\/assets.*\.svg/g, '')
|
|
@@ -130,7 +130,7 @@ describe('AudioSelector', () => {
|
|
|
130
130
|
).toBe('Spanish')
|
|
131
131
|
})
|
|
132
132
|
it('should highlight the selected menu item', () => {
|
|
133
|
-
const selectedItem =
|
|
133
|
+
const selectedItem = audioTracks.$el.find(
|
|
134
134
|
'#audiotracks-select .current',
|
|
135
135
|
)
|
|
136
136
|
expect(selectedItem.text().trim()).toBe('Spanish')
|
|
@@ -142,10 +142,10 @@ describe('AudioSelector', () => {
|
|
|
142
142
|
})
|
|
143
143
|
it('should unhighlight any previously highlighted menu item', () => {
|
|
144
144
|
expect(
|
|
145
|
-
|
|
145
|
+
audioTracks.$el.find('#audiotracks-select li.current').length,
|
|
146
146
|
).toBe(1)
|
|
147
147
|
expect(
|
|
148
|
-
|
|
148
|
+
audioTracks.$el.find(
|
|
149
149
|
'#audiotracks-select a.gcore-skin-active[data-audiotracks-select]',
|
|
150
150
|
).length,
|
|
151
151
|
).toBe(1)
|
|
@@ -156,8 +156,8 @@ describe('AudioSelector', () => {
|
|
|
156
156
|
})
|
|
157
157
|
describe('when audio tracks are not available', () => {
|
|
158
158
|
it('should not render the button', () => {
|
|
159
|
-
expect(
|
|
160
|
-
expect(
|
|
159
|
+
expect(audioTracks.$el.find('#audiotracks-button').length).toBe(0)
|
|
160
|
+
expect(audioTracks.$el.find('#audiotracks-select').length).toBe(0)
|
|
161
161
|
})
|
|
162
162
|
})
|
|
163
163
|
})
|
|
@@ -65,3 +65,69 @@ exports[`AudioSelector > given that audio tracks are available > when button is
|
|
|
65
65
|
</ul>
|
|
66
66
|
"
|
|
67
67
|
`;
|
|
68
|
+
|
|
69
|
+
exports[`AudioTracks > given that audio tracks are available > should render menu hidden 1`] = `
|
|
70
|
+
"<button data-audiotracks-button="" class="gcore-skin-button-color" id="audiotracks-button" aria-haspopup="menu" aria-expanded="false">
|
|
71
|
+
<span class="audio-text"></span> <span class="audio-arrow">/assets/icons/old/quality-arrow.svg</span>
|
|
72
|
+
</button>
|
|
73
|
+
<ul class="gcore-skin-bg-color menu hidden" id="audiotracks-select" role="menu">
|
|
74
|
+
|
|
75
|
+
<li class="">
|
|
76
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="1" role="menuitemradio" aria-checked="false">
|
|
77
|
+
English
|
|
78
|
+
</a>
|
|
79
|
+
</li>
|
|
80
|
+
|
|
81
|
+
<li class="">
|
|
82
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="2" role="menuitemradio" aria-checked="false">
|
|
83
|
+
Spanish
|
|
84
|
+
</a>
|
|
85
|
+
</li>
|
|
86
|
+
|
|
87
|
+
</ul>
|
|
88
|
+
"
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
exports[`AudioTracks > given that audio tracks are available > when button is clicked > should show menu 1`] = `
|
|
92
|
+
"<button data-audiotracks-button="" class="gcore-skin-button-color" id="audiotracks-button" aria-haspopup="menu" aria-expanded="true">
|
|
93
|
+
<span class="audio-text"></span> <span class="audio-arrow">/assets/icons/old/quality-arrow.svg</span>
|
|
94
|
+
</button>
|
|
95
|
+
<ul class="gcore-skin-bg-color menu" id="audiotracks-select" role="menu">
|
|
96
|
+
|
|
97
|
+
<li class="">
|
|
98
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="1" role="menuitemradio" aria-checked="false">
|
|
99
|
+
English
|
|
100
|
+
</a>
|
|
101
|
+
</li>
|
|
102
|
+
|
|
103
|
+
<li class="">
|
|
104
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="2" role="menuitemradio" aria-checked="false">
|
|
105
|
+
Spanish
|
|
106
|
+
</a>
|
|
107
|
+
</li>
|
|
108
|
+
|
|
109
|
+
</ul>
|
|
110
|
+
"
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
exports[`AudioTracks > given that audio tracks are available > when button is clicked > when audio track is selected > should hide the menu 1`] = `
|
|
114
|
+
"<button data-audiotracks-button="" class="gcore-skin-button-color changing" id="audiotracks-button" aria-haspopup="menu" aria-expanded="true">
|
|
115
|
+
<span class="audio-text"></span> <span class="audio-arrow">/assets/icons/old/quality-arrow.svg</span>
|
|
116
|
+
</button>
|
|
117
|
+
<ul class="gcore-skin-bg-color menu hidden" id="audiotracks-select" role="menu">
|
|
118
|
+
|
|
119
|
+
<li class="">
|
|
120
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="1" role="menuitemradio" aria-checked="false">
|
|
121
|
+
English
|
|
122
|
+
</a>
|
|
123
|
+
</li>
|
|
124
|
+
|
|
125
|
+
<li class="">
|
|
126
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="2" role="menuitemradio" aria-checked="false">
|
|
127
|
+
Spanish
|
|
128
|
+
</a>
|
|
129
|
+
</li>
|
|
130
|
+
|
|
131
|
+
</ul>
|
|
132
|
+
"
|
|
133
|
+
`;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`AudioTracks > given that audio tracks are available > should render menu hidden 1`] = `
|
|
4
|
+
"<button data-audiotracks-button="" class="gcore-skin-button-color" id="audiotracks-button" aria-haspopup="menu" aria-expanded="false">
|
|
5
|
+
<span class="audio-text"></span> <span class="audio-arrow">/assets/icons/old/quality-arrow.svg</span>
|
|
6
|
+
</button>
|
|
7
|
+
<ul class="gcore-skin-bg-color menu hidden" id="audiotracks-select" role="menu">
|
|
8
|
+
|
|
9
|
+
<li class="">
|
|
10
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="1" role="menuitemradio" aria-checked="false">
|
|
11
|
+
English
|
|
12
|
+
</a>
|
|
13
|
+
</li>
|
|
14
|
+
|
|
15
|
+
<li class="">
|
|
16
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="2" role="menuitemradio" aria-checked="false">
|
|
17
|
+
Spanish
|
|
18
|
+
</a>
|
|
19
|
+
</li>
|
|
20
|
+
|
|
21
|
+
</ul>
|
|
22
|
+
"
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
exports[`AudioTracks > given that audio tracks are available > when button is clicked > should show menu 1`] = `
|
|
26
|
+
"<button data-audiotracks-button="" class="gcore-skin-button-color" id="audiotracks-button" aria-haspopup="menu" aria-expanded="true">
|
|
27
|
+
<span class="audio-text"></span> <span class="audio-arrow">/assets/icons/old/quality-arrow.svg</span>
|
|
28
|
+
</button>
|
|
29
|
+
<ul class="gcore-skin-bg-color menu" id="audiotracks-select" role="menu">
|
|
30
|
+
|
|
31
|
+
<li class="">
|
|
32
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="1" role="menuitemradio" aria-checked="false">
|
|
33
|
+
English
|
|
34
|
+
</a>
|
|
35
|
+
</li>
|
|
36
|
+
|
|
37
|
+
<li class="">
|
|
38
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="2" role="menuitemradio" aria-checked="false">
|
|
39
|
+
Spanish
|
|
40
|
+
</a>
|
|
41
|
+
</li>
|
|
42
|
+
|
|
43
|
+
</ul>
|
|
44
|
+
"
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
exports[`AudioTracks > given that audio tracks are available > when button is clicked > when audio track is selected > should hide the menu 1`] = `
|
|
48
|
+
"<button data-audiotracks-button="" class="gcore-skin-button-color changing" id="audiotracks-button" aria-haspopup="menu" aria-expanded="true">
|
|
49
|
+
<span class="audio-text"></span> <span class="audio-arrow">/assets/icons/old/quality-arrow.svg</span>
|
|
50
|
+
</button>
|
|
51
|
+
<ul class="gcore-skin-bg-color menu hidden" id="audiotracks-select" role="menu">
|
|
52
|
+
|
|
53
|
+
<li class="">
|
|
54
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="1" role="menuitemradio" aria-checked="false">
|
|
55
|
+
English
|
|
56
|
+
</a>
|
|
57
|
+
</li>
|
|
58
|
+
|
|
59
|
+
<li class="">
|
|
60
|
+
<a href="#" class="gcore-skin-text-color" data-audiotracks-select="2" role="menuitemradio" aria-checked="false">
|
|
61
|
+
Spanish
|
|
62
|
+
</a>
|
|
63
|
+
</li>
|
|
64
|
+
|
|
65
|
+
</ul>
|
|
66
|
+
"
|
|
67
|
+
`;
|
|
@@ -10,6 +10,7 @@ import '../../../assets/bottom-gear/gear-sub-menu.scss'
|
|
|
10
10
|
import gearIcon from '../../../assets/icons/new/gear.svg'
|
|
11
11
|
import gearHdIcon from '../../../assets/icons/new/gear-hd.svg'
|
|
12
12
|
import { ZeptoResult } from '../../types.js'
|
|
13
|
+
import { ExtendedEvents } from '../media-control/MediaControl.js'
|
|
13
14
|
|
|
14
15
|
const VERSION = '2.19.12'
|
|
15
16
|
|
|
@@ -254,10 +255,14 @@ export class BottomGear extends UICorePlugin {
|
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
private toggleGearMenu() {
|
|
258
|
+
this.core
|
|
259
|
+
.getPlugin('media_control')
|
|
260
|
+
.trigger(ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE)
|
|
257
261
|
this.$el.find('#gear-options-wrapper').toggle()
|
|
258
262
|
}
|
|
259
263
|
|
|
260
264
|
private hide() {
|
|
265
|
+
trace(`${T} hide`)
|
|
261
266
|
this.$el.find('#gear-options-wrapper').hide()
|
|
262
267
|
}
|
|
263
268
|
|
|
@@ -271,6 +276,11 @@ export class BottomGear extends UICorePlugin {
|
|
|
271
276
|
this.onMediaControlRendered,
|
|
272
277
|
)
|
|
273
278
|
this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide)
|
|
279
|
+
this.listenTo(
|
|
280
|
+
mediaControl,
|
|
281
|
+
ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE,
|
|
282
|
+
this.hide,
|
|
283
|
+
)
|
|
274
284
|
}
|
|
275
285
|
|
|
276
286
|
private onMediaControlRendered() {
|
|
@@ -71,7 +71,7 @@ const T = 'plugins.nerd_stats'
|
|
|
71
71
|
* - {@link BottomGear} - where the button is attached
|
|
72
72
|
*
|
|
73
73
|
* - {@link ClapprStats} - to get the metrics from
|
|
74
|
-
*
|
|
74
|
+
*
|
|
75
75
|
* The plugin is rendered as an item in the gear menu.
|
|
76
76
|
*
|
|
77
77
|
* When clicked, it shows an overlay window with the information about the network speed, latency, etc,
|
|
@@ -312,7 +312,7 @@ export class NerdStats extends UICorePlugin {
|
|
|
312
312
|
|
|
313
313
|
private updateMetrics(metrics: PerfMetrics) {
|
|
314
314
|
trace(`${T} updateMetrics`, { custom: this.speedtestMetrics })
|
|
315
|
-
Object.assign(this.metrics, metrics)
|
|
315
|
+
Object.assign(this.metrics, metrics)
|
|
316
316
|
this.metrics.custom = {
|
|
317
317
|
...this.speedtestMetrics,
|
|
318
318
|
}
|
|
@@ -394,9 +394,15 @@ export class NerdStats extends UICorePlugin {
|
|
|
394
394
|
}
|
|
395
395
|
|
|
396
396
|
private updateCustomMetrics() {
|
|
397
|
-
this.$el
|
|
398
|
-
|
|
399
|
-
|
|
397
|
+
this.$el
|
|
398
|
+
.find('#nerd-stats-dl-text')
|
|
399
|
+
.text(this.metrics.custom.connectionSpeed.toFixed(2))
|
|
400
|
+
this.$el
|
|
401
|
+
.find('#nerd-stats-ping-text')
|
|
402
|
+
.text(this.metrics.custom.ping.toFixed(2))
|
|
403
|
+
this.$el
|
|
404
|
+
.find('#nerd-stats-jitter-text')
|
|
405
|
+
.text(this.metrics.custom.jitter.toFixed(2))
|
|
400
406
|
}
|
|
401
407
|
|
|
402
408
|
private updateEstimatedQuality() {
|
|
@@ -465,7 +471,7 @@ export class NerdStats extends UICorePlugin {
|
|
|
465
471
|
this.speedtestMetrics.connectionSpeed = 0
|
|
466
472
|
this.speedtestMetrics.ping = 0
|
|
467
473
|
this.speedtestMetrics.jitter = 0
|
|
468
|
-
|
|
474
|
+
|
|
469
475
|
if (clapprStats) {
|
|
470
476
|
clapprStats.clearMetrics()
|
|
471
477
|
this.updateMetrics(clapprStats.exportMetrics())
|
|
@@ -71,9 +71,6 @@ export const drawSummary = (
|
|
|
71
71
|
) => {
|
|
72
72
|
const { connectionSpeed, ping } = customMetrics
|
|
73
73
|
|
|
74
|
-
// if (!connectionSpeed || !ping) {
|
|
75
|
-
// return
|
|
76
|
-
// }
|
|
77
74
|
const downloadQuality = getDownloadQuality(connectionSpeed)
|
|
78
75
|
const pingQuality = getPingQuality(ping)
|
|
79
76
|
const liveQuality = Math.min(downloadQuality, pingQuality)
|
|
@@ -138,6 +138,7 @@ const LEFT_ORDER = [
|
|
|
138
138
|
|
|
139
139
|
export enum ExtendedEvents {
|
|
140
140
|
MEDIACONTROL_VOLUME = 'mediacontrol:volume',
|
|
141
|
+
MEDIACONTROL_MENU_COLLAPSE = 'mediacontrol:menu:collapse',
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
const { Config, Fullscreen, formatTime, extend, removeArrayItem } = Utils
|
|
@@ -1,113 +1,120 @@
|
|
|
1
|
-
import { UICorePlugin
|
|
1
|
+
import { UICorePlugin, Browser, Playback, Events, template } from '@clappr/core'
|
|
2
2
|
|
|
3
|
-
import { CLAPPR_VERSION } from '../../build.js'
|
|
3
|
+
import { CLAPPR_VERSION } from '../../build.js'
|
|
4
4
|
|
|
5
|
-
import pluginHtml from '../../../assets/skip-time/skip-time.ejs'
|
|
6
|
-
import '../../../assets/skip-time/style.scss'
|
|
5
|
+
import pluginHtml from '../../../assets/skip-time/skip-time.ejs'
|
|
6
|
+
import '../../../assets/skip-time/style.scss'
|
|
7
7
|
|
|
8
|
-
type Position = 'mid' | 'left' | 'right'
|
|
8
|
+
type Position = 'mid' | 'left' | 'right'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* `PLUGIN` that adds skip controls to the media control UI.
|
|
12
12
|
* @beta
|
|
13
13
|
*/
|
|
14
|
-
export class SkipTime extends
|
|
14
|
+
export class SkipTime extends UICorePlugin {
|
|
15
15
|
get name() {
|
|
16
|
-
return 'skip_time'
|
|
16
|
+
return 'skip_time'
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
get supportedVersion() {
|
|
20
|
-
return { min: CLAPPR_VERSION }
|
|
20
|
+
return { min: CLAPPR_VERSION }
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
get container() {
|
|
24
|
-
return this.core && this.core.activeContainer
|
|
24
|
+
return this.core && this.core.activeContainer
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
get template() {
|
|
28
|
-
return template(pluginHtml)
|
|
28
|
+
return template(pluginHtml)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
override get attributes() {
|
|
32
32
|
return {
|
|
33
|
-
|
|
34
|
-
'data-skip-time': ''
|
|
35
|
-
}
|
|
33
|
+
class: this.name + '_plugin',
|
|
34
|
+
'data-skip-time': '',
|
|
35
|
+
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
private position: Position = 'mid'
|
|
38
|
+
private position: Position = 'mid'
|
|
39
39
|
|
|
40
40
|
override get events() {
|
|
41
41
|
return {
|
|
42
42
|
'click [data-skip-left]': 'setBack',
|
|
43
43
|
'click [data-skip-mid]': 'setMidClick',
|
|
44
44
|
'click [data-skip-right]': 'setForward',
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
override bindEvents() {
|
|
49
|
-
this.listenTo(this.core, Events.CORE_READY, this.render)
|
|
49
|
+
this.listenTo(this.core, Events.CORE_READY, this.render)
|
|
50
50
|
if (!this.container) {
|
|
51
|
-
return
|
|
51
|
+
return
|
|
52
52
|
}
|
|
53
|
-
this.listenTo(
|
|
53
|
+
this.listenTo(
|
|
54
|
+
this.container,
|
|
55
|
+
Events.CONTAINER_DBLCLICK,
|
|
56
|
+
this.handleRewindClicks,
|
|
57
|
+
)
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
setBack() {
|
|
57
|
-
this.position = 'left'
|
|
61
|
+
this.position = 'left'
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
handleRewindClicks() {
|
|
61
|
-
if (
|
|
62
|
-
this.
|
|
65
|
+
if (
|
|
66
|
+
this.core.getPlaybackType() === Playback.LIVE &&
|
|
67
|
+
!this.container.isDvrEnabled()
|
|
68
|
+
) {
|
|
69
|
+
this.toggleFullscreen()
|
|
63
70
|
|
|
64
|
-
return
|
|
71
|
+
return
|
|
65
72
|
}
|
|
66
73
|
if (Browser.isMobile) {
|
|
67
74
|
if (this.position === 'left') {
|
|
68
|
-
const seekPos = this.container.getCurrentTime() - 10
|
|
75
|
+
const seekPos = this.container.getCurrentTime() - 10
|
|
69
76
|
|
|
70
77
|
if (seekPos < 0) {
|
|
71
|
-
return
|
|
78
|
+
return
|
|
72
79
|
}
|
|
73
|
-
this.container.seek(seekPos)
|
|
80
|
+
this.container.seek(seekPos)
|
|
74
81
|
} else if (this.position === 'right') {
|
|
75
|
-
const seekPos = this.container.getCurrentTime() + 30
|
|
82
|
+
const seekPos = this.container.getCurrentTime() + 30
|
|
76
83
|
|
|
77
84
|
if (seekPos > this.container.getDuration()) {
|
|
78
|
-
return
|
|
85
|
+
return
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
this.container.seek(seekPos)
|
|
88
|
+
this.container.seek(seekPos)
|
|
82
89
|
} else {
|
|
83
|
-
this.toggleFullscreen()
|
|
90
|
+
this.toggleFullscreen()
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
setMidClick() {
|
|
89
|
-
this.position = 'mid'
|
|
96
|
+
this.position = 'mid'
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
setForward() {
|
|
93
|
-
this.position = 'right'
|
|
100
|
+
this.position = 'right'
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
toggleFullscreen() {
|
|
97
|
-
this.trigger(Events.MEDIACONTROL_FULLSCREEN, this.name)
|
|
98
|
-
this.container.fullscreen()
|
|
99
|
-
this.core.toggleFullscreen()
|
|
104
|
+
this.trigger(Events.MEDIACONTROL_FULLSCREEN, this.name)
|
|
105
|
+
this.container.fullscreen()
|
|
106
|
+
this.core.toggleFullscreen()
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
override render() {
|
|
103
|
-
this.$el.html(template(pluginHtml))
|
|
110
|
+
this.$el.html(template(pluginHtml))
|
|
104
111
|
|
|
105
112
|
if (this.core.activeContainer) {
|
|
106
|
-
this.core.activeContainer.$el.append(this.el)
|
|
113
|
+
this.core.activeContainer.$el.append(this.el)
|
|
107
114
|
}
|
|
108
115
|
|
|
109
|
-
this.bindEvents()
|
|
116
|
+
this.bindEvents()
|
|
110
117
|
|
|
111
|
-
return this
|
|
118
|
+
return this
|
|
112
119
|
}
|
|
113
120
|
}
|
|
@@ -13,6 +13,7 @@ import stringHTML from '../../../assets/subtitles/string.ejs'
|
|
|
13
13
|
|
|
14
14
|
import { isFullscreen } from '../utils/fullscreen.js'
|
|
15
15
|
import type { ZeptoResult } from '../../types.js'
|
|
16
|
+
import { ExtendedEvents } from '../media-control/MediaControl.js'
|
|
16
17
|
|
|
17
18
|
const VERSION: string = '2.19.14'
|
|
18
19
|
|
|
@@ -114,7 +115,11 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
private get preselectedLanguage(): string {
|
|
117
|
-
return
|
|
118
|
+
return (
|
|
119
|
+
this.core.options.cc?.language ??
|
|
120
|
+
this.core.options.subtitles?.language ??
|
|
121
|
+
''
|
|
122
|
+
)
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
/**
|
|
@@ -135,9 +140,10 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
135
140
|
const mediaControl = this.core.getPlugin('media_control')
|
|
136
141
|
assert(mediaControl, 'media_control plugin is required')
|
|
137
142
|
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.render)
|
|
143
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, this.hideMenu)
|
|
138
144
|
this.listenTo(
|
|
139
145
|
mediaControl,
|
|
140
|
-
|
|
146
|
+
ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE,
|
|
141
147
|
this.hideMenu,
|
|
142
148
|
)
|
|
143
149
|
}
|
|
@@ -386,18 +392,20 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
386
392
|
}
|
|
387
393
|
|
|
388
394
|
private hideMenu() {
|
|
395
|
+
trace(`${T} hideMenu`)
|
|
389
396
|
;(this.$('[data-cc] ul') as ZeptoResult).hide()
|
|
390
397
|
}
|
|
391
398
|
|
|
392
399
|
private toggleMenu() {
|
|
393
400
|
trace(`${T} toggleMenu`)
|
|
394
|
-
|
|
401
|
+
this.core
|
|
402
|
+
.getPlugin('media_control')
|
|
403
|
+
.trigger(ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE)
|
|
404
|
+
this.$el.find('[data-cc] ul').toggle()
|
|
395
405
|
}
|
|
396
406
|
|
|
397
407
|
private itemElement(id: number): ZeptoResult {
|
|
398
|
-
return (
|
|
399
|
-
this.$(`ul li a[data-cc-select="${id}"]`) as ZeptoResult
|
|
400
|
-
).parent()
|
|
408
|
+
return (this.$(`ul li a[data-cc-select="${id}"]`) as ZeptoResult).parent()
|
|
401
409
|
}
|
|
402
410
|
|
|
403
411
|
private allItemElements(): ZeptoResult {
|
|
@@ -453,7 +461,9 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
453
461
|
trace(`${T} highlightCurrentSubtitles`, {
|
|
454
462
|
track: this.track?.id,
|
|
455
463
|
})
|
|
456
|
-
const currentLevelElement = this.itemElement(
|
|
464
|
+
const currentLevelElement = this.itemElement(
|
|
465
|
+
this.track ? this.track.id : -1,
|
|
466
|
+
)
|
|
457
467
|
currentLevelElement
|
|
458
468
|
.addClass('current')
|
|
459
469
|
.find('a')
|