@gcorevideo/player 2.10.0 → 2.12.1

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.
Files changed (65) hide show
  1. package/LICENSE +13 -0
  2. package/coverage/clover.xml +6 -0
  3. package/coverage/coverage-final.json +1 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +87 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +101 -0
  8. package/coverage/lcov-report/prettify.css +1 -0
  9. package/coverage/lcov-report/prettify.js +2 -0
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/sorter.js +196 -0
  12. package/coverage/lcov.info +0 -0
  13. package/dist/index.js +3115 -1185
  14. package/lib/Player.d.ts +3 -2
  15. package/lib/Player.d.ts.map +1 -1
  16. package/lib/Player.js +33 -20
  17. package/lib/index.d.ts +6 -5
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +5 -5
  20. package/lib/internal.types.d.ts +3 -1
  21. package/lib/internal.types.d.ts.map +1 -1
  22. package/lib/playback/index.d.ts +4 -0
  23. package/lib/playback/index.d.ts.map +1 -0
  24. package/lib/playback/index.js +13 -0
  25. package/lib/playback.types.d.ts +9 -0
  26. package/lib/playback.types.d.ts.map +1 -1
  27. package/lib/playback.types.js +9 -1
  28. package/lib/plugins/dash-playback/DashPlayback.d.ts +0 -1
  29. package/lib/plugins/dash-playback/DashPlayback.d.ts.map +1 -1
  30. package/lib/plugins/dash-playback/DashPlayback.js +32 -96
  31. package/lib/plugins/dash-playback/types.d.ts +6 -0
  32. package/lib/plugins/dash-playback/types.d.ts.map +1 -0
  33. package/lib/plugins/dash-playback/types.js +1 -0
  34. package/lib/plugins/hls-playback/HlsPlayback.d.ts +3 -3
  35. package/lib/plugins/hls-playback/HlsPlayback.d.ts.map +1 -1
  36. package/lib/plugins/hls-playback/HlsPlayback.js +136 -63
  37. package/lib/types.d.ts +3 -3
  38. package/lib/types.d.ts.map +1 -1
  39. package/lib/utils/mediaSources.d.ts +14 -6
  40. package/lib/utils/mediaSources.d.ts.map +1 -1
  41. package/lib/utils/mediaSources.js +56 -53
  42. package/lib/utils/testUtils.d.ts +3 -0
  43. package/lib/utils/testUtils.d.ts.map +1 -0
  44. package/lib/utils/testUtils.js +12 -0
  45. package/package.json +6 -4
  46. package/src/Player.ts +46 -26
  47. package/src/__tests__/Player.test.ts +357 -0
  48. package/src/index.ts +6 -5
  49. package/src/internal.types.ts +3 -1
  50. package/src/playback/index.ts +17 -0
  51. package/src/playback.types.ts +11 -1
  52. package/src/plugins/dash-playback/DashPlayback.ts +38 -114
  53. package/src/plugins/hls-playback/HlsPlayback.ts +561 -386
  54. package/src/types.ts +5 -3
  55. package/src/typings/@clappr/core/error_mixin.d.ts +0 -2
  56. package/src/typings/@clappr/core/index.d.ts +5 -0
  57. package/src/typings/@clappr/index.d.ts +1 -0
  58. package/src/utils/__tests__/mediaSources.test.ts +230 -0
  59. package/src/utils/mediaSources.ts +67 -63
  60. package/src/utils/testUtils.ts +15 -0
  61. package/tsconfig.json +0 -9
  62. package/tsconfig.tsbuildinfo +1 -1
  63. package/vitest.config.ts +8 -0
  64. package/licenses.json +0 -782
  65. package/src/utils/queryParams.ts +0 -5
package/src/types.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ContainerPlugin, CorePlugin } from "@clappr/core"
2
+
1
3
  /**
2
4
  * Describes a media source with its MIME type and URL.
3
5
  *
@@ -44,7 +46,7 @@ export type PlaybackType = 'live' | 'vod'
44
46
  /**
45
47
  * @beta
46
48
  */
