@vindral/web-sdk 3.4.4 → 4.0.0-101-g094c7a1b

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.
@@ -1,18 +1,35 @@
1
- type AudioCodec = "aac" | "opus" | "mp3";
2
- type VideoCodec = "h264" | "av1";
3
1
  /**
4
- * Represents a timed metadata event
2
+ * Channel
5
3
  */
6
- export interface Metadata {
4
+ export interface Channel {
7
5
  /**
8
- * The raw string content as it was ingested (if using JSON, it needs to be parsed on your end)
6
+ * Channel ID for the channel
9
7
  */
10
- content: string;
8
+ channelId: string;
11
9
  /**
12
- * Timestamp in ms
10
+ * Display name
13
11
  */
14
- timestamp: number;
12
+ name: string;
13
+ /**
14
+ * Indicates whether there is an incoming source feed for the channel
15
+ */
16
+ isLive: boolean;
17
+ /**
18
+ * URLs to fetch thumbnail from
19
+ */
20
+ thumbnailUrls: string[];
21
+ }
22
+ interface ClientOverrides {
23
+ maxVideoBitRate?: number;
24
+ minBufferTime?: number;
25
+ maxBufferTime?: number;
26
+ burstEnabled?: boolean;
27
+ sizeBasedResolutionCapEnabled?: boolean;
28
+ separateVideoSocketEnabled?: boolean;
29
+ videoCodecs?: string[];
15
30
  }
31
+ export type AudioCodec = "aac" | "opus" | "mp3";
32
+ export type VideoCodec = "h264" | "av1";
16
33
  type MatchingKeys<TRecord, TMatch, K extends keyof TRecord = keyof TRecord> = K extends (TRecord[K] extends TMatch ? K : never) ? K : never;
17
34
  type VoidKeys<Record> = MatchingKeys<Record, void>;
18
35
  type EventListenerReturnType = (() => void) | void;
@@ -20,6 +37,9 @@ declare class Emitter<TEvents, TEmits = TEvents, ArgLessEvents extends VoidKeys<
20
37
  private listeners;
21
38
  emit<T extends ArgLessEmits>(eventName: T): void;
22
39
  emit<T extends ArgEmits>(eventName: T, args: TEmits[T]): void;
40
+ /**
41
+ * Remove an event listener from `eventName`
42
+ */
23
43
  off<T extends ArgLessEvents>(eventName: T, fn: () => EventListenerReturnType): void;
24
44
  off<T extends ArgEvents>(eventName: T, fn: (args: TEvents[T]) => EventListenerReturnType): void;
25
45
  /**
@@ -38,10 +58,13 @@ declare class Emitter<TEvents, TEmits = TEvents, ArgLessEvents extends VoidKeys<
38
58
  */
39
59
  once<T extends ArgLessEvents>(eventName: T, fn: () => void): void;
40
60
  once<T extends ArgEvents>(eventName: T, fn: (args: TEvents[T]) => void): void;
61
+ /**
62
+ * Reset the event emitter
63
+ */
41
64
  reset(): void;
42
65
  private add;
43
66
  }
