@gcorevideo/player 2.20.22 → 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/audio-selector/style.scss +48 -82
- package/assets/audio-selector/track-selector.ejs +3 -3
- package/assets/bottom-gear/bottomgear.ejs +10 -12
- package/assets/bottom-gear/gear-sub-menu.scss +0 -15
- package/assets/bottom-gear/gear.scss +3 -32
- package/assets/media-control/media-control.ejs +5 -25
- package/assets/media-control/media-control.scss +114 -34
- package/assets/media-control/width370.scss +35 -109
- package/assets/picture-in-picture/button.ejs +1 -1
- package/assets/picture-in-picture/button.scss +5 -4
- package/assets/subtitles/combobox.ejs +7 -9
- package/assets/subtitles/style.scss +8 -15
- package/dist/core.js +151 -23
- package/dist/index.css +897 -1000
- package/dist/index.js +416 -438
- package/dist/player.d.ts +19 -16
- package/dist/plugins/index.css +1454 -1557
- package/dist/plugins/index.js +826 -23550
- package/docs/api/player.audioselector.md +4 -59
- package/docs/api/player.md +1 -1
- package/docs/api/player.mediacontrol.getelement.md +5 -0
- package/docs/api/player.mediacontrol.md +14 -0
- package/docs/api/{player.audioselector.updatecurrenttrack.md → player.mediacontrol.putelement.md} +7 -7
- package/docs/api/player.mediacontrolelement.md +1 -1
- package/docs/api/{player.audioselector.starttrackswitch.md → player.pictureinpicture.attributes.md} +5 -7
- package/docs/api/player.pictureinpicture.md +45 -0
- package/lib/playback/BasePlayback.d.ts +1 -1
- package/lib/playback/BasePlayback.d.ts.map +1 -1
- package/lib/playback/BasePlayback.js +3 -1
- package/lib/playback/HTML5Video.d.ts +4 -0
- package/lib/playback/HTML5Video.d.ts.map +1 -1
- package/lib/playback/HTML5Video.js +53 -4
- package/lib/playback/dash-playback/DashPlayback.d.ts +5 -0
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +48 -4
- package/lib/playback/hls-playback/HlsPlayback.d.ts +31 -25
- package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
- package/lib/playback/hls-playback/HlsPlayback.js +47 -14
- package/lib/playback.types.d.ts +5 -0
- package/lib/playback.types.d.ts.map +1 -1
- package/lib/plugins/audio-selector/AudioSelector.d.ts +12 -11
- package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
- package/lib/plugins/audio-selector/AudioSelector.js +65 -185
- package/lib/plugins/bottom-gear/BottomGear.d.ts +2 -2
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +12 -10
- package/lib/plugins/level-selector/LevelSelector.js +1 -1
- package/lib/plugins/media-control/MediaControl.d.ts +3 -4
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +23 -13
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts +3 -0
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
- package/lib/plugins/picture-in-picture/PictureInPicture.js +6 -1
- 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/source-controller/SourceController.d.ts.map +1 -1
- package/lib/plugins/source-controller/SourceController.js +0 -1
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts +0 -2
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts.map +1 -1
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.js +1 -18
- 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/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +2 -0
- package/package.json +1 -1
- package/src/playback/BasePlayback.ts +4 -1
- package/src/playback/HTML5Video.ts +57 -4
- package/src/playback/dash-playback/DashPlayback.ts +64 -6
- package/src/playback/hls-playback/HlsPlayback.ts +82 -40
- package/src/playback.types.ts +6 -0
- package/src/plugins/audio-selector/AudioSelector.ts +84 -278
- package/src/plugins/bottom-gear/BottomGear.ts +14 -11
- package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +1 -3
- package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +14 -37
- package/src/plugins/level-selector/LevelSelector.ts +1 -1
- package/src/plugins/media-control/MediaControl.ts +54 -32
- package/src/plugins/picture-in-picture/PictureInPicture.ts +7 -1
- package/src/plugins/playback-rate/PlaybackRate.ts +1 -0
- package/src/plugins/source-controller/SourceController.ts +0 -1
- package/src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts +1 -20
- package/src/plugins/subtitles/Subtitles.ts +144 -179
- package/src/testUtils.ts +2 -0
- package/src/typings/globals.d.ts +19 -0
- package/temp/player.api.json +102 -143
- package/tsconfig.tsbuildinfo +1 -1
- package/assets/media-control/plugins.scss +0 -94
- package/docs/api/player.audioselector.highlightcurrenttrack.md +0 -18
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { Events, UICorePlugin, template } from '@clappr/core'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
AudioTracksUpdatedData,
|
|
6
|
-
Events as HlsEvents,
|
|
7
|
-
} from 'hls.js'
|
|
2
|
+
import { AudioTrack } from '@clappr/core/types/base/playback/playback.js'
|
|
3
|
+
import { trace } from '@gcorevideo/utils'
|
|
4
|
+
import assert from 'assert'
|
|
8
5
|
|
|
9
6
|
import { CLAPPR_VERSION } from '../../build.js'
|
|
10
7
|
|
|
@@ -12,48 +9,25 @@ import pluginHtml from '../../../assets/audio-selector/track-selector.ejs'
|
|
|
12
9
|
import '../../../assets/audio-selector/style.scss'
|
|
13
10
|
import audioArrow from '../../../assets/icons/old/quality-arrow.svg'
|
|
14
11
|
import { ZeptoResult } from '../../types.js'
|
|
15
|
-
import assert from 'assert'
|
|
16
12
|
|
|
17
13
|
const VERSION: string = '0.0.1'
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const AUTO = 0
|
|
22
|
-
|
|
23
|
-
type AudioTrackW3C = {
|
|
24
|
-
enabled: boolean
|
|
25
|
-
id: string
|
|
26
|
-
kind: string
|
|
27
|
-
label: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type AudioTrackItem = {
|
|
31
|
-
id: number
|
|
32
|
-
label: string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type AudioTrackList = {
|
|
36
|
-
length: number
|
|
37
|
-
addEventListener(
|
|
38
|
-
type: 'change' | 'addtrack' | 'removetrack',
|
|
39
|
-
listener: EventListenerOrEventListenerObject,
|
|
40
|
-
): void
|
|
41
|
-
getTrackById(id: string): AudioTrackW3C | null
|
|
42
|
-
[Symbol.iterator](): IterableIterator<AudioTrackW3C>
|
|
43
|
-
}
|
|
15
|
+
const T = 'plugins.audio_selector'
|
|
44
16
|
|
|
45
17
|
/**
|
|
46
|
-
* `PLUGIN` that
|
|
18
|
+
* `PLUGIN` that makes possible to switch audio tracks via the media control UI.
|
|
47
19
|
* @beta
|
|
20
|
+
* @remarks
|
|
21
|
+
* The plugin is activated when there are multiple audio tracks available.
|
|
22
|
+
* The plugin adds a button showing the current audio track and a dropdown to switch to another audio track.
|
|
23
|
+
* Depends on:
|
|
24
|
+
*
|
|
25
|
+
* - {@link MediaControl}
|
|
48
26
|
*/
|
|
49
27
|
export class AudioSelector extends UICorePlugin {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
private selectedTrackId: number | undefined
|
|
28
|
+
private currentTrack: AudioTrack | null = null
|
|
53
29
|
|
|
54
|
-
private
|
|
55
|
-
|
|
56
|
-
private tracks: AudioTrackItem[] = []
|
|
30
|
+
private tracks: AudioTrack[] = []
|
|
57
31
|
|
|
58
32
|
/**
|
|
59
33
|
* @internal
|
|
@@ -83,7 +57,7 @@ export class AudioSelector extends UICorePlugin {
|
|
|
83
57
|
*/
|
|
84
58
|
override get attributes() {
|
|
85
59
|
return {
|
|
86
|
-
class:
|
|
60
|
+
class: 'media-control-audio-tracks',
|
|
87
61
|
'data-track-selector': '',
|
|
88
62
|
}
|
|
89
63
|
}
|
|
@@ -102,148 +76,73 @@ export class AudioSelector extends UICorePlugin {
|
|
|
102
76
|
* @internal
|
|
103
77
|
*/
|
|
104
78
|
override bindEvents() {
|
|
105
|
-
this.listenTo(this.core, Events.CORE_READY, this.
|
|
106
|
-
// TODO CORE_ACTIVE_CONTAINER_CHANGED
|
|
79
|
+
this.listenTo(this.core, Events.CORE_READY, this.onCoreReady)
|
|
107
80
|
this.listenTo(
|
|
108
|
-
this.core
|
|
109
|
-
Events.
|
|
110
|
-
this.
|
|
111
|
-
)
|
|
112
|
-
this.listenTo(
|
|
113
|
-
this.core.mediaControl,
|
|
114
|
-
Events.MEDIACONTROL_RENDERED,
|
|
115
|
-
this.render,
|
|
81
|
+
this.core,
|
|
82
|
+
Events.CORE_ACTIVE_CONTAINER_CHANGED,
|
|
83
|
+
this.onActiveContainerChanged,
|
|
116
84
|
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private onCoreReady() {
|
|
88
|
+
trace(`${T} onCoreReady`)
|
|
89
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
90
|
+
assert(mediaControl, 'media_control plugin is required')
|
|
91
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.render)
|
|
117
92
|
this.listenTo(
|
|
118
|
-
|
|
93
|
+
mediaControl,
|
|
119
94
|
Events.MEDIACONTROL_HIDE,
|
|
120
95
|
this.hideSelectTrackMenu,
|
|
121
96
|
)
|
|
122
97
|
}
|
|
123
98
|
|
|
124
|
-
private unBindEvents() {
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
this.stopListening(this.core, Events.CORE_READY)
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
this.stopListening(
|
|
129
|
-
this.core.mediaControl,
|
|
130
|
-
Events.MEDIACONTROL_CONTAINERCHANGED,
|
|
131
|
-
)
|
|
132
|
-
// @ts-ignore
|
|
133
|
-
this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_RENDERED)
|
|
134
|
-
// @ts-ignore
|
|
135
|
-
this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_HIDE)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
99
|
private bindPlaybackEvents() {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
this.
|
|
142
|
-
const currentPlayback = this.core.activePlayback
|
|
143
|
-
|
|
144
|
-
this.listenTo(currentPlayback, Events.PLAYBACK_STOP, this.onStop)
|
|
100
|
+
trace(`${T} bindPlaybackEvents`)
|
|
101
|
+
this.currentTrack = null
|
|
102
|
+
this.listenTo(this.core.activePlayback, Events.PLAYBACK_STOP, this.onStop)
|
|
145
103
|
this.setupAudioTrackListeners()
|
|
146
104
|
}
|
|
147
105
|
|
|
148
106
|
private setupAudioTrackListeners() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
this.fillTracks(
|
|
173
|
-
data.audioTracks.map((p) => ({
|
|
174
|
-
id: p.id,
|
|
175
|
-
label: p.name,
|
|
176
|
-
})),
|
|
177
|
-
defaultTrack?.id,
|
|
178
|
-
)
|
|
179
|
-
},
|
|
180
|
-
)
|
|
181
|
-
currentPlayback._hls.on(
|
|
182
|
-
HlsEvents.AUDIO_TRACK_SWITCHING,
|
|
183
|
-
this.startTrackSwitch.bind(this),
|
|
184
|
-
)
|
|
185
|
-
currentPlayback._hls.on(
|
|
186
|
-
HlsEvents.AUDIO_TRACK_SWITCHED,
|
|
187
|
-
this.updateCurrentTrack.bind(this),
|
|
188
|
-
)
|
|
189
|
-
currentPlayback._hls.on(
|
|
190
|
-
HlsEvents.AUDIO_TRACK_LOADED,
|
|
191
|
-
this.updateCurrentTrack.bind(this),
|
|
192
|
-
)
|
|
193
|
-
} else {
|
|
194
|
-
this.listenToOnce(currentPlayback, Events.PLAYBACK_PLAY, () => {
|
|
195
|
-
const mediaElement = currentPlayback.$el.get(0)
|
|
196
|
-
// const { audioTracks } = currentPlayback.$el.get(0);
|
|
197
|
-
const audioTracks: AudioTrackList = mediaElement.audioTracks
|
|
198
|
-
|
|
199
|
-
if (audioTracks && audioTracks.length) {
|
|
200
|
-
let index = 0
|
|
201
|
-
const trackItems: AudioTrackItem[] = []
|
|
202
|
-
for (const audioTrack of audioTracks) {
|
|
203
|
-
if (audioTrack.enabled) {
|
|
204
|
-
const t = {
|
|
205
|
-
id: index,
|
|
206
|
-
label: audioTrack.label,
|
|
207
|
-
}
|
|
208
|
-
this.currentTrack = t
|
|
209
|
-
trackItems.push(t)
|
|
210
|
-
index++
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
audioTracks.addEventListener('change', () =>
|
|
215
|
-
this.updateCurrentTrackW3C(),
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
this.fillTracks(trackItems, trackItems[0].id)
|
|
219
|
-
}
|
|
220
|
-
})
|
|
221
|
-
}
|
|
107
|
+
this.listenTo(
|
|
108
|
+
this.core.activePlayback,
|
|
109
|
+
Events.PLAYBACK_AUDIO_AVAILABLE,
|
|
110
|
+
(tracks: AudioTrack[]) => {
|
|
111
|
+
trace(`${T} on PLAYBACK_AUDIO_AVAILABLE`, { audioTracks: tracks })
|
|
112
|
+
this.currentTrack =
|
|
113
|
+
tracks.find((track) => track.kind === 'main') ?? null
|
|
114
|
+
this.fillTracks(tracks)
|
|
115
|
+
},
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
this.listenTo(
|
|
119
|
+
this.core.activePlayback,
|
|
120
|
+
Events.PLAYBACK_AUDIO_CHANGED,
|
|
121
|
+
(track: AudioTrack) => {
|
|
122
|
+
trace(`${T} PLAYBACK_AUDIO_CHANGED`, { audioTrack: track })
|
|
123
|
+
this.currentTrack = track
|
|
124
|
+
this.highlightCurrentTrack()
|
|
125
|
+
this.buttonElement().removeClass('changing')
|
|
126
|
+
this.updateText()
|
|
127
|
+
},
|
|
128
|
+
)
|
|
222
129
|
}
|
|
223
130
|
|
|
224
|
-
private onStop() {
|
|
131
|
+
private onStop() {
|
|
132
|
+
trace(`${T} onStop`)
|
|
133
|
+
}
|
|
225
134
|
|
|
226
|
-
private
|
|
227
|
-
|
|
228
|
-
this.bindEvents()
|
|
135
|
+
private onActiveContainerChanged() {
|
|
136
|
+
trace(`${T} onActiveContainerChanged`)
|
|
229
137
|
this.bindPlaybackEvents()
|
|
230
138
|
}
|
|
231
139
|
|
|
232
140
|
private shouldRender() {
|
|
233
|
-
if (!this.core.
|
|
234
|
-
return false
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const currentPlayback = this.core.activePlayback
|
|
238
|
-
|
|
239
|
-
if (!currentPlayback) {
|
|
141
|
+
if (!this.core.activePlayback) {
|
|
240
142
|
return false
|
|
241
143
|
}
|
|
242
144
|
|
|
243
|
-
|
|
244
|
-
currentPlayback.activePlayback._hls || currentPlayback.$el.get(0)
|
|
245
|
-
|
|
246
|
-
this.tracks = audioTracks
|
|
145
|
+
this.tracks = this.core.activePlayback.audioTracks
|
|
247
146
|
|
|
248
147
|
// Only care if we have at least 2 to choose from
|
|
249
148
|
return this.tracks && this.tracks.length > 1
|
|
@@ -258,76 +157,41 @@ export class AudioSelector extends UICorePlugin {
|
|
|
258
157
|
}
|
|
259
158
|
|
|
260
159
|
const mediaControl = this.core.getPlugin('media_control')
|
|
261
|
-
assert(mediaControl, 'media_control plugin is required')
|
|
262
160
|
this.$el.html(
|
|
263
161
|
AudioSelector.template({ tracks: this.tracks, title: this.getTitle() }),
|
|
264
162
|
)
|
|
163
|
+
this.$('.audio-arrow').append(audioArrow)
|
|
164
|
+
mediaControl.putElement('audioTracksSelector', this.$el)
|
|
265
165
|
|
|
266
|
-
|
|
267
|
-
if (!(ats && ats.length > 0)) {
|
|
268
|
-
return this
|
|
269
|
-
}
|
|
270
|
-
ats.append(this.el)
|
|
271
|
-
|
|
166
|
+
this.updateText()
|
|
272
167
|
this.highlightCurrentTrack()
|
|
273
168
|
|
|
274
|
-
const aa = ats.find('audioArrow')
|
|
275
|
-
if (aa.length > 0) {
|
|
276
|
-
aa.append(audioArrow)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
169
|
return this
|
|
280
170
|
}
|
|
281
171
|
|
|
282
|
-
private fillTracks(tracks:
|
|
283
|
-
if (this.selectedTrackId === undefined) {
|
|
284
|
-
this.selectedTrackId = selected
|
|
285
|
-
}
|
|
286
|
-
// this.tracks = levels.audioTracks;
|
|
287
|
-
// for (let i = 0; i < this.tracks.length; i++) {
|
|
288
|
-
// if (this.tracks[i].name && !this.tracks[i].label) {
|
|
289
|
-
// this.tracks[i].label = this.tracks[i].name;
|
|
290
|
-
// }
|
|
291
|
-
// }
|
|
172
|
+
private fillTracks(tracks: AudioTrack[]) {
|
|
292
173
|
this.tracks = tracks
|
|
293
|
-
|
|
294
|
-
// Player.player.trigger('tracks', this.tracks);
|
|
295
|
-
// this.core.trigger('tracks', this.tracks);
|
|
296
174
|
this.render()
|
|
297
175
|
}
|
|
298
176
|
|
|
299
|
-
private findTrackBy(id:
|
|
177
|
+
private findTrackBy(id: string) {
|
|
300
178
|
return this.tracks.find((track) => track.id === id)
|
|
301
179
|
}
|
|
302
180
|
|
|
303
181
|
private onTrackSelect(event: MouseEvent) {
|
|
304
|
-
// this.selectedTrackId = parseInt(event.target.dataset.levelSelectorSelect, 10)
|
|
305
182
|
const id = (event.target as HTMLElement)?.dataset?.trackSelectorSelect
|
|
306
183
|
if (id) {
|
|
307
|
-
this.
|
|
184
|
+
this.selectAudioTrack(id)
|
|
308
185
|
}
|
|
309
186
|
this.toggleContextMenu()
|
|
310
187
|
event.stopPropagation()
|
|
311
188
|
return false
|
|
312
189
|
}
|
|
313
190
|
|
|
314
|
-
private
|
|
315
|
-
this.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
this.core.activePlayback._hls.audioTrack.id === this.selectedTrackId
|
|
319
|
-
) {
|
|
320
|
-
return
|
|
321
|
-
}
|
|
322
|
-
this.core.activePlayback._hls.audioTrack = this.selectedTrackId
|
|
323
|
-
} else {
|
|
324
|
-
const { audioTracks } = this.core.activePlayback.$el.get(0)
|
|
325
|
-
|
|
326
|
-
for (const track of audioTracks) {
|
|
327
|
-
track.enabled = track.id === this.selectedTrackId
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
this.updateText(this.selectedTrackId)
|
|
191
|
+
private selectAudioTrack(id: string) {
|
|
192
|
+
this.startTrackSwitch()
|
|
193
|
+
this.core.activePlayback.switchAudioTrack(id)
|
|
194
|
+
this.updateText()
|
|
331
195
|
}
|
|
332
196
|
|
|
333
197
|
private onShowLevelSelectMenu() {
|
|
@@ -335,112 +199,54 @@ export class AudioSelector extends UICorePlugin {
|
|
|
335
199
|
}
|
|
336
200
|
|
|
337
201
|
private hideSelectTrackMenu() {
|
|
338
|
-
;(this.$('
|
|
202
|
+
;(this.$('ul') as ZeptoResult).hide()
|
|
339
203
|
}
|
|
340
204
|
|
|
341
205
|
private toggleContextMenu() {
|
|
342
|
-
;(this.$('
|
|
206
|
+
;(this.$('ul') as ZeptoResult).toggle()
|
|
343
207
|
}
|
|
344
208
|
|
|
345
209
|
private buttonElement(): ZeptoResult {
|
|
346
|
-
return this.$('
|
|
210
|
+
return this.$('button')
|
|
347
211
|
}
|
|
348
212
|
|
|
349
213
|
private buttonElementText(): ZeptoResult {
|
|
350
|
-
return this.$('
|
|
214
|
+
return this.$('button .audio-text')
|
|
351
215
|
}
|
|
352
216
|
|
|
353
|
-
private trackElement(id?:
|
|
217
|
+
private trackElement(id?: string): ZeptoResult {
|
|
354
218
|
return (
|
|
355
219
|
this.$(
|
|
356
|
-
'
|
|
220
|
+
'ul a' +
|
|
357
221
|
(id !== undefined ? '[data-track-selector-select="' + id + '"]' : ''),
|
|
358
222
|
) as ZeptoResult
|
|
359
223
|
).parent()
|
|
360
224
|
}
|
|
361
225
|
|
|
362
226
|
private getTitle(): string {
|
|
363
|
-
|
|
364
|
-
return ''
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
const selectedTrackId = this.selectedTrackId || 0
|
|
368
|
-
|
|
369
|
-
const selectedTrack = this.tracks[selectedTrackId]
|
|
370
|
-
|
|
371
|
-
return selectedTrack?.label || ''
|
|
227
|
+
return this.currentTrack?.label || ''
|
|
372
228
|
}
|
|
373
229
|
|
|
374
|
-
startTrackSwitch() {
|
|
230
|
+
private startTrackSwitch() {
|
|
375
231
|
this.buttonElement().addClass('changing')
|
|
376
232
|
}
|
|
377
233
|
|
|
378
|
-
private updateText(
|
|
379
|
-
if (
|
|
234
|
+
private updateText() {
|
|
235
|
+
if (!this.currentTrack) {
|
|
380
236
|
return
|
|
381
237
|
}
|
|
382
|
-
|
|
383
|
-
const track = this.findTrackBy(trackId)
|
|
384
|
-
|
|
385
|
-
if (track) {
|
|
386
|
-
this.buttonElementText().text(track.label)
|
|
387
|
-
}
|
|
238
|
+
this.buttonElementText().text(this.currentTrack.label)
|
|
388
239
|
}
|
|
389
240
|
|
|
390
|
-
|
|
391
|
-
e: HlsEvents.AUDIO_TRACK_SWITCHED,
|
|
392
|
-
info: AudioTrackSwitchedData | AudioTrackLoadedData,
|
|
393
|
-
) {
|
|
394
|
-
// if (!info) {
|
|
395
|
-
// const { audioTracks } = this.core.activePlayback.$el.get(0);
|
|
396
|
-
|
|
397
|
-
// for (const track of audioTracks) {
|
|
398
|
-
// if (track.enabled) {
|
|
399
|
-
// info = track;
|
|
400
|
-
// }
|
|
401
|
-
// }
|
|
402
|
-
// }
|
|
403
|
-
// if (!info) {
|
|
404
|
-
// return;
|
|
405
|
-
// }
|
|
406
|
-
|
|
407
|
-
// const track = this.findTrackBy(info.id);
|
|
408
|
-
|
|
409
|
-
// this.currentTrack = track ? track : null;
|
|
410
|
-
// this.selectedTrackId = track?.id;
|
|
411
|
-
// this.highlightCurrentTrack();
|
|
412
|
-
// this.buttonElement().removeClass('changing');
|
|
413
|
-
this.setCurrentTrack(info.id)
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
private updateCurrentTrackW3C() {
|
|
417
|
-
const { audioTracks } = this.core.activePlayback.$el.get(0)
|
|
418
|
-
const index = audioTracks.findIndex((track: AudioTrackW3C) => track.enabled)
|
|
419
|
-
if (index >= 0) {
|
|
420
|
-
this.setCurrentTrack(index)
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
private setCurrentTrack(index: number) {
|
|
425
|
-
const track = this.findTrackBy(index)
|
|
426
|
-
|
|
427
|
-
this.currentTrack = track ?? null
|
|
428
|
-
this.selectedTrackId = index
|
|
429
|
-
this.highlightCurrentTrack()
|
|
430
|
-
this.buttonElement().removeClass('changing')
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
highlightCurrentTrack() {
|
|
241
|
+
private highlightCurrentTrack() {
|
|
434
242
|
this.trackElement().removeClass('current')
|
|
435
243
|
this.trackElement().find('a').removeClass('gcore-skin-active')
|
|
436
244
|
|
|
437
245
|
if (this.currentTrack) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
246
|
+
this.trackElement(this.currentTrack.id)
|
|
247
|
+
.addClass('current')
|
|
248
|
+
.find('a')
|
|
249
|
+
.addClass('gcore-skin-active')
|
|
442
250
|
}
|
|
443
|
-
|
|
444
|
-
this.updateText(this.selectedTrackId)
|
|
445
251
|
}
|
|
446
252
|
}
|
|
@@ -22,6 +22,8 @@ const T = 'plugins.bottom_gear';
|
|
|
22
22
|
*/
|
|
23
23
|
export type GearItemElement = 'quality' | 'rate' | 'nerd';
|
|
24
24
|
|
|
25
|
+
// TODO disabled if no items added
|
|
26
|
+
|
|
25
27
|
/**
|
|
26
28
|
* `PLUGIN` that adds the gear button with an extra options menu on the right side of the {@link MediaControl | media control} UI
|
|
27
29
|
* @beta
|
|
@@ -30,7 +32,7 @@ export type GearItemElement = 'quality' | 'rate' | 'nerd';
|
|
|
30
32
|
*
|
|
31
33
|
* Depends on:
|
|
32
34
|
*
|
|
33
|
-
* - {@link MediaControl
|
|
35
|
+
* - {@link MediaControl}
|
|
34
36
|
*/
|
|
35
37
|
export class BottomGear extends UICorePlugin {
|
|
36
38
|
private isHd = false;
|
|
@@ -63,8 +65,7 @@ export class BottomGear extends UICorePlugin {
|
|
|
63
65
|
*/
|
|
64
66
|
override get attributes() {
|
|
65
67
|
return {
|
|
66
|
-
'class':
|
|
67
|
-
'data-track-selector': ''
|
|
68
|
+
'class': 'media-control-gear',
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
71
|
|
|
@@ -81,12 +82,8 @@ export class BottomGear extends UICorePlugin {
|
|
|
81
82
|
* @internal
|
|
82
83
|
*/
|
|
83
84
|
override bindEvents() {
|
|
84
|
-
|
|
85
|
-
assert(mediaControl, 'media_control plugin is required');
|
|
86
|
-
|
|
85
|
+
this.listenTo(this.core, ClapprEvents.CORE_READY, this.onCoreReady)
|
|
87
86
|
this.listenTo(this.core, ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
|
|
88
|
-
this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_RENDERED, this.render);
|
|
89
|
-
this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide); // TODO mediacontrol show as well
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
/**
|
|
@@ -94,7 +91,7 @@ export class BottomGear extends UICorePlugin {
|
|
|
94
91
|
* @returns Zepto result of the element
|
|
95
92
|
*/
|
|
96
93
|
getElement(name: GearItemElement): ZeptoResult | null {
|
|
97
|
-
return this.
|
|
94
|
+
return this.$el.find(`.gear-options-list [data-${name}]`);
|
|
98
95
|
}
|
|
99
96
|
|
|
100
97
|
/**
|
|
@@ -126,7 +123,6 @@ export class BottomGear extends UICorePlugin {
|
|
|
126
123
|
*/
|
|
127
124
|
override render() {
|
|
128
125
|
const mediaControl = this.core.getPlugin('media_control');
|
|
129
|
-
assert(mediaControl, 'media_control plugin is required');
|
|
130
126
|
|
|
131
127
|
// TODO use options.mediaControl.gear.items
|
|
132
128
|
const items: GearItemElement[] = [
|
|
@@ -137,7 +133,7 @@ export class BottomGear extends UICorePlugin {
|
|
|
137
133
|
const icon = this.isHd ? gearHdIcon : gearIcon;
|
|
138
134
|
this.$el.html(BottomGear.template({ icon, items }));
|
|
139
135
|
|
|
140
|
-
mediaControl.
|
|
136
|
+
mediaControl.putElement('gear', this.$el);
|
|
141
137
|
mediaControl.trigger(MediaControlEvents.MEDIACONTROL_GEAR_RENDERED);
|
|
142
138
|
return this;
|
|
143
139
|
}
|
|
@@ -159,4 +155,11 @@ export class BottomGear extends UICorePlugin {
|
|
|
159
155
|
private hide() {
|
|
160
156
|
this.$el.find('.gear-wrapper').hide();
|
|
161
157
|
}
|
|
158
|
+
|
|
159
|
+
private onCoreReady() {
|
|
160
|
+
const mediaControl = this.core.getPlugin('media_control');
|
|
161
|
+
assert(mediaControl, 'media_control plugin is required');
|
|
162
|
+
this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_RENDERED, this.render);
|
|
163
|
+
this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide); // TODO mediacontrol show as well
|
|
164
|
+
}
|
|
162
165
|
}
|
|
@@ -26,9 +26,7 @@ describe('BottomGear', () => {
|
|
|
26
26
|
expect(bottomGear.el.innerHTML).toMatchSnapshot()
|
|
27
27
|
})
|
|
28
28
|
it('should attach to media control', () => {
|
|
29
|
-
|
|
30
|
-
expect(gearElement[0].innerHTML).not.toEqual('')
|
|
31
|
-
expect(gearElement[0].innerHTML).toMatchSnapshot()
|
|
29
|
+
expect(mediaControl.putElement).toHaveBeenCalledWith('gear', bottomGear.$el)
|
|
32
30
|
})
|
|
33
31
|
it('should emit event', () => {
|
|
34
32
|
expect(onGearRendered).toHaveBeenCalled()
|
|
@@ -1,41 +1,18 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`BottomGear > should attach to media control 1`] = `
|
|
4
|
-
"<div class="bottom_gear" data-track-selector=""><div class="media-control-gear" data-="">
|
|
5
|
-
<button type="button" class="button-gear gplayer-lite-btn gcore-skin-button-color" data-gear-button="-1">
|
|
6
|
-
<span class="gear-icon">/assets/icons/new/gear.svg</span>
|
|
7
|
-
</button>
|
|
8
|
-
<div class="gear-wrapper gcore-skin-bg-color">
|
|
9
|
-
<ul class="gear-options-list">
|
|
10
|
-
|
|
11
|
-
<li data-quality=""></li>
|
|
12
|
-
|
|
13
|
-
<li data-rate=""></li>
|
|
14
|
-
|
|
15
|
-
<li data-nerd=""></li>
|
|
16
|
-
|
|
17
|
-
</ul>
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
</div>"
|
|
21
|
-
`;
|
|
22
|
-
|
|
23
3
|
exports[`BottomGear > should render 1`] = `
|
|
24
|
-
"<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
"
|
|
4
|
+
"<button type="button" class="button-gear media-control-button gplayer-lite-btn gcore-skin-button-color gear-icon" data-gear-button="-1">
|
|
5
|
+
/assets/icons/new/gear.svg
|
|
6
|
+
</button>
|
|
7
|
+
<div class="gear-wrapper gcore-skin-bg-color">
|
|
8
|
+
<ul class="gear-options-list">
|
|
9
|
+
|
|
10
|
+
<li data-quality=""></li>
|
|
11
|
+
|
|
12
|
+
<li data-rate=""></li>
|
|
13
|
+
|
|
14
|
+
<li data-nerd=""></li>
|
|
15
|
+
|
|
16
|
+
</ul>
|
|
17
|
+
</div>"
|
|
41
18
|
`;
|