47
- export type MediaTransport = 'dash' | 'hls' | 'mpegts'
49
+ export type MediaTransport = 'dash' | 'hls'
48
50
 
49
51
  /**
50
52
  * @beta
@@ -57,7 +59,7 @@ export type TransportPreference = MediaTransport | 'auto'
57
59
  */
58
60
  export type PlayerPlugin = {
59
61
  new (...args: any[]): unknown
60
- type: 'core' | 'container'
62
+ name: string
61
63
  }
62
64
 
63
65
  /**
@@ -161,7 +163,7 @@ export interface PlayerConfig extends Record<string, unknown> {
161
163
  /**
162
164
  * Localization strings for the player UI.
163
165
  */
164
- strings: TranslationSettings
166
+ strings?: TranslationSettings
165
167
  }
166
168
 
167
169
  /**
@@ -1,7 +1,5 @@
1
1
  import '@clappr/core';
2
- // import ErrorMixin from "@clappr/core/src/base/error_mixin/error_mixin";
3
2
 
4
- // export as namespace "@clappr/core";
5
3
  declare module "@clappr/core" {
6
4
  // export ErrorMixin;
7
5
 
@@ -0,0 +1,5 @@
1
+ import '@clappr/core'
2
+
3
+ declare module '@clappr/core' {
4
+
5
+ }
@@ -0,0 +1 @@
1
+ declare module '@clappr' {}
@@ -0,0 +1,230 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
+
3
+ import { isDashSource, isHlsSource, buildMediaSourcesList } from '../mediaSources'
4
+ import { TransportPreference } from '../../types'
5
+ import { canPlayDash, canPlayHls } from '../../playback/index'
6
+
7
+ vi.mock('../../playback/index.js', () => ({
8
+ canPlayDash: vi.fn(),
9
+ canPlayHls: vi.fn(),
10
+ }))
11
+
12
+ beforeEach(() => {
13
+ vi.mocked(canPlayDash).mockImplementation(isDashSource)
14
+ vi.mocked(canPlayHls).mockImplementation(isHlsSource)
15
+ })
16
+
17
+ describe('mediaSources', () => {
18
+ describe('buildMediaSourcesList', () => {
19
+ describe.each([
20
+ [
21
+ 'dash',
22
+ true,
23
+ true,
24
+ [
25
+ {
26
+ source: 'http://example.com/video.m3u8',
27
+ mimeType: 'application/vnd.apple.mpegurl',
28
+ },
29
+ {
30
+ source: 'http://example.com/video.mpd',
31
+ mimeType: 'application/dash+xml',
32
+ },
33
+ {
34
+ source: 'http://example.com/video2.mpd',
35
+ mimeType: 'application/dash+xml',
36
+ },
37
+ {
38
+ source: 'http://example.com/video3.m3u8',
39
+ mimeType: 'application/vnd.apple.mpegurl',
40
+ },
41
+ ],
42
+ [
43
+ {
44
+ source: 'http://example.com/video.mpd',
45
+ mimeType: 'application/dash+xml',
46
+ },
47
+ {
48
+ source: 'http://example.com/video2.mpd',
49
+ mimeType: 'application/dash+xml',
50
+ },
51
+ {
52
+ source: 'http://example.com/video.m3u8',
53
+ mimeType: 'application/vnd.apple.mpegurl',
54
+ },
55
+ {
56
+ source: 'http://example.com/video3.m3u8',
57
+ mimeType: 'application/vnd.apple.mpegurl',
58
+ },
59
+ ],
60
+ ],
61
+ [
62
+ 'auto',
63
+ true,
64
+ true,
65
+ [
66
+ {
67
+ source: 'http://example.com/video.m3u8',
68
+ mimeType: 'application/vnd.apple.mpegurl',
69
+ },
70
+ {
71
+ source: 'http://example.com/video.mpd',
72
+ mimeType: 'application/dash+xml',
73
+ },
74
+ {
75
+ source: 'http://example.com/video2.mpd',
76
+ mimeType: 'application/dash+xml',
77
+ },
78
+ {
79
+ source: 'http://example.com/video3.m3u8',
80
+ mimeType: 'application/vnd.apple.mpegurl',
81
+ },
82
+ ],
83
+ [
84
+ {
85
+ source: 'http://example.com/video.mpd',
86
+ mimeType: 'application/dash+xml',
87
+ },
88
+ {
89
+ source: 'http://example.com/video2.mpd',
90
+ mimeType: 'application/dash+xml',
91
+ },
92
+ {
93
+ source: 'http://example.com/video.m3u8',
94
+ mimeType: 'application/vnd.apple.mpegurl',
95
+ },
96
+ {
97
+ source: 'http://example.com/video3.m3u8',
98
+ mimeType: 'application/vnd.apple.mpegurl',
99
+ },
100
+ ],
101
+ ],
102
+ [
103
+ 'hls',
104
+ true,
105
+ true,
106
+ [
107
+ {
108
+ source: 'http://example.com/video.m3u8',
109
+ mimeType: 'application/vnd.apple.mpegurl',
110
+ },
111
+ {
112
+ source: 'http://example.com/video.mpd',
113
+ mimeType: 'application/dash+xml',
114
+ },
115
+ {
116
+ source: 'http://example.com/video2.mpd',
117
+ mimeType: 'application/dash+xml',
118
+ },
119
+ {
120
+ source: 'http://example.com/video3.m3u8',
121
+ mimeType: 'application/vnd.apple.mpegurl',
122
+ },
123
+ ],
124
+ [
125
+ {
126
+ source: 'http://example.com/video.m3u8',
127
+ mimeType: 'application/vnd.apple.mpegurl',
128
+ },
129
+ {
130
+ source: 'http://example.com/video3.m3u8',
131
+ mimeType: 'application/vnd.apple.mpegurl',
132
+ },
133
+ {
134
+ source: 'http://example.com/video.mpd',
135
+ mimeType: 'application/dash+xml',
136
+ },
137
+ {
138
+ source: 'http://example.com/video2.mpd',
139
+ mimeType: 'application/dash+xml',
140
+ },
141
+ ],
142
+ ],
143
+ [
144
+ 'dash',
145
+ false,
146
+ true,
147
+ [
148
+ {
149
+ source: 'http://example.com/video.m3u8',
150
+ mimeType: 'application/vnd.apple.mpegurl',
151
+ },
152
+ {
153
+ source: 'http://example.com/video.mpd',
154
+ mimeType: 'application/dash+xml',
155
+ },
156
+ {
157
+ source: 'http://example.com/video2.mpd',
158
+ mimeType: 'application/dash+xml',
159
+ },
160
+ {
161
+ source: 'http://example.com/video3.m3u8',
162
+ mimeType: 'application/vnd.apple.mpegurl',
163
+ },
164
+ ],
165
+ [
166
+ {
167
+ source: 'http://example.com/video.m3u8',
168
+ mimeType: 'application/vnd.apple.mpegurl',
169
+ },
170
+ {
171
+ source: 'http://example.com/video3.m3u8',
172
+ mimeType: 'application/vnd.apple.mpegurl',
173
+ },
174
+ ],
175
+ ],
176
+ [
177
+ 'hls',
178
+ true,
179
+ false,
180
+ [
181
+ {
182
+ source: 'http://example.com/video.m3u8',
183
+ mimeType: 'application/vnd.apple.mpegurl',
184
+ },
185
+ {
186
+ source: 'http://example.com/video.mpd',
187
+ mimeType: 'application/dash+xml',
188
+ },
189
+ {
190
+ source: 'http://example.com/video2.mpd',
191
+ mimeType: 'application/dash+xml',
192
+ },
193
+ {
194
+ source: 'http://example.com/video3.m3u8',
195
+ mimeType: 'application/vnd.apple.mpegurl',
196
+ },
197
+ ],
198
+ [
199
+ {
200
+ source: 'http://example.com/video.mpd',
201
+ mimeType: 'application/dash+xml',
202
+ },
203
+ {
204
+ source: 'http://example.com/video2.mpd',
205
+ mimeType: 'application/dash+xml',
206
+ },
207
+ ],
208
+ ],
209
+ ])('prefer %s, dash=%s,hls=%s', (preference, dash, hls, sources, expected) => {
210
+ beforeEach(() => {
211
+ if (!dash) {
212
+ vi.mocked(canPlayDash).mockReturnValue(false)
213
+ }
214
+ if (!hls) {
215
+ vi.mocked(canPlayHls).mockReturnValue(false)
216
+ }
217
+ })
218
+ // afterEach(() => {
219
+ // vi.mocked(canPlayDash)
220
+ // })
221
+ it('should build the ordered list of available sources', () => {
222
+ const ordered = buildMediaSourcesList(
223
+ sources,
224
+ preference as TransportPreference,
225
+ )
226
+ expect(ordered).toEqual(expect.objectContaining(expected))
227
+ })
228
+ })
229
+ })
230
+ })
@@ -1,90 +1,94 @@
1
- import DashPlayback from '../plugins/dash-playback/DashPlayback'
2
- import HlsPlayback from '../plugins/hls-playback/HlsPlayback'
3
- import type { PlayerMediaSource, TransportPreference } from '../types'
1
+ import type { PlayerMediaSource, PlayerMediaSourceDesc, TransportPreference } from '../types'
2
+ import { canPlayDash, canPlayHls } from '../playback/index.js'
4
3
 
5
4
  export type SourceVariants = {
6
- dash: string | null
7
- master: string | null
8
- hls: string | null
9
- mpegts: string | null
5
+ dash: PlayerMediaSourceDesc | null
6
+ hls: PlayerMediaSourceDesc | null
7
+ mpegts: PlayerMediaSourceDesc | null
10
8
  }
11
9
 
10
+ /**
11
+ *
12
+ * @param sources
13
+ * @deprecated
14
+ * @returns
15
+ */
12
16
  export function buildSourcesSet(sources: PlayerMediaSource[]): SourceVariants {
13
17
  const sv: SourceVariants = {
14
18
  dash: null,
15
- master: null,
16
19
  hls: null,
17
20
  mpegts: null,
18
21
  }
19
22
  sources.forEach((ps) => {
20
- const [s, t] = typeof ps === 'string' ? [ps, ''] : [ps.source, ps.mimeType]
21
- if (DashPlayback.canPlay(s, t)) {
22
- sv.dash = s
23
- } else if (HlsPlayback.canPlay(s, t)) {
24
- sv.hls = s
23
+ const ws = wrapSource(ps)
24
+ if (canPlayDash(ws.source, ws.mimeType)) {
25
+ sv.dash = ws
26
+ } else if (canPlayHls(ws.source, ws.mimeType)) {
27
+ sv.hls = ws
25
28
  } else {
26
- sv.master = s
29
+ sv.mpegts = ws
27
30
  }
28
31
  })
29
32
  return sv
30
33
  }
31
34
 
32
- export function buildSourcesPriorityList(
33
- sources: SourceVariants,
35
+ export function buildMediaSourcesList(
36
+ sources: PlayerMediaSourceDesc[],
34
37
  priorityTransport: TransportPreference = 'auto',
35
- ): PlayerMediaSource[] {
36
- const msl: string[] = []
37
- switch (priorityTransport) {
38
- case 'dash':
39
- addDash()
40
- break
41
- case 'hls':
42
- addHls()
43
- break
44
- case 'mpegts':
45
- addMpegts()
46
- break
47
- case 'auto':
48
- addDash()
49
- addHls()
50
- break
51
- }
52
- Object.values(sources).forEach((s) => {
53
- if (s) {
54
- msl.push(s)
38
+ ): PlayerMediaSourceDesc[] {
39
+ const [preferred, rest] = sources.reduce(
40
+ priorityTransport === 'dash' || priorityTransport === 'auto'
41
+ ? (acc: [PlayerMediaSourceDesc[], PlayerMediaSourceDesc[]], item: PlayerMediaSourceDesc) => {
42
+ if (canPlayDash(item.source, item.mimeType)) {
43
+ acc[0].push(item)
44
+ } else if (canPlayHls(item.source, item.mimeType)) {
45
+ acc[1].push(item)
46
+ }
47
+ return acc
55
48
  }
56
- })
57
- return msl
49
+ : (acc: [PlayerMediaSourceDesc[], PlayerMediaSourceDesc[]], item: PlayerMediaSourceDesc) => {
50
+ if (canPlayHls(item.source, item.mimeType)) {
51
+ acc[0].push(item)
52
+ } else if (canPlayDash(item.source, item.mimeType)) {
53
+ acc[1].push(item)
54
+ }
55
+ return acc
56
+ },
57
+ [[], []]
58
+ )
59
+ return preferred.concat(rest)
60
+ }
58
61
 
59
- function addMpegts() {
60
- if (sources.mpegts) {
61
- msl.push(sources.mpegts)
62
- sources.mpegts = null
63
- }
64
- }
62
+ export function unwrapSource(s: PlayerMediaSource): string {
63
+ return typeof s === 'string' ? s : s.source
64
+ }
65
65
 
66
- function addHls() {
67
- if (sources.hls && HlsPlayback.canPlay(sources.hls, undefined)) {
68
- msl.push(sources.hls)
69
- sources.hls = null
70
- }
71
- if (
72
- sources.master?.endsWith('.m3u8') &&
73
- HlsPlayback.canPlay(sources.master, undefined)
74
- ) {
75
- msl.push(sources.master)
76
- sources.master = null
77
- }
66
+ export function wrapSource(s: PlayerMediaSource): PlayerMediaSourceDesc {
67
+ return typeof s === 'string' ? { source: s, mimeType: guessMimeType(s) } : s
68
+ }
69
+
70
+ function guessMimeType(s: string): string {
71
+ if (s.endsWith('.mpd')) {
72
+ return 'application/dash+xml'
78
73
  }
74
+ if (s.endsWith('.m3u8')) {
75
+ return 'application/vnd.apple.mpegurl'
76
+ }
77
+ throw new Error('Unrecognized media source type')
78
+ }
79
79
 
80
- function addDash() {
81
- if (sources.dash && DashPlayback.canPlay(sources.dash, undefined)) {
82
- msl.push(sources.dash)
83
- sources.dash = null
84
- }
80
+ export function isDashSource(source: string, mimeType?: string) {
81
+ if (mimeType) {
82
+ return mimeType === 'application/dash+xml'
85
83
  }
84
+ return source.endsWith('.mpd')
86
85
  }
87
86
 
88
- export function unwrapSource(s: PlayerMediaSource): string {
89
- return typeof s === 'string' ? s : s.source
87
+ export function isHlsSource(source: string, mimeType?: string) {
88
+ if (mimeType) {
89
+ return ['application/vnd.apple.mpegurl', 'application/x-mpegURL'].includes(
90
+ mimeType,
91
+ )
92
+ }
93
+ return source.endsWith('.m3u8')
90
94
  }
@@ -0,0 +1,15 @@
1
+ export function isDashSource(source: string, mimeType?: string) {
2
+ if (mimeType) {
3
+ return mimeType === 'application/dash+xml'
4
+ }
5
+ return source.endsWith('.mpd')
6
+ }
7
+
8
+ export function isHlsSource(source: string, mimeType?: string) {
9
+ if (mimeType) {
10
+ return ['application/vnd.apple.mpegurl', 'application/x-mpegURL'].includes(
11
+ mimeType,
12
+ )
13
+ }
14
+ return source.endsWith('.m3u8')
15
+ }
package/tsconfig.json CHANGED
@@ -26,15 +26,6 @@
26
26
  "DOM.Iterable"
27
27
  ],
28
28
  "module": "ESNext",
29
- // "paths": {
30
- // // "@assets/*": ["src/assets/*"],
31
- // // "@vendor/*": ["src/vendor/*"],
32
- // },
33
- "types": [
34
- "node",
35
- // "@clappr/core",
36
- // "@clappr/plugins",
37
- ],
38
29
  "typeRoots": [
39
30
  "node_modules/@types",
40
31
  "src/typings"