@gcorevideo/player 2.16.17 → 2.18.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.
Files changed (91) hide show
  1. package/README.md +68 -19
  2. package/dist/index.js +272 -125
  3. package/dist/player.d.ts +230 -73
  4. package/docs/api/index.md +1 -1
  5. package/docs/api/player.containersize.md +19 -0
  6. package/docs/api/player.dashsettings.md +2 -0
  7. package/docs/api/player.errorlevel.md +1 -0
  8. package/docs/api/player.langtag.md +6 -0
  9. package/docs/api/player.md +59 -24
  10. package/docs/api/player.mediatransport.md +1 -0
  11. package/docs/api/player.playbackerror.code.md +2 -0
  12. package/docs/api/player.playbackerror.description.md +2 -0
  13. package/docs/api/player.playbackerror.level.md +2 -0
  14. package/docs/api/player.playbackerror.md +43 -4
  15. package/docs/api/player.playbackerror.message.md +2 -0
  16. package/docs/api/player.playbackerror.origin.md +21 -0
  17. package/docs/api/player.playbackerror.scope.md +16 -0
  18. package/docs/api/player.playbackerrorcode.md +8 -7
  19. package/docs/api/player.playbackmodule.md +1 -0
  20. package/docs/api/player.player.attachto.md +26 -0
  21. package/docs/api/player.player.configure.md +6 -2
  22. package/docs/api/player.player.destroy.md +1 -1
  23. package/docs/api/player.player.getcurrenttime.md +6 -2
  24. package/docs/api/player.player.getduration.md +4 -0
  25. package/docs/api/player.player.getvolume.md +22 -0
  26. package/docs/api/player.player.isdvrenabled.md +20 -0
  27. package/docs/api/player.player.isdvrinuse.md +24 -0
  28. package/docs/api/player.player.isplaying.md +20 -0
  29. package/docs/api/player.player.md +76 -8
  30. package/docs/api/player.player.mute.md +1 -1
  31. package/docs/api/player.player.off.md +5 -5
  32. package/docs/api/player.player.on.md +5 -5
  33. package/docs/api/player.player.registerplugin.md +14 -1
  34. package/docs/api/player.player.resize.md +6 -5
  35. package/docs/api/player.player.seek.md +1 -1
  36. package/docs/api/player.player.setvolume.md +56 -0
  37. package/docs/api/player.player.unmute.md +1 -1
  38. package/docs/api/player.player.unregisterplugin.md +2 -2
  39. package/docs/api/player.playercomponenttype.md +16 -0
  40. package/docs/api/player.playerdebugsettings.md +1 -1
  41. package/docs/api/player.playerdebugtag.md +1 -0
  42. package/docs/api/player.playerevent.md +96 -0
  43. package/docs/api/player.playereventhandler.md +3 -2
  44. package/docs/api/player.playereventparams.md +20 -0
  45. package/docs/api/player.playermediasourcedesc.md +1 -1
  46. package/docs/api/player.playermediasourcedesc.mimetype.md +1 -1
  47. package/docs/api/player.qualitylevel.bitrate.md +16 -0
  48. package/docs/api/player.qualitylevel.height.md +16 -0
  49. package/docs/api/player.qualitylevel.level.md +16 -0
  50. package/docs/api/player.qualitylevel.md +104 -7
  51. package/docs/api/player.qualitylevel.width.md +16 -0
  52. package/docs/api/player.timeposition.current.md +16 -0
  53. package/docs/api/player.timeposition.md +65 -7
  54. package/docs/api/player.timeposition.total.md +16 -0
  55. package/docs/api/player.timevalue.md +1 -1
  56. package/docs/api/player.translationsettings.md +7 -1
  57. package/docs/api/player.transportpreference.md +1 -0
  58. package/lib/Player.d.ts +107 -26
  59. package/lib/Player.d.ts.map +1 -1
  60. package/lib/Player.js +161 -77
  61. package/lib/index.d.ts +2 -3
  62. package/lib/index.d.ts.map +1 -1
  63. package/lib/index.js +2 -3
  64. package/lib/internal.types.d.ts +3 -5
  65. package/lib/internal.types.d.ts.map +1 -1
  66. package/lib/playback/dash-playback/DashPlayback.d.ts +2 -0
  67. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  68. package/lib/playback/dash-playback/DashPlayback.js +37 -25
  69. package/lib/playback/hls-playback/HlsPlayback.d.ts +3 -0
  70. package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
  71. package/lib/playback/hls-playback/HlsPlayback.js +33 -18
  72. package/lib/playback.types.d.ts +65 -6
  73. package/lib/playback.types.d.ts.map +1 -1
  74. package/lib/playback.types.js +10 -0
  75. package/lib/types.d.ts +54 -5
  76. package/lib/types.d.ts.map +1 -1
  77. package/lib/types.js +31 -2
  78. package/package.json +1 -1
  79. package/rollup.config.js +1 -1
  80. package/src/Player.ts +202 -91
  81. package/src/__tests__/Player.test.ts +9 -3
  82. package/src/index.ts +2 -3
  83. package/src/internal.types.ts +3 -2
  84. package/src/playback/dash-playback/DashPlayback.ts +64 -35
  85. package/src/playback/hls-playback/HlsPlayback.ts +46 -22
  86. package/src/playback.types.ts +65 -5
  87. package/src/types.ts +56 -6
  88. package/src/utils/__tests__/mediaSources.test.ts +8 -2
  89. package/temp/player.api.json +771 -106
  90. package/tsconfig.tsbuildinfo +1 -1
  91. package/dist/DashPlayback-BRJzl8D8.js +0 -901
