@clappr/hlsjs-playback 2.0.0 → 3.0.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/README.md +16 -7
- package/dist/hlsjs-playback.esm.js +901 -37303
- package/dist/hlsjs-playback.esm.js.map +1 -1
- package/dist/hlsjs-playback.js +888 -37291
- package/dist/hlsjs-playback.js.map +1 -1
- package/dist/hlsjs-playback.min.js +1 -1
- package/dist/hlsjs-playback.min.js.map +1 -1
- package/package.json +7 -6
- package/src/dist.smoke.test.js +65 -39
- package/src/hls.js +6 -3
- package/src/hls.test.js +780 -12
- package/dist/hlsjs-playback.external.js +0 -733
- package/dist/hlsjs-playback.external.js.map +0 -1
- package/dist/hlsjs-playback.external.min.js +0 -2
- package/dist/hlsjs-playback.external.min.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clappr/hlsjs-playback",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.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",
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
"build": "rollup --config --bundleConfigAsCjs",
|
|
11
11
|
"watch": "rollup --config --bundleConfigAsCjs --watch",
|
|
12
12
|
"bundle-check": "ANALYZE_BUNDLE=true rollup --config --bundleConfigAsCjs",
|
|
13
|
-
"release": "MINIMIZE=true rollup --config --bundleConfigAsCjs",
|
|
14
|
-
"test": "jest ./src --
|
|
13
|
+
"release": "rm -rf dist && MINIMIZE=true rollup --config --bundleConfigAsCjs",
|
|
14
|
+
"test": "jest ./src --coverage --silent",
|
|
15
|
+
"test:smoke": "jest ./src/dist.smoke.test.js --testPathIgnorePatterns=/node_modules/ --silent",
|
|
15
16
|
"test:watch": "jest ./src --watch",
|
|
16
17
|
"lint": "eslint *.js ./src",
|
|
17
18
|
"lint:fix": "yarn lint -- --fix",
|
|
@@ -37,12 +38,12 @@
|
|
|
37
38
|
"homepage": "https://github.com/clappr/hlsjs-playback",
|
|
38
39
|
"peerDependencies": {
|
|
39
40
|
"@clappr/core": "*",
|
|
40
|
-
"hls.js": "1
|
|
41
|
+
"hls.js": "^1"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
|
-
"@clappr/core": "^0.
|
|
44
|
+
"@clappr/core": "^0.16.0",
|
|
44
45
|
"@rollup/plugin-replace": "^2.4.2",
|
|
45
|
-
"hls.js": "1.6.
|
|
46
|
+
"hls.js": "~1.6.17",
|
|
46
47
|
"rollup-plugin-filesize": "^9.1.1",
|
|
47
48
|
"rollup-plugin-serve": "^1.1.0"
|
|
48
49
|
}
|
package/src/dist.smoke.test.js
CHANGED
|
@@ -4,19 +4,25 @@
|
|
|
4
4
|
*/
|
|
5
5
|
const fs = require('fs')
|
|
6
6
|
const path = require('path')
|
|
7
|
+
const vm = require('vm')
|
|
8
|
+
const { TextEncoder, TextDecoder } = require('util')
|
|
9
|
+
|
|
10
|
+
// jest-environment-jsdom omits these; must run before the require below —
|
|
11
|
+
// jsdom's whatwg-url throws on load without TextEncoder/TextDecoder.
|
|
12
|
+
global.TextEncoder = global.TextEncoder || TextEncoder
|
|
13
|
+
global.TextDecoder = global.TextDecoder || TextDecoder
|
|
14
|
+
const { JSDOM } = require('jsdom')
|
|
15
|
+
const { expectNoNativeClasses } = require('../../../test/dist-contract')
|
|
7
16
|
|
|
8
17
|
const DIST = path.join(__dirname, '..', 'dist')
|
|
9
18
|
|
|
10
19
|
const ARTIFACTS = {
|
|
11
20
|
main: 'hlsjs-playback.js',
|
|
12
21
|
mainMin: 'hlsjs-playback.min.js',
|
|
13
|
-
external: 'hlsjs-playback.external.js',
|
|
14
|
-
externalMin: 'hlsjs-playback.external.min.js',
|
|
15
22
|
esm: 'hlsjs-playback.esm.js'
|
|
16
23
|
}
|
|
17
24
|
|
|
18
|
-
const
|
|
19
|
-
const EXTERNAL_HLS = [ARTIFACTS.external, ARTIFACTS.externalMin]
|
|
25
|
+
const UMD_ARTIFACTS = [ARTIFACTS.main, ARTIFACTS.mainMin]
|
|
20
26
|
|
|
21
27
|
function readArtifact(name) {
|
|
22
28
|
return fs.readFileSync(path.join(DIST, name), 'utf8')
|
|
@@ -27,11 +33,30 @@ function loadArtifact(name) {
|
|
|
27
33
|
return require(path.join(DIST, name))
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
function resolvePlayback(HlsjsPlaybackExport) {
|
|
37
|
+
return HlsjsPlaybackExport.default || HlsjsPlaybackExport
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function loadUmdInSandbox(filename, { hls } = {}) {
|
|
41
|
+
const code = readArtifact(filename)
|
|
42
|
+
const dom = new JSDOM('<!doctype html><html><body></body></html>', {
|
|
43
|
+
url: 'http://localhost/',
|
|
44
|
+
pretendToBeVisual: true,
|
|
45
|
+
runScripts: 'outside-only'
|
|
46
|
+
})
|
|
47
|
+
const sandbox = dom.getInternalVMContext()
|
|
48
|
+
sandbox.Clappr = require('@clappr/core')
|
|
49
|
+
if (hls !== undefined) sandbox.Hls = hls
|
|
50
|
+
|
|
51
|
+
vm.runInContext(code, sandbox, { filename: path.join(DIST, filename) })
|
|
52
|
+
return sandbox
|
|
53
|
+
}
|
|
54
|
+
|
|
30
55
|
function assertPlaybackContract(HlsjsPlaybackExport) {
|
|
31
56
|
// Must re-require after resetModules so the prototype identity matches the
|
|
32
57
|
// @clappr/core instance the artifact just resolved.
|
|
33
58
|
const { HTML5Video } = require('@clappr/core')
|
|
34
|
-
const Playback = HlsjsPlaybackExport
|
|
59
|
+
const Playback = resolvePlayback(HlsjsPlaybackExport)
|
|
35
60
|
|
|
36
61
|
expect(typeof Playback).toBe('function')
|
|
37
62
|
expect(Object.getPrototypeOf(Playback.prototype)).toBe(HTML5Video.prototype)
|
|
@@ -54,31 +79,13 @@ function assertPlaybackContract(HlsjsPlaybackExport) {
|
|
|
54
79
|
playback.destroy()
|
|
55
80
|
}
|
|
56
81
|
|
|
57
|
-
function
|
|
58
|
-
|
|
59
|
-
expect(source).not.toMatch(/\bZepto\b/)
|
|
60
|
-
expect(source).not.toContain('clappr-core')
|
|
61
|
-
expect(source).not.toContain('@clappr/zepto')
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function assertDoesNotEmbedHls(source) {
|
|
65
|
-
expect(source).toMatch(/['"]hls\.js['"]/)
|
|
66
|
-
// External builds are ~14–31 KB; 100 KB leaves headroom without matching the
|
|
67
|
-
// ~500 KB+ hls.js-embedded family.
|
|
68
|
-
expect(source.length).toBeLessThan(100000)
|
|
82
|
+
function assertSourceMappingURL(filename) {
|
|
83
|
+
expect(readArtifact(filename)).toContain(`sourceMappingURL=${filename}.map`)
|
|
69
84
|
}
|
|
70
85
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
expect(source.length).toBeGreaterThan(100000)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function assertSourceMap(filename) {
|
|
78
|
-
const mapName = `${filename}.map`
|
|
79
|
-
expect(fs.existsSync(path.join(DIST, mapName))).toBe(true)
|
|
80
|
-
expect(readArtifact(filename)).toContain(`sourceMappingURL=${mapName}`)
|
|
81
|
-
}
|
|
86
|
+
const EXPECTED_SOURCEMAPS = Object.values(ARTIFACTS)
|
|
87
|
+
.map(filename => `${filename}.map`)
|
|
88
|
+
.sort()
|
|
82
89
|
|
|
83
90
|
afterEach(() => {
|
|
84
91
|
jest.restoreAllMocks()
|
|
@@ -87,29 +94,48 @@ afterEach(() => {
|
|
|
87
94
|
describe.each([
|
|
88
95
|
['main UMD', ARTIFACTS.main],
|
|
89
96
|
['main UMD minified', ARTIFACTS.mainMin],
|
|
90
|
-
['external UMD', ARTIFACTS.external],
|
|
91
|
-
['external UMD minified', ARTIFACTS.externalMin],
|
|
92
97
|
['ESM', ARTIFACTS.esm]
|
|
93
98
|
])('%s (%s)', (_label, filename) => {
|
|
94
99
|
test('exports a HlsjsPlayback class that extends HTML5Video and exposes HLSJS', () => {
|
|
95
100
|
assertPlaybackContract(loadArtifact(filename))
|
|
96
101
|
})
|
|
97
102
|
|
|
98
|
-
test('
|
|
99
|
-
|
|
103
|
+
test('publishes a sourcemap comment', () => {
|
|
104
|
+
assertSourceMappingURL(filename)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('does not emit native class syntax', () => {
|
|
108
|
+
expectNoNativeClasses(readArtifact(filename))
|
|
100
109
|
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
describe('dist sourcemap inventory', () => {
|
|
113
|
+
test('ships exactly the expected .map files', () => {
|
|
114
|
+
const maps = fs
|
|
115
|
+
.readdirSync(DIST)
|
|
116
|
+
.filter(f => f.endsWith('.map'))
|
|
117
|
+
.sort()
|
|
118
|
+
expect(maps).toEqual(EXPECTED_SOURCEMAPS)
|
|
119
|
+
})
|
|
120
|
+
})
|
|
101
121
|
|
|
102
|
-
|
|
103
|
-
|
|
122
|
+
describe('hls.js peer identity', () => {
|
|
123
|
+
test.each(Object.values(ARTIFACTS))('%s defers to the consumer hls.js', filename => {
|
|
124
|
+
const Playback = resolvePlayback(loadArtifact(filename))
|
|
125
|
+
expect(Playback.HLSJS).toBe(require('hls.js'))
|
|
104
126
|
})
|
|
105
127
|
})
|
|
106
128
|
|
|
107
|
-
describe('
|
|
108
|
-
test.each(
|
|
109
|
-
|
|
129
|
+
describe('UMD global.Hls branch', () => {
|
|
130
|
+
test.each(UMD_ARTIFACTS)('%s resolves HLSJS from window.Hls', filename => {
|
|
131
|
+
const hls = require('hls.js')
|
|
132
|
+
const sandbox = loadUmdInSandbox(filename, { hls })
|
|
133
|
+
expect(sandbox.HlsjsPlayback.HLSJS).toBe(hls)
|
|
110
134
|
})
|
|
111
135
|
|
|
112
|
-
test.each(
|
|
113
|
-
|
|
136
|
+
test.each(UMD_ARTIFACTS)('%s throws a clear error when window.Hls is missing', filename => {
|
|
137
|
+
expect(() => loadUmdInSandbox(filename)).toThrow(
|
|
138
|
+
'@clappr/hlsjs-playback requires hls.js (^1) to be loaded before it'
|
|
139
|
+
)
|
|
114
140
|
})
|
|
115
141
|
})
|
package/src/hls.js
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
import { Events, HTML5Video, Log, Playback, PlayerError, Utils } from '@clappr/core'
|
|
6
6
|
import HLSJS from 'hls.js'
|
|
7
7
|
|
|
8
|
+
if (!HLSJS) {
|
|
9
|
+
throw new Error('@clappr/hlsjs-playback requires hls.js (^1) to be loaded before it')
|
|
10
|
+
}
|
|
11
|
+
|
|
8
12
|
const { now, listContainsIgnoreCase } = Utils
|
|
9
13
|
const AUTO = -1
|
|
10
14
|
const DEFAULT_RECOVER_ATTEMPTS = 16
|
|
@@ -213,7 +217,7 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
213
217
|
this._segmentTargetDuration = null
|
|
214
218
|
// #EXT-X-PLAYLIST-TYPE
|
|
215
219
|
this._playlistType = null
|
|
216
|
-
this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts
|
|
220
|
+
this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts ?? DEFAULT_RECOVER_ATTEMPTS
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
_setup() {
|
|
@@ -372,8 +376,7 @@ export default class HlsjsPlayback extends HTML5Video {
|
|
|
372
376
|
}
|
|
373
377
|
|
|
374
378
|
seekPercentage(percentage) {
|
|
375
|
-
|
|
376
|
-
this.seek(seekTo)
|
|
379
|
+
this.seek(this._duration * (percentage / 100))
|
|
377
380
|
}
|
|
378
381
|
|
|
379
382
|
seek(time) {
|