44
- declare const Levels: readonly [
67
+ declare const LogLevels: readonly [
45
68
  "off",
46
69
  "error",
47
70
  "warn",
@@ -49,8 +72,8 @@ declare const Levels: readonly [
49
72
  "debug",
50
73
  "trace"
51
74
  ];
52
- export type Level = (typeof Levels)[number];
53
- export declare const Level: {
75
+ type LogLevel = (typeof LogLevels)[number];
76
+ declare const LogLevel: {
54
77
  ERROR: "error";
55
78
  WARN: "warn";
56
79
  INFO: "info";
@@ -73,41 +96,80 @@ interface MinMaxAverage {
73
96
  */
74
97
  min: number;
75
98
  }
76
- export interface TimeRange {
77
- start: number;
78
- end: number;
99
+ declare const tags: unique symbol;
100
+ type Tagged<BaseType, Tag extends PropertyKey> = BaseType & {
101
+ [tags]: {
102
+ [K in Tag]: void;
103
+ };
104
+ };
105
+ type Namespace = Tagged<Array<string>, "Namespace">;
106
+ interface TrackObject {
107
+ namespace?: Namespace;
108
+ name: string;
109
+ format: string;
110
+ label?: string;
111
+ renderGroup?: number;
112
+ altGroup?: number;
113
+ initData?: string;
114
+ initTrack?: string;
115
+ depends?: Array<string>;
116
+ temporalId?: number;
117
+ spatialId?: number;
118
+ codec?: string;
119
+ mimeType?: string;
120
+ framerate?: [
121
+ number,
122
+ number
123
+ ];
124
+ bitrate?: number;
125
+ width?: number;
126
+ height?: number;
127
+ samplerate?: number;
128
+ channelConfig?: string;
129
+ displayWidth?: number;
130
+ displayHeight?: number;
131
+ language?: string;
132
+ ["com.vindral.variant_uid"]?: string;
79
133
  }
80
- /**
81
- * The current reconnect state to use to decide whether to kep reconnecting or not
82
- */
83
- export interface ReconnectState {
84
- /**
85
- * The number or retry attempts so far.
86
- * This gets reset on every successful connect, so it will start from zero every
87
- * time the client instance gets disconnected and will increment until the
88
- * client instance makes a connection attempt is successful.
89
- */
90
- reconnectRetries: number;
134
+ interface CatalogRoot {
135
+ version: number;
136
+ streamingFormat?: number;
137
+ streamingFormatVersion?: string;
138
+ }
139
+ interface TracksCatalog extends CatalogRoot {
140
+ namespace: Namespace;
141
+ tracks: Array<TrackObject>;
91
142
  }
92
143
  interface RenditionProps {
93
144
  id: number;
145
+ /** */
94
146
  bitRate: number;
147
+ /** */
95
148
  codecString?: string;
149
+ /** */
96
150
  language?: string;
151
+ /** */
97
152
  meta?: Record<string, string>;
98
153
  }
99
154
  interface VideoRenditionProps {
155
+ /** */
100
156
  codec: VideoCodec;
157
+ /** */
101
158
  frameRate: [
102
159
  number,
103
160
  number
104
161
  ];
162
+ /** */
105
163
  width: number;
164
+ /** */
106
165
  height: number;
107
166
  }
108
167
  interface AudioRenditionProps {
168
+ /** */
109
169
  codec: AudioCodec;
170
+ /** */
110
171
  channels: number;
172
+ /** */
111
173
  sampleRate: number;
112
174
  }
113
175
  interface TextRenditionProps {
@@ -115,19 +177,110 @@ interface TextRenditionProps {
115
177
  kind: "subtitles" | "captions";
116
178
  label?: string;
117
179
  }
118
- type VideoRendition = VideoRenditionProps & RenditionProps;
119
- type AudioRendition = AudioRenditionProps & RenditionProps;
180
+ /**
181
+ * @interface
182
+ */
183
+ export type VideoRendition = VideoRenditionProps & RenditionProps;
184
+ /**
185
+ * @interface
186
+ */
187
+ export type AudioRendition = AudioRenditionProps & RenditionProps;
120
188
  type TextRendition = TextRenditionProps & RenditionProps;
121
189
  type Rendition = VideoRendition | AudioRendition | TextRendition;
122
- interface Size {
190
+ interface Telemetry {
191
+ url: string;
192
+ probability?: number;
193
+ includeErrors?: boolean;
194
+ includeEvents?: boolean;
195
+ includeStats?: boolean;
196
+ maxRetries?: number;
197
+ maxErrorReports?: number;
198
+ interval?: number;
199
+ }
200
+ interface ChannelWithCatalog extends Channel {
201
+ catalog: TracksCatalog;
202
+ renditions: Rendition[];
203
+ overrides?: ClientOverrides;
204
+ }
205
+ interface ChannelWithRenditions extends Channel {
206
+ renditions: Rendition[];
207
+ overrides?: ClientOverrides;
208
+ }
209
+ interface ServerCertificateHash {
210
+ algorithm: string;
211
+ value: string;
212
+ }
213
+ interface Edge {
214
+ moqUrl?: string;
215
+ moqWsUrl: string;
216
+ serverCertificateHashes?: ServerCertificateHash[];
217
+ }
218
+ interface MoQConnectInfo {
219
+ logsUrl?: string;
220
+ statsUrl?: string;
221
+ telemetry?: Telemetry;
222
+ channels: ChannelWithCatalog[];
223
+ edges: Edge[];
224
+ }
225
+ interface VindralConnectInfo {
226
+ logsUrl?: string;
227
+ statsUrl?: string;
228
+ telemetry?: Telemetry;
229
+ channels: ChannelWithRenditions[];
230
+ edges: string[];
231
+ }
232
+ export type ConnectInfo = VindralConnectInfo | MoQConnectInfo;
233
+ /**
234
+ * Represents a timed metadata event
235
+ */
236
+ export interface Metadata {
237
+ /**
238
+ * The raw string content as it was ingested (if using JSON, it needs to be parsed on your end)
239
+ */
240
+ content: string;
241
+ /**
242
+ * Timestamp in ms
243
+ */
244
+ timestamp: number;
245
+ }
246
+ /** */
247
+ export interface TimeRange {
248
+ /** */
249
+ start: number;
250
+ /** */
251
+ end: number;
252
+ }
253
+ /**
254
+ * The current reconnect state to use to decide whether to kep reconnecting or not
255
+ */
256
+ export interface ReconnectState {
257
+ /**
258
+ * The number or retry attempts so far.
259
+ * This gets reset on every successful connect, so it will start from zero every
260
+ * time the client instance gets disconnected and will increment until the
261
+ * client instance makes a connection attempt is successful.
262
+ */
263
+ reconnectRetries: number;
264
+ }
265
+ /**
266
+ * Represents a size with a width and height.
267
+ */
268
+ export interface Size {
269
+ /** */
123
270
  width: number;
271
+ /** */
124
272
  height: number;
125
273
  }
126
- interface VideoConstraint {
274
+ export interface VideoConstraint {
275
+ /** */
127
276
  width: number;
277
+ /** */
128
278
  height: number;
279
+ /** */
129
280
  bitRate: number;
281
+ /** */
130
282
  codec?: VideoCodec;
283
+ /** */
131
284
  codecString?: string;
132
285
  }
133
286
  /**
@@ -141,7 +294,23 @@ export interface AdvancedOptions {
141
294
  */
142
295
  wasmDecodingConstraint: Partial<VideoConstraint>;
143
296
  }
144
- type Media = "audio" | "video" | "audio+video";
297
+ /**
298
+ * DRM options to provide to the Vindral instance
299
+ */
300
+ export interface DrmOptions {
301
+ /**
302
+ * Headers to be added to requests to license servers
303
+ */
304
+ headers?: Record<string, string>;
305
+ /**
306
+ * Query parameters to be added to requests to license servers
307
+ */
308
+ queryParams?: Record<string, string>;
309
+ }
310
+ /**
311
+ * Type of media.
312
+ */
313
+ export type Media = "audio" | "video" | "audio+video";
145
314
  /**
146
315
  * Options for the Vindral instance
147
316
  *
@@ -181,7 +350,7 @@ export interface Options {
181
350
  /**
182
351
  * Sets the log level - defaults to info
183
352
  */
184
- logLevel?: Level;
353
+ logLevel?: LogLevel;
185
354
  /**
186
355
  * Sets the minimum and initial buffer time
187
356
  */
@@ -311,6 +480,7 @@ export interface Options {
311
480
  edgeUrl?: string;
312
481
  logShippingEnabled?: boolean;
313
482
  statsShippingEnabled?: boolean;
483
+ webtransportEnabled?: boolean;
314
484
  /**
315
485
  * Enable wake lock for iOS devices.
316
486
  * The wake lock requires that the audio has been activated at least once for the instance, othwerwise it will not work.
@@ -335,77 +505,103 @@ export interface Options {
335
505
  advanced?: AdvancedOptions;
336
506
  media?: Media;
337
507
  videoCodecs?: VideoCodec[];
508
+ /**
509
+ * DRM options to provide to the Vindral instance
510
+ */
511
+ drm?: DrmOptions;
338
512
  }
339
513
  /**
340
514
  * Represents a rendition (quality level).
341
515
  */
342
516
  export interface RenditionLevel {
517
+ /** */
343
518
  audio?: AudioRendition;
519
+ /** */
344
520
  video?: VideoRendition;
345
521
  }
346
- type RenditionLevelChangedReason = "abr" | "manual";
522
+ /**
523
+ * Reason for the rendition level change.
524
+ */
525
+ export type RenditionLevelChangedReason = "abr" | "manual";
347
526
  /**
348
527
  * Contextual information about the rendition level change.
349
528
  */
350
529
  export interface RenditionLevelChanged {
530
+ /** */
351
531
  from?: RenditionLevel;
532
+ /** */
352
533
  to?: RenditionLevel;
534
+ /** */
353
535
  reason: RenditionLevelChangedReason;
354
536
  }
537
+ interface VindralErrorProps {
538
+ isFatal: boolean;
539
+ type?: ErrorType;
540
+ code: string;
541
+ source?: Error | MediaError;
542
+ }
543
+ export declare const CONNECTION_FAILED_CODE = "connection_failed";
544
+ export declare const CONNECTION_FAILED_AFTER_RETRIES_CODE = "connection_failed_will_not_attempt_again";
545
+ export declare const AUTHENTICATION_FAILED_CODE = "authentication_error";
546
+ export declare const AUTHENTICATION_EXPIRED_CODE = "authentication_expired";
547
+ export declare const CHANNEL_NOT_FOUND_CODE = "channel_not_found";
548
+ export declare const NO_INCOMING_DATA = "no_incoming_data_error";
549
+ export declare const INACTIVITY_CODE = "connection_inactivity";
550
+ export declare const DISCONNECTED_BY_EDGE = "disconnected_by_edge";
551
+ export type ErrorType = "internal" | "external";
355
552
  /**
356
- * Channel
553
+ * Represents a vindral error - all errors emitted from the Vindral instance inherit from this class.
357
554
  */
358
- export interface Channel {
555
+ export declare class VindralError extends Error {
556
+ private props;
557
+ private extra;
558
+ constructor(message: string, props: VindralErrorProps, extra?: {});
359
559
  /**
360
- * Channel ID for the channel
560
+ * The error code is a stable string that represents the error type - this should be treated as an
561
+ * opaque string that can be used as a key for looking up localized strings for displaying error messages.
562
+ * @returns the error code
361
563
  */
362
- channelId: string;
564
+ code: () => string;
363
565
  /**
364
- * Display name
566
+ * Indicates whether the error is fatal - if it is that means the Vindral instance will be unloaded because of this error.
365
567
  */
366
- name: string;
568
+ isFatal: () => boolean;
367
569
  /**
368
- * Indicates whether there is an incoming source feed for the channel
570
+ * The underlying error that caused the Vindral error
571
+ * @returns the underlying error
369
572
  */
370
- isLive: boolean;
573
+ source: () => Error | MediaError | undefined;
574
+ type: () => ErrorType;
371
575
  /**
372
- * URLs to fetch thumbnail from
576
+ * @returns a stringifiable represenation of the error
373
577
  */
374
- thumbnailUrls: string[];
375
- }
376
- interface ClientOverrides {
377
- maxVideoBitRate?: number;
378
- minBufferTime?: number;
379
- maxBufferTime?: number;
380
- burstEnabled?: boolean;
381
- sizeBasedResolutionCapEnabled?: boolean;
382
- separateVideoSocketEnabled?: boolean;
383
- videoCodecs?: string[];
384
- }
385
- interface ChannelWithRenditionsAndOverrides extends Channel {
386
- renditions: Rendition[];
387
- overrides?: ClientOverrides;
388
- }
389
- interface ConnectOptions {
390
- channelGroupId?: string;
391
- channelId: string;
578
+ toStringifiable: () => Record<string, unknown>;
392
579
  }
393
- interface Telemetry {
394
- url: string;
395
- probability?: number;
396
- includeErrors?: boolean;
397
- includeEvents?: boolean;
398
- includeStats?: boolean;
399
- maxRetries?: number;
400
- maxErrorReports?: number;
401
- interval?: number;
580
+ /**
581
+ * Represents a playback state.
582
+ */
583
+ export type PlaybackState = "buffering" | "playing" | "paused";
584
+ export type BufferStateEvent = "filled" | "drained";
585
+ interface PlaybackModuleStatistics {
586
+ /**
587
+ * Current target buffer time if using dynamic buffer. Otherwise, this is the statically set buffer time from instantiation.
588
+ */
589
+ bufferTime: number;
590
+ needsInputForAudioCount: number;
591
+ needsInputForVideoCount: number;
402
592
  }
403
- export interface ConnectResponse {
404
- logsUrl?: string;
405
- statsUrl?: string;
406
- telemetry?: Telemetry;
407
- channels: ChannelWithRenditionsAndOverrides[];
408
- edges: string[];
593
+ /**
594
+ * Shows for what context the browser needs a user input event.
595
+ */
596
+ export interface NeedsUserInputContext {
597
+ /**
598
+ * True if user input is needed for audio
599
+ */
600
+ forAudio: boolean;
601
+ /**
602
+ * True if user input is needed for video
603
+ */
604
+ forVideo: boolean;
409
605
  }
410
606
  /**
411
607
  * ApiClientOptions
@@ -433,6 +629,10 @@ export interface AuthorizationContext {
433
629
  */
434
630
  channelId?: string;
435
631
  }
632
+ interface ConnectOptions {
633
+ channelGroupId?: string;
634
+ channelId: string;
635
+ }
436
636
  /**
437
637
  * AuthorizationTokenFactory
438
638
  */
@@ -445,9 +645,10 @@ export declare class ApiClient {
445
645
  private tokenFactory?;
446
646
  constructor(options: ApiClientOptions);
447
647
  /**
648
+ * @ignore
448
649
  * Returns everything needed to setup the connection of Vindral instance.
449
650
  */
450
- connect(options: ConnectOptions): Promise<ConnectResponse>;
651
+ connect(options: ConnectOptions): Promise<ConnectInfo>;
451
652
  /**
452
653
  * Fetches information regarding a single channel.
453
654
  *
@@ -460,7 +661,7 @@ export declare class ApiClient {
460
661
  *
461
662
  * Note: The returned list includes inactive channels - check isLive to filter out only active channels
462
663
  *
463
- * @param channelGroup the channel group to fetch channels from
664
+ * @param channelGroupId the channel group to fetch channels from
464
665
  * @returns an array of [[Channel]] that belong to the channel group
465
666
  */
466
667
  getChannels(channelGroupId: string): Promise<Channel[]>;
@@ -469,580 +670,678 @@ export declare class ApiClient {
469
670
  private toChannels;
470
671
  private toChannel;
471
672
  }
472
- /**
473
- * Available events to listen to
474
- */
475
- export interface CastSenderEvents {
673
+ interface AdaptivityStatistics {
476
674
  /**
477
- * When a connection has been established with a CastReceiver
675
+ * True if adaptive bitrate (ABR) is enabled.
478
676
  */
479
- ["connected"]: void;
677
+ isAbrEnabled: boolean;
678
+ }
679
+ interface BufferTimeStatistics {
480
680
  /**
481
- * When a previous session has been resumed
681
+ * Number of time buffer time has been adjusted. This will only happen when using dynamic buffer time
682
+ * (different min/max values of bufferTime).
482
683
  */
483
- ["resumed"]: void;
684
+ bufferTimeAdjustmentCount: number;
685
+ }
686
+ interface RenditionsModuleStatistics {
484
687
  /**
485
- * When a CastReceiver has lost or stopped a connection
688
+ * Id of current video rendition subscribed to.
486
689
  */
487
- ["disconnected"]: void;
690
+ videoRenditionId?: number;
488
691
  /**
489
- * When a connection attempt was initiated unsuccessfully
692
+ * Id of current audio rendition subscribed to.
490
693
  */
491
- ["failed"]: void;
694
+ audioRenditionId?: number;
492
695
  /**
493
- * When the remote connection emits a metadata event
696
+ * Current video codec being used.
494
697
  */
495
- ["metadata"]: Metadata;
698
+ videoCodec?: string;
496
699
  /**
497
- * When the remote connection receives a server wallclock time event
498
- */
499
- ["server wallclock time"]: number;
500
- }
501
- /**
502
- * Used for initializing the CastSender
503
- */
504
- export interface CastConfig {
505
- /**
506
- * The [Vindral Options](./Options) to use for the Cast Receiver
507
- */
508
- options: Options;
509
- /**
510
- * URL to a background image.
511
- * Example: "https://via.placeholder.com/256x144"
700
+ * Current audio codec being used.
512
701
  */
513
- background?: string;
702
+ audioCodec?: string;
514
703
  /**
515
- * Override this if you have your own custom receiver
704
+ * Width of current video rendition (if any).
516
705
  */
517
- receiverApplicationId?: string;
518
- }
519
- /**
520
- * CastSender handles initiation of and communication with the Google Cast Receiver
521
- */
522
- export declare class CastSender extends Emitter<CastSenderEvents> {
523
- private state;
524
- private config;
525
- private unloaded;
526
- constructor(config: CastConfig);
706
+ videoWidth?: number;
527
707
  /**
528
- * True if the instance is casting right now
708
+ * Height of current video rendition (if any).
529
709
  */
530
- get casting(): boolean;
710
+ videoHeight?: number;
531
711
  /**
532
- * The current volume
712
+ * Currently expected video bit rate according to metadata in bits/s.
533
713
  */
534
- get volume(): number;
714
+ expectedVideoBitRate?: number;
535
715
  /**
536
- * Set the current volume. Setting this to zero is equivalent to muting the video
716
+ * Currently expected audio bit rate according to metadata in bits/s.
537
717
  */
538
- set volume(volume: number);
718
+ expectedAudioBitRate?: number;
539
719
  /**
540
- * The current language
720
+ * Current language. For non-multi language streams, this will often be unset.
541
721
  */
542
- get language(): string | undefined;
722
+ language?: string;
543
723
  /**
544
- * Set the current language
724
+ * Frame rate. Example: `"frameRate": [24000, 1001]`.
545
725
  */
546
- set language(language: string | undefined);
726
+ frameRate?: [
727
+ number,
728
+ number
729
+ ];
547
730
  /**
548
- * The current channelId
731
+ * Total count of rendition level changes (quality downgrades/upgrades).
549
732
  */
550
- get channelId(): string;
733
+ renditionLevelChangeCount: number;
734
+ }
735
+ interface VideoConstraintCap {
736
+ width: number;
737
+ height: number;
738
+ bitRate: number;
739
+ }
740
+ interface AudioConstraintCap {
741
+ bitRate: number;
742
+ }
743
+ interface ConstraintCap {
744
+ video: VideoConstraintCap;
745
+ audio: AudioConstraintCap;
746
+ }
747
+ interface ConstraintCapStatistics {
748
+ constraintCap?: ConstraintCap;
749
+ windowInnerWidth: number;
750
+ windowInnerHeight: number;
751
+ elementWidth: number;
752
+ elementHeight: number;
753
+ pixelRatio: number;
754
+ }
755
+ interface DecoderStatistics {
756
+ videoDecodeRate: number;
757
+ videoDecodeTime: MinMaxAverage;
758
+ audioDecodeTime: MinMaxAverage;
759
+ videoTransportTime: MinMaxAverage;
760
+ }
761
+ interface DocumentStateModulesStatistics {
762
+ isVisible: boolean;
763
+ isOnline: boolean;
764
+ isVisibleCount: number;
765
+ isHiddenCount: number;
766
+ isOnlineCount: number;
767
+ isOfflineCount: number;
768
+ navigatorRtt?: number;
769
+ navigatorEffectiveType?: EffectiveConnectionType;
770
+ navigatorConnectionType?: ConnectionType;
771
+ navigatorSaveData?: boolean;
772
+ navigatorDownlink?: number;
773
+ }
774
+ interface IncomingDataModuleStatistics {
551
775
  /**
552
- * Set the current channelId
776
+ * Current video bitrate in bits/second.
553
777
  */
554
- set channelId(channelId: string);
778
+ videoBitRate?: number;
555
779
  /**
556
- * Update authentication token on an already established and authenticated connection
780
+ * Current audio bitrate in bits/second.
557
781
  */
558
- updateAuthenticationToken: (token: string) => void;
782
+ audioBitRate?: number;
559
783
  /**
560
- * Fully unloads the instance. This disconnects the current listener but lets the
561
- * cast session continue on the receiving device
784
+ * Counter of number of bytes received.
562
785
  */
563
- unload: () => void;
786
+ bytesReceived: number;
787
+ }
788
+ interface MseModuleStatistics {
789
+ quotaErrorCount: number;
790
+ mediaSourceOpenTime: number;
791
+ totalVideoFrames?: number;
792
+ droppedVideoFrames?: number;
793
+ successfulVideoAppendCalls?: number;
794
+ successfulAudioAppendsCalls?: number;
795
+ }
796
+ interface QualityOfServiceModuleStatistics {
564
797
  /**
565
- * Initiates the CastSender.
566
- * Will reject if Cast is not available on the device or the network.
798
+ * Time in milliseconds spent in buffering state. Note that this value will increase while in background if
799
+ * buffering when leaving foreground.
567
800
  */
568
- init: () => Promise<void>;
801
+ timeSpentBuffering: number;
569
802
  /**
570
- * Requests a session. It will open the native cast receiver chooser dialog
803
+ * Total number of buffering events since instantiation.
571
804
  */
572
- start: () => Promise<void>;
805
+ bufferingEventsCount: number;
573
806
  /**
574
- * Stops a session. It will stop playback on device as well.
807
+ * Number of fatal quality of service events.
575
808
  */
576
- stop: () => void;
809
+ fatalQosCount: number;
577
810
  /**
578
- * Returns a string representing the name of the Cast receiver device or undefined if no receiver exists
811
+ * Ratio of time being spent on different bitrates.
812
+ * Example: `"timeSpentRatio": { "1160000": 0.2, "2260000": 0.8 }` shows 20% spent on 1.16 Mbps, 80% spent on 2.26 Mbps.
579
813
  */
580
- getReceiverName: () => string | undefined;
581
- private onGCastApiAvailable;
582
- private send;
583
- private onMessage;
584
- private onSessionStarted;
585
- private onSessionStateChanged;
586
- private getInstance;
587
- private getSession;
588
- private castLibrariesAdded;
589
- private verifyCastLibraries;
814
+ timeSpentRatio: {
815
+ [bitRate: string]: number;
816
+ };
590
817
  }
591
- interface VindralErrorProps {
592
- isFatal: boolean;
593
- type?: ErrorType;
594
- code: string;
595
- source?: Error | MediaError;
818
+ interface SyncModuleStatistics {
819
+ drift: number | undefined;
820
+ driftAdjustmentCount: number;
821
+ timeshiftDriftAdjustmentCount: number;
822
+ seekTime: number;
596
823
  }
597
- export declare const CONNECTION_FAILED_CODE = "connection_failed";
598
- export declare const CONNECTION_FAILED_AFTER_RETRIES_CODE = "connection_failed_will_not_attempt_again";
599
- export declare const AUTHENTICATION_FAILED_CODE = "authentication_error";
600
- export declare const AUTHENTICATION_EXPIRED_CODE = "authentication_expired";
601
- export declare const CHANNEL_NOT_FOUND_CODE = "channel_not_found";
602
- export declare const NO_INCOMING_DATA = "no_incoming_data_error";
603
- export declare const INACTIVITY_CODE = "connection_inactivity";
604
- export declare const DISCONNECTED_BY_EDGE = "disconnected_by_edge";
605
- type ErrorType = "internal" | "external";
824
+ interface VideoPlayerStatistics {
825
+ renderedFrameCount: number;
826
+ rendererDroppedFrameCount: number;
827
+ contextLostCount: number;
828
+ contextRestoredCount: number;
829
+ }
830
+ declare class UserAgentInformation {
831
+ private highEntropyValues?;
832
+ constructor();
833
+ getUserAgentInformation(): {
834
+ locationOrigin: string;
835
+ locationPath: string;
836
+ ancestorOrigins: string[] | undefined;
837
+ hardwareConcurrency: number;
838
+ deviceMemory: number | undefined;
839
+ userAgentLegacy: string;
840
+ ua: {
841
+ browser: {
842
+ brands: string[];
843
+ fullVersionBrands: string[];
844
+ majorVersions: string[];
845
+ };
846
+ device: string;
847
+ os: {
848
+ family: string;
849
+ version: string;
850
+ major_version: number;
851
+ };
852
+ };
853
+ } | {
854
+ locationOrigin: string;
855
+ locationPath: string;
856
+ ancestorOrigins: string[] | undefined;
857
+ hardwareConcurrency: number;
858
+ deviceMemory: number | undefined;
859
+ userAgent: string;
860
+ };
861
+ }
862
+ type ModuleStatistics = AdaptivityStatistics & BufferTimeStatistics & ConnectionStatistics & ConstraintCapStatistics & DecoderStatistics & DocumentStateModulesStatistics & IncomingDataModuleStatistics & MseModuleStatistics & PlaybackModuleStatistics & QualityOfServiceModuleStatistics & RenditionsModuleStatistics & SyncModuleStatistics & TelemetryModuleStatistics & VideoPlayerStatistics;
606
863
  /**
607
- * Represents a vindral error - all errors emitted from the Vindral instance inherit from this class.
864
+ * Contains internal statistics.
865
+ *
866
+ * Note that this object will have some undocumented properties, used internally or temporarily,
867
+ * for monitoring and improving the performance of the service.
868
+ *
869
+ * @interface
608
870
  */
609
- export declare class VindralError extends Error {
610
- private props;
611
- private extra;
612
- constructor(message: string, props: VindralErrorProps, extra?: {});
871
+ export type Statistics = ModuleStatistics & ReturnType<UserAgentInformation["getUserAgentInformation"]> & {
613
872
  /**
614
- * The error code is a stable string that represents the error type - this should be treated as an
615
- * opaque string that can be used as a key for looking up localized strings for displaying error messages.
616
- * @returns the error code
873
+ * Version of the @vindral/web-sdk being used.
617
874
  */
618
- code: () => string;
875
+ version: string;
619
876
  /**
620
- * Indicates whether the error is fatal - if it is that means the Vindral instance will be unloaded because of this error.
877
+ * IP of the client.
621
878
  */
622
- isFatal: () => boolean;
879
+ ip?: string;
623
880
  /**
624
- * The underlying error that caused the Vindral error
625
- * @returns the underlying error
881
+ * URL being used for connecting to the stream.
626
882
  */
627
- source: () => Error | MediaError | undefined;
628
- type: () => ErrorType;
883
+ url: string;
629
884
  /**
630
- * @returns a stringifiable represenation of the error
885
+ * A session is bound to a connection. If the client reconnects for any reason (e.g. coming back from inactivity
886
+ * or a problem with network on client side), a new sessionId will be used.
887
+ *
631
888
  */
632
- toStringifiable: () => Record<string, unknown>;
633
- }
634
- interface AirPlaySenderEvents {
889
+ sessionId?: string;
635
890
  /**
636
- * When airplay targets are available.
891
+ * Unlike `sessionId`, `clientId` will remain the same even after reconnections and represents this unique Vindral instance.
637
892
  */
638
- ["available"]: void;
893
+ clientId: string;
639
894
  /**
640
- * When a connection has been established with an airplay target.
895
+ * How long in milliseconds since the instance was created.
641
896
  */
642
- ["connected"]: void;
897
+ uptime: number;
643
898
  /**
644
- * When the airplay target has lost or stopped a connection.
899
+ * Current channel ID being subscribed to.
645
900
  */
646
- ["disconnected"]: void;
647
- }
648
- interface AirPlayConfig {
901
+ channelId: string;
902
+ /**
903
+ * Channel group being subscribed to.
904
+ */
905
+ channelGroupId?: string;
906
+ /**
907
+ * Time in milliseconds from instantiation to playback of video and audio being started.
908
+ * Note that an actual frame render often happens much quicker, but that is not counted as TTFF.
909
+ */
910
+ timeToFirstFrame?: number;
911
+ iosMediaElementEnabled?: boolean;
912
+ };
913
+ /**
914
+ * Represents a Vindral client instance
915
+ *
916
+ * The most most essential methods when using the Vindral class are:
917
+ *
918
+ * - connect() - this has to be called to actually start connecting
919
+ * - attach() - to attach the Vindral video view to the DOM so that users can see it
920
+ * - userInput() - to activate audio on browsers that require a user gesture to play audio
921
+ * - unload() - unloads the instance, its very important that this is called when cleaning up the Vindral instance, otherwise background timers may leak.
922
+ *
923
+ * The Vindral instance will emit a variety of events during its lifetime. Use .on("event-name", callback) to listen to these events.
924
+ * See [[PublicVindralEvents]] for the events types that can be emitted.
925
+ *
926
+ * ```typescript
927
+ * // minimal configuration of a Vindral client instance
928
+ * const instance = new Vindral({
929
+ * url: "https://lb.cdn.vindral.com",
930
+ * channelId: "vindral_demo1_ci_099ee1fa-80f3-455e-aa23-3d184e93e04f",
931
+ * })
932
+ *
933
+ * // Will be called when timed metadata is received
934
+ * instance.on("metadata", console.log)
935
+ *
936
+ * // Will be called when a user interaction is needed to activate audio
937
+ * instance.on("needs user input", console.log)
938
+ *
939
+ * // Start connecting to the cdn
940
+ * instance.connect()
941
+ *
942
+ * // Attach the video view to the DOM
943
+ * instance.attach(document.getElementById("root"))
944
+ *
945
+ * // When done with the instance
946
+ * instance.unload()
947
+ * ```
948
+ */
949
+ export declare class Vindral extends Emitter<PublicVindralEvents> {
950
+ #private;
951
+ private static MAX_POOL_SIZE;
952
+ private static INITIAL_MAX_BIT_RATE;
953
+ private static DISCONNECT_TIMEOUT;
954
+ private static REMOVE_CUE_THRESHOLD;
955
+ /**
956
+ * Picture in picture
957
+ */
958
+ readonly pictureInPicture: {
959
+ /**
960
+ * Enters picture in picture
961
+ * @returns a promise that resolves if successful
962
+ */
963
+ enter: () => Promise<void>;
964
+ /**
965
+ * Exits picture in picture
966
+ * @returns a promise that resolves if successful
967
+ */
968
+ exit: () => Promise<void>;
969
+ /**
970
+ * returns whether picture in picture is currently active
971
+ */
972
+ isActive: () => boolean;
973
+ /**
974
+ * returns whether picture in picture is supported
975
+ */
976
+ isSupported: () => boolean;
977
+ };
978
+ private browser;
979
+ private options;
980
+ private element;
981
+ private playbackSource;
982
+ private emitter;
983
+ private logger;
984
+ private modules;
985
+ private clientIp?;
986
+ private sessionId?;
987
+ private clientId;
988
+ private _channels;
989
+ private createdAt;
990
+ private hasCalledConnect;
991
+ private latestEmittedLanguages;
992
+ private wakeLock;
993
+ private pool;
994
+ private userAgentInformation;
995
+ private encryptedMediaExtensions;
996
+ private sampleProcessingSesssions;
997
+ private sizes;
998
+ private isSuspended;
999
+ private disconnectTimeout;
1000
+ constructor(options: Options);
1001
+ /**
1002
+ * Attaches the video view to a DOM element. The Vindral video view will be sized to fill this element while
1003
+ * maintaining the correct aspect ratio.
1004
+ * @param container the container element to append the video view to. Often a div element.
1005
+ * @returns
1006
+ */
1007
+ attach: (container: HTMLElement) => void;
649
1008
  /**
650
- * URL to use when connecting to the stream.
1009
+ * Set the current volume.
1010
+ * Setting this to 0 is not equivalent to muting the audio.
1011
+ * Setting this to >0 is not equivalent to unmuting the audio.
1012
+ *
1013
+ * Note that setting volume is not allowed on iPadOS and iOS devices.
1014
+ * This is an OS/browser limitation on the video element.
1015
+ *
1016
+ * [Read more about it on Apple docs](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html)
1017
+ * for iOS-Specific Considerations. The following section is the important part:
1018
+ * On iOS devices, the audio level is always under the user's physical control. The volume property is not settable in JavaScript. Reading the volume property always returns 1.
1019
+ *
1020
+ * @param volume The volume to set. A floating point value between 0-1.
1021
+ *
651
1022
  */
652
- url: string;
1023
+ set volume(volume: number);
653
1024
  /**
654
- * Channel ID to connect to.
1025
+ * The current volume. Note that if the playback is muted volume can still be set.
655
1026
  */
656
- channelId: string;
1027
+ get volume(): number;
657
1028
  /**
658
- * A container to attach the video element in. This should be the same container that the vindral video element is attached to.
1029
+ * Set playback to muted/unmuted
659
1030
  */
660
- container: HTMLElement;
1031
+ set muted(muted: boolean);
661
1032
  /**
662
- * An authentication token to provide to the server when connecting - only needed for channels with authentication enabled
663
- * Note: If not supplied when needed, an "Authentication Failed" error will be raised.
1033
+ * Whether the playback is muted or not
664
1034
  */
665
- authenticationToken?: string;
666
- }
667
- declare class AirPlaySender extends Emitter<AirPlaySenderEvents> {
668
- private config;
669
- private hlsUrl;
670
- private element;
671
- private connectingTimeout?;
672
- constructor(config: AirPlayConfig);
1035
+ get muted(): boolean;
673
1036
  /**
674
- * True if the instance is casting right now.
1037
+ * Which media type is currently being played
675
1038
  */
676
- get casting(): boolean;
1039
+ get media(): Media;
677
1040
  /**
678
- * Set the current channelId.
1041
+ * The current average video bit rate in bits/s
679
1042
  */
680
- set channelId(channelId: string);
1043
+ get videoBitRate(): number;
681
1044
  /**
682
- * Update authentication token on an already established and authenticated connection.
1045
+ * The current average audio bit rate in bits/s
683
1046
  */
684
- updateAuthenticationToken: (_token: string) => void;
1047
+ get audioBitRate(): number;
685
1048
  /**
686
- * Fully unloads the instance. This disconnects the current listeners.
1049
+ * The current connection state
687
1050
  */
688
- unload: () => void;
1051
+ get connectionState(): Readonly<ConnectionState>;
689
1052
  /**
690
- * Show the AirPlay picker.
1053
+ * The current playback state
691
1054
  */
692
- showPlaybackTargetPicker(): void;
1055
+ get playbackState(): Readonly<PlaybackState>;
693
1056
  /**
694
- * Returns if AirPlay is supported.
1057
+ * The current buffer fullness as a floating point value between 0-1, where 1 is full and 0 i empty.
695
1058
  */
696
- static isAirPlaySupported(): boolean;
697
- private onAirPlayAvailable;
698
- private onAirPlayPlaybackChanged;
699
- private checkHlsUrl;
700
- }
701
- type PlaybackState = "buffering" | "playing" | "paused";
702
- type BufferStateEvent = "filled" | "drained";
703
- interface PlaybackModuleStatistics {
1059
+ get bufferFullness(): number;
704
1060
  /**
705
- * Current target buffer time if using dynamic buffer. Otherwise, this is the statically set buffer time from instantiation.
1061
+ * Whether user bandwidth savings by capping the video resolution to the size of the video element is enabled
706
1062
  */
707
- bufferTime: number;
708
- needsInputForAudioCount: number;
709
- needsInputForVideoCount: number;
710
- }
711
- interface NeedsUserInputContext {
1063
+ get sizeBasedResolutionCapEnabled(): boolean;
712
1064
  /**
713
- * True if user input is needed for audio
1065
+ * Enables or disables user bandwidth savings by capping the video resolution to the size of the video element.
714
1066
  */
715
- forAudio: boolean;
1067
+ set sizeBasedResolutionCapEnabled(enabled: boolean);
716
1068
  /**
717
- * True if user input is needed for video
1069
+ * Whether ABR is currently enabled
718
1070
  */
719
- forVideo: boolean;
720
- }
721
- type State = "connected" | "disconnected" | "connecting";
722
- type ContextSwitchState = "completed" | "started";
723
- interface ConnectionStatistics {
1071
+ get abrEnabled(): boolean;
724
1072
  /**
725
- * RTT (round trip time) between client and server(s).
1073
+ * Enable or disable ABR
1074
+ *
1075
+ * The client will immediatly stop changing renditon level based on QoS metrics
1076
+ *
1077
+ * Note: It is strongly recommended to keep this enabled as it can severly increase
1078
+ * the number of buffering events for viewers.
726
1079
  */
727
- rtt: MinMaxAverage;
1080
+ set abrEnabled(enabled: boolean);
728
1081
  /**
729
- * A very rough initial estimation of minimum available bandwidth.
1082
+ * Estimated live edge time for the current channel
730
1083
  */
731
- estimatedBandwidth: number;
732
- edgeUrl?: string;
1084
+ get serverEdgeTime(): number | undefined;
733
1085
  /**
734
- * Total number of connections that have been established since instantiation.
1086
+ * @returns Estimated wallclock time on the edge server in milliseconds
735
1087
  */
736
- connectCount: number;
1088
+ get serverWallclockTime(): number | undefined;
737
1089
  /**
738
- * Total number of connection attempts since instantiation.
1090
+ * Local current time normalized between all channels in the channel group
739
1091
  */
740
- connectionAttemptCount: number;
741
- }
742
- /**
743
- * Contextual information about the language switch
744
- */
745
- export interface LanguageSwitchContext {
1092
+ get currentTime(): number;
746
1093
  /**
747
- * The new language that was switched to
1094
+ * Current time for the channel. This is the actual stream time, passed on from your ingress.
1095
+ * Integer overflow could make this value differ from your encoder timestamps if it has been rolling for more
1096
+ * than 42 days with RTMP as target.
1097
+ *
1098
+ * Note: This is not normalized between channels, thus it can make jumps when switching channels
748
1099
  */
749
- language: string;
750
- }
751
- /**
752
- * Contextual information about the channel switch
753
- */
754
- export interface ChannelSwitchContext {
1100
+ get channelCurrentTime(): number;
755
1101
  /**
756
- * The new channel id that was switched to
1102
+ * The current target buffer time in milliseconds
757
1103
  */
758
- channelId: string;
759
- }
760
- interface VolumeState {
1104
+ get targetBufferTime(): number;
761
1105
  /**
762
- * Wether the audio is muted
1106
+ * Set the current target buffer time in milliseconds
763
1107
  */
764
- isMuted: boolean;
1108
+ set targetBufferTime(bufferTimeMs: number);
765
1109
  /**
766
- * The volume level
1110
+ * The estimated playback latency based on target buffer time, the connection rtt and local playback drift
767
1111
  */
768
- volume: number;
769
- }
770
- /**
771
- * The events that can be emitted from the Vindral instance
772
- */
773
- export interface PublicVindralEvents {
1112
+ get playbackLatency(): number | undefined;
774
1113
  /**
775
- * When an error that requires action has occured
776
- *
777
- * Can be a fatal error that will unload the Vindral instance - this is indicated by `isFatal()` on the error object returning true.
778
- *
779
- * In case of a fatal error it is appropriate to indicate what the error was to the user, either by displaying the error.message or
780
- * by using the error.code() as a key to look up a localization string. To resume streaming it is required to create a new Vindral instance.
1114
+ * The estimated utc timestamp (in ms) for the playhead.
781
1115
  */
782
- ["error"]: Readonly<VindralError>;
1116
+ get playbackWallclockTime(): number | undefined;
783
1117
  /**
784
- * When the instance needs user input to activate audio or sometimes video playback.
785
- * Is called with an object
786
- * ```javascript
787
- * {
788
- * forAudio: boolean // true if user input is needed for audio playback
789
- * forVideo: boolean // true if user input is needed for video playback
790
- * }
791
- * ```
1118
+ * Channels that can be switched between
792
1119
  */
793
- ["needs user input"]: NeedsUserInputContext;
1120
+ get channels(): ReadonlyArray<Channel>;
794
1121
  /**
795
- * When a timed metadata event has been triggered
1122
+ * Languages available
796
1123
  */
797
- ["metadata"]: Readonly<Metadata>;
1124
+ get languages(): ReadonlyArray<string>;
798
1125
  /**
799
- * When the playback state changes
1126
+ * The current language
800
1127
  */
801
- ["playback state"]: Readonly<PlaybackState>;
1128
+ get language(): string | undefined;
802
1129
  /**
803
- * When the connection state changes
1130
+ * Set the current language
804
1131
  */
805
- ["connection state"]: Readonly<State>;
1132
+ set language(language: string | undefined);
806
1133
  /**
807
- * When the available rendition levels is changed
1134
+ * Set the active text track
808
1135
  */
809
- ["rendition levels"]: ReadonlyArray<RenditionLevel>;
1136
+ set textTrack(label: string | undefined);
810
1137
  /**
811
- * When the rendition level is changed
1138
+ * Get the available text tracks
812
1139
  */
813
- ["rendition level"]: Readonly<RenditionLevel>;
1140
+ get textTracks(): string[];
814
1141
  /**
815
- * When the available languages is changed
1142
+ * Get the active text track
816
1143
  */
817
- ["languages"]: ReadonlyArray<string>;
1144
+ get textTrack(): string | undefined;
818
1145
  /**
819
- * When the available text tracks are changed
1146
+ * The current channelId
820
1147
  */
821
- ["text tracks"]: ReadonlyArray<string>;
1148
+ get channelId(): string;
822
1149
  /**
823
- * When the available channels is changed
1150
+ * Set the current channelId
1151
+ *
1152
+ * Possible channels to set are available from [[channels]]
1153
+ *
1154
+ * Note that the following scenarios are not possible right now:
1155
+ * - switching channel from a channel with audio to a channel without audio (unless audio only mode is active)
1156
+ * - switching channel from a channel with video to a channel without video (unless video only mode is active)
824
1157
  */
825
- ["channels"]: ReadonlyArray<Channel>;
1158
+ set channelId(channelId: string);
826
1159
  /**
827
- * When a context switch state change has occured.
828
- * E.g. when a channel change has been requested, or quality is changed.
1160
+ * Max size that will be subscribed to
829
1161
  */
830
- ["context switch"]: Readonly<ContextSwitchState>;
1162
+ get maxSize(): Size;
831
1163
  /**
832
- * Emitted when a wallclock time message has been received from the server.
1164
+ * Set max size that will be subscribed to
833
1165
  *
834
- * Note: This is the edge server wallclock time and thus may differ slightly
835
- * between two viewers if they are connected to different edge servers.
1166
+ * Note: If ABR is disabled, setting this will make the client instantly subscribe to this size
836
1167
  */
837
- ["server wallclock time"]: Readonly<number>;
1168
+ set maxSize(size: Size);
838
1169
  /**
839
- * Is emitted during connection whether the channel is live or not.
840
- *
841
- * If the channel is not live, the Vindral instance will try to reconnect until the `reconnectHandler`
842
- * determines that no more retries should be made.
1170
+ * The max video bit rate that will be subscribed to
843
1171
  *
844
- * Note: If the web-sdk is instantiated at the same time as you are starting the stream it is possible
845
- * that this emits false until the started state has propagated through the system.
1172
+ * Note: Returns Number.MAX_SAFE_INTEGER if no limits have been set
846
1173
  */
847
- ["is live"]: boolean;
1174
+ get maxVideoBitRate(): number;
848
1175
  /**
849
- * Emitted when a channel switch has been completed and the first frame of the new channel is rendered.
850
- * A string containing the channel id of the new channel is provided as an argument.
1176
+ * Set max video bit rate that will be subscribed to
1177
+ *
1178
+ * Note: If ABR is disabled, setting this will make the client instantly subscribe to this bitrate
851
1179
  */
852
- ["channel switch"]: Readonly<ChannelSwitchContext>;
1180
+ set maxVideoBitRate(bitRate: number);
853
1181
  /**
854
- * Emitted when a language switch has been completed and the new language starts playing.
1182
+ * The max audio bit rate that will be subscribed to
1183
+ *
1184
+ * Note: Returns Number.MAX_SAFE_INTEGER if no limits have been set
855
1185
  */
856
- ["language switch"]: Readonly<LanguageSwitchContext>;
1186
+ get maxAudioBitRate(): number;
857
1187
  /**
858
- * Emitted when the volume state changes.
1188
+ * Set max audio bit rate that will be subscribed to
859
1189
  *
860
- * This is triggered triggered both when the user changes the volume through the Vindral instance, but also
861
- * from external sources such as OS media shortcuts or other native UI outside of the browser.
1190
+ * Note: If ABR is disabled, setting this will make the client instantly subscribe to this bit rate
862
1191
  */
863
- ["volume state"]: Readonly<VolumeState>;
864
- ["buffer state event"]: Readonly<BufferStateEvent>;
865
- ["initialized media"]: void;
866
- }
867
- declare const defaultOptions: {
868
- sizeBasedResolutionCapEnabled: boolean;
869
- pictureInPictureEnabled: boolean;
870
- abrEnabled: boolean;
871
- burstEnabled: boolean;
872
- mseEnabled: boolean;
873
- mseOpusEnabled: boolean;
874
- muted: boolean;
875
- minBufferTime: number;
876
- maxBufferTime: number;
877
- logLevel: "off" | "error" | "warn" | "info" | "debug" | "trace";
878
- maxSize: Size;
879
- maxVideoBitRate: number;
880
- maxAudioBitRate: number;
881
- tags: string[];
882
- media: Media;
883
- poster: string | boolean;
884
- reconnectHandler: (state: ReconnectState) => Promise<boolean> | boolean;
885
- iosWakeLockEnabled: boolean;
886
- telemetryEnabled: boolean;
887
- iosMediaElementEnabled: boolean;
888
- pauseSupportEnabled: boolean;
889
- advanced: {
890
- wasmDecodingConstraint: Partial<VideoConstraint>;
891
- };
892
- videoCodecs: VideoCodec[];
893
- };
894
- interface AdaptivityStatistics {
1192
+ set maxAudioBitRate(bitRate: number);
895
1193
  /**
896
- * True if adaptive bitrate (ABR) is enabled.
1194
+ * The rendition levels available.
897
1195
  */
898
- isAbrEnabled: boolean;
899
- }
900
- interface BufferTimeStatistics {
1196
+ get renditionLevels(): ReadonlyArray<RenditionLevel>;
901
1197
  /**
902
- * Number of time buffer time has been adjusted. This will only happen when using dynamic buffer time
903
- * (different min/max values of bufferTime).
1198
+ * The current rendition level
904
1199
  */
905
- bufferTimeAdjustmentCount: number;
906
- }
907
- interface RenditionsModuleStatistics {
1200
+ get currentRenditionLevel(): Readonly<RenditionLevel> | undefined;
908
1201
  /**
909
- * Id of current video rendition subscribed to.
1202
+ * The target rendition level that the client is currently switching to
910
1203
  */
911
- videoRenditionId?: number;
1204
+ get targetRenditionLevel(): Readonly<RenditionLevel> | undefined;
912
1205
  /**
913
- * Id of current audio rendition subscribed to.
1206
+ * True if the client is currently switching from one rendition level to another
914
1207
  */
915
- audioRenditionId?: number;
1208
+ get isSwitchingRenditionLevel(): boolean;
916
1209
  /**
917
- * Current video codec being used.
1210
+ * The time ranges buffered for video.
1211
+ * The ranges are specified in milliseconds.
918
1212
  */
919
- videoCodec?: string;
1213
+ get videoBufferedRanges(): ReadonlyArray<TimeRange>;
920
1214
  /**
921
- * Current audio codec being used.
1215
+ * The time ranges buffered for audio.
1216
+ * The ranges are specified in milliseconds.
922
1217
  */
923
- audioCodec?: string;
1218
+ get audioBufferedRanges(): ReadonlyArray<TimeRange>;
924
1219
  /**
925
- * Width of current video rendition (if any).
1220
+ * The API client for calls to the public available endpoints of the Vindral Live CDN.
926
1221
  */
927
- videoWidth?: number;
1222
+ getApiClient(): ApiClient;
1223
+ get lastBufferEvent(): Readonly<BufferStateEvent>;
1224
+ get activeRatios(): Map<string, number>;
1225
+ get bufferingRatios(): Map<string, number>;
1226
+ get timeSpentBuffering(): number;
1227
+ get timeActive(): number;
1228
+ get mediaElement(): HTMLMediaElement | HTMLCanvasElement;
1229
+ get audioNode(): AudioNode | undefined;
1230
+ get drmStatistics(): {
1231
+ keySystem?: string | undefined;
1232
+ licenseServerUrl?: string | undefined;
1233
+ mediaKeySystemConfiguration?: MediaKeySystemConfiguration | undefined;
1234
+ provider?: string | undefined;
1235
+ clearkeys?: Record<string, string>;
1236
+ playreadyLicenseUrl?: string;
1237
+ widevineLicenseUrl?: string;
1238
+ fairplayLicenseUrl?: string;
1239
+ fairplayCertificate?: ArrayBuffer;
1240
+ videoCodec?: string;
1241
+ audioCodec?: string;
1242
+ } | null;
928
1243
  /**
929
- * Height of current video rendition (if any).
1244
+ * Get active Vindral Options
930
1245
  */
931
- videoHeight?: number;
1246
+ getOptions: () => Options;
932
1247
  /**
933
- * Currently expected video bit rate according to metadata in bits/s.
1248
+ * Get url for fetching thumbnail. Note that fetching thumbnails only works for an active channel.
934
1249
  */
935
- expectedVideoBitRate?: number;
1250
+ getThumbnailUrl: () => string;
936
1251
  /**
937
- * Currently expected audio bit rate according to metadata in bits/s.
1252
+ * Update authentication token on an already established and authenticated connection
938
1253
  */
939
- expectedAudioBitRate?: number;
1254
+ updateAuthenticationToken: (token: string) => void;
940
1255
  /**
941
- * Current language. For non-multi language streams, this will often be unset.
1256
+ * @deprecated since 3.0.0 Use play instead.
1257
+ * Connects to the configured channel and starts streaming
942
1258
  */
943
- language?: string;
1259
+ connect: () => void;
1260
+ private _connect;
944
1261
  /**
945
- * Frame rate. Example: `"frameRate": [24000, 1001]`.
1262
+ * Get options that can be used for CastSender
946
1263
  */
947
- frameRate?: [
948
- number,
949
- number
950
- ];
1264
+ getCastOptions: () => Options;
1265
+ private onConnectInfo;
1266
+ private emitLanguagesIfChanged;
1267
+ private updateTextTracks;
1268
+ private cleanupTextTracks;
1269
+ private filterRenditions;
951
1270
  /**
952
- * Total count of rendition level changes (quality downgrades/upgrades).
1271
+ * Patch the subscription with properties from the channel that isn't known until connection
1272
+ * @param channel Channel with the renditions to patch the subscription based on
953
1273
  */
954
- renditionLevelChangeCount: number;
955
- }
956
- interface VideoConstraintCap {
957
- width: number;
958
- height: number;
959
- bitRate: number;
960
- }
961
- interface AudioConstraintCap {
962
- bitRate: number;
963
- }
964
- interface ConstraintCap {
965
- video: VideoConstraintCap;
966
- audio: AudioConstraintCap;
967
- }
968
- interface ConstraintCapStatistics {
969
- constraintCap?: ConstraintCap;
970
- windowInnerWidth: number;
971
- windowInnerHeight: number;
972
- elementWidth: number;
973
- elementHeight: number;
974
- pixelRatio: number;
975
- }
976
- interface DecoderStatistics {
977
- videoDecodeRate: number;
978
- videoDecodeTime: MinMaxAverage;
979
- audioDecodeTime: MinMaxAverage;
980
- videoTransportTime: MinMaxAverage;
981
- }
982
- type ConnectionType = "bluetooth" | "cellular" | "ethernet" | "mixed" | "none" | "other" | "unknown" | "wifi" | "wimax";
983
- type EffectiveConnectionType = "2g" | "3g" | "4g" | "slow-2g";
984
- interface DocumentStateModulesStatistics {
985
- isVisible: boolean;
986
- isOnline: boolean;
987
- isVisibleCount: number;
988
- isHiddenCount: number;
989
- isOnlineCount: number;
990
- isOfflineCount: number;
991
- navigatorRtt?: number;
992
- navigatorEffectiveType?: EffectiveConnectionType;
993
- navigatorConnectionType?: ConnectionType;
994
- navigatorSaveData?: boolean;
995
- navigatorDownlink?: number;
996
- }
997
- interface IncomingDataModuleStatistics {
1274
+ private patchSubscription;
1275
+ private isSupportedVideoCodecProfile;
1276
+ private supportedAudioCodecs;
1277
+ private initializeDecodingModule;
998
1278
  /**
999
- * Current video bitrate in bits/second.
1279
+ * Fully unloads the instance. This disconnects the clients and stops any background tasks.
1280
+ * This client instance can not be used after this has been called.
1000
1281
  */
1001
- videoBitRate?: number;
1282
+ unload: () => Promise<void>;
1002
1283
  /**
1003
- * Current audio bitrate in bits/second.
1284
+ * @deprecated since 3.0.0 Use play instead.
1285
+ *
1286
+ * Activates audio or video on web browsers that require a user gesture to enable media playback.
1287
+ * The Vindral instance will emit a "needs user input" event to indicate when this is needed.
1288
+ * But it is also safe to pre-emptively call this if it is more convenient - such as in cases where
1289
+ * the Vindral instance itself is created in a user input event.
1290
+ *
1291
+ * Requirements: This method needs to be called within an user-input event handler to function properly, such as
1292
+ * an onclick handler.
1293
+ *
1294
+ * Note: Even if you pre-emptively call this it is still recommended to listen to "needs user input"
1295
+ * and handle that event gracefully.
1004
1296
  */
1005
- audioBitRate?: number;
1297
+ userInput: () => void;
1006
1298
  /**
1007
- * Counter of number of bytes received.
1299
+ * Pauses the stream. Call .play() to resume playback again.
1008
1300
  */
1009
- bytesReceived: number;
1010
- }
1011
- interface MseModuleStatistics {
1012
- quotaErrorCount: number;
1013
- mediaSourceOpenTime: number;
1014
- totalVideoFrames?: number;
1015
- droppedVideoFrames?: number;
1016
- successfulVideoAppendCalls?: number;
1017
- successfulAudioAppendsCalls?: number;
1018
- }
1019
- interface QualityOfServiceModuleStatistics {
1301
+ pause: () => void;
1302
+ private registerDebugInstance;
1020
1303
  /**
1021
- * Time in milliseconds spent in buffering state. Note that this value will increase while in background if
1022
- * buffering when leaving foreground.
1304
+ *
1305
+ * Start playing the stream.
1306
+ *
1307
+ * This method also activates audio or video on web browsers that require a user gesture to enable media playback.
1308
+ * The Vindral instance will emit a "needs user input" event to indicate when this is needed.
1309
+ * But it is also safe to pre-emptively call this if it is more convenient - such as in cases where
1310
+ * the Vindral instance itself is created in a user input event.
1311
+ *
1312
+ * Note: In most browsers this method needs to be called within an user-input event handler, such as
1313
+ * an onclick handler in order to activate audio. Most implementations call this directly after constructing the Vindral
1314
+ * instance once in order to start playing, and then listen to a user-event in order to allow audio to be activated.
1315
+ *
1316
+ * Note 2: Even if you pre-emptively call this it is still recommended to listen to "needs user input"
1317
+ * and handle that event gracefully.
1023
1318
  */
1024
- timeSpentBuffering: number;
1319
+ play: () => void;
1025
1320
  /**
1026
- * Total number of buffering events since instantiation.
1321
+ * How long in milliseconds since the instance was created
1027
1322
  */
1028
- bufferingEventsCount: number;
1323
+ get uptime(): number;
1029
1324
  /**
1030
- * Number of fatal quality of service events.
1325
+ * This method collects a statistics report from internal modules. While many of the report's properties are documented, the report may also contain undocumented
1326
+ * properties used internally or temporarily for monitoring and improving the performance of the service.
1327
+ *
1328
+ * Use undocumented properties at your own risk.
1031
1329
  */
1032
- fatalQosCount: number;
1330
+ getStatistics: () => Statistics;
1331
+ private resetModules;
1332
+ private suspend;
1333
+ private unsuspend;
1334
+ private getRuntimeInfo;
1335
+ private onMediaElementState;
1336
+ private onBufferEvent;
1033
1337
  /**
1034
- * Ratio of time being spent on different bitrates.
1035
- * Example: `"timeSpentRatio": { "1160000": 0.2, "2260000": 0.8 }` shows 20% spent on 1.16 Mbps, 80% spent on 2.26 Mbps.
1338
+ * Aligns size and bitrate to match a rendition level correctly
1036
1339
  */
1037
- timeSpentRatio: {
1038
- [bitRate: string]: number;
1039
- };
1040
- }
1041
- interface SyncModuleStatistics {
1042
- drift: number | undefined;
1043
- driftAdjustmentCount: number;
1044
- timeshiftDriftAdjustmentCount: number;
1045
- seekTime: number;
1340
+ private alignSizeAndBitRate;
1341
+ private get currentSubscription();
1342
+ private get targetSubscription();
1343
+ private timeToFirstFrame;
1344
+ private willUseMediaSource;
1046
1345
  }
1047
1346
  interface TelemetryModuleStatistics {
1048
1347
  /**
@@ -1053,515 +1352,353 @@ interface TelemetryModuleStatistics {
1053
1352
  */
1054
1353
  errorCount: number;
1055
1354
  }
1056
- interface VideoPlayerStatistics {
1057
- renderedFrameCount: number;
1058
- rendererDroppedFrameCount: number;
1059
- contextLostCount: number;
1060
- contextRestoredCount: number;
1061
- }
1062
- declare class UserAgentInformation {
1063
- private highEntropyValues?;
1064
- constructor();
1065
- getUserAgentInformation(): {
1066
- locationOrigin: string;
1067
- locationPath: string;
1068
- ancestorOrigins: string[] | undefined;
1069
- hardwareConcurrency: number;
1070
- deviceMemory: number | undefined;
1071
- userAgentLegacy: string;
1072
- ua: {
1073
- browser: {
1074
- brands: string[];
1075
- fullVersionBrands: string[];
1076
- majorVersions: string[];
1077
- };
1078
- device: string;
1079
- os: {
1080
- family: string;
1081
- version: string;
1082
- major_version: number;
1083
- };
1084
- };
1085
- } | {
1086
- locationOrigin: string;
1087
- locationPath: string;
1088
- ancestorOrigins: string[] | undefined;
1089
- hardwareConcurrency: number;
1090
- deviceMemory: number | undefined;
1091
- userAgent: string;
1092
- };
1093
- }
1094
- type ModuleStatistics = AdaptivityStatistics & BufferTimeStatistics & ConnectionStatistics & ConstraintCapStatistics & DecoderStatistics & DocumentStateModulesStatistics & IncomingDataModuleStatistics & MseModuleStatistics & PlaybackModuleStatistics & QualityOfServiceModuleStatistics & RenditionsModuleStatistics & SyncModuleStatistics & TelemetryModuleStatistics & VideoPlayerStatistics;
1095
1355
  /**
1096
- * Contains internal statistics.
1097
- *
1098
- * Note that this object will have some undocumented properties, used internally or temporarily,
1099
- * for monitoring and improving the performance of the service.
1100
- *
1101
- * @interface
1356
+ * Represents a connection state.
1102
1357
  */
1103
- export type Statistics = ModuleStatistics & ReturnType<UserAgentInformation["getUserAgentInformation"]> & {
1104
- /**
1105
- * Version of the @vindral/web-sdk being used.
1106
- */
1107
- version: string;
1108
- /**
1109
- * IP of the client.
1110
- */
1111
- ip?: string;
1112
- /**
1113
- * URL being used for connecting to the stream.
1114
- */
1115
- url: string;
1116
- /**
1117
- * A session is bound to a connection. If the client reconnects for any reason (e.g. coming back from inactivity
1118
- * or a problem with network on client side), a new sessionId will be used.
1119
- *
1358
+ export type ConnectionState = "connected" | "disconnected" | "connecting";
1359
+ /**
1360
+ * Represents state of a context switch. The state change starts when connection starts receiving a new
1361
+ * channel or quality and is completed when the new quality/channel has received its init segments and key frames.
1362
+ */
1363
+ export type ContextSwitchState = "completed" | "started";
1364
+ interface ConnectionStatistics {
1365
+ /**
1366
+ * RTT (round trip time) between client and server(s).
1120
1367
  */
1121
- sessionId?: string;
1368
+ rtt: MinMaxAverage;
1122
1369
  /**
1123
- * Unlike `sessionId`, `clientId` will remain the same even after reconnections and represents this unique Vindral instance.
1370
+ * A very rough initial estimation of minimum available bandwidth.
1124
1371
  */
1125
- clientId: string;
1372
+ estimatedBandwidth: number;
1373
+ edgeUrl?: string;
1126
1374
  /**
1127
- * How long in milliseconds since the instance was created.
1375
+ * Total number of connections that have been established since instantiation.
1128
1376
  */
1129
- uptime: number;
1377
+ connectCount: number;
1130
1378
  /**
1131
- * Current channel ID being subscribed to.
1379
+ * Total number of connection attempts since instantiation.
1132
1380
  */
1133
- channelId: string;
1381
+ connectionAttemptCount: number;
1382
+ connectionProtocol: "vindral_ws" | "moq" | undefined;
1383
+ }
1384
+ /**
1385
+ * Contextual information about the language switch
1386
+ */
1387
+ export interface LanguageSwitchContext {
1134
1388
  /**
1135
- * Channel group being subscribed to.
1389
+ * The new language that was switched to
1136
1390
  */
1137
- channelGroupId?: string;
1391
+ language: string;
1392
+ }
1393
+ /**
1394
+ * Contextual information about the channel switch
1395
+ */
1396
+ export interface ChannelSwitchContext {
1138
1397
  /**
1139
- * Time in milliseconds from instantiation to playback of video and audio being started.
1140
- * Note that an actual frame render often happens much quicker, but that is not counted as TTFF.
1398
+ * The new channel id that was switched to
1141
1399
  */
1142
- timeToFirstFrame?: number;
1143
- iosMediaElementEnabled?: boolean;
1144
- };
1400
+ channelId: string;
1401
+ }
1145
1402
  /**
1146
- * Represents a Vindral client instance
1147
- *
1148
- * The most most essential methods when using the Vindral class are:
1149
- *
1150
- * - connect() - this has to be called to actually start connecting
1151
- * - attach() - to attach the Vindral video view to the DOM so that users can see it
1152
- * - userInput() - to activate audio on browsers that require a user gesture to play audio
1153
- * - unload() - unloads the instance, its very important that this is called when cleaning up the Vindral instance, otherwise background timers may leak.
1154
- *
1155
- * The Vindral instance will emit a variety of events during its lifetime. Use .on("event-name", callback) to listen to these events.
1156
- * See [[PublicVindralEvents]] for the events types that can be emitted.
1157
- *
1158
- * ```typescript
1159
- * // minimal configuration of a Vindral client instance
1160
- * const instance = new Vindral({
1161
- * url: "https://lb.cdn.vindral.com",
1162
- * channelId: "vindral_demo1_ci_099ee1fa-80f3-455e-aa23-3d184e93e04f",
1163
- * })
1164
- *
1165
- * // Will be called when timed metadata is received
1166
- * instance.on("metadata", console.log)
1167
- *
1168
- * // Will be called when a user interaction is needed to activate audio
1169
- * instance.on("needs user input", console.log)
1170
- *
1171
- * // Start connecting to the cdn
1172
- * instance.connect()
1173
- *
1174
- * // Attach the video view to the DOM
1175
- * instance.attach(document.getElementById("root"))
1176
- *
1177
- * // When done with the instance
1178
- * instance.unload()
1179
- * ```
1403
+ * Volume state changes
1180
1404
  */
1181
- export declare class Vindral extends Emitter<PublicVindralEvents> {
1182
- #private;
1183
- private static MAX_POOL_SIZE;
1184
- private static INITIAL_MAX_BIT_RATE;
1185
- private static PING_TIMEOUT;
1186
- private static DISCONNECT_TIMEOUT;
1187
- private static REMOVE_CUE_THRESHOLD;
1405
+ export interface VolumeState {
1188
1406
  /**
1189
- * Picture in picture
1407
+ * Wether the audio is muted
1190
1408
  */
1191
- readonly pictureInPicture: {
1192
- /**
1193
- * Enters picture in picture
1194
- * @returns a promise that resolves if successful
1195
- */
1196
- enter: () => Promise<void>;
1197
- /**
1198
- * Exits picture in picture
1199
- * @returns a promise that resolves if successful
1200
- */
1201
- exit: () => Promise<void>;
1202
- /**
1203
- * returns whether picture in picture is currently active
1204
- */
1205
- isActive: () => boolean;
1206
- /**
1207
- * returns whether picture in picture is supported
1208
- */
1209
- isSupported: () => boolean;
1210
- };
1211
- private browser;
1212
- private options;
1213
- private element;
1214
- private playbackSource;
1215
- private emitter;
1216
- private logger;
1217
- private modules;
1218
- private clientIp?;
1219
- private sessionId?;
1220
- private clientId;
1221
- private _channels;
1222
- private createdAt;
1223
- private hasCalledConnect;
1224
- private apiClient;
1225
- private latestEmittedLanguages;
1226
- private wakeLock;
1227
- private cachedEdges;
1228
- private shiftedEdges;
1229
- private pool;
1230
- private userAgentInformation;
1231
- private sampleProcessingSesssions;
1232
- private sizes;
1233
- private isSuspended;
1234
- private disconnectTimeout;
1235
- constructor(options: Options);
1409
+ isMuted: boolean;
1236
1410
  /**
1237
- * Attaches the video view to a DOM element. The Vindral video view will be sized to fill this element while
1238
- * maintaining the correct aspect ratio.
1239
- * @param container the container element to append the video view to. Often a div element.
1240
- * @returns
1411
+ * The volume level
1241
1412
  */
1242
- attach: (container: HTMLElement) => void;
1413
+ volume: number;
1414
+ }
1415
+ /**
1416
+ * The events that can be emitted from the Vindral instance
1417
+ */
1418
+ export interface PublicVindralEvents {
1243
1419
  /**
1244
- * Set the current volume.
1245
- * Setting this to 0 is not equivalent to muting the audio.
1246
- * Setting this to >0 is not equivalent to unmuting the audio.
1420
+ * When an error that requires action has occured
1247
1421
  *
1248
- * Note that setting volume is not allowed on iPadOS and iOS devices.
1249
- * This is an OS/browser limitation on the video element.
1422
+ * Can be a fatal error that will unload the Vindral instance - this is indicated by `isFatal()` on the error object returning true.
1250
1423
  *
1251
- * [Read more about it on Apple docs](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html)
1252
- * for iOS-Specific Considerations. The following section is the important part:
1253
- * On iOS devices, the audio level is always under the user's physical control. The volume property is not settable in JavaScript. Reading the volume property always returns 1.
1254
- */
1255
- set volume(volume: number);
1256
- /**
1257
- * The current volume. Note that if the playback is muted volume can still be set.
1424
+ * In case of a fatal error it is appropriate to indicate what the error was to the user, either by displaying the error.message or
1425
+ * by using the error.code() as a key to look up a localization string. To resume streaming it is required to create a new Vindral instance.
1258
1426
  */
1259
- get volume(): number;
1427
+ ["error"]: Readonly<VindralError>;
1260
1428
  /**
1261
- * Set playback to muted/unmuted
1429
+ * When the instance needs user input to activate audio or sometimes video playback.
1430
+ * Is called with an object
1431
+ * ```javascript
1432
+ * {
1433
+ * forAudio: boolean // true if user input is needed for audio playback
1434
+ * forVideo: boolean // true if user input is needed for video playback
1435
+ * }
1436
+ * ```
1262
1437
  */
1263
- set muted(muted: boolean);
1438
+ ["needs user input"]: NeedsUserInputContext;
1264
1439
  /**
1265
- * Whether the playback is muted or not
1440
+ * When a timed metadata event has been triggered
1266
1441
  */
1267
- get muted(): boolean;
1442
+ ["metadata"]: Readonly<Metadata>;
1268
1443
  /**
1269
- * Media (audio | video | audio+video)
1444
+ * When the playback state changes
1270
1445
  */
1271
- get media(): Media;
1446
+ ["playback state"]: Readonly<PlaybackState>;
1272
1447
  /**
1273
- * The current average video bit rate in bits/s
1448
+ * When the connection state changes
1274
1449
  */
1275
- get videoBitRate(): number;
1450
+ ["connection state"]: Readonly<ConnectionState>;
1276
1451
  /**
1277
- * The current average audio bit rate in bits/s
1452
+ * When the available rendition levels is changed
1278
1453
  */
1279
- get audioBitRate(): number;
1454
+ ["rendition levels"]: ReadonlyArray<RenditionLevel>;
1280
1455
  /**
1281
- * The current connection state
1456
+ * When the rendition level is changed
1282
1457
  */
1283
- get connectionState(): Readonly<State>;
1458
+ ["rendition level"]: Readonly<RenditionLevel>;
1284
1459
  /**
1285
- * The current playback state
1460
+ * When the available languages is changed
1286
1461
  */
1287
- get playbackState(): Readonly<PlaybackState>;
1462
+ ["languages"]: ReadonlyArray<string>;
1288
1463
  /**
1289
- * The current buffer fullness as a floating point value between 0-1, where 1 is full and 0 i empty.
1464
+ * When the available text tracks are changed
1290
1465
  */
1291
- get bufferFullness(): number;
1466
+ ["text tracks"]: ReadonlyArray<string>;
1292
1467
  /**
1293
- * Whether user bandwidth savings by capping the video resolution to the size of the video element is enabled
1468
+ * When the available channels is changed
1294
1469
  */
1295
- get sizeBasedResolutionCapEnabled(): boolean;
1470
+ ["channels"]: ReadonlyArray<Channel>;
1296
1471
  /**
1297
- * Enables or disables user bandwidth savings by capping the video resolution to the size of the video element.
1472
+ * When a context switch state change has occured.
1473
+ * E.g. when a channel change has been requested, or quality is changed.
1298
1474
  */
1299
- set sizeBasedResolutionCapEnabled(enabled: boolean);
1475
+ ["context switch"]: Readonly<ContextSwitchState>;
1300
1476
  /**
1301
- * Whether ABR is currently enabled
1477
+ * Emitted when a wallclock time message has been received from the server.
1478
+ *
1479
+ * Note: This is the edge server wallclock time and thus may differ slightly
1480
+ * between two viewers if they are connected to different edge servers.
1302
1481
  */
1303
- get abrEnabled(): boolean;
1482
+ ["server wallclock time"]: Readonly<number>;
1304
1483
  /**
1305
- * Enable or disable ABR
1484
+ * Is emitted during connection whether the channel is live or not.
1306
1485
  *
1307
- * The client will immediatly stop changing renditon level based on QoS metrics
1486
+ * If the channel is not live, the Vindral instance will try to reconnect until the `reconnectHandler`
1487
+ * determines that no more retries should be made.
1308
1488
  *
1309
- * Note: It is strongly recommended to keep this enabled as it can severly increase
1310
- * the number of buffering events for viewers.
1489
+ * Note: If the web-sdk is instantiated at the same time as you are starting the stream it is possible
1490
+ * that this emits false until the started state has propagated through the system.
1311
1491
  */
1312
- set abrEnabled(enabled: boolean);
1492
+ ["is live"]: boolean;
1313
1493
  /**
1314
- * Estimated live edge time for the current channel
1494
+ * Emitted when a channel switch has been completed and the first frame of the new channel is rendered.
1495
+ * A string containing the channel id of the new channel is provided as an argument.
1315
1496
  */
1316
- get serverEdgeTime(): number | undefined;
1497
+ ["channel switch"]: Readonly<ChannelSwitchContext>;
1317
1498
  /**
1318
- * @returns Estimated wallclock time on the edge server in milliseconds
1499
+ * Emmitted when a channel switch fails.
1500
+ * A string containing the channel id of the current channel is provided as an argument.
1319
1501
  */
1320
- get serverWallclockTime(): number | undefined;
1502
+ ["channel switch failed"]: Readonly<ChannelSwitchContext>;
1321
1503
  /**
1322
- * Local current time normalized between all channels in the channel group
1504
+ * Emitted when a language switch has been completed and the new language starts playing.
1323
1505
  */
1324
- get currentTime(): number;
1506
+ ["language switch"]: Readonly<LanguageSwitchContext>;
1325
1507
  /**
1326
- * Current time for the channel. This is the actual stream time, passed on from your ingress.
1327
- * Integer overflow could make this value differ from your encoder timestamps if it has been rolling for more
1328
- * than 42 days with RTMP as target.
1508
+ * Emitted when the volume state changes.
1329
1509
  *
1330
- * Note: This is not normalized between channels, thus it can make jumps when switching channels
1331
- */
1332
- get channelCurrentTime(): number;
1333
- /**
1334
- * The current target buffer time in milliseconds
1335
- */
1336
- get targetBufferTime(): number;
1337
- /**
1338
- * Set the current target buffer time in milliseconds
1339
- */
1340
- set targetBufferTime(bufferTimeMs: number);
1341
- /**
1342
- * The estimated playback latency based on target buffer time, the connection rtt and local playback drift
1343
- */
1344
- get playbackLatency(): number | undefined;
1345
- /**
1346
- * The estimated utc timestamp (in ms) for the playhead.
1510
+ * This is triggered triggered both when the user changes the volume through the Vindral instance, but also
1511
+ * from external sources such as OS media shortcuts or other native UI outside of the browser.
1347
1512
  */
1348
- get playbackWallclockTime(): number | undefined;
1513
+ ["volume state"]: Readonly<VolumeState>;
1514
+ ["buffer state event"]: Readonly<BufferStateEvent>;
1515
+ ["initialized media"]: void;
1516
+ }
1517
+ /**
1518
+ * Available events to listen to
1519
+ */
1520
+ export interface CastSenderEvents {
1349
1521
  /**
1350
- * Channels that can be switched between
1522
+ * When a connection has been established with a CastReceiver
1351
1523
  */
1352
- get channels(): ReadonlyArray<Channel>;
1524
+ ["connected"]: void;
1353
1525
  /**
1354
- * Languages available
1526
+ * When a previous session has been resumed
1355
1527
  */
1356
- get languages(): ReadonlyArray<string>;
1528
+ ["resumed"]: void;
1357
1529
  /**
1358
- * The current language
1530
+ * When a CastReceiver has lost or stopped a connection
1359
1531
  */
1360
- get language(): string | undefined;
1532
+ ["disconnected"]: void;
1361
1533
  /**
1362
- * Set the current language
1534
+ * When a connection attempt was initiated unsuccessfully
1363
1535
  */
1364
- set language(language: string | undefined);
1536
+ ["failed"]: void;
1365
1537
  /**
1366
- * Set the active text track
1538
+ * When the remote connection emits a metadata event
1367
1539
  */
1368
- set textTrack(label: string | undefined);
1540
+ ["metadata"]: Metadata;
1369
1541
  /**
1370
- * Get the available text tracks
1542
+ * When the remote connection receives a server wallclock time event
1371
1543
  */
1372
- get textTracks(): string[];
1544
+ ["server wallclock time"]: number;
1545
+ }
1546
+ /**
1547
+ * Used for initializing the CastSender
1548
+ */
1549
+ export interface CastConfig {
1373
1550
  /**
1374
- * Get the active text track
1551
+ * The Vindral Options to use for the Cast Receiver
1375
1552
  */
1376
- get textTrack(): string | undefined;
1553
+ options: Options;
1377
1554
  /**
1378
- * The current channelId
1555
+ * URL to a background image.
1556
+ * Example: "https://via.placeholder.com/256x144"
1379
1557
  */
1380
- get channelId(): string;
1558
+ background?: string;
1381
1559
  /**
1382
- * Set the current channelId
1383
- *
1384
- * Possible channels to set are available from [[channels]]
1385
- *
1386
- * Note that the following scenarios are not possible right now:
1387
- * - switching channel from a channel with audio to a channel without audio (unless audio only mode is active)
1388
- * - switching channel from a channel with video to a channel without video (unless video only mode is active)
1560
+ * Override this if you have your own custom receiver
1389
1561
  */
1390
- set channelId(channelId: string);
1562
+ receiverApplicationId?: string;
1563
+ }
1564
+ /**
1565
+ * CastSender handles initiation of and communication with the Google Cast Receiver
1566
+ */
1567
+ export declare class CastSender extends Emitter<CastSenderEvents> {
1568
+ private state;
1569
+ private config;
1570
+ private unloaded;
1571
+ constructor(config: CastConfig);
1391
1572
  /**
1392
- * Max size that will be subcribed to
1573
+ * True if the instance is casting right now
1393
1574
  */
1394
- get maxSize(): Size;
1575
+ get casting(): boolean;
1395
1576
  /**
1396
- * Set max size that will be subscribed to
1397
- *
1398
- * Note: If ABR is disabled, setting this will make the client instantly subscribe to this size
1577
+ * The current volume
1399
1578
  */
1400
- set maxSize(size: Size);
1579
+ get volume(): number;
1401
1580
  /**
1402
- * The max video bit rate that will be subscribed to
1403
- *
1404
- * Note: Returns Number.MAX_SAFE_INTEGER if no limits have been set
1581
+ * Set the current volume. Setting this to zero is equivalent to muting the video
1405
1582
  */
1406
- get maxVideoBitRate(): number;
1583
+ set volume(volume: number);
1407
1584
  /**
1408
- * Set max video bit rate that will be subscribed to
1409
- *
1410
- * Note: If ABR is disabled, setting this will make the client instantly subscribe to this bitrate
1585
+ * The current language
1411
1586
  */
1412
- set maxVideoBitRate(bitRate: number);
1587
+ get language(): string | undefined;
1413
1588
  /**
1414
- * The max audio bit rate that will be subscribed to
1415
- *
1416
- * Note: Returns Number.MAX_SAFE_INTEGER if no limits have been set
1589
+ * Set the current language
1417
1590
  */
1418
- get maxAudioBitRate(): number;
1591
+ set language(language: string | undefined);
1419
1592
  /**
1420
- * Set max audio bit rate that will be subscribed to
1421
- *
1422
- * Note: If ABR is disabled, setting this will make the client instantly subscribe to this bit rate
1593
+ * The current channelId
1423
1594
  */
1424
- set maxAudioBitRate(bitRate: number);
1595
+ get channelId(): string;
1425
1596
  /**
1426
- * The rendition levels available.
1597
+ * Set the current channelId
1427
1598
  */
1428
- get renditionLevels(): ReadonlyArray<RenditionLevel>;
1599
+ set channelId(channelId: string);
1429
1600
  /**
1430
- * The current rendition level
1601
+ * Update authentication token on an already established and authenticated connection
1431
1602
  */
1432
- get currentRenditionLevel(): Readonly<RenditionLevel> | undefined;
1603
+ updateAuthenticationToken: (token: string) => void;
1433
1604
  /**
1434
- * The target rendition level that the client is currently switching to
1605
+ * Fully unloads the instance. This disconnects the current listener but lets the
1606
+ * cast session continue on the receiving device
1435
1607
  */
1436
- get targetRenditionLevel(): Readonly<RenditionLevel> | undefined;
1608
+ unload: () => void;
1437
1609
  /**
1438
- * True if the client is currently switching from one rendition level to another
1610
+ * Initiates the CastSender.
1611
+ * Will reject if Cast is not available on the device or the network.
1439
1612
  */
1440
- get isSwitchingRenditionLevel(): boolean;
1613
+ init: () => Promise<void>;
1441
1614
  /**
1442
- * The time ranges buffered for video.
1443
- * The ranges are specified in milliseconds.
1615
+ * Requests a session. It will open the native cast receiver chooser dialog
1444
1616
  */
1445
- get videoBufferedRanges(): ReadonlyArray<TimeRange>;
1617
+ start: () => Promise<void>;
1446
1618
  /**
1447
- * The time ranges buffered for audio.
1448
- * The ranges are specified in milliseconds.
1619
+ * Stops a session. It will stop playback on device as well.
1449
1620
  */
1450
- get audioBufferedRanges(): ReadonlyArray<TimeRange>;
1621
+ stop: () => void;
1451
1622
  /**
1452
- * The API client for calls to the public available endpoints of the Vindral Live CDN.
1623
+ * Returns a string representing the name of the Cast receiver device or undefined if no receiver exists
1453
1624
  */
1454
- getApiClient(): ApiClient;
1455
- get lastBufferEvent(): Readonly<BufferStateEvent>;
1456
- get activeRatios(): Map<string, number>;
1457
- get bufferingRatios(): Map<string, number>;
1458
- get timeSpentBuffering(): number;
1459
- get timeActive(): number;
1460
- get mediaElement(): HTMLMediaElement | HTMLCanvasElement;
1625
+ getReceiverName: () => string | undefined;
1626
+ private onGCastApiAvailable;
1627
+ private send;
1628
+ private onMessage;
1629
+ private onSessionStarted;
1630
+ private onSessionStateChanged;
1631
+ private getInstance;
1632
+ private getSession;
1633
+ private castLibrariesAdded;
1634
+ private verifyCastLibraries;
1635
+ }
1636
+ interface AirPlaySenderEvents {
1461
1637
  /**
1462
- * Get active Vindral Options
1638
+ * When airplay targets are available.
1463
1639
  */
1464
- getOptions: () => Options & typeof defaultOptions;
1640
+ ["available"]: void;
1465
1641
  /**
1466
- * Get url for fetching thumbnail. Note that fetching thumbnails only works for an active channel.
1642
+ * When a connection has been established with an airplay target.
1467
1643
  */
1468
- getThumbnailUrl: () => string;
1644
+ ["connected"]: void;
1469
1645
  /**
1470
- * Update authentication token on an already established and authenticated connection
1646
+ * When the airplay target has lost or stopped a connection.
1471
1647
  */
1472
- updateAuthenticationToken: (token: string) => void;
1648
+ ["disconnected"]: void;
1649
+ }
1650
+ interface AirPlayConfig {
1473
1651
  /**
1474
- * @deprecated since 3.0.0 Use play instead.
1475
- * Connects to the configured channel and starts streaming
1652
+ * URL to use when connecting to the stream.
1476
1653
  */
1477
- connect: () => void;
1478
- private _connect;
1654
+ url: string;
1479
1655
  /**
1480
- * Get options that can be used for CastSender
1656
+ * Channel ID to connect to.
1481
1657
  */
1482
- getCastOptions: () => Options;
1483
- private connectionInfo;
1484
- private estimateRTT;
1485
- private connectHandler;
1486
- private emitLanguagesIfChanged;
1487
- private updateTextTracks;
1488
- private cleanupTextTracks;
1489
- private filterRenditions;
1658
+ channelId: string;
1490
1659
  /**
1491
- * Patch the subscription with properties from the channel that isn't known until connection
1492
- * @param channel Channel with the renditions to patch the subscription based on
1660
+ * A container to attach the video element in. This should be the same container that the vindral video element is attached to.
1493
1661
  */
1494
- private patchSubscription;
1495
- private isSupportedVideoCodecProfile;
1496
- private supportedAudioCodecs;
1497
- private initializeDecodingModule;
1662
+ container: HTMLElement;
1498
1663
  /**
1499
- * Fully unloads the instance. This disconnects the clients and stops any background tasks.
1500
- * This client instance can not be used after this has been called.
1664
+ * An authentication token to provide to the server when connecting - only needed for channels with authentication enabled
1665
+ * Note: If not supplied when needed, an "Authentication Failed" error will be raised.
1501
1666
  */
1502
- unload: () => Promise<void>;
1667
+ authenticationToken?: string;
1668
+ }
1669
+ declare class AirPlaySender extends Emitter<AirPlaySenderEvents> {
1670
+ private config;
1671
+ private hlsUrl;
1672
+ private element;
1673
+ private connectingTimeout?;
1674
+ constructor(config: AirPlayConfig);
1503
1675
  /**
1504
- * @deprecated since 3.0.0 Use play instead.
1505
- *
1506
- * Activates audio or video on web browsers that require a user gesture to enable media playback.
1507
- * The Vindral instance will emit a "needs user input" event to indicate when this is needed.
1508
- * But it is also safe to pre-emptively call this if it is more convenient - such as in cases where
1509
- * the Vindral instance itself is created in a user input event.
1510
- *
1511
- * Requirements: This method needs to be called within an user-input event handler to function properly, such as
1512
- * an onclick handler.
1513
- *
1514
- * Note: Even if you pre-emptively call this it is still recommended to listen to "needs user input"
1515
- * and handle that event gracefully.
1676
+ * True if the instance is casting right now.
1516
1677
  */
1517
- userInput: () => void;
1678
+ get casting(): boolean;
1518
1679
  /**
1519
- * Pauses the stream. Call .play() to resume playback again.
1680
+ * Set the current channelId.
1520
1681
  */
1521
- pause: () => void;
1522
- private registerDebugInstance;
1682
+ set channelId(channelId: string);
1523
1683
  /**
1524
- *
1525
- * Start playing the stream.
1526
- *
1527
- * This method also activates audio or video on web browsers that require a user gesture to enable media playback.
1528
- * The Vindral instance will emit a "needs user input" event to indicate when this is needed.
1529
- * But it is also safe to pre-emptively call this if it is more convenient - such as in cases where
1530
- * the Vindral instance itself is created in a user input event.
1531
- *
1532
- * Note: In most browsers this method needs to be called within an user-input event handler, such as
1533
- * an onclick handler in order to activate audio. Most implementations call this directly after constructing the Vindral
1534
- * instance once in order to start playing, and then listen to a user-event in order to allow audio to be activated.
1535
- *
1536
- * Note 2: Even if you pre-emptively call this it is still recommended to listen to "needs user input"
1537
- * and handle that event gracefully.
1684
+ * Update authentication token on an already established and authenticated connection.
1538
1685
  */
1539
- play: () => void;
1686
+ updateAuthenticationToken: (_token: string) => void;
1540
1687
  /**
1541
- * How long in milliseconds since the instance was created
1688
+ * Fully unloads the instance. This disconnects the current listeners.
1542
1689
  */
1543
- get uptime(): number;
1690
+ unload: () => void;
1544
1691
  /**
1545
- * This method collects a statistics report from internal modules. While many of the report's properties are documented, the report may also contain undocumented
1546
- * properties used internally or temporarily for monitoring and improving the performance of the service.
1547
- *
1548
- * Use undocumented properties at your own risk.
1692
+ * Show the AirPlay picker.
1549
1693
  */
1550
- getStatistics: () => Statistics;
1551
- private resetModules;
1552
- private suspend;
1553
- private unsuspend;
1554
- private getRuntimeInfo;
1555
- private onMediaElementState;
1556
- private onBufferEvent;
1694
+ showPlaybackTargetPicker(): void;
1557
1695
  /**
1558
- * Aligns size and bitrate to match a rendition level correctly
1696
+ * Returns if AirPlay is supported.
1559
1697
  */
1560
- private alignSizeAndBitRate;
1561
- private get currentSubscription();
1562
- private get targetSubscription();
1563
- private timeToFirstFrame;
1564
- private willUseMediaSource;
1698
+ static isAirPlaySupported(): boolean;
1699
+ private onAirPlayAvailable;
1700
+ private onAirPlayPlaybackChanged;
1701
+ private checkHlsUrl;
1565
1702
  }
1566
1703
  /**
1567
1704
  * Available options when initializing the Player. Used for enabling/disabling features