@vindral/web-sdk 3.4.3 → 4.0.0-190-g016e452d

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