@gcorevideo/player 2.22.24 → 2.22.26
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 +11 -0
- package/assets/seek-time/seek-time.html +3 -2
- package/dist/core.js +1 -1
- package/dist/index.css +1448 -1441
- package/dist/index.js +147 -139
- package/dist/plugins/index.css +724 -724
- package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/speedtest/Speedtest.js +1 -0
- package/lib/plugins/clappr-nerd-stats/speedtest/index.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/speedtest/index.js +7 -1
- package/lib/plugins/seek-time/SeekTime.d.ts +14 -10
- package/lib/plugins/seek-time/SeekTime.d.ts.map +1 -1
- package/lib/plugins/seek-time/SeekTime.js +72 -69
- package/package.json +1 -1
- package/rollup.config.js +28 -28
- package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +0 -3
- package/src/plugins/clappr-nerd-stats/speedtest/Speedtest.ts +1 -0
- package/src/plugins/clappr-nerd-stats/speedtest/index.ts +8 -1
- package/src/plugins/seek-time/SeekTime.ts +156 -113
- package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style
|
|
3
3
|
// license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE
|
|
4
4
|
|
|
5
|
-
import { Events, Playback, UICorePlugin, Utils, template } from '@clappr/core'
|
|
6
|
-
import { TimePosition } from '../../playback.types.js'
|
|
5
|
+
import { Events, Playback, UICorePlugin, Utils, template } from '@clappr/core'
|
|
6
|
+
import { TimePosition } from '../../playback.types.js'
|
|
7
7
|
|
|
8
|
-
import { CLAPPR_VERSION } from '../../build.js'
|
|
8
|
+
import { CLAPPR_VERSION } from '../../build.js'
|
|
9
9
|
|
|
10
|
-
import seekTimeHTML from '../../../assets/seek-time/seek-time.html'
|
|
11
|
-
import '../../../assets/seek-time/seek-time.scss'
|
|
12
|
-
import { ZeptoResult } from '../../types.js'
|
|
10
|
+
import seekTimeHTML from '../../../assets/seek-time/seek-time.html'
|
|
11
|
+
import '../../../assets/seek-time/seek-time.scss'
|
|
12
|
+
import { ZeptoResult } from '../../types.js'
|
|
13
|
+
import assert from 'assert'
|
|
13
14
|
|
|
14
|
-
const { formatTime } = Utils
|
|
15
|
+
const { formatTime } = Utils
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* `PLUGIN` that adds a seek time indicator to the media control UI.
|
|
@@ -19,176 +20,218 @@ const { formatTime } = Utils;
|
|
|
19
20
|
*/
|
|
20
21
|
export class SeekTime extends UICorePlugin {
|
|
21
22
|
get name() {
|
|
22
|
-
return 'seek_time'
|
|
23
|
+
return 'seek_time'
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
get supportedVersion() {
|
|
26
|
-
return { min: CLAPPR_VERSION }
|
|
27
|
+
return { min: CLAPPR_VERSION }
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
return template(seekTimeHTML);
|
|
31
|
-
}
|
|
30
|
+
private static readonly template = template(seekTimeHTML)
|
|
32
31
|
|
|
33
32
|
override get attributes() {
|
|
34
33
|
return {
|
|
35
|
-
|
|
36
|
-
'data-seek-time': ''
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
get mediaControl() {
|
|
41
|
-
return this.core.mediaControl;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get mediaControlContainer() {
|
|
45
|
-
return this.mediaControl.container;
|
|
34
|
+
class: 'seek-time',
|
|
35
|
+
'data-seek-time': '',
|
|
36
|
+
}
|
|
46
37
|
}
|
|
47
38
|
|
|
48
|
-
get isLiveStreamWithDvr() {
|
|
49
|
-
return
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
39
|
+
private get isLiveStreamWithDvr() {
|
|
40
|
+
return (
|
|
41
|
+
this.core.activeContainer &&
|
|
42
|
+
this.core.activeContainer.getPlaybackType() === Playback.LIVE &&
|
|
43
|
+
this.core.activeContainer.isDvrEnabled()
|
|
44
|
+
)
|
|
52
45
|
}
|
|
53
46
|
|
|
54
|
-
get durationShown() {
|
|
55
|
-
return !this.isLiveStreamWithDvr
|
|
47
|
+
private get durationShown() {
|
|
48
|
+
return !this.isLiveStreamWithDvr
|
|
56
49
|
}
|
|
57
50
|
|
|
58
|
-
private hoveringOverSeekBar = false
|
|
51
|
+
private hoveringOverSeekBar = false
|
|
59
52
|
|
|
60
|
-
private hoverPosition = 0
|
|
53
|
+
private hoverPosition = 0
|
|
61
54
|
|
|
62
|
-
private displayedDuration: string | null = null
|
|
55
|
+
private displayedDuration: string | null = null
|
|
63
56
|
|
|
64
|
-
private displayedSeekTime: string| null = null
|
|
57
|
+
private displayedSeekTime: string | null = null
|
|
65
58
|
|
|
66
|
-
private duration = 0
|
|
59
|
+
private duration = 0
|
|
67
60
|
// private firstFragDateTime = 0;
|
|
68
61
|
|
|
69
|
-
private rendered = false
|
|
62
|
+
private rendered = false
|
|
70
63
|
|
|
71
|
-
private $durationEl: ZeptoResult | null = null
|
|
64
|
+
private $durationEl: ZeptoResult | null = null
|
|
72
65
|
|
|
73
|
-
private $seekTimeEl: ZeptoResult | null = null
|
|
66
|
+
private $seekTimeEl: ZeptoResult | null = null
|
|
74
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
75
71
|
override bindEvents() {
|
|
76
|
-
this.listenTo(this.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
72
|
+
this.listenTo(this.core, Events.CORE_READY, this.onCoreReady)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private onCoreReady() {
|
|
76
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
77
|
+
assert(
|
|
78
|
+
mediaControl,
|
|
79
|
+
'MediaControl plugin is required for SeekTime plugin to work',
|
|
80
|
+
)
|
|
81
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.mount)
|
|
82
|
+
this.listenTo(
|
|
83
|
+
mediaControl,
|
|
84
|
+
Events.MEDIACONTROL_MOUSEMOVE_SEEKBAR,
|
|
85
|
+
this.showTime,
|
|
86
|
+
)
|
|
87
|
+
this.listenTo(
|
|
88
|
+
mediaControl,
|
|
89
|
+
Events.MEDIACONTROL_MOUSELEAVE_SEEKBAR,
|
|
90
|
+
this.hideTime,
|
|
91
|
+
)
|
|
92
|
+
this.listenTo(
|
|
93
|
+
mediaControl,
|
|
94
|
+
Events.MEDIACONTROL_CONTAINERCHANGED,
|
|
95
|
+
this.onContainerChanged,
|
|
96
|
+
)
|
|
97
|
+
if (this.core.activeContainer) {
|
|
98
|
+
this.listenTo(
|
|
99
|
+
this.core.activeContainer,
|
|
100
|
+
Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
|
|
101
|
+
this.update,
|
|
102
|
+
)
|
|
103
|
+
this.listenTo(
|
|
104
|
+
this.core.activeContainer,
|
|
105
|
+
Events.CONTAINER_TIMEUPDATE,
|
|
106
|
+
this.onTimeUpdate,
|
|
107
|
+
)
|
|
83
108
|
}
|
|
84
109
|
}
|
|
85
110
|
|
|
86
111
|
private onContainerChanged() {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
112
|
+
this.listenTo(
|
|
113
|
+
this.core.activeContainer,
|
|
114
|
+
Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
|
|
115
|
+
this.update,
|
|
116
|
+
)
|
|
117
|
+
this.listenTo(
|
|
118
|
+
this.core.activeContainer,
|
|
119
|
+
Events.CONTAINER_TIMEUPDATE,
|
|
120
|
+
this.onTimeUpdate,
|
|
121
|
+
)
|
|
90
122
|
}
|
|
91
123
|
|
|
92
124
|
private onTimeUpdate({ total }: TimePosition) {
|
|
93
|
-
this.duration = total
|
|
94
|
-
this.update()
|
|
125
|
+
this.duration = total
|
|
126
|
+
this.update()
|
|
95
127
|
}
|
|
96
128
|
|
|
97
129
|
private showTime(event: MouseEvent) {
|
|
98
|
-
this.hoveringOverSeekBar = true
|
|
99
|
-
this.calculateHoverPosition(event)
|
|
100
|
-
this.update()
|
|
130
|
+
this.hoveringOverSeekBar = true
|
|
131
|
+
this.calculateHoverPosition(event)
|
|
132
|
+
this.update()
|
|
101
133
|
}
|
|
102
134
|
|
|
103
135
|
private hideTime() {
|
|
104
|
-
this.hoveringOverSeekBar = false
|
|
105
|
-
this.update()
|
|
136
|
+
this.hoveringOverSeekBar = false
|
|
137
|
+
this.update()
|
|
106
138
|
}
|
|
107
139
|
|
|
108
140
|
private calculateHoverPosition(event: MouseEvent) {
|
|
109
|
-
const
|
|
141
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
142
|
+
const offset = event.pageX - mediaControl.$seekBarContainer.offset().left
|
|
110
143
|
|
|
111
144
|
// proportion into the seek bar that the mouse is hovered over 0-1
|
|
112
|
-
this.hoverPosition = Math.min(
|
|
145
|
+
this.hoverPosition = Math.min(
|
|
146
|
+
1,
|
|
147
|
+
Math.max(offset / mediaControl.$seekBarContainer.width(), 0),
|
|
148
|
+
)
|
|
113
149
|
}
|
|
114
150
|
|
|
115
|
-
getSeekTime() {
|
|
116
|
-
|
|
151
|
+
private getSeekTime() {
|
|
152
|
+
const seekTime = this.isLiveStreamWithDvr
|
|
153
|
+
? this.duration - this.hoverPosition * this.duration
|
|
154
|
+
: this.hoverPosition * this.duration
|
|
117
155
|
|
|
118
|
-
|
|
119
|
-
seekTime = this.duration - this.hoverPosition * this.duration;
|
|
120
|
-
} else {
|
|
121
|
-
seekTime = this.hoverPosition * this.duration;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return { seekTime };
|
|
156
|
+
return { seekTime }
|
|
125
157
|
}
|
|
126
158
|
|
|
127
|
-
update() {
|
|
159
|
+
private update() {
|
|
128
160
|
if (!this.rendered) {
|
|
129
161
|
// update() is always called after a render
|
|
130
|
-
return
|
|
162
|
+
return
|
|
131
163
|
}
|
|
132
164
|
if (!this.shouldBeVisible()) {
|
|
133
|
-
this.$el.hide()
|
|
134
|
-
this.$el.css('left', '-100%')
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
let currentSeekTime = formatTime(seekTime.seekTime, false);
|
|
165
|
+
this.$el.hide()
|
|
166
|
+
this.$el.css('left', '-100%')
|
|
167
|
+
return
|
|
168
|
+
}
|
|
138
169
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
170
|
+
const seekTime = this.getSeekTime()
|
|
171
|
+
let currentSeekTime = formatTime(seekTime.seekTime, false)
|
|
142
172
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
this.displayedSeekTime = currentSeekTime;
|
|
147
|
-
}
|
|
173
|
+
if (this.isLiveStreamWithDvr) {
|
|
174
|
+
currentSeekTime = `-${currentSeekTime}`
|
|
175
|
+
}
|
|
148
176
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
177
|
+
// only update dom if necessary, ie time actually changed
|
|
178
|
+
if (currentSeekTime !== this.displayedSeekTime) {
|
|
179
|
+
this.$seekTimeEl.text(currentSeekTime)
|
|
180
|
+
this.displayedSeekTime = currentSeekTime
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (this.durationShown) {
|
|
184
|
+
this.$durationEl.show()
|
|
185
|
+
const currentDuration = formatTime(this.duration, false)
|
|
152
186
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
this.$durationEl.hide();
|
|
187
|
+
if (currentDuration !== this.displayedDuration) {
|
|
188
|
+
this.$durationEl.text(currentDuration)
|
|
189
|
+
this.displayedDuration = currentDuration
|
|
159
190
|
}
|
|
191
|
+
} else {
|
|
192
|
+
this.$durationEl.hide()
|
|
193
|
+
}
|
|
160
194
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
195
|
+
// the element must be unhidden before its width is requested, otherwise it's width will be reported as 0
|
|
196
|
+
this.$el.show()
|
|
197
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
198
|
+
const containerWidth = mediaControl.$seekBarContainer.width()
|
|
199
|
+
const elWidth = this.$el.width()
|
|
200
|
+
let elLeftPos = this.hoverPosition * containerWidth
|
|
166
201
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
202
|
+
elLeftPos -= elWidth / 2
|
|
203
|
+
elLeftPos = Math.max(0, Math.min(elLeftPos, containerWidth - elWidth))
|
|
204
|
+
this.$el.css('left', elLeftPos)
|
|
171
205
|
}
|
|
172
206
|
|
|
173
|
-
shouldBeVisible() {
|
|
174
|
-
return
|
|
175
|
-
this.
|
|
207
|
+
private shouldBeVisible() {
|
|
208
|
+
return (
|
|
209
|
+
this.core.activeContainer &&
|
|
210
|
+
this.core.activeContainer.settings.seekEnabled &&
|
|
176
211
|
this.hoveringOverSeekBar &&
|
|
177
212
|
this.hoverPosition !== null &&
|
|
178
|
-
this.duration !== null
|
|
213
|
+
this.duration !== null
|
|
214
|
+
)
|
|
179
215
|
}
|
|
180
216
|
|
|
217
|
+
/**
|
|
218
|
+
* @internal
|
|
219
|
+
*/
|
|
181
220
|
override render() {
|
|
182
|
-
this.rendered = true
|
|
183
|
-
this.displayedDuration = null
|
|
184
|
-
this.displayedSeekTime = null
|
|
185
|
-
this.$el.html(
|
|
186
|
-
this.$el.hide()
|
|
187
|
-
this.mediaControl.$el.append(this.el);
|
|
188
|
-
this.$seekTimeEl = this.$el.find('
|
|
189
|
-
this.$durationEl = this.$el.find('
|
|
190
|
-
this.$durationEl.hide()
|
|
191
|
-
this.update()
|
|
192
|
-
return this
|
|
221
|
+
this.rendered = true
|
|
222
|
+
this.displayedDuration = null
|
|
223
|
+
this.displayedSeekTime = null
|
|
224
|
+
this.$el.html(SeekTime.template())
|
|
225
|
+
this.$el.hide()
|
|
226
|
+
// this.mediaControl.$el.append(this.el);
|
|
227
|
+
this.$seekTimeEl = this.$el.find('#mc-seek-time')
|
|
228
|
+
this.$durationEl = this.$el.find('#mc-duration')
|
|
229
|
+
this.$durationEl.hide()
|
|
230
|
+
this.update()
|
|
231
|
+
return this
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private mount() {
|
|
235
|
+
this.core.getPlugin('media_control').$el.append(this.$el) // TODO use a method
|
|
193
236
|
}
|
|
194
237
|
}
|
|
@@ -5,6 +5,7 @@ import { createMockCore, createMockMediaControl } from '../../../testUtils.js'
|
|
|
5
5
|
import { ExtendedEvents } from '../../media-control/MediaControl.js'
|
|
6
6
|
|
|
7
7
|
import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
|
|
8
|
+
import { Events } from '@clappr/core'
|
|
8
9
|
// import { Events } from '@clappr/core';
|
|
9
10
|
|
|
10
11
|
// Logger.enable('*')
|