@clappr/hlsjs-playback 1.3.0 → 1.5.0
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/dist/hlsjs-playback.esm.js +26309 -23254
- package/dist/hlsjs-playback.external.js +32 -34
- package/dist/hlsjs-playback.external.min.js +1 -1
- package/dist/hlsjs-playback.external.min.js.map +1 -1
- package/dist/hlsjs-playback.js +26287 -23232
- package/dist/hlsjs-playback.min.js +1 -280
- package/dist/hlsjs-playback.min.js.map +1 -1
- package/package.json +14 -5
- package/src/hls.js +14 -16
- package/src/hls.test.js +23 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clappr/hlsjs-playback",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "HLS Playback based on hls.js",
|
|
5
5
|
"main": "./dist/hlsjs-playback.js",
|
|
6
6
|
"module": "./dist/hlsjs-playback.esm.js",
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://github.com/clappr/hlsjs-playback",
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@clappr/core": "
|
|
40
|
-
"hls.js": "
|
|
39
|
+
"@clappr/core": "*",
|
|
40
|
+
"hls.js": "1.5.14"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@babel/core": "^7.14.2",
|
|
44
44
|
"@babel/preset-env": "^7.14.2",
|
|
45
|
-
"@clappr/core": "^0.
|
|
45
|
+
"@clappr/core": "^0.9.0",
|
|
46
46
|
"@rollup/plugin-babel": "^5.3.0",
|
|
47
47
|
"@rollup/plugin-commonjs": "^19.0.0",
|
|
48
48
|
"@rollup/plugin-node-resolve": "^13.0.0",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"coveralls": "^3.1.0",
|
|
52
52
|
"cz-conventional-changelog": "^3.3.0",
|
|
53
53
|
"eslint": "^7.26.0",
|
|
54
|
-
"hls.js": "
|
|
54
|
+
"hls.js": "1.5.14",
|
|
55
55
|
"jest": "^26.6.3",
|
|
56
56
|
"rollup": "^2.47.0",
|
|
57
57
|
"rollup-plugin-filesize": "^9.1.1",
|
|
@@ -65,5 +65,14 @@
|
|
|
65
65
|
"commitizen": {
|
|
66
66
|
"path": "./node_modules/cz-conventional-changelog"
|
|
67
67
|
}
|
|
68
|
+
},
|
|
69
|
+
"nx": {
|
|
70
|
+
"targets": {
|
|
71
|
+
"test": {
|
|
72
|
+
"dependsOn": [
|
|
73
|
+
"^release"
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
68
77
|
}
|
|
69
78
|
}
|
package/src/hls.js
CHANGED
|
@@ -143,6 +143,8 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
143
143
|
constructor(...args) {
|
|
144
144
|
super(...args)
|
|
145
145
|
this.options.hlsPlayback = { ...this.defaultOptions, ...this.options.hlsPlayback }
|
|
146
|
+
this._timeUpdateFiringRate = 0.2
|
|
147
|
+
this._durationChangeMinOffset = 0.5
|
|
146
148
|
this._setInitialState()
|
|
147
149
|
}
|
|
148
150
|
|
|
@@ -155,7 +157,7 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
155
157
|
this._extrapolatedWindowNumSegments = !this.options.playback || typeof (this.options.playback.extrapolatedWindowNumSegments) === 'undefined' ? 2 : this.options.playback.extrapolatedWindowNumSegments
|
|
156
158
|
|
|
157
159
|
this._playbackType = Playback.VOD
|
|
158
|
-
this._lastTimeUpdate = { current: 0, total: 0 }
|
|
160
|
+
this._lastTimeUpdate = { current: 0, total: 0, firstFragDateTime: 0 }
|
|
159
161
|
this._lastDuration = null
|
|
160
162
|
// for hls streams which have dvr with a sliding window,
|
|
161
163
|
// the content at the start of the playlist is removed as new
|
|
@@ -196,7 +198,7 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
196
198
|
|
|
197
199
|
_destroyHLSInstance() {
|
|
198
200
|
if (!this._hls) return
|
|
199
|
-
this.
|
|
201
|
+
this._manifestLoading = false
|
|
200
202
|
this._ccIsSetup = false
|
|
201
203
|
this._ccTracksUpdated = false
|
|
202
204
|
this._setInitialState()
|
|
@@ -217,7 +219,7 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
217
219
|
_listenHLSEvents() {
|
|
218
220
|
if (!this._hls) return
|
|
219
221
|
this._hls.once(HLSJS.Events.MEDIA_ATTACHED, () => { this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src) })
|
|
220
|
-
this._hls.on(HLSJS.Events.
|
|
222
|
+
this._hls.on(HLSJS.Events.MANIFEST_LOADING, () => this._manifestLoading = true)
|
|
221
223
|
this._hls.on(HLSJS.Events.LEVEL_LOADED, (evt, data) => this._updatePlaybackType(evt, data))
|
|
222
224
|
this._hls.on(HLSJS.Events.LEVEL_UPDATED, (evt, data) => this._onLevelUpdated(evt, data))
|
|
223
225
|
this._hls.on(HLSJS.Events.LEVEL_SWITCHING, (evt,data) => this._onLevelSwitch(evt, data))
|
|
@@ -265,10 +267,12 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
265
267
|
if (!this._recoveredDecodingError) {
|
|
266
268
|
this._recoveredDecodingError = true
|
|
267
269
|
this._hls.recoverMediaError()
|
|
270
|
+
this.play()
|
|
268
271
|
} else if (!this._recoveredAudioCodecError) {
|
|
269
272
|
this._recoveredAudioCodecError = true
|
|
270
273
|
this._hls.swapAudioCodec()
|
|
271
274
|
this._hls.recoverMediaError()
|
|
275
|
+
this.play()
|
|
272
276
|
} else {
|
|
273
277
|
Log.error('hlsjs: failed to recover', { evt, data })
|
|
274
278
|
error.level = PlayerError.Levels.FATAL
|
|
@@ -333,8 +337,6 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
333
337
|
Log.warn('Attempt to seek to a negative time. Resetting to live point. Use seekToLivePoint() to seek to the live point.')
|
|
334
338
|
time = this.getDuration()
|
|
335
339
|
}
|
|
336
|
-
// assume live if time within 3 seconds of end of stream
|
|
337
|
-
this.dvrEnabled && this._updateDvr(time < this.getDuration()-3)
|
|
338
340
|
time += this._startTime
|
|
339
341
|
this.el.currentTime = time
|
|
340
342
|
}
|
|
@@ -343,11 +345,6 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
343
345
|
this.seek(this.getDuration())
|
|
344
346
|
}
|
|
345
347
|
|
|
346
|
-
_updateDvr(status) {
|
|
347
|
-
this.trigger(Events.PLAYBACK_DVR, status)
|
|
348
|
-
this.trigger(Events.PLAYBACK_STATS_ADD, { 'dvr': status })
|
|
349
|
-
}
|
|
350
|
-
|
|
351
348
|
_updateSettings() {
|
|
352
349
|
if (this._playbackType === Playback.VOD)
|
|
353
350
|
this.settings.left = ['playpause', 'position', 'duration']
|
|
@@ -441,9 +438,10 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
441
438
|
|
|
442
439
|
_onTimeUpdate() {
|
|
443
440
|
const update = { current: this.getCurrentTime(), total: this.getDuration(), firstFragDateTime: this.getProgramDateTime() }
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
441
|
+
const isSameTime = Math.abs(update.current - this._lastTimeUpdate.current) < this._timeUpdateFiringRate
|
|
442
|
+
const isSameDuration = Math.abs(update.total - this._lastTimeUpdate.total) < this._durationChangeMinOffset
|
|
443
|
+
const isSameFirstFragDateTime = update.firstFragDateTime === this._lastTimeUpdate.firstFragDateTime
|
|
444
|
+
const isSame = isSameTime && isSameDuration && isSameFirstFragDateTime
|
|
447
445
|
if (isSame) return
|
|
448
446
|
this._lastTimeUpdate = update
|
|
449
447
|
this.trigger(Events.PLAYBACK_TIMEUPDATE, update, this.name)
|
|
@@ -451,7 +449,8 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
451
449
|
|
|
452
450
|
_onDurationChange() {
|
|
453
451
|
const duration = this.getDuration()
|
|
454
|
-
|
|
452
|
+
const isSameDuration = Math.abs(this._lastDuration - duration) < this._durationChangeMinOffset
|
|
453
|
+
if (isSameDuration) return
|
|
455
454
|
this._lastDuration = duration
|
|
456
455
|
super._onDurationChange()
|
|
457
456
|
}
|
|
@@ -486,7 +485,7 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
486
485
|
|
|
487
486
|
play() {
|
|
488
487
|
!this._hls && this._setup()
|
|
489
|
-
!this.
|
|
488
|
+
!this._manifestLoading && !this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src)
|
|
490
489
|
super.play()
|
|
491
490
|
this._startTimeUpdateTimer()
|
|
492
491
|
}
|
|
@@ -494,7 +493,6 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
494
493
|
pause() {
|
|
495
494
|
if (!this._hls) return
|
|
496
495
|
this.el.pause()
|
|
497
|
-
if (this.dvrEnabled) this._updateDvr(true)
|
|
498
496
|
}
|
|
499
497
|
|
|
500
498
|
stop() {
|
package/src/hls.test.js
CHANGED
|
@@ -151,13 +151,13 @@ describe('HlsjsPlayback', () => {
|
|
|
151
151
|
})
|
|
152
152
|
|
|
153
153
|
describe('_setup method', () => {
|
|
154
|
-
test('sets
|
|
154
|
+
test('sets _manifestLoading flag to false', () => {
|
|
155
155
|
const playback = new HlsjsPlayback({ src: 'http://clappr.io/foo.m3u8' })
|
|
156
|
-
expect(playback.
|
|
156
|
+
expect(playback._manifestLoading).toBeUndefined()
|
|
157
157
|
|
|
158
158
|
playback._setup()
|
|
159
159
|
|
|
160
|
-
expect(playback.
|
|
160
|
+
expect(playback._manifestLoading).toBeFalsy()
|
|
161
161
|
})
|
|
162
162
|
|
|
163
163
|
test('calls this._hls.loadSource when MEDIA_ATTACHED event is triggered and hlsPlayback.preload is true', () => {
|
|
@@ -176,15 +176,16 @@ describe('HlsjsPlayback', () => {
|
|
|
176
176
|
expect(playback._hls.loadSource).toHaveBeenCalledTimes(1)
|
|
177
177
|
})
|
|
178
178
|
|
|
179
|
-
test('updates
|
|
180
|
-
const
|
|
179
|
+
test('updates _manifestLoading flag value to true if MANIFEST_LOADING event is triggered', () => {
|
|
180
|
+
const src = 'http://clappr.io/foo.m3u8'
|
|
181
|
+
const playback = new HlsjsPlayback({ src })
|
|
181
182
|
|
|
182
|
-
expect(playback.
|
|
183
|
+
expect(playback._manifestLoading).toBeUndefined()
|
|
183
184
|
|
|
184
185
|
playback._setup()
|
|
185
|
-
playback._hls.trigger(HLSJS.Events.
|
|
186
|
+
playback._hls.trigger(HLSJS.Events.MANIFEST_LOADING, { url: src })
|
|
186
187
|
|
|
187
|
-
expect(playback.
|
|
188
|
+
expect(playback._manifestLoading).toBeTruthy()
|
|
188
189
|
})
|
|
189
190
|
|
|
190
191
|
test('calls bindCustomListeners method', () => {
|
|
@@ -241,24 +242,29 @@ describe('HlsjsPlayback', () => {
|
|
|
241
242
|
})
|
|
242
243
|
|
|
243
244
|
describe('play method', () => {
|
|
244
|
-
test('calls this._hls.loadSource if
|
|
245
|
-
|
|
245
|
+
test('calls this._hls.loadSource once if _manifestLoading flag and options.hlsPlayback.preload are falsy', () => {
|
|
246
|
+
jest.spyOn(HLSJS.prototype, 'loadSource').mockImplementation()
|
|
247
|
+
const src = 'http://clappr.io/foo.m3u8'
|
|
248
|
+
const playback = new HlsjsPlayback({ src, hlsPlayback: { preload: false } })
|
|
246
249
|
playback._setup()
|
|
247
|
-
|
|
248
|
-
playback.play()
|
|
250
|
+
playback._hls.trigger(HLSJS.Events.MEDIA_ATTACHED, { media: playback.el })
|
|
249
251
|
|
|
250
252
|
expect(playback._hls.loadSource).not.toHaveBeenCalled()
|
|
251
253
|
|
|
252
|
-
playback.options.hlsPlayback.preload = false
|
|
253
|
-
playback._manifestParsed = true
|
|
254
254
|
playback.play()
|
|
255
|
+
playback._hls.trigger(HLSJS.Events.MANIFEST_LOADING, { url: src })
|
|
255
256
|
|
|
256
|
-
expect(playback._hls.loadSource).
|
|
257
|
+
expect(playback._hls.loadSource).toHaveBeenCalledTimes(1)
|
|
257
258
|
|
|
258
|
-
|
|
259
|
+
// do not call loadSource again while loading a manifest
|
|
259
260
|
playback.play()
|
|
260
|
-
|
|
261
261
|
expect(playback._hls.loadSource).toHaveBeenCalledTimes(1)
|
|
262
|
+
|
|
263
|
+
playback._manifestLoading = false
|
|
264
|
+
playback.play()
|
|
265
|
+
|
|
266
|
+
expect(playback._hls.loadSource).toHaveBeenCalledTimes(2)
|
|
267
|
+
HLSJS.prototype.loadSource.mockRestore()
|
|
262
268
|
})
|
|
263
269
|
})
|
|
264
270
|
|