@gcorevideo/player 2.28.36 → 2.30.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 (60) hide show
  1. package/README.md +108 -0
  2. package/assets/media-control/media-control.scss +8 -6
  3. package/assets/multi-camera/multicamera.ejs +27 -23
  4. package/assets/multi-camera/style.scss +7 -34
  5. package/assets/style/main.scss +2 -2
  6. package/dist/core.js +24 -7
  7. package/dist/index.css +324 -346
  8. package/dist/index.embed.js +24 -46
  9. package/dist/index.js +471 -245
  10. package/docs/api/player.md +22 -9
  11. package/docs/api/player.mediacontrol.setkeepvisible.md +56 -0
  12. package/docs/api/player.multicamera.md +0 -28
  13. package/docs/api/player.multiccamerasourceinfo.md +27 -0
  14. package/docs/api/{player.multicamera.unbindevents.md → player.multisourcesmode.md} +4 -7
  15. package/docs/api/player.sourcecontroller.md +0 -37
  16. package/lib/Player.d.ts +9 -0
  17. package/lib/Player.d.ts.map +1 -1
  18. package/lib/Player.js +11 -0
  19. package/lib/index.plugins.d.ts +1 -0
  20. package/lib/index.plugins.d.ts.map +1 -1
  21. package/lib/index.plugins.js +1 -0
  22. package/lib/playback/dash-playback/DashPlayback.d.ts +2 -1
  23. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  24. package/lib/playback/dash-playback/DashPlayback.js +5 -1
  25. package/lib/playback/hls-playback/HlsPlayback.d.ts +2 -1
  26. package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
  27. package/lib/playback/types.d.ts +9 -0
  28. package/lib/playback/types.d.ts.map +1 -1
  29. package/lib/playback.types.d.ts +0 -6
  30. package/lib/playback.types.d.ts.map +1 -1
  31. package/lib/plugins/multi-camera/MultiCamera.d.ts +21 -4
  32. package/lib/plugins/multi-camera/MultiCamera.d.ts.map +1 -1
  33. package/lib/plugins/multi-camera/MultiCamera.js +70 -134
  34. package/lib/plugins/source-controller/SourceController.d.ts +0 -39
  35. package/lib/plugins/source-controller/SourceController.d.ts.map +1 -1
  36. package/lib/plugins/source-controller/SourceController.js +0 -39
  37. package/lib/plugins/token-refresh/TokenRefreshPlugin.d.ts +119 -0
  38. package/lib/plugins/token-refresh/TokenRefreshPlugin.d.ts.map +1 -0
  39. package/lib/plugins/token-refresh/TokenRefreshPlugin.js +318 -0
  40. package/lib/plugins/token-refresh/index.d.ts +2 -0
  41. package/lib/plugins/token-refresh/index.d.ts.map +1 -0
  42. package/lib/plugins/token-refresh/index.js +1 -0
  43. package/lib/utils/mediaSources.d.ts +4 -0
  44. package/lib/utils/mediaSources.d.ts.map +1 -1
  45. package/lib/utils/mediaSources.js +8 -6
  46. package/package.json +1 -1
  47. package/src/Player.ts +12 -0
  48. package/src/index.plugins.ts +1 -0
  49. package/src/playback/dash-playback/DashPlayback.ts +7 -3
  50. package/src/playback/hls-playback/HlsPlayback.ts +1 -1
  51. package/src/playback/types.ts +10 -0
  52. package/src/playback.types.ts +0 -6
  53. package/src/plugins/multi-camera/MultiCamera.ts +103 -166
  54. package/src/plugins/source-controller/SourceController.ts +0 -39
  55. package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
  56. package/src/plugins/token-refresh/TokenRefreshPlugin.ts +425 -0
  57. package/src/plugins/token-refresh/index.ts +5 -0
  58. package/src/utils/mediaSources.ts +10 -6
  59. package/tsconfig.tsbuildinfo +1 -1
  60. package/docs/api/player.multicamera.activebyid.md +0 -67
@@ -12554,6 +12554,9 @@ var PlayerEvent;
12554
12554
  PlayerEvent["VolumeUpdate"] = "volumeupdate";
12555
12555
  })(PlayerEvent || (PlayerEvent = {}));
12556
12556
 
