@vindral/web-sdk 3.4.3 → 4.0.0-100-g47797f66

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