@vindral/web-sdk 4.1.9 → 4.1.10

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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.1.9",
2
+ "version": "4.1.10",
3
3
  "name": "@vindral/web-sdk",
4
4
  "main": "./legacy.umd.js",
5
5
  "module": "./legacy.es.js",
package/player.d.ts CHANGED
@@ -20,17 +20,6 @@ interface Channel {
20
20
  */
21
21
  timeshiftUrls?: string[];
22
22
  }
23
- interface ClientOverrides {
24
- maxVideoBitRate?: number;
25
- minBufferTime?: number;
26
- maxBufferTime?: number;
27
- burstEnabled?: boolean;
28
- sizeBasedResolutionCapEnabled?: boolean;
29
- separateVideoSocketEnabled?: boolean;
30
- videoCodecs?: string[];
31
- }
32
- type AudioCodec = "aac" | "opus" | "mp3";
33
- type VideoCodec = "h264" | "av1";
34
23
  interface MinMaxAverage {
35
24
  last: number;
36
25
  /**
@@ -103,44 +92,48 @@ type Tagged<BaseType, Tag extends PropertyKey> = BaseType & {
103
92
  [K in Tag]: void;
104
93
  };
105
94
  };
106
- type Namespace = Tagged<Array<string>, "Namespace">;
107
- interface TrackObject {
108
- namespace?: Namespace;
109
- name: string;
110
- format: string;
111
- label?: string;
112
- renderGroup?: number;
113
- altGroup?: number;
114
- initData?: string;
115
- initTrack?: string;
116
- depends?: Array<string>;
117
- temporalId?: number;
118
- spatialId?: number;
119
- codec?: string;
120
- mimeType?: string;
121
- framerate?: [
122
- number,
123
- number
124
- ];
125
- bitrate?: number;
126
- width?: number;
127
- height?: number;
128
- samplerate?: number;
129
- channelConfig?: string;
130
- displayWidth?: number;
131
- displayHeight?: number;
132
- language?: string;
133
- ["com.vindral.variant_uid"]?: string;
134
- ["com.vindral.drm"]?: string;
135
- }
136
- interface CatalogRoot {
137
- version: number;
138
- streamingFormat?: number;
139
- streamingFormatVersion?: string;
95
+ declare class UserAgentInformation {
96
+ private highEntropyValues?;
97
+ constructor();
98
+ getUserAgentInformation(): {
99
+ locationOrigin: string;
100
+ locationPath: string;
101
+ ancestorOrigins: string[] | undefined;
102
+ hardwareConcurrency: number;
103
+ deviceMemory: number | undefined;
104
+ userAgentLegacy: string;
105
+ ua: {
106
+ browser: {
107
+ brands: string[];
108
+ fullVersionBrands: string[];
109
+ majorVersions: string[];
110
+ };
111
+ device: string;
112
+ os: {
113
+ family: string;
114
+ version: string;
115
+ major_version: number;
116
+ };
117
+ };
118
+ } | {
119
+ locationOrigin: string;
120
+ locationPath: string;
121
+ ancestorOrigins: string[] | undefined;
122
+ hardwareConcurrency: number;
123
+ deviceMemory: number | undefined;
124
+ userAgent: string;
125
+ };
140
126
  }
141
- interface TracksCatalog extends CatalogRoot {
142
- namespace: Namespace;
143
- tracks: Array<TrackObject>;
127
+ type AudioCodec = "aac" | "opus" | "mp3";
128
+ type VideoCodec = "h264" | "av1";
129
+ interface ReconnectState {
130
+ /**
131
+ * The number or retry attempts so far.
132
+ * This gets reset on every successful connect, so it will start from zero every
133
+ * time the client instance gets disconnected and will increment until the
134
+ * client instance makes a connection attempt is successful.
135
+ */
136
+ reconnectRetries: number;
144
137
  }