12557
+ const MIME_TYPES_HLS = ['application/x-mpegurl', 'application/vnd.apple.mpegurl'];
12558
+ const MIME_TYPE_HLS = MIME_TYPES_HLS[0];
12559
+ const MIME_TYPE_DASH = 'application/dash+xml';
12557
12560
  // TODO rewrite using the Playback classes and canPlay static methods
12558
12561
  function buildMediaSourcesList(sources, priorityTransport = 'dash') {
12559
12562
  const playbacks = Loader.registeredPlaybacks;
@@ -12592,22 +12595,21 @@ function wrapSource(s) {
12592
12595
  }
12593
12596
  function guessMimeType(s) {
12594
12597
  if (s.endsWith('.mpd')) {
12595
- return 'application/dash+xml';
12598
+ return MIME_TYPE_DASH;
12596
12599
  }
12597
12600
  if (s.endsWith('.m3u8')) {
12598
- // return 'application/vnd.apple.mpegurl'
12599
- return 'application/x-mpegurl';
12601
+ return MIME_TYPE_HLS;
12600
12602
  }
12601
12603
  }
12602
12604
  function isDashSource(source, mimeType) {
12603
12605
  if (mimeType) {
12604
- return mimeType === 'application/dash+xml'; // TODO consider video/mp4
12606
+ return mimeType === MIME_TYPE_DASH; // TODO consider video/mp4
12605
12607
  }
12606
12608
  return source.endsWith('.mpd');
12607
12609
  }
12608
12610
  function isHlsSource(source, mimeType) {
12609
12611
  if (mimeType) {
12610
- return ['application/vnd.apple.mpegurl', 'application/x-mpegurl'].includes(mimeType.toLowerCase());
12612
+ return MIME_TYPES_HLS.includes(mimeType.toLowerCase());
12611
12613
  }
12612
12614
  return source.endsWith('.m3u8');
12613
12615
  }
@@ -12828,6 +12830,7 @@ class DashPlayback extends BasePlayback {
12828
12830
  this._dash = dash;
12829
12831
  this._dash.initialize();
12830
12832
  if (this.options.dash) {
12833
+ const { requestInterceptor, ...dashSettings } = this.options.dash;
12831
12834
  const settings = $.extend(true, {
12832
12835
  streaming: {
12833
12836
  text: {
@@ -12839,8 +12842,11 @@ class DashPlayback extends BasePlayback {
12839
12842
  // dispatchForManualRendering: true, // TODO only when useNativeSubtitles is not true?
12840
12843
  },
12841
12844
  },
12842
- }, this.options.dash);
12845
+ }, dashSettings);
12843
12846
  this._dash.updateSettings(settings);
12847
+ if (typeof requestInterceptor === 'function') {
12848
+ this._dash.addRequestInterceptor(requestInterceptor);
12849
+ }
12844
12850
  }
12845
12851
  this._dash.attachView(this.el);
12846
12852
  this._dash.setAutoPlay(false);
@@ -51065,6 +51071,17 @@ class Player {
51065
51071
  }
51066
51072
  this.player?.load(ms, ms[0].mimeType ?? '');
51067
51073
  }
51074
+ /**
51075
+ * Returns a registered core plugin instance by name, or `null` if not found.
51076
+ *
51077
+ * @example
51078
+ * ```ts
51079
+ * const tokenRefresh = player.getPlugin('token_refresh') as TokenRefreshPlugin | null
51080
+ * ```
51081
+ */
51082
+ getPlugin(name) {
51083
+ return this.player?.core.getPlugin(name) ?? null;
51084
+ }
51068
51085
  /**
51069
51086
  * Mutes the sound of the video.
51070
51087
  */