@@ -2,7 +2,15 @@
2
2
  // Use of this source code is governed by a BSD-style
3
3
  // license that can be found in the LICENSE file.
4
4
 
5
- import { Events, HTML5Video, Log, Playback, PlayerError, Utils } from '@clappr/core'
5
+ import {
6
+ Events,
7
+ HTML5Video,
8
+ Log,
9
+ Playback,
10
+ PlayerError,
11
+ Utils,
12
+ $,
13
+ } from '@clappr/core'
6
14
  import { trace } from '@gcorevideo/utils'
7
15
  import assert from 'assert'
8
16
  import DASHJS, {
@@ -14,7 +22,15 @@ import DASHJS, {
14
22
  IManifestInfo,
15
23
  } from 'dashjs'
16
24
 
17
- import { PlaybackError, PlaybackErrorCode, QualityLevel, TimePosition, TimeUpdate, TimeValue } from '../../playback.types.js'
25
+ import {
26
+ PlaybackError,
27
+ PlaybackErrorCode,
28
+ PlayerComponentType,
29
+ QualityLevel,
30
+ TimePosition,
31
+ TimeUpdate,
32
+ TimeValue,
33
+ } from '../../playback.types.js'
18
34
  import { isDashSource } from '../../utils/mediaSources.js'
19
35
 
20
36
  const AUTO = -1
@@ -123,13 +139,15 @@ export default class DashPlayback extends HTML5Video {
123
139
  )
124
140
  const dash = this._dash
125
141
 
126
- // TODO use $.extend
127
- const settings = this.options.dash ? structuredClone(this.options.dash) : {}
128
- settings.streaming = settings.streaming || {}
129
- settings.streaming.abr = settings.streaming.abr || {}
130
- settings.streaming.abr.autoSwitchBitrate =
131
- settings.streaming.abr.autoSwitchBitrate || {}
132
- settings.streaming.abr.autoSwitchBitrate.video = id === -1
142
+ const settings = $.extend(true, {}, this.options.dash, {
143
+ streaming: {
144
+ abr: {
145
+ autoSwitchBitrate: {
146
+ video: id === -1,
147
+ },
148
+ },
149
+ },
150
+ })
133
151
 
134
152
  dash.updateSettings(settings)
135
153
  if (id !== -1) {
@@ -222,16 +240,14 @@ export default class DashPlayback extends HTML5Video {
222
240
 
223
241
  if (this.options.dash) {
224
242
  // TODO use $.extend
225
- const settings = structuredClone(this.options.dash)
226
- if (!settings.streaming) {
227
- settings.streaming = {}
228
- }
229
- if (!settings.streaming.text) {
230
- settings.streaming.text = {
231
- defaultEnabled: false,
232
- }
233
- }
234
- this._dash.updateSettings(this.options.dash)
243
+ const settings = $.extend({}, this.options.dash, {
244
+ streaming: {
245
+ text: {
246
+ defaultEnabled: false,
247
+ },
248
+ },
249
+ })
250
+ this._dash.updateSettings(settings)
235
251
  }
236
252
 
237
253
  this._dash.attachView(this.el)
@@ -250,20 +266,18 @@ export default class DashPlayback extends HTML5Video {
250
266
 
251
267
  this._updatePlaybackType()
252
268
  this._fillLevels(bitrates)
269
+
253
270
  dash.on(DASHJS.MediaPlayer.events.QUALITY_CHANGE_REQUESTED, (evt) => {
254
- // TODO
255
- assert.ok(
256
- this._levels,
257
- 'An array of levels is required to change quality',
258
- )
259
- const newLevel = this._levels.find(
260
- (level) => level.level === evt.newQuality,
261
- ) // TODO or simply this._levels[evt.newQuality]?
262
- assert.ok(newLevel, 'A valid level is required to change quality')
271
+ const newLevel = this.getLevel(evt.newQuality)
263
272
  this.onLevelSwitch(newLevel)
264
273
  })
265
274
  })
266
275
 
276
+ this._dash.on(DASHJS.MediaPlayer.events.QUALITY_CHANGE_RENDERED, (evt: DASHJS.QualityChangeRenderedEvent) => {
277
+ const currentLevel = this.getLevel(evt.newQuality)
278
+ this.onLevelSwitchEnd(currentLevel)
279
+ })
280
+
267
281
  this._dash.on(
268
282
  DASHJS.MediaPlayer.events.METRIC_ADDED,
269
283
  (e: DashMetricEvent) => {
@@ -409,7 +423,6 @@ export default class DashPlayback extends HTML5Video {
409
423
  trace(`${T} _onDASHJSSError`, { event })
410
424
  this._stopTimeUpdateTimer()
411
425
 
412
-
413
426
  // Note that the other error types are deprecated
414
427
  const e = (event as MediaPlayerErrorEvent).error
415
428
  switch (e.code) {
@@ -419,7 +432,7 @@ export default class DashPlayback extends HTML5Video {
419
432
  case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_MANIFEST_CODE:
420
433
  case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_CONTENT_CODE:
421
434
  case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_INITIALIZATION_CODE:
422
- // TODO these probably indicate a broken manifest and should be treated by removing the source
435
+ // TODO these probably indicate a broken manifest and should be treated by removing the source
423
436
  case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_NOSTREAMS_CODE:
424
437
  case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_PARSE_CODE:
425
438
  case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_MULTIPLEXED_CODE:
@@ -431,7 +444,7 @@ export default class DashPlayback extends HTML5Video {
431
444
  description: e.message,
432
445
  level: PlayerError.Levels.FATAL,
433
446
  })
434
- break;
447
+ break
435
448
  // TODO more cases
436
449
  default:
437
450
  this.triggerError({
@@ -443,9 +456,15 @@ export default class DashPlayback extends HTML5Video {
443
456
  }
444
457
  }
445
458
 
446
- private triggerError(error: PlaybackError) {
459
+ private triggerError(
460
+ error: Pick<PlaybackError, 'code' | 'message' | 'description' | 'level'>,
461
+ ) {
447
462
  trace(`${T} triggerError`, { error })
448
- this.trigger(Events.PLAYBACK_ERROR, error)
463
+ this.trigger(Events.PLAYBACK_ERROR, {
464
+ ...error,
465
+ origin: this.name,
466
+ scope: DashPlayback.type as PlayerComponentType,
467
+ })
449
468
  // only reset the dash player in 10ms async, so that the rest of the
450
469
  // calling function finishes
451
470
  setTimeout(() => {
@@ -591,9 +610,13 @@ export default class DashPlayback extends HTML5Video {
591
610
  private onLevelSwitch(currentLevel: QualityLevel) {
592
611
  // TODO check the two below
593
612
  this.trigger(Events.PLAYBACK_LEVEL_SWITCH, currentLevel)
613
+ }
614
+
615
+ private onLevelSwitchEnd(currentLevel: QualityLevel) {
594
616
  this.trigger(Events.PLAYBACK_LEVEL_SWITCH_END)
595
- const isHD = (currentLevel.height >= 720 || (currentLevel.bitrate / 1000) >= 2000);
596
- this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, isHD);
617
+ const isHD =
618
+ currentLevel.height >= 720 || currentLevel.bitrate / 1000 >= 2000
619
+ this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, isHD)
597
620
  this.trigger(Events.PLAYBACK_BITRATE, currentLevel)
598
621
  }
599
622
 
@@ -604,6 +627,12 @@ export default class DashPlayback extends HTML5Video {
604
627
  isSeekEnabled() {
605
628
  return this._playbackType === Playback.VOD || this.dvrEnabled
606
629
  }
630
+
631
+ private getLevel(quality: number) {
632
+ const ret = this.levels.find((level) => level.level === quality)
633
+ assert.ok(ret, 'Invalid quality level')
634
+ return ret
635
+ }
607
636
  }
608
637
 
609
638
  DashPlayback.canPlay = function (resource, mimeType) {
@@ -28,6 +28,7 @@ import HLSJS, {
28
28
  import {
29
29
  PlaybackError,
30
30
  PlaybackErrorCode,
31
+ PlayerComponentType,
31
32
  QualityLevel,
32
33
  TimePosition,
33
34
  TimeUpdate,
@@ -426,6 +427,11 @@ export default class HlsPlayback extends HTML5Video {
426
427
  (evt: HlsEvents.LEVEL_SWITCHING, data: LevelSwitchingData) =>
427
428
  this._onLevelSwitch(evt, data),
428
429
  )
430
+ this._hls.on(
431
+ HLSJS.Events.LEVEL_SWITCHED,
432
+ (evt: HlsEvents.LEVEL_SWITCHED, data: { level: number }) =>
433
+ this._onLevelSwitched(evt, data),
434
+ )
429
435
  this._hls.on(
430
436
  HLSJS.Events.FRAG_CHANGED,
431
437
  (evt: HlsEvents.FRAG_CHANGED, data: FragChangedData) =>
@@ -511,7 +517,10 @@ export default class HlsPlayback extends HTML5Video {
511
517
  this._hls.recoverMediaError()
512
518
  } else {
513
519
  Log.error('hlsjs: failed to recover', { evt, data })
514
- trace(`${T} _recover failed to recover`, { type: data.type, details: data.details })
520
+ trace(`${T} _recover failed to recover`, {
521
+ type: data.type,
522
+ details: data.details,
523
+ })
515
524
  error.level = PlayerError.Levels.FATAL
516
525
 
517
526
  this.triggerError(error)
@@ -614,12 +623,18 @@ export default class HlsPlayback extends HTML5Video {
614
623
  }
615
624
 
616
625
  _onHLSJSError(evt: HlsEvents.ERROR, data: HlsErrorData) {
617
- trace(`${T} _onHLSJSError`, { fatal: data.fatal, type: data.type, details: data.details })
626
+ trace(`${T} _onHLSJSError`, {
627
+ fatal: data.fatal,
628
+ type: data.type,
629
+ details: data.details,
630
+ })
618
631
  const error: PlaybackError = {
619
632
  code: PlaybackErrorCode.Generic,
620
633
  description: `${this.name} error: type: ${data.type}, details: ${data.details} fatal: ${data.fatal}`,
621
634
  level: data.fatal ? PlayerError.Levels.FATAL : PlayerError.Levels.WARN,
622
635
  message: `${this.name} error: type: ${data.type}, details: ${data.details}`,
636
+ origin: this.name,
637
+ scope: HlsPlayback.type as PlayerComponentType,
623
638
  }
624
639
 
625
640
  if (data.response) {
@@ -657,9 +672,12 @@ export default class HlsPlayback extends HTML5Video {
657
672
  evt,
658
673
  data,
659
674
  })
660
- trace(`${T} _onHLSJSError trying to recover from network error`, {
661
- details: data.details,
662
- })
675
+ trace(
676
+ `${T} _onHLSJSError trying to recover from network error`,
677
+ {
678
+ details: data.details,
679
+ },
680
+ )
663
681
  error.level = PlayerError.Levels.WARN
664
682
  this._hls?.startLoad()
665
683
  break
@@ -705,7 +723,10 @@ export default class HlsPlayback extends HTML5Video {
705
723
  }
706
724
 
707
725
  Log.warn('hlsjs: non-fatal error occurred', { evt, data })
708
- trace(`${T} _onHLSJSError non-fatal error occurred`, { type: data.type, details: data.details })
726
+ trace(`${T} _onHLSJSError non-fatal error occurred`, {
727
+ type: data.type,
728
+ details: data.details,
729
+ })
709
730
  }
710
731
  }
711
732
 
@@ -1035,23 +1056,26 @@ export default class HlsPlayback extends HTML5Video {
1035
1056
  if (!this.levels.length) {
1036
1057
  this._fillLevels()
1037
1058
  }
1038
- this.trigger(Events.PLAYBACK_LEVEL_SWITCH_END)
1039
1059
  this.trigger(Events.PLAYBACK_LEVEL_SWITCH, data)
1040
- assert(this._hls, 'Hls.js instance is not available')
1041
- const currentLevel = this._hls.levels[data.level]
1042
-
1043
- if (currentLevel) {
1044
- // TODO should highDefinition be private and maybe have a read only accessor if it's used somewhere
1045
- this.highDefinition =
1046
- currentLevel.height >= 720 || currentLevel.bitrate / 1000 >= 2000
1047
- this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, this.highDefinition)
1048
- this.trigger(Events.PLAYBACK_BITRATE, {
1049
- height: currentLevel.height,
1050
- width: currentLevel.width,
1051
- bitrate: currentLevel.bitrate,
1052
- level: data.level,
1053
- })
1054
- }
1060
+ }
1061
+
1062
+ _onLevelSwitched(evt: HlsEvents.LEVEL_SWITCHED, data: { level: number }) {
1063
+ // @ts-ignore
1064
+ const currentLevel = this._hls.levels[data.level] // TODO or find by .id == level?
1065
+ assert.ok(currentLevel, 'Invalid quality level')
1066
+ this._currentLevel = data.level
1067
+
1068
+ // TODO should highDefinition be private and maybe have a read only accessor if it's used somewhere
1069
+ this.highDefinition =
1070
+ currentLevel.height >= 720 || currentLevel.bitrate / 1000 >= 2000
1071
+ this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, this.highDefinition)
1072
+ this.trigger(Events.PLAYBACK_BITRATE, {
1073
+ height: currentLevel.height,
1074
+ width: currentLevel.width,
1075
+ bitrate: currentLevel.bitrate,
1076
+ level: data.level,
1077
+ })
1078
+ this.trigger(Events.PLAYBACK_LEVEL_SWITCH_END)
1055
1079
  }
1056
1080
 
1057
1081
  get dvrEnabled() {
@@ -1,16 +1,21 @@
1
1
  /**
2
2
  * Playback time in seconds since the beginning of the stream (or a segment for the live streams)
3
- * For the plugin development
4
3
  * @beta
5
4
  */
6
5
  export type TimeValue = number
7
6
 
8
7
  /**
9
- * For the plugin development
8
+ * Current playback time and total duration of the media.
10
9
  * @beta
11
10
  */
12
- export type TimePosition = {
11
+ export interface TimePosition {
12
+ /**
13
+ * Current playback time, 0..duration, seconds.
14
+ */
13
15
  current: TimeValue
16
+ /**
17
+ * Total duration of the media, seconds.
18
+ */
14
19
  total: TimeValue
15
20
  }
16
21
 
@@ -29,35 +34,90 @@ export type TimeUpdate = TimePosition & {
29
34
  }
30
35
 
31
36
  /**
37
+ * A level of quality within a media source.
32
38
  * @beta
33
39
  */
34
- export type QualityLevel = {
35
- level: number // 0-based index
40
+ export interface QualityLevel {
41
+ /**
42
+ * Zero-based index of the quality level.
43
+ */
44
+ level: number
45
+ /**
46
+ * Width of the video, pixels.
47
+ */
36
48
  width: number
49
+ /**
50
+ * Height of the video, pixels.
51
+ */
37
52
  height: number
53
+ /**
54
+ * Bitrate of the video, bps.
55
+ */
38
56
  bitrate: number
39
57
  }
40
58
 
41
59
  /**
60
+ * Codes of errors occurring within the playback component.
42
61
  * @beta
43
62
  */
44
63
  export enum PlaybackErrorCode {
64
+ /**
65
+ * An unknown or uncategorised error.
66
+ */
45
67
  Generic = 0,
68
+ /**
69
+ * The media source is not available. Typically a network error.
70
+ */
46
71
  MediaSourceUnavailable = 1,
72
+ /**
73
+ * The media source is not accessible due to some protection policy.
74
+ */
47
75
  MediaSourceAccessDenied = 3,
48
76
  }
49
77
 
50
78
  /**
79
+ * Levels of severity of errors. Non-fatal errors usually can be ignored.
51
80
  * @beta
52
81
  */
53
82
  export type ErrorLevel = 'FATAL' | 'WARN' | 'INFO'
54
83
 
55
84
  /**
85
+ * Subsystems of a player component.
86
+ * @beta
87
+ */
88
+ export type PlayerComponentType = 'container' | 'core' | 'playback'
89
+
90
+ /**
91
+ * An error occurred during the playback.
56
92
  * @beta
57
93
  */
58
94
  export interface PlaybackError {
95
+ /**
96
+ * Error code.
97
+ */
59
98
  code: PlaybackErrorCode
99
+ /**
100
+ * Detailed description of the error.
101
+ */
60
102
  description: string
103
+ /**
104
+ * Level of severity of the error.
105
+ */
61
106
  level: ErrorLevel
107
+ /**
108
+ * Error message. Non-fatal usually can be ignored.
109
+ */
62
110
  message: string
111
+ /**
112
+ * Exact component that originated the error.
113
+ * @example
114
+ * - 'core'
115
+ * - 'dash'
116
+ * - 'media_control'
117
+ */
118
+ origin: string
119
+ /**
120
+ * Component subsystem of the error origin
121
+ */
122
+ scope: PlayerComponentType
63
123
  }
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ContainerPlugin, CorePlugin } from "@clappr/core"
1
+ import { ContainerPlugin, CorePlugin } from '@clappr/core'
2
2
 
3
3
  /**
4
4
  * Describes a media source with its MIME type and URL.
@@ -10,7 +10,8 @@ import { ContainerPlugin, CorePlugin } from "@clappr/core"
10
10
  */
11
11
  export interface PlayerMediaSourceDesc {
12
12
  /**
13
- * The MIME type of the media source (e.g. "video/mp4", "application/x-mpegURL")
13
+ * The MIME type of the media source (e.g. `"video/mp4"`, `"application/x-mpegURL"`).
14
+ * Necessary if the type cannot be detected from file extension of the source URL.
14
15
  */
15
16
  mimeType?: string
16
17
 
@@ -27,12 +28,13 @@ export interface PlayerMediaSourceDesc {
27
28
  export type PlayerMediaSource = string | PlayerMediaSourceDesc
28
29
 
29
30
  /**
31
+ * Debug output category selector
30
32
  * @beta
31
33
  */
32
34
  export type PlayerDebugTag = 'all' | 'clappr' | 'dash' | 'hls' | 'none'
33
35
 
34
36
  /**
35
- * @remarks true is equivalent to 'all', false is equivalent to 'none'
37
+ * @remarks `true` is equivalent to `'all'`, `false` is equivalent to `'none'`
36
38
  * @beta
37
39
  */
38
40
  export type PlayerDebugSettings = PlayerDebugTag | boolean
@@ -44,11 +46,13 @@ export type PlayerDebugSettings = PlayerDebugTag | boolean
44
46
  export type PlaybackType = 'live' | 'vod'
45
47
 
46
48
  /**
49
+ * Media delivery protocol
47
50
  * @beta
48
51
  */
49
52
  export type MediaTransport = 'dash' | 'hls'
50
53
 
51
54
  /**
55
+ * Preferred media delivery protocol
52
56
  * @beta
53
57
  */
54
58
  export type TransportPreference = MediaTransport
@@ -167,6 +171,8 @@ export interface PlayerConfig extends Record<string, unknown> {
167
171
  }
168
172
 
169
173
  /**
174
+ * An ISO 639-1 language code.
175
+ * @example `pt`
170
176
  * @beta
171
177
  */
172
178
  export type LangTag = string
@@ -177,13 +183,19 @@ export type LangTag = string
177
183
  export type TranslationKey = string
178
184
 
179
185
  /**
186
+ * A plain JS object that must conform to the DASH.js settings schema.
180
187
  * @beta
181
188
  * {@link https://cdn.dashjs.org/latest/jsdoc/module-Settings.html | DASH.js settings}
182
189
  */
183
190
  export type DashSettings = Record<string, unknown>
184
191
 
185
192
  /**
186
- * [language][key] =\> string
193
+ * Localization strings for the player UI.
194
+ * @remarks
195
+ * The keys are language codes, and the values are objects with keys being the translation keys and values being the translations.
196
+ *
197
+ * This dictionary is used to localize the player UI, including the error messages and is shared across all the player components (including the plugins).
198
+ *
187
199
  * @example
188
200
  * ```
189
201
  * {
@@ -205,11 +217,34 @@ export type TranslationSettings = Partial<
205
217
  Record<LangTag, Record<TranslationKey, string>>
206
218
  >
207
219
 
220
+ /**
221
+ * Dimensions of the player container DOM element.
222
+ * @beta
223
+ */
224
+ export type ContainerSize = {
225
+ width: number
226
+ height: number
227
+ }
228
+
208
229
  /**
209
230
  * A top-level event on the player object
210
231
  * @beta
211
232
  */
212
233
  export enum PlayerEvent {
234
+ /**
235
+ * Playback has reached the end of the media.
236
+ */
237
+ Ended = 'ended',
238
+ /**
239
+ * An error occurred.
240
+ * Parameters: {@link PlaybackError}
241
+ */
242
+ Error = 'error',
243
+ /**
244
+ * The player has switched to or from the fullscreen mode.
245
+ * Parameters:`boolean` isFullscreen
246
+ */
247
+ Fullscreen = 'fullscreen',
213
248
  /**
214
249
  * The player is ready to use.
215
250
  */
@@ -222,12 +257,27 @@ export enum PlayerEvent {
222
257
  * Playback has been paused.
223
258
  */
224
259
  Pause = 'pause',
260
+ /**
261
+ * The player's container has been resized.
262
+ * Parameters: {@link ContainerSize}
263
+ */
264
+ Resize = 'resize',
265
+ /**
266
+ * The player is seeking to a new position.
267
+ */
268
+ Seek = 'seek',
225
269
  /**
226
270
  * Playback has been stopped.
227
271
  */
228
272
  Stop = 'stop',
229
273
  /**
230
- * Playback has reached the end of the media.
274
+ * The current playback time has changed.
275
+ * Parameters: {@link TimePosition}
231
276
  */
232
- Ended = 'ended',
277
+ TimeUpdate = 'timeupdate',
278
+ /**
279
+ * The volume has changed.
280
+ * Parameters: `number` volume in the range 0..1
281
+ */
282
+ VolumeUpdate = 'volumeupdate',
233
283
  }
@@ -10,21 +10,27 @@ vi.mock('@clappr/core', () => ({
10
10
  registeredPlaybacks: [
11
11
  {
12
12
  _supported: true,
13
+ prototype: {
13
14
  name: 'dash',
15
+ },
14
16
  canPlay(source, mimeType) {
15
17
  return this._supported && (mimeType === 'application/dash+xml' || source.endsWith('.mpd'))
16
18
  },
17
19
  },
18
20
  {
19
21
  _supported: true,
20
- name: 'hls',
22
+ prototype: {
23
+ name: 'hls',
24
+ },
21
25
  canPlay(source, mimeType) {
22
26
  return this._supported && (['application/vnd.apple.mpegurl', 'application/x-mpegurl'].includes(mimeType) || source.endsWith('.m3u8'))
23
27
  },
24
28
  },
25
29
  {
26
30
  _supported: true,
27
- name: 'html5_video',
31
+ prototype: {
32
+ name: 'html5_video',
33
+ },
28
34
  canPlay: function (source, mimeType) {
29
35
  return this._supported && mimeType === 'video/mp4'
30
36
  },