@gcorevideo/player 2.21.1 → 2.21.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/media-control/media-control.ejs +0 -5
- package/assets/media-control/media-control.scss +44 -54
- package/assets/media-control/width370.scss +3 -5
- package/assets/subtitles/combobox.ejs +7 -9
- package/assets/subtitles/style.scss +8 -15
- package/dist/core.js +4 -1
- package/dist/index.css +733 -750
- package/dist/index.js +135 -159
- package/dist/plugins/index.css +1401 -1418
- package/dist/plugins/index.js +124 -155
- package/lib/playback/BasePlayback.d.ts +1 -0
- package/lib/playback/BasePlayback.d.ts.map +1 -1
- package/lib/playback/BasePlayback.js +3 -0
- package/lib/playback.types.d.ts +5 -0
- package/lib/playback.types.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.d.ts +1 -1
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +2 -1
- package/lib/plugins/media-control/MediaControl.d.ts +0 -1
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +7 -5
- package/lib/plugins/playback-rate/PlaybackRate.d.ts +1 -0
- package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
- package/lib/plugins/playback-rate/PlaybackRate.js +1 -0
- package/lib/plugins/subtitles/Subtitles.d.ts +21 -19
- package/lib/plugins/subtitles/Subtitles.d.ts.map +1 -1
- package/lib/plugins/subtitles/Subtitles.js +121 -151
- package/package.json +1 -1
- package/src/playback/BasePlayback.ts +4 -0
- package/src/playback.types.ts +6 -0
- package/src/plugins/bottom-gear/BottomGear.ts +3 -1
- package/src/plugins/media-control/MediaControl.ts +37 -20
- package/src/plugins/playback-rate/PlaybackRate.ts +1 -0
- package/src/plugins/subtitles/Subtitles.ts +144 -179
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -171,8 +171,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
171
171
|
|
|
172
172
|
private $seekBarScrubber: ZeptoResult | null = null
|
|
173
173
|
|
|
174
|
-
private $subtitlesSelector: ZeptoResult | null = null
|
|
175
|
-
|
|
176
174
|
private $volumeBarContainer: ZeptoResult | null = null
|
|
177
175
|
|
|
178
176
|
private $volumeBarBackground: ZeptoResult | null = null
|
|
@@ -203,7 +201,8 @@ export class MediaControl extends UICorePlugin {
|
|
|
203
201
|
|
|
204
202
|
private get disabled() {
|
|
205
203
|
const playbackIsNOOP =
|
|
206
|
-
this.core.activeContainer &&
|
|
204
|
+
this.core.activeContainer &&
|
|
205
|
+
this.core.activeContainer.getPlaybackType() === Playback.NO_OP
|
|
207
206
|
|
|
208
207
|
return this.userDisabled || playbackIsNOOP
|
|
209
208
|
}
|
|
@@ -296,9 +295,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
296
295
|
this.bindKeyEvents()
|
|
297
296
|
|
|
298
297
|
this.userDisabled = false
|
|
299
|
-
if (
|
|
300
|
-
this.options.chromeless
|
|
301
|
-
) {
|
|
298
|
+
if (this.options.chromeless) {
|
|
302
299
|
this.disable()
|
|
303
300
|
}
|
|
304
301
|
|
|
@@ -364,9 +361,21 @@ export class MediaControl extends UICorePlugin {
|
|
|
364
361
|
}
|
|
365
362
|
|
|
366
363
|
private bindContainerEvents() {
|
|
367
|
-
this.listenTo(
|
|
368
|
-
|
|
369
|
-
|
|
364
|
+
this.listenTo(
|
|
365
|
+
this.core.activeContainer,
|
|
366
|
+
Events.CONTAINER_PLAY,
|
|
367
|
+
this.changeTogglePlay,
|
|
368
|
+
)
|
|
369
|
+
this.listenTo(
|
|
370
|
+
this.core.activeContainer,
|
|
371
|
+
Events.CONTAINER_PAUSE,
|
|
372
|
+
this.changeTogglePlay,
|
|
373
|
+
)
|
|
374
|
+
this.listenTo(
|
|
375
|
+
this.core.activeContainer,
|
|
376
|
+
Events.CONTAINER_STOP,
|
|
377
|
+
this.changeTogglePlay,
|
|
378
|
+
)
|
|
370
379
|
this.listenTo(
|
|
371
380
|
this.core.activeContainer,
|
|
372
381
|
Events.CONTAINER_DBLCLICK,
|
|
@@ -408,7 +417,11 @@ export class MediaControl extends UICorePlugin {
|
|
|
408
417
|
this.enable,
|
|
409
418
|
)
|
|
410
419
|
this.listenTo(this.core.activeContainer, Events.CONTAINER_ENDED, this.ended)
|
|
411
|
-
this.listenTo(
|
|
420
|
+
this.listenTo(
|
|
421
|
+
this.core.activeContainer,
|
|
422
|
+
Events.CONTAINER_VOLUME,
|
|
423
|
+
this.onVolumeChanged,
|
|
424
|
+
)
|
|
412
425
|
this.listenTo(
|
|
413
426
|
this.core.activeContainer,
|
|
414
427
|
Events.CONTAINER_OPTIONS_CHANGE,
|
|
@@ -977,11 +990,15 @@ export class MediaControl extends UICorePlugin {
|
|
|
977
990
|
}
|
|
978
991
|
|
|
979
992
|
private settingsUpdate() {
|
|
980
|
-
const newSettings = $.extend(
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
993
|
+
const newSettings = $.extend(
|
|
994
|
+
true,
|
|
995
|
+
{
|
|
996
|
+
left: [],
|
|
997
|
+
default: [],
|
|
998
|
+
right: [],
|
|
999
|
+
},
|
|
1000
|
+
this.core.activeContainer?.settings,
|
|
1001
|
+
)
|
|
985
1002
|
|
|
986
1003
|
newSettings.left = orderByOrderPattern(
|
|
987
1004
|
[...newSettings.left, 'clipsText', 'volume'],
|
|
@@ -1055,9 +1072,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
1055
1072
|
this.$volumeBarBackground = this.$el.find('.bar-background[data-volume]')
|
|
1056
1073
|
this.$volumeBarFill = this.$el.find('.bar-fill-1[data-volume]')
|
|
1057
1074
|
this.$volumeBarScrubber = this.$el.find('.bar-scrubber[data-volume]')
|
|
1058
|
-
this.$subtitlesSelector = this.$el.find(
|
|
1059
|
-
'.media-control-subtitles[data-subtitles]',
|
|
1060
|
-
)
|
|
1061
1075
|
this.$playbackRate = this.$el.find(
|
|
1062
1076
|
'.media-control-playbackrate[data-playbackrate]',
|
|
1063
1077
|
)
|
|
@@ -1107,7 +1121,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
1107
1121
|
case 'seekBarContainer':
|
|
1108
1122
|
return this.$seekBarContainer
|
|
1109
1123
|
case 'subtitlesSelector':
|
|
1110
|
-
return
|
|
1124
|
+
return null
|
|
1111
1125
|
}
|
|
1112
1126
|
}
|
|
1113
1127
|
|
|
@@ -1116,10 +1130,13 @@ export class MediaControl extends UICorePlugin {
|
|
|
1116
1130
|
case 'audioTracksSelector':
|
|
1117
1131
|
this.getRightPanel().append(element)
|
|
1118
1132
|
break
|
|
1133
|
+
case 'gear':
|
|
1134
|
+
this.getRightPanel().append(element)
|
|
1135
|
+
break
|
|
1119
1136
|
case 'pip':
|
|
1120
1137
|
this.getRightPanel().append(element)
|
|
1121
1138
|
break
|
|
1122
|
-
case '
|
|
1139
|
+
case 'subtitlesSelector':
|
|
1123
1140
|
this.getRightPanel().append(element)
|
|
1124
1141
|
break
|
|
1125
1142
|
}
|
|
@@ -46,6 +46,7 @@ const T = 'plugins.playback_rate';
|
|
|
46
46
|
* - {@link BottomGear | bottom_gear}
|
|
47
47
|
*
|
|
48
48
|
* It renders a button in the gear menu, which opens a dropdown with the options to change the playback rate.
|
|
49
|
+
* Note that the playback rate change is supported only for VOD or DVR enabled live streams.
|
|
49
50
|
*/
|
|
50
51
|
export class PlaybackRate extends UICorePlugin {
|
|
51
52
|
private playbackRates: PlaybackRateOption[] = DEFAULT_PLAYBACK_RATES;
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Events,
|
|
3
|
-
UICorePlugin,
|
|
4
|
-
Browser,
|
|
5
|
-
template,
|
|
6
|
-
$,
|
|
7
|
-
} from '@clappr/core'
|
|
1
|
+
import { Events, UICorePlugin, Browser, template, $ } from '@clappr/core'
|
|
8
2
|
import { reportError, trace } from '@gcorevideo/utils'
|
|
9
3
|
import assert from 'assert'
|
|
10
4
|
|
|
11
5
|
import { CLAPPR_VERSION } from '../../build.js'
|
|
6
|
+
import type { TextTrackItem } from '../../playback.types.js'
|
|
12
7
|
|
|
13
8
|
import '../../../assets/subtitles/style.scss'
|
|
14
9
|
import subtitlesOffIcon from '../../../assets/icons/new/subtitles-off.svg'
|
|
@@ -21,18 +16,17 @@ import type { ZeptoResult } from '../../types.js'
|
|
|
21
16
|
|
|
22
17
|
const VERSION: string = '2.19.14'
|
|
23
18
|
|
|
24
|
-
const LOCAL_STORAGE_SUBTITLES_ID =
|
|
25
|
-
'gplayer.plugins.subtitles.selected'
|
|
19
|
+
const LOCAL_STORAGE_SUBTITLES_ID = 'gplayer.plugins.subtitles.selected'
|
|
26
20
|
|
|
27
21
|
const T = 'plugins.subtitles'
|
|
28
22
|
|
|
29
|
-
type
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
export type SubtitlesPluginSettings = {
|
|
24
|
+
/**
|
|
25
|
+
* Initially selected subtitles language
|
|
26
|
+
*/
|
|
27
|
+
language?: string
|
|
32
28
|
}
|
|
33
29
|
|
|
34
|
-
const NO_TRACK = { language: 'off' }
|
|
35
|
-
|
|
36
30
|
/**
|
|
37
31
|
* `PLUGIN` that provides a UI to select the subtitles when available.
|
|
38
32
|
* @beta
|
|
@@ -42,10 +36,7 @@ const NO_TRACK = { language: 'off' }
|
|
|
42
36
|
*
|
|
43
37
|
* - {@link MediaControl}
|
|
44
38
|
*
|
|
45
|
-
* Configuration options
|
|
46
|
-
*
|
|
47
|
-
* - subtitles.language - The language of the subtitles to select by default.
|
|
48
|
-
*
|
|
39
|
+
* Configuration options - {@link SubtitlesPluginSettings}
|
|
49
40
|
* @example
|
|
50
41
|
* ```ts
|
|
51
42
|
* import { Subtitles } from '@gcorevideo/player'
|
|
@@ -61,15 +52,13 @@ const NO_TRACK = { language: 'off' }
|
|
|
61
52
|
* ```
|
|
62
53
|
*/
|
|
63
54
|
export class Subtitles extends UICorePlugin {
|
|
64
|
-
private currentLevel: TextTrackInfo | null = null
|
|
65
|
-
|
|
66
55
|
private isPreselectedApplied = false
|
|
67
56
|
|
|
68
57
|
private isShowing = false
|
|
69
58
|
|
|
70
|
-
private track:
|
|
59
|
+
private track: TextTrackItem | null = null
|
|
71
60
|
|
|
72
|
-
private tracks:
|
|
61
|
+
private tracks: TextTrackItem[] = []
|
|
73
62
|
|
|
74
63
|
private $string: ZeptoResult | null = null
|
|
75
64
|
|
|
@@ -103,7 +92,7 @@ export class Subtitles extends UICorePlugin {
|
|
|
103
92
|
*/
|
|
104
93
|
override get attributes() {
|
|
105
94
|
return {
|
|
106
|
-
class:
|
|
95
|
+
class: 'media-control-subtitles',
|
|
107
96
|
'data-subtitles': '',
|
|
108
97
|
}
|
|
109
98
|
}
|
|
@@ -113,51 +102,62 @@ export class Subtitles extends UICorePlugin {
|
|
|
113
102
|
*/
|
|
114
103
|
override get events() {
|
|
115
104
|
return {
|
|
116
|
-
'click [data-subtitles-select]': '
|
|
117
|
-
'click [data-subtitles-button]': '
|
|
105
|
+
'click [data-subtitles-select]': 'onItemSelect',
|
|
106
|
+
'click [data-subtitles-button]': 'toggleMenu',
|
|
118
107
|
}
|
|
119
108
|
}
|
|
120
109
|
|
|
121
110
|
private get preselectedLanguage(): string {
|
|
122
|
-
return this.core.options.subtitles?.language ?? '
|
|
111
|
+
return this.core.options.subtitles?.language ?? ''
|
|
123
112
|
}
|
|
124
113
|
|
|
125
114
|
/**
|
|
126
115
|
* @internal
|
|
127
116
|
*/
|
|
128
117
|
override bindEvents() {
|
|
129
|
-
|
|
130
|
-
assert(mediaControl, 'media_control plugin is required')
|
|
118
|
+
this.listenTo(this.core, Events.CORE_READY, this.onCoreReady)
|
|
131
119
|
this.listenTo(this.core, Events.CORE_RESIZE, this.playerResize)
|
|
132
120
|
this.listenTo(
|
|
133
121
|
this.core,
|
|
134
122
|
Events.CORE_ACTIVE_CONTAINER_CHANGED,
|
|
135
|
-
this.
|
|
123
|
+
this.onContainerChanged,
|
|
136
124
|
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private onCoreReady() {
|
|
128
|
+
trace(`${T} onCoreReady`)
|
|
129
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
130
|
+
assert(mediaControl, 'media_control plugin is required')
|
|
137
131
|
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.render)
|
|
138
132
|
this.listenTo(
|
|
139
133
|
mediaControl,
|
|
140
134
|
Events.MEDIACONTROL_HIDE,
|
|
141
|
-
this.
|
|
135
|
+
this.hideMenu,
|
|
142
136
|
)
|
|
143
137
|
}
|
|
144
138
|
|
|
145
|
-
private
|
|
139
|
+
private onContainerChanged() {
|
|
140
|
+
trace(`${T} onContainerChanged`)
|
|
146
141
|
this.listenTo(
|
|
147
142
|
this.core.activeContainer,
|
|
148
143
|
Events.CONTAINER_FULLSCREEN,
|
|
149
144
|
this.playerResize,
|
|
150
145
|
)
|
|
151
|
-
this.listenToOnce(
|
|
152
|
-
this.core.activePlayback,
|
|
153
|
-
Events.PLAYBACK_PLAY,
|
|
154
|
-
this.getTracks,
|
|
155
|
-
)
|
|
156
146
|
this.listenTo(
|
|
157
147
|
this.core.activeContainer,
|
|
158
148
|
'container:advertisement:start',
|
|
159
149
|
this.onStartAd,
|
|
160
150
|
)
|
|
151
|
+
this.listenTo(
|
|
152
|
+
this.core.activePlayback,
|
|
153
|
+
Events.PLAYBACK_SUBTITLE_AVAILABLE,
|
|
154
|
+
this.onSubtitleAvailable,
|
|
155
|
+
)
|
|
156
|
+
this.listenTo(
|
|
157
|
+
this.core.activePlayback,
|
|
158
|
+
Events.PLAYBACK_SUBTITLE_CHANGED,
|
|
159
|
+
this.onSubtitleChanged,
|
|
160
|
+
)
|
|
161
161
|
|
|
162
162
|
// fix for iOS
|
|
163
163
|
const video = this.core.activePlayback.el
|
|
@@ -176,20 +176,52 @@ export class Subtitles extends UICorePlugin {
|
|
|
176
176
|
})
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
private
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
179
|
+
private onSubtitleAvailable() {
|
|
180
|
+
trace(`${T} onSubtitleAvailable`)
|
|
181
|
+
this.applyTracks()
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private onSubtitleChanged({ id }: { id: number }) {
|
|
185
|
+
trace(`${T} onSubtitleChanged`, { id })
|
|
186
|
+
if (id === -1) {
|
|
187
|
+
this.clearSubtitleText()
|
|
188
|
+
}
|
|
189
|
+
for (const track of this.tracks) {
|
|
190
|
+
if (track.id === id) {
|
|
191
|
+
track.track.mode = 'showing'
|
|
192
|
+
|
|
193
|
+
this.setSubtitleText(this.getSubtitleText(track.track))
|
|
194
|
+
|
|
195
|
+
track.track.oncuechange = (e) => {
|
|
196
|
+
try {
|
|
197
|
+
if (track.track.activeCues?.length) {
|
|
198
|
+
const html = (track.track.activeCues[0] as VTTCue).getCueAsHTML()
|
|
199
|
+
|
|
200
|
+
this.setSubtitleText(html)
|
|
201
|
+
} else {
|
|
202
|
+
this.clearSubtitleText()
|
|
203
|
+
}
|
|
204
|
+
} catch (error) {
|
|
205
|
+
reportError(error)
|
|
206
|
+
}
|
|
186
207
|
}
|
|
187
|
-
}
|
|
188
|
-
|
|
208
|
+
} else {
|
|
209
|
+
track.track.oncuechange = null
|
|
210
|
+
track.track.mode = 'hidden'
|
|
189
211
|
}
|
|
190
212
|
}
|
|
191
213
|
}
|
|
192
214
|
|
|
215
|
+
private applyTracks() {
|
|
216
|
+
try {
|
|
217
|
+
this.tracks = this.core.activePlayback.closedCaptionsTracks
|
|
218
|
+
this.applyPreselectedSubtitles()
|
|
219
|
+
this.render()
|
|
220
|
+
} catch (error) {
|
|
221
|
+
reportError(error)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
193
225
|
private onStartAd() {
|
|
194
226
|
if (this.isShowing && this.core.activeContainer) {
|
|
195
227
|
this.hide()
|
|
@@ -211,11 +243,12 @@ export class Subtitles extends UICorePlugin {
|
|
|
211
243
|
}
|
|
212
244
|
|
|
213
245
|
private playerResize() {
|
|
246
|
+
trace(`${T} playerResize`)
|
|
214
247
|
const shouldShow =
|
|
215
248
|
this.core.activeContainer &&
|
|
216
249
|
isFullscreen(this.core.activeContainer.el) &&
|
|
217
|
-
this.
|
|
218
|
-
this.
|
|
250
|
+
this.track &&
|
|
251
|
+
this.track.track.mode &&
|
|
219
252
|
Browser.isiOS &&
|
|
220
253
|
this.isShowing
|
|
221
254
|
|
|
@@ -239,7 +272,7 @@ export class Subtitles extends UICorePlugin {
|
|
|
239
272
|
this.$string.hide()
|
|
240
273
|
if (this.tracks) {
|
|
241
274
|
for (const t of this.tracks) {
|
|
242
|
-
t.mode = 'hidden'
|
|
275
|
+
t.track.mode = 'hidden'
|
|
243
276
|
}
|
|
244
277
|
}
|
|
245
278
|
}
|
|
@@ -253,26 +286,22 @@ export class Subtitles extends UICorePlugin {
|
|
|
253
286
|
if (
|
|
254
287
|
this.core.activeContainer &&
|
|
255
288
|
isFullscreen(this.core.activeContainer.el) &&
|
|
256
|
-
this.
|
|
257
|
-
this.
|
|
289
|
+
this.track &&
|
|
290
|
+
this.track.track.mode &&
|
|
258
291
|
Browser.isiOS
|
|
259
292
|
) {
|
|
260
293
|
this.$string.hide()
|
|
261
|
-
this.
|
|
294
|
+
this.track.track.mode = 'showing'
|
|
262
295
|
} else {
|
|
263
296
|
this.$string.show()
|
|
264
297
|
}
|
|
265
298
|
}
|
|
266
299
|
|
|
267
300
|
private shouldRender() {
|
|
268
|
-
return
|
|
301
|
+
return this.tracks.length > 0
|
|
269
302
|
}
|
|
270
303
|
|
|
271
304
|
private resizeFont() {
|
|
272
|
-
if (!this.core.activeContainer) {
|
|
273
|
-
return
|
|
274
|
-
}
|
|
275
|
-
|
|
276
305
|
if (!this.$string) {
|
|
277
306
|
return
|
|
278
307
|
}
|
|
@@ -294,71 +323,42 @@ export class Subtitles extends UICorePlugin {
|
|
|
294
323
|
return this
|
|
295
324
|
}
|
|
296
325
|
|
|
297
|
-
trace(`${T} render`, {
|
|
298
|
-
tracks: this.tracks?.length,
|
|
299
|
-
track: this.track?.language,
|
|
300
|
-
})
|
|
301
|
-
|
|
302
326
|
const mediaControl = this.core.getPlugin('media_control')
|
|
303
|
-
assert(mediaControl, 'media_control plugin is required')
|
|
304
327
|
|
|
305
328
|
this.$el.html(Subtitles.template({ tracks: this.tracks }))
|
|
306
329
|
this.core.activeContainer.$el.find('.subtitle-string').remove()
|
|
307
330
|
this.$string = $(Subtitles.templateString())
|
|
308
331
|
this.resizeFont()
|
|
309
332
|
|
|
310
|
-
this.core.activeContainer.$el.append(this.$string
|
|
311
|
-
|
|
312
|
-
if (ss && ss.length > 0) {
|
|
313
|
-
ss.append(this.el)
|
|
314
|
-
} else {
|
|
315
|
-
mediaControl.getRightPanel().append(this.el)
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
this.updateCurrentLevel(this.track)
|
|
319
|
-
this.highlightCurrentSubtitles()
|
|
333
|
+
this.core.activeContainer.$el.append(this.$string)
|
|
334
|
+
mediaControl.putElement('subtitlesSelector', this.$el)
|
|
320
335
|
|
|
321
|
-
this.
|
|
336
|
+
this.updateSelection()
|
|
322
337
|
|
|
323
338
|
this.renderIcon()
|
|
324
339
|
|
|
325
340
|
return this
|
|
326
341
|
}
|
|
327
342
|
|
|
328
|
-
private
|
|
329
|
-
this.tracks
|
|
330
|
-
this.render()
|
|
343
|
+
private findById(id: number) {
|
|
344
|
+
return this.tracks.find((track) => track.id === id) ?? null
|
|
331
345
|
}
|
|
332
346
|
|
|
333
|
-
private
|
|
334
|
-
if (this.tracks) {
|
|
335
|
-
for (const track of this.tracks) {
|
|
336
|
-
if (track.language === id) {
|
|
337
|
-
return track // TODO TrackInfo?
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
private selectLevel(id: string) {
|
|
347
|
+
private selectItem(item: TextTrackItem | null) {
|
|
344
348
|
this.clearSubtitleText()
|
|
345
|
-
this.track =
|
|
346
|
-
|
|
347
|
-
this.hideSelectLevelMenu()
|
|
348
|
-
if (!this.track) {
|
|
349
|
-
this.track = { language: 'off' }
|
|
350
|
-
}
|
|
349
|
+
this.track = item
|
|
351
350
|
|
|
352
|
-
this.
|
|
351
|
+
this.hideMenu()
|
|
352
|
+
this.updateSelection()
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
private
|
|
356
|
-
const id = (event.target as HTMLElement).dataset.subtitlesSelect
|
|
355
|
+
private onItemSelect(event: MouseEvent) {
|
|
356
|
+
const id = (event.target as HTMLElement).dataset.subtitlesSelect ?? '-1'
|
|
357
357
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
358
|
+
trace(`${T} onItemSelect`, { id })
|
|
359
|
+
|
|
360
|
+
localStorage.setItem(LOCAL_STORAGE_SUBTITLES_ID, id)
|
|
361
|
+
this.selectItem(this.findById(Number(id)))
|
|
362
362
|
|
|
363
363
|
return false
|
|
364
364
|
}
|
|
@@ -366,91 +366,57 @@ export class Subtitles extends UICorePlugin {
|
|
|
366
366
|
private applyPreselectedSubtitles() {
|
|
367
367
|
if (!this.isPreselectedApplied) {
|
|
368
368
|
this.isPreselectedApplied = true
|
|
369
|
+
if (!this.preselectedLanguage) {
|
|
370
|
+
return
|
|
371
|
+
}
|
|
369
372
|
setTimeout(() => {
|
|
370
|
-
this.
|
|
371
|
-
|
|
373
|
+
this.selectItem(
|
|
374
|
+
this.tracks.find(
|
|
375
|
+
(t) => t.track.language === this.preselectedLanguage,
|
|
376
|
+
) ?? null,
|
|
377
|
+
)
|
|
378
|
+
}, 300) // TODO why delay?
|
|
372
379
|
}
|
|
373
380
|
}
|
|
374
381
|
|
|
375
|
-
private
|
|
376
|
-
trace(`${T} onShowLevelSelectMenu`)
|
|
377
|
-
this.toggleContextMenu()
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
private hideSelectLevelMenu() {
|
|
382
|
+
private hideMenu() {
|
|
381
383
|
;(this.$('[data-subtitles] ul') as ZeptoResult).hide()
|
|
382
384
|
}
|
|
383
385
|
|
|
384
|
-
private
|
|
385
|
-
(this.$('[data-subtitles] ul') as ZeptoResult).toggle()
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
private buttonElement(): ZeptoResult {
|
|
389
|
-
return this.$('[data-subtitles] button')
|
|
386
|
+
private toggleMenu() {
|
|
387
|
+
;(this.$('[data-subtitles] ul') as ZeptoResult).toggle()
|
|
390
388
|
}
|
|
391
389
|
|
|
392
|
-
private
|
|
390
|
+
private itemElement(id: number): ZeptoResult {
|
|
393
391
|
return (
|
|
394
|
-
this.$(
|
|
395
|
-
'[data-subtitles] ul a' + (id ? '[data-subtitles-select="' + id + '"]' : ''),
|
|
396
|
-
) as ZeptoResult
|
|
392
|
+
this.$(`ul li a[data-subtitles-select="${id}"]`) as ZeptoResult
|
|
397
393
|
).parent()
|
|
398
394
|
}
|
|
399
395
|
|
|
400
|
-
private
|
|
401
|
-
this
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
private stopLevelSwitch() {
|
|
405
|
-
this.buttonElement().removeClass('changing')
|
|
396
|
+
private allItemElements(): ZeptoResult {
|
|
397
|
+
return this.$('[data-subtitles] li')
|
|
406
398
|
}
|
|
407
399
|
|
|
408
400
|
private selectSubtitles() {
|
|
409
|
-
|
|
410
|
-
return
|
|
411
|
-
}
|
|
401
|
+
const trackId = this.track ? this.track.id : -1
|
|
412
402
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const track = this.tracks[i]
|
|
416
|
-
if (track.language === this.currentLevel.language) {
|
|
417
|
-
track.mode = 'showing'
|
|
418
|
-
|
|
419
|
-
const currentTime = this.core.activePlayback?.getCurrentTime() ?? 0
|
|
420
|
-
const cues = track.cues
|
|
421
|
-
let subtitleText = ''
|
|
422
|
-
|
|
423
|
-
if (cues && cues.length) {
|
|
424
|
-
for (const cue of cues) {
|
|
425
|
-
if (currentTime >= cue.startTime && currentTime <= cue.endTime) {
|
|
426
|
-
subtitleText +=
|
|
427
|
-
(cue as VTTCue).getCueAsHTML().textContent + '\n'
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
this.setSubtitleText(subtitleText)
|
|
403
|
+
this.core.activePlayback.closedCaptionsTrackId = trackId
|
|
404
|
+
}
|
|
433
405
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
406
|
+
private getSubtitleText(track: TextTrack) {
|
|
407
|
+
const currentTime = this.core.activePlayback?.getCurrentTime() ?? 0
|
|
408
|
+
const cues = track.cues
|
|
409
|
+
const lines = []
|
|
438
410
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
} catch (error) {
|
|
444
|
-
// console.error(error);
|
|
445
|
-
reportError(error)
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
continue
|
|
411
|
+
if (cues && cues.length) {
|
|
412
|
+
for (const cue of cues) {
|
|
413
|
+
if (currentTime >= cue.startTime && currentTime <= cue.endTime) {
|
|
414
|
+
lines.push((cue as VTTCue).getCueAsHTML().textContent)
|
|
449
415
|
}
|
|
450
|
-
this.tracks[i].oncuechange = null
|
|
451
|
-
this.tracks[i].mode = 'hidden'
|
|
452
416
|
}
|
|
453
417
|
}
|
|
418
|
+
|
|
419
|
+
return lines.join('\n')
|
|
454
420
|
}
|
|
455
421
|
|
|
456
422
|
private setSubtitleText(text: string | DocumentFragment) {
|
|
@@ -461,9 +427,8 @@ export class Subtitles extends UICorePlugin {
|
|
|
461
427
|
this.setSubtitleText('')
|
|
462
428
|
}
|
|
463
429
|
|
|
464
|
-
private
|
|
465
|
-
this.
|
|
466
|
-
if (track.language === 'off') {
|
|
430
|
+
private updateSelection() {
|
|
431
|
+
if (!this.track) {
|
|
467
432
|
this.hide()
|
|
468
433
|
} else {
|
|
469
434
|
this.show()
|
|
@@ -473,24 +438,24 @@ export class Subtitles extends UICorePlugin {
|
|
|
473
438
|
}
|
|
474
439
|
|
|
475
440
|
private highlightCurrentSubtitles() {
|
|
476
|
-
this.
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
const currentLevelElement = this.levelElement(this.currentLevel.language)
|
|
441
|
+
this.allItemElements()
|
|
442
|
+
.removeClass('current')
|
|
443
|
+
.find('a')
|
|
444
|
+
.removeClass('gcore-skin-active')
|
|
481
445
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
}
|
|
446
|
+
trace(`${T} highlightCurrentSubtitles`, {
|
|
447
|
+
track: this.track?.id,
|
|
448
|
+
})
|
|
449
|
+
const currentLevelElement = this.itemElement(this.track ? this.track.id : -1)
|
|
450
|
+
currentLevelElement
|
|
451
|
+
.addClass('current')
|
|
452
|
+
.find('a')
|
|
453
|
+
.addClass('gcore-skin-active')
|
|
485
454
|
}
|
|
486
455
|
|
|
487
456
|
private renderIcon() {
|
|
488
457
|
const icon = this.isShowing ? subtitlesOnIcon : subtitlesOffIcon
|
|
489
458
|
|
|
490
|
-
this.
|
|
491
|
-
.getPlugin('media_control')
|
|
492
|
-
.getElement('subtitlesSelector')
|
|
493
|
-
?.find('span.subtitle-text')
|
|
494
|
-
.html(icon)
|
|
459
|
+
this.$el.find('span.subtitle-text').html(icon)
|
|
495
460
|
}
|
|
496
461
|
}
|