@@ -57001,7 +57018,7 @@ class ErrorScreen extends UICorePlugin {
57001
57018
 
57002
57019
  insertStyle(".player-logo[data-logo] {\n position: absolute;\n z-index: 2;\n width: 100%;\n height: 100%;\n}\n\n.clappr-logo {\n position: absolute;\n}");
57003
57020
 
57004
- insertStyle("*,\n:focus,\n:visited {\n outline: none !important;\n}\n\n.multicamera[data-multicamera] {\n float: right;\n margin-top: 4px;\n position: relative;\n margin-right: 20px;\n width: 20px;\n}\n.multicamera[data-multicamera] button {\n background-color: transparent;\n color: #fff;\n font-family: Roboto, \"Open Sans\", Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n border: none;\n font-size: 14px;\n padding: 0;\n}\n.multicamera[data-multicamera] button svg {\n height: 20px;\n position: relative;\n margin-top: 6px;\n}\n.multicamera[data-multicamera] button:hover {\n color: #c9c9c9;\n}\n.multicamera[data-multicamera] button.changing {\n animation: pulse 0.5s infinite alternate;\n}\n.multicamera[data-multicamera] button span.quality-arrow {\n width: 9px;\n height: 6px;\n margin-top: 11px;\n margin-left: 5px;\n}\n.multicamera[data-multicamera] > ul {\n padding: 6px 0;\n right: -24px;\n width: 245px;\n list-style-type: none;\n position: absolute;\n bottom: 48px;\n border-radius: 4px;\n display: none;\n background-color: rgba(74, 74, 74, 0.9);\n}\n.multicamera[data-multicamera] > ul::after {\n content: \"\";\n position: absolute;\n top: 100%;\n left: 85%;\n margin-left: -10px;\n width: 0;\n height: 0;\n border-top: 10px solid rgba(74, 74, 74, 0.9);\n border-right: 10px solid transparent;\n border-left: 10px solid transparent;\n}\n.multicamera[data-multicamera] li {\n font-size: 10px;\n cursor: pointer;\n}\n.multicamera[data-multicamera] li .multicamera-item {\n display: flex;\n padding: 10px 0;\n justify-content: center;\n position: relative;\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false] .multicamera-screenshot {\n opacity: 0.5;\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false] .multicamera-text {\n opacity: 0.5;\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false]:hover {\n background-color: rgba(0, 0, 0, 0);\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false] {\n pointer-events: none;\n}\n.multicamera[data-multicamera] li .multicamera-item:hover, .multicamera[data-multicamera] li .multicamera-item.multicamera-active {\n background-color: rgba(0, 0, 0, 0.3);\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-screenshot {\n width: 80px;\n height: 60px;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-screenshot img {\n width: 80px;\n height: 60px;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text {\n width: 120px;\n text-align: left;\n margin-left: 15px;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text .multicamera-title,\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text .multicamera-description {\n width: 120px;\n height: 20px;\n font-family: Roboto, \"Open Sans\", Arial, sans-serif;\n font-size: 14px;\n font-weight: normal;\n font-style: normal;\n font-stretch: normal;\n line-height: 1.43;\n letter-spacing: normal;\n text-align: left;\n color: #fff;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text .multicamera-description {\n opacity: 0.6;\n}\n.multicamera[data-multicamera] li a {\n color: #444;\n padding: 2px 10px;\n display: block;\n text-decoration: none;\n}\n.multicamera[data-multicamera] li a:hover {\n background-color: #555;\n color: white;\n}\n.multicamera[data-multicamera] li a:hover a {\n color: white;\n text-decoration: none;\n}\n.multicamera[data-multicamera] li.current a {\n color: #f00;\n}");
57021
+ insertStyle("*,\n:focus,\n:visited {\n outline: none !important;\n}\n\n.multicamera[data-multicamera] {\n position: relative;\n order: 80;\n}\n.multicamera[data-multicamera] button {\n background-color: transparent;\n color: #fff;\n font-family: Roboto, \"Open Sans\", Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n border: none;\n font-size: 14px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 20px;\n}\n.multicamera[data-multicamera] button svg {\n height: 20px;\n position: relative;\n}\n.multicamera[data-multicamera] button:hover {\n color: #c9c9c9;\n}\n.multicamera[data-multicamera] button.changing {\n animation: pulse 0.5s infinite alternate;\n}\n.multicamera[data-multicamera] > ul {\n padding: 6px 0;\n right: -24px;\n width: 245px;\n list-style-type: none;\n position: absolute;\n bottom: 48px;\n border-radius: 4px;\n display: none;\n background-color: rgba(74, 74, 74, 0.9);\n}\n.multicamera[data-multicamera] > ul::after {\n content: \"\";\n position: absolute;\n top: 100%;\n left: 85%;\n margin-left: -10px;\n width: 0;\n height: 0;\n border-top: 10px solid rgba(74, 74, 74, 0.9);\n border-right: 10px solid transparent;\n border-left: 10px solid transparent;\n}\n.multicamera[data-multicamera] li {\n font-size: 10px;\n cursor: pointer;\n}\n.multicamera[data-multicamera] li .multicamera-item {\n display: flex;\n padding: 10px 0;\n justify-content: center;\n position: relative;\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false] .multicamera-screenshot {\n opacity: 0.5;\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false] .multicamera-text {\n opacity: 0.5;\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false]:hover {\n background-color: rgba(0, 0, 0, 0);\n}\n.multicamera[data-multicamera] li .multicamera-item[data-mulitcamera-selector-live=false] {\n pointer-events: none;\n}\n.multicamera[data-multicamera] li .multicamera-item:hover, .multicamera[data-multicamera] li .multicamera-item.multicamera-active {\n background-color: rgba(0, 0, 0, 0.3);\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-screenshot {\n width: 80px;\n height: 60px;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-screenshot img {\n width: 80px;\n height: 60px;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text {\n width: 120px;\n text-align: left;\n margin-left: 15px;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text .multicamera-title,\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text .multicamera-description {\n width: 120px;\n height: 20px;\n font-family: Roboto, \"Open Sans\", Arial, sans-serif;\n font-size: 14px;\n font-weight: normal;\n font-style: normal;\n font-stretch: normal;\n line-height: 1.43;\n letter-spacing: normal;\n text-align: left;\n color: #fff;\n text-overflow: ellipsis;\n overflow: hidden;\n}\n.multicamera[data-multicamera] li .multicamera-item .multicamera-text .multicamera-description {\n opacity: 0.6;\n}");
57005
57022
 
57006
57023
  const pipIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M21.05 3.00001C21.302 3.00001 21.5435 3.10003 21.7217 3.27833C21.9 3.45646 22 3.69802 22 3.95003V10.6H20.1V4.90003H4.90001V18.2H10.6V20.1H3.95001C3.69802 20.1 3.45647 20 3.27832 19.8217C3.10002 19.6436 3 19.402 3 19.15V3.95001C3 3.69802 3.10002 3.45647 3.27832 3.27832C3.45644 3.10002 3.69801 3 3.95001 3L21.05 3.00001ZM21.05 12.5C21.302 12.5 21.5435 12.6 21.7217 12.7783C21.9 12.9565 22 13.198 22 13.45V19.15C22 19.402 21.9 19.6436 21.7217 19.8217C21.5436 20 21.302 20.1 21.05 20.1H13.45C13.198 20.1 12.9564 20 12.7783 19.8217C12.6 19.6436 12.5 19.402 12.5 19.15V13.45C12.5 13.198 12.6 12.9565 12.7783 12.7783C12.9564 12.6 13.198 12.5 13.45 12.5H21.05ZM7.47178 6.12823L9.60928 8.26572L11.5501 6.32492V11.5499H6.32509L8.26589 9.60911L6.12839 7.47161L7.47178 6.12823Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
57007
57024
 
@@ -58301,45 +58318,6 @@ function noSync(cb) {
58301
58318
  * `PLUGIN` that is managing the automatic failover between media sources.
58302
58319
  * @public
58303
58320
  * @remarks
58304
- * Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
58305
- * on how sources ordering and selection works. Below is a simplified diagram:
58306
- *
58307
- * ```markdown
58308
- * sources_list:
58309
- * - a.mpd | +--------------------+
58310
- * - b.m3u8 |--->| init |
58311
- * - ... | |--------------------|
58312
- * | current_source = 0 |
58313
- * +--------------------+
58314
- * |
58315
- * | source = a.mpd
58316
- * | playback = dash.js
58317
- * v
58318
- * +------------------+
58319
- * +-->| load source |
58320
- * | +---------|--------+
58321
- * | v
58322
- * | +------------------+
58323
- * | | play |
58324
- * | +---------|--------+
58325
- * | |
58326
- * | v
58327
- * | +-----------------------+
58328
- * | | on playback_error |
58329
- * | |-----------------------|
58330
- * | | current_source = |
58331
- * | | (current_source + 1) |
58332
- * | | % len sources_list |
58333
- * | | |
58334
- * | | delay 1..3s |
58335
- * | +---------------|-------+
58336
- * | |
58337
- * | source=b.m3u8 |
58338
- * | playback=hls.js |
58339
- * +-------------------+
58340
- *
58341
- * ```
58342
- *
58343
58321
  * @example
58344
58322
  * ```ts
58345
58323
  * import { SourceController } from '@gcorevideo/player'