145
138
  interface RenditionProps {
146
139
  id: number;
@@ -183,78 +176,6 @@ type VideoRendition = VideoRenditionProps & RenditionProps;
183
176
  type AudioRendition = AudioRenditionProps & RenditionProps;
184
177
  type TextRendition = TextRenditionProps & RenditionProps;
185
178
  type Rendition = VideoRendition | AudioRendition | TextRendition;
186
- interface Telemetry {
187
- url: string;
188
- probability?: number;
189
- includeErrors?: boolean;
190
- includeEvents?: boolean;
191
- includeStats?: boolean;
192
- maxRetries?: number;
193
- maxErrorReports?: number;
194
- interval?: number;
195
- }
196
- interface ChannelWithCatalog extends Channel {
197
- catalog: TracksCatalog;
198
- renditions: Rendition[];
199
- overrides?: ClientOverrides;
200
- }
201
- interface ChannelWithRenditions extends Channel {
202
- renditions: Rendition[];
203
- overrides?: ClientOverrides;
204
- }
205
- interface ServerCertificateHash {
206
- algorithm: string;
207
- value: string;
208
- }
209
- interface Edge {
210
- moqUrl?: string;
211
- moqWsUrl: string;
212
- serverCertificateHashes?: ServerCertificateHash[];
213
- }
214
- interface MoQConnectInfo {
215
- logsUrl?: string;
216
- statsUrl?: string;
217
- telemetry?: Telemetry;
218
- channels: ChannelWithCatalog[];
219
- edges: Edge[];
220
- timeshift: {
221
- urls: string[];
222
- duration: string;
223
- };
224
- }
225
- interface VindralConnectInfo {
226
- logsUrl?: string;
227
- statsUrl?: string;
228
- telemetry?: Telemetry;
229
- channels: ChannelWithRenditions[];
230
- edges: string[];
231
- }
232
- type ConnectInfo = VindralConnectInfo | MoQConnectInfo;
233
- interface Metadata {
234
- /**
235
- * The raw string content as it was ingested (if using JSON, it needs to be parsed on your end)
236
- */
237
- content: string;
238
- /**
239
- * Timestamp in ms
240
- */
241
- timestamp: number;
242
- }
243
- interface TimeRange {
244
- /** */
245
- start: number;
246
- /** */
247
- end: number;
248
- }
249
- interface ReconnectState {
250
- /**
251
- * The number or retry attempts so far.
252
- * This gets reset on every successful connect, so it will start from zero every
253
- * time the client instance gets disconnected and will increment until the
254
- * client instance makes a connection attempt is successful.
255
- */
256
- reconnectRetries: number;
257
- }
258
179
  interface Size {
259
180
  /** */
260
181
  width: number;
@@ -306,6 +227,7 @@ interface DrmOptions {
306
227
  };
307
228
  }
308
229
  type Media = "audio" | "video" | "audio+video";
230
+ type WebCodecsHardwareAccelerationPreference = "no-preference" | "prefer-hardware" | "prefer-software";
309
231
  interface Options {
310
232
  /**
311
233
  * URL to use when connecting to the stream
@@ -506,6 +428,38 @@ interface Options {
506
428
  * Enables iOS devices to use a media element for playback. This enables fullscreen and picture in picture support on iOS.
507
429
  */
508
430
  iosMediaElementEnabled?: boolean;
431
+ /**
432
+ * Enable WebCodecs API for hardware-accelerated decoding.
433
+ *
434
+ * When enabled, the browser's native VideoDecoder and AudioDecoder APIs will be used instead
435
+ * of WASM decoding on supported browsers (Chrome 94+, Edge 94+, Safari 16.4+). This provides:
436
+ * - Hardware-accelerated decoding (uses GPU for video)
437
+ * - Better performance at higher resolutions
438
+ * - Lower CPU usage and battery consumption
439
+ *
440
+ * Disabled by default to allow gradual rollout and testing.
441
+ *
442
+ * Note: Automatically falls back to WASM decoding if:
443
+ * - The browser doesn't support WebCodecs
444
+ * - WebCodecs initialization fails
445
+ * - This option is set to false or undefined
446
+ */
447
+ webcodecsEnabled?: boolean;
448
+ /**
449
+ * Hardware acceleration preference for WebCodecs video decoding.
450
+ *
451
+ * Defaults to `"no-preference"`.
452
+ */
453
+ webcodecsHardwareAcceleration?: WebCodecsHardwareAccelerationPreference;
454
+ /**
455
+ * Enable OffscreenCanvas rendering in worker thread (requires webcodecsEnabled: true).
456
+ *
457
+ * When enabled, video rendering happens in the worker thread using OffscreenCanvas.
458
+ * Disabled by default to allow gradual rollout and testing.
459
+ *
460
+ * Note: Requires browser support for OffscreenCanvas and webcodecsEnabled must be true, and iosMediaElementEnabled must be false.
461
+ */
462
+ offscreenCanvasEnabled?: boolean;
509
463
  /**
510
464
  * Advanced options to override default behaviour.
511
465
  */
@@ -517,6 +471,120 @@ interface Options {
517
471
  */
518
472
  drm?: DrmOptions;
519
473
  }
474
+ interface ClientOverrides {
475
+ maxVideoBitRate?: number;
476
+ minBufferTime?: number;
477
+ maxBufferTime?: number;
478
+ burstEnabled?: boolean;
479
+ sizeBasedResolutionCapEnabled?: boolean;
480
+ separateVideoSocketEnabled?: boolean;
481
+ webcodecsEnabled?: boolean;
482
+ webcodecsHardwareAcceleration?: WebCodecsHardwareAccelerationPreference;
483
+ offscreenCanvasEnabled?: boolean;
484
+ videoCodecs?: string[];
485
+ }
486
+ type Namespace = Tagged<Array<string>, "Namespace">;
487
+ interface TrackObject {
488
+ namespace?: Namespace;
489
+ name: string;
490
+ format: string;
491
+ label?: string;
492
+ renderGroup?: number;
493
+ altGroup?: number;
494
+ initData?: string;
495
+ initTrack?: string;
496
+ depends?: Array<string>;
497
+ temporalId?: number;
498
+ spatialId?: number;
499
+ codec?: string;
500
+ mimeType?: string;
501
+ framerate?: [
502
+ number,
503
+ number
504
+ ];
505
+ bitrate?: number;
506
+ width?: number;
507
+ height?: number;
508
+ samplerate?: number;
509
+ channelConfig?: string;
510
+ displayWidth?: number;
511
+ displayHeight?: number;
512
+ language?: string;
513
+ ["com.vindral.variant_uid"]?: string;
514
+ ["com.vindral.drm"]?: string;
515
+ }
516
+ interface CatalogRoot {
517
+ version: number;
518
+ streamingFormat?: number;
519
+ streamingFormatVersion?: string;
520
+ }
521
+ interface TracksCatalog extends CatalogRoot {
522
+ namespace: Namespace;
523
+ tracks: Array<TrackObject>;
524
+ }
525
+ interface Telemetry {
526
+ url: string;
527
+ probability?: number;
528
+ includeErrors?: boolean;
529
+ includeEvents?: boolean;
530
+ includeStats?: boolean;
531
+ maxRetries?: number;
532
+ maxErrorReports?: number;
533
+ interval?: number;
534
+ }
535
+ interface ChannelWithCatalog extends Channel {
536
+ catalog: TracksCatalog;
537
+ renditions: Rendition[];
538
+ overrides?: ClientOverrides;
539
+ }
540
+ interface ChannelWithRenditions extends Channel {
541
+ renditions: Rendition[];
542
+ overrides?: ClientOverrides;
543
+ }
544
+ interface ServerCertificateHash {
545
+ algorithm: string;
546
+ value: string;
547
+ }
548
+ interface Edge {
549
+ moqUrl?: string;
550
+ moqWsUrl: string;
551
+ serverCertificateHashes?: ServerCertificateHash[];
552
+ }
553
+ interface MoQConnectInfo {
554
+ logsUrl?: string;
555
+ statsUrl?: string;
556
+ telemetry?: Telemetry;
557
+ channels: ChannelWithCatalog[];
558
+ edges: Edge[];
559
+ timeshift: {
560
+ urls: string[];
561
+ duration: string;
562
+ };
563
+ }
564
+ interface VindralConnectInfo {
565
+ logsUrl?: string;
566
+ statsUrl?: string;
567
+ telemetry?: Telemetry;
568
+ channels: ChannelWithRenditions[];
569
+ edges: string[];
570
+ }
571
+ type ConnectInfo = VindralConnectInfo | MoQConnectInfo;
572
+ interface Metadata {
573
+ /**
574
+ * The raw string content as it was ingested (if using JSON, it needs to be parsed on your end)
575
+ */
576
+ content: string;
577
+ /**
578
+ * Timestamp in ms
579
+ */
580
+ timestamp: number;
581
+ }
582
+ interface TimeRange {
583
+ /** */
584
+ start: number;
585
+ /** */
586
+ end: number;
587
+ }
520
588
  interface RenditionLevel {
521
589
  /** */
522
590
  audio?: AudioRendition;
@@ -849,38 +917,6 @@ interface VideoPlayerStatistics {
849
917
  contextLostCount: number;
850
918
  contextRestoredCount: number;
851
919
  }
852
- declare class UserAgentInformation {
853
- private highEntropyValues?;
854
- constructor();
855
- getUserAgentInformation(): {
856
- locationOrigin: string;
857
- locationPath: string;
858
- ancestorOrigins: string[] | undefined;
859
- hardwareConcurrency: number;
860
- deviceMemory: number | undefined;
861
- userAgentLegacy: string;
862
- ua: {
863
- browser: {
864
- brands: string[];
865
- fullVersionBrands: string[];
866
- majorVersions: string[];
867
- };
868
- device: string;
869
- os: {
870
- family: string;
871
- version: string;
872
- major_version: number;
873
- };
874
- };
875
- } | {
876
- locationOrigin: string;
877
- locationPath: string;
878
- ancestorOrigins: string[] | undefined;
879
- hardwareConcurrency: number;
880
- deviceMemory: number | undefined;
881
- userAgent: string;
882
- };
883
- }
884
920
  type ModuleStatistics = AdaptivityStatistics & BufferTimeStatistics & ConnectionStatistics & ConstraintCapStatistics & DecoderStatistics & DocumentStateModulesStatistics & IncomingDataModuleStatistics & JitterModuleStatistics & MseModuleStatistics & PlaybackModuleStatistics & QualityOfServiceModuleStatistics & RenditionsModuleStatistics & SyncModuleStatistics & TelemetryModuleStatistics & VideoPlayerStatistics;
885
921
  type Statistics = ModuleStatistics & ReturnType<UserAgentInformation["getUserAgentInformation"]> & {
886
922
  /**
@@ -1541,6 +1577,37 @@ export declare class AirPlayButton extends VindralButton {
1541
1577
  get isAirPlaying(): boolean;
1542
1578
  protected handleClick(_: Event): void;
1543
1579
  }
1580
+ declare class VindralMenuButton extends VindralButton {
1581
+ #private;
1582
+ constructor();
1583
+ connectedCallback(): void;
1584
+ set button(button: HTMLElement);
1585
+ set listbox(listbox: HTMLElement);
1586
+ set listboxSlot(listboxSlot: HTMLElement);
1587
+ enable(): void;
1588
+ hide(): void;
1589
+ protected handleClick(e: Event): void;
1590
+ }
1591
+ declare class AdvancedRenditionMenu extends VindralMenuButton {
1592
+ #private;
1593
+ static observedAttributes: string[];
1594
+ constructor();
1595
+ connectedCallback(): void;
1596
+ attributeChangedCallback(name: string, old: string, value: string): void;
1597
+ }
1598
+ declare class AdvancedRenditionMenuList extends HTMLElement {
1599
+ #private;
1600
+ static observedAttributes: ("rendition-levels" | "rendition-level" | "max-video-bit-rate" | "abr-enabled" | "size-based-resolution-cap-enabled")[];
1601
+ constructor();
1602
+ connectedCallback(): void;
1603
+ disconnectedCallback(): void;
1604
+ attributeChangedCallback(name: string, old: string | null, value: string | null): void;
1605
+ private set list(value);
1606
+ private set maxVideoBitrate(value);
1607
+ get keysUsed(): string[];
1608
+ handleEvent: (event: Event) => void;
1609
+ focus(): void;
1610
+ }
1544
1611
  declare class BufferingIcon extends HTMLElement {
1545
1612
  #private;
1546
1613
  static observedAttributes: "buffering"[];
@@ -1720,7 +1787,7 @@ type ControllerAttributes = (typeof Controller.observedAttributes)[number];
1720
1787
  export declare class Controller extends HTMLElement {
1721
1788
  #private;
1722
1789
  static observedAttributes: readonly [
1723
- ...("language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src")[],
1790
+ ...("language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "abr-enabled" | "size-based-resolution-cap-enabled" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src")[],
1724
1791
  "url",
1725
1792
  "edge-url",
1726
1793
  "target-buffer-time",
@@ -1751,6 +1818,9 @@ export declare class Controller extends HTMLElement {
1751
1818
  "drm-playready-video-robustness",
1752
1819
  "drm-playready-audio-robustness",
1753
1820
  "webtransport-enabled",
1821
+ "webcodecs-enabled",
1822
+ "webcodecs-hardware-acceleration",
1823
+ "offscreen-canvas-enabled",
1754
1824
  "reconnect-retries",
1755
1825
  "auto-instance-enabled",
1756
1826
  "language"
@@ -1778,17 +1848,6 @@ export declare class FullscreenButton extends VindralButton {
1778
1848
  get isFullscreen(): boolean;
1779
1849
  protected handleClick(_: Event): void;
1780
1850
  }
1781
- declare class VindralMenuButton extends VindralButton {
1782
- #private;
1783
- constructor();
1784
- connectedCallback(): void;
1785
- set button(button: HTMLElement);
1786
- set listbox(listbox: HTMLElement);
1787
- set listboxSlot(listboxSlot: HTMLElement);
1788
- enable(): void;
1789
- hide(): void;
1790
- protected handleClick(e: Event): void;
1791
- }
1792
1851
  export declare class LanguageMenu extends VindralMenuButton {
1793
1852
  #private;
1794
1853
  static observedAttributes: string[];
@@ -1849,7 +1908,7 @@ export declare class PlayButton extends VindralButton {
1849
1908
  */
1850
1909
  export declare class Player extends HTMLElement {
1851
1910
  #private;
1852
- static observedAttributes: readonly ("title" | "advanced" | "poster" | "language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src" | "url" | "offline" | "edge-url" | "target-buffer-time" | "cast-receiver-id" | "cast-background" | "log-level" | "max-size" | "min-buffer-time" | "max-buffer-time" | "max-audio-bit-rate" | "burst-enabled" | "mse-enabled" | "mse-opus-enabled" | "ios-background-play-enabled" | "ios-wake-lock-enabled" | "ios-media-element-enabled" | "abr-enabled" | "size-based-resolution-cap-enabled" | "telemetry-enabled" | "video-codecs" | "drm-headers" | "drm-queryparams" | "drm-widevine-video-robustness" | "drm-widevine-audio-robustness" | "drm-playready-video-robustness" | "drm-playready-audio-robustness" | "webtransport-enabled" | "reconnect-retries" | "auto-instance-enabled" | "refresh-poster-enabled" | "stream-poll-enabled")[];
1911
+ static observedAttributes: readonly ("title" | "offline" | "advanced" | "poster" | "language" | "channels" | "buffering" | "paused" | "volume" | "muted" | "duration" | "user-interacting" | "is-casting" | "cast-available" | "cast-receiver-name" | "ui-locked" | "hide-ui-on-pause" | "is-fullscreen" | "is-fullscreen-fallback" | "rendition-levels" | "rendition-level" | "max-video-bit-rate" | "max-initial-bit-rate" | "abr-enabled" | "size-based-resolution-cap-enabled" | "channel-id" | "channel-group-id" | "pip-available" | "is-pip" | "airplay-available" | "is-airplaying" | "media" | "languages" | "text-tracks" | "text-track" | "needs-user-input-video" | "needs-user-input-audio" | "authentication-token" | "volume-level" | "cast" | "airplay" | "pip" | "fullscreen" | "vu-meter" | "timeshift" | "timeshift-position" | "poster-src" | "url" | "edge-url" | "target-buffer-time" | "cast-receiver-id" | "cast-background" | "log-level" | "max-size" | "min-buffer-time" | "max-buffer-time" | "max-audio-bit-rate" | "burst-enabled" | "mse-enabled" | "mse-opus-enabled" | "ios-background-play-enabled" | "ios-wake-lock-enabled" | "ios-media-element-enabled" | "telemetry-enabled" | "video-codecs" | "drm-headers" | "drm-queryparams" | "drm-widevine-video-robustness" | "drm-widevine-audio-robustness" | "drm-playready-video-robustness" | "drm-playready-audio-robustness" | "webtransport-enabled" | "webcodecs-enabled" | "webcodecs-hardware-acceleration" | "offscreen-canvas-enabled" | "reconnect-retries" | "auto-instance-enabled" | "advanced-rendition-menu-enabled" | "refresh-poster-enabled" | "stream-poll-enabled")[];
1853
1912
  constructor();
1854
1913
  connectedCallback(): void;
1855
1914
  disconnectedCallback(): void;
@@ -1905,7 +1964,7 @@ export declare class ScrollOverlay extends HTMLElement {
1905
1964
  constructor();
1906
1965
  connectedCallback(): void;
1907
1966
  disconnectedCallback(): void;
1908
- attributeChangedCallback(name: string, old: string, value: string): void;
1967
+ attributeChangedCallback(name: string, old: string | null, value: string | null): void;
1909
1968
  handleEvent: (event: Event) => void;
1910
1969
  set open(value: boolean);
1911
1970
  get open(): boolean;
@@ -1972,6 +2031,8 @@ export declare function registerComponents(): void;
1972
2031
  export declare interface VindralHTMLElementTagNameMap {
1973
2032
  "vindral-controller": Controller;
1974
2033
  "vindral-control-bar": ControlBar;
2034
+ "vindral-advanced-rendition-menu": AdvancedRenditionMenu;
2035
+ "vindral-advanced-rendition-menu-list": AdvancedRenditionMenuList;
1975
2036
  "vindral-play-button": PlayButton;
1976
2037
  "vindral-mute-button": MuteButton;
1977
2038
  "vindral-buffering-overlay": BufferingOverlay;