@vindral/web-sdk 2.0.9 → 2.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -60,10 +60,10 @@ This example attaches a player to an element with the id `#root`. The player wil
60
60
 
61
61
  The example assumes that there is a html page that loads this script that has at least a div with `id="#root"`.
62
62
 
63
- ```typescript
63
+ ```javascript
64
64
  import { Player } from "@vindral/web-sdk"
65
65
 
66
- const root = document.querySelector<HTMLElement>("#root")
66
+ const root = document.querySelector("#root")
67
67
 
68
68
  const player = new Player({
69
69
  url: "https://lb.cdn.vindral.com",
@@ -85,12 +85,12 @@ The Core SDK is the lowest level method to integrate that provides only a video
85
85
 
86
86
  The example assumes that there is a html page that loads this script that has at least a div with `id="#root"`, `id="#playback-state"` and a button with `id="#activate-audio-button"`.
87
87
 
88
- ```typescript
88
+ ```javascript
89
89
  import { Vindral } from "@vindral/web-sdk"
90
90
 
91
- const root = document.querySelector<HTMLElement>("#root")!
92
- const button = document.querySelector<HTMLElement>("#activate-audio-button")!
93
- const playbackState = document.querySelector<HTMLElement>("#playback-state")!
91
+ const root = document.querySelector("#root")!
92
+ const button = document.querySelector("#activate-audio-button")!
93
+ const playbackState = document.querySelector("#playback-state")!
94
94
 
95
95
  button.style.display = "none"
96
96
 
package/index.d.ts CHANGED
@@ -173,6 +173,64 @@ declare class LoggerInstance implements Logger {
173
173
  error: (message: string, meta?: Meta | undefined) => void;
174
174
  critical: (message: string, meta?: Meta | undefined) => void;
175
175
  }
176
+ export declare type PlayInitiator = "user input" | "programatically";
177
+ export interface PlaybackSource {
178
+ volume: number;
179
+ muted: boolean;
180
+ currentTime: number;
181
+ playbackRate?: number;
182
+ isActivated: boolean;
183
+ readonly seekTime: number;
184
+ readonly isSeeking: boolean;
185
+ play(initiator: PlayInitiator): Promise<void>;
186
+ }
187
+ interface MediaElementOptions {
188
+ autoplay: boolean;
189
+ muted: boolean;
190
+ type: "audio" | "video";
191
+ logger: Logger;
192
+ }
193
+ interface NeedsUserInputContext {
194
+ forAudio: boolean;
195
+ forVideo: boolean;
196
+ }
197
+ interface MediaElementEvents {
198
+ ["needs user input"]: NeedsUserInputContext;
199
+ ["buffer state"]: Readonly<BufferState>;
200
+ }
201
+ declare class MediaElement extends Emitter<MediaElementEvents> {
202
+ readonly element: HTMLMediaElement;
203
+ private logger;
204
+ private seekTimes;
205
+ private seekStartTime?;
206
+ private _userProvidedMuted;
207
+ private _userHasProvidedInput;
208
+ isActivated: boolean;
209
+ constructor({ type, autoplay, muted, logger }: MediaElementOptions);
210
+ attach: (container: HTMLElement) => void;
211
+ get seekTime(): number;
212
+ get isSeeking(): boolean;
213
+ get currentTime(): number;
214
+ set currentTime(value: number);
215
+ get playbackRate(): number;
216
+ set playbackRate(rate: number);
217
+ get volume(): number;
218
+ set volume(volume: number);
219
+ get muted(): boolean;
220
+ set muted(muted: boolean);
221
+ get userHasProvidedInput(): boolean;
222
+ get paused(): boolean;
223
+ getPlaybackRate: () => number;
224
+ getPlaybackState: () => PlaybackState;
225
+ setPlaybackRate: (rate: number) => void;
226
+ getBuffer: () => TimeRange[];
227
+ play: (initiator: PlayInitiator) => Promise<void>;
228
+ private _play;
229
+ private onEvent;
230
+ private onBufferStateChange;
231
+ private onSeekStart;
232
+ private onSeekEnd;
233
+ }
176
234
  declare type PlaybackState = "buffering" | "playing";
177
235
  declare type BufferStateEvent = "filled" | "drained";
178
236
  declare type BufferState = {
@@ -182,6 +240,7 @@ declare type BufferState = {
182
240
  };
183
241
  interface PlaybackModuleListeners {
184
242
  ["buffer state"]: Readonly<BufferState>;
243
+ ["needs user input"]: NeedsUserInputContext;
185
244
  }
186
245
  interface PlaybackModuleEvents {
187
246
  ["buffer state event"]: Readonly<BufferStateEvent>;
@@ -193,6 +252,8 @@ interface ClockSource {
193
252
  }
194
253
  interface PlaybackModuleStatistics {
195
254
  bufferTime: number;
255
+ needsInputForAudioCount: number;
256
+ needsInputForVideoCount: number;
196
257
  }
197
258
  declare class PlaybackModule {
198
259
  private emitter;
@@ -203,6 +264,8 @@ declare class PlaybackModule {
203
264
  private targetBufferTime;
204
265
  private lastBufferStateEvent;
205
266
  private firstFrameTime?;
267
+ private needsInputForAudioCount;
268
+ private needsInputForVideoCount;
206
269
  constructor(emitter: Emitter<PlaybackModuleListeners, PlaybackModuleEvents>, logger: Logger, clockSource: ClockSource, targetBufferTime: number);
207
270
  static create: (emitter: Emitter<PlaybackModuleListeners, PlaybackModuleEvents>, logger: Logger, clockSource: ClockSource, targetBufferTime: number) => PlaybackModule;
208
271
  unload: () => void;
@@ -214,6 +277,7 @@ declare class PlaybackModule {
214
277
  getFirstFrameTime: () => number | undefined;
215
278
  getStatistics: () => PlaybackModuleStatistics;
216
279
  private onBufferedStateChanged;
280
+ private onNeedsUserInput;
217
281
  }
218
282
  declare type Direction = "upgrade" | "downgrade" | "double downgrade" | "reconnect";
219
283
  interface QualityOfServiceConfig {
@@ -269,10 +333,6 @@ declare class AdaptivityModule {
269
333
  private tooMuchTimeBuffering;
270
334
  private tooManyBufferingEvents;
271
335
  }
272
- interface NeedsUserInputContext {
273
- forAudio: boolean;
274
- forVideo: boolean;
275
- }
276
336
  interface AudioPlayerModuleListeners {
277
337
  ["decoded frame"]: Readonly<DecodedSample>;
278
338
  }
@@ -300,6 +360,8 @@ declare class AudioPlayerModule {
300
360
  private clockSource;
301
361
  private clockDelta?;
302
362
  private startTimeIsInvalidated;
363
+ private lastSampleTimestamp;
364
+ isActivated: boolean;
303
365
  get volume(): number;
304
366
  set volume(volume: number);
305
367
  get seekTime(): number;
@@ -332,6 +394,8 @@ export declare const AUTHENTICATION_EXPIRED_CODE = "authentication_expired";
332
394
  export declare const CHANNEL_NOT_FOUND_CODE = "channel_not_found";
333
395
  export declare const NO_INCOMING_DATA = "no_incoming_data_error";
334
396
  export declare const INACTIVITY_CODE = "connection_inactivity";
397
+ export declare const MISSING_INIT_SEGMENT = "missing_init_segment";
398
+ export declare const NO_TRACK_CONTEXT = "no_track_context";
335
399
  export declare class VindralError extends Error {
336
400
  private props;
337
401
  private extra;
@@ -342,6 +406,8 @@ export declare class VindralError extends Error {
342
406
  toStringifiable: () => Record<string, unknown>;
343
407
  }
344
408
  export declare const mediaElementError: (isFatal: boolean, mediaError: MediaError) => VindralError;
409
+ export declare const missingInitSegmentError: (renditionId: number, channelId: string) => VindralError;
410
+ export declare const noTrackContextError: (type: "audio" | "video", renditionId: number, channelId: string) => VindralError;
345
411
  export declare const audioContextTimeoutError: () => VindralError;
346
412
  export declare const authenticationError: () => VindralError;
347
413
  export declare const authenticationExpiredError: () => VindralError;
@@ -351,9 +417,11 @@ export declare const noIncomingDataError: () => VindralError;
351
417
  export declare const unableToConnectError: (source?: Error | undefined) => VindralError;
352
418
  export declare const unableToConnectAfterRetriesError: () => VindralError;
353
419
  declare type State = "connected" | "disconnected" | "connecting";
420
+ declare type ContextSwitchState = "completed" | "started";
354
421
  interface ConnectionModuleListeners {
355
422
  ["send signal"]: Readonly<string>;
356
423
  ["disconnect"]: void;
424
+ ["reconnect"]: string;
357
425
  }
358
426
  interface ConnectionModuleEvents {
359
427
  ["received signal"]: Readonly<Signal>;
@@ -361,6 +429,8 @@ interface ConnectionModuleEvents {
361
429
  ["connection state"]: Readonly<State>;
362
430
  ["rtt"]: number;
363
431
  ["error"]: Readonly<VindralError>;
432
+ ["context switch complete"]: Readonly<void>;
433
+ ["context switch started"]: Readonly<void>;
364
434
  }
365
435
  interface ConnectOptions {
366
436
  connectHandler: () => Promise<string>;
@@ -374,6 +444,7 @@ interface ConnectionStatistics {
374
444
  }
375
445
  declare class ConnectionModule {
376
446
  private static PING_INTERVAL;
447
+ private static MAX_MISSED_PINGS;
377
448
  private static TLS_ROUNDTRIPS;
378
449
  private timers;
379
450
  private emitter;
@@ -386,6 +457,7 @@ declare class ConnectionModule {
386
457
  private connectCount;
387
458
  private _firstConnectionTime?;
388
459
  private _lastConnectionTime?;
460
+ private missedPings;
389
461
  private contextSwitchesInProgress;
390
462
  private contextSwitchesCompleted;
391
463
  private buffer;
@@ -408,6 +480,7 @@ declare class ConnectionModule {
408
480
  private onTransportChange;
409
481
  disconnect: (reason?: string) => void;
410
482
  reconnect: (reason: string) => void;
483
+ private cleanupOnDisconnect;
411
484
  private sendPing;
412
485
  }
413
486
  interface Size {
@@ -482,6 +555,7 @@ declare class RenditionsModule {
482
555
  setRenditions: (channelId: ChannelId, renditions: Rendition[]) => void;
483
556
  getLanguages: () => ReadonlyArray<string>;
484
557
  getVideoRendition: (renditionId: number, channelId?: string) => Readonly<VideoRendition> | undefined;
558
+ getAudioRenditions: (channelId: ChannelId) => Readonly<AudioRendition[]> | undefined;
485
559
  getAudioRendition: (renditionId: number, channelId?: string) => Readonly<AudioRendition> | undefined;
486
560
  getRendition: (renditionId: number, channelId?: string) => Readonly<Rendition> | undefined;
487
561
  getStatistics: () => RenditionsModuleStatistics;
@@ -614,6 +688,10 @@ declare class DecoderModule {
614
688
  }
615
689
  type ConnectionType = "bluetooth" | "cellular" | "ethernet" | "mixed" | "none" | "other" | "unknown" | "wifi" | "wimax";
616
690
  type EffectiveConnectionType = "2g" | "3g" | "4g" | "slow-2g";
691
+ interface DocumentState {
692
+ readonly isVisible: boolean;
693
+ readonly isOnline: boolean;
694
+ }
617
695
  interface DocumentStateEvents {
618
696
  ["page active"]: boolean;
619
697
  ["pagehide"]: PageTransitionEvent;
@@ -631,7 +709,7 @@ interface DocumentStateModulesStatistics {
631
709
  navigatorSaveData?: boolean;
632
710
  navigatorDownlink?: number;
633
711
  }
634
- declare class DocumentStateModule {
712
+ declare class DocumentStateModule implements DocumentState {
635
713
  private emitter;
636
714
  private isVisibleCount;
637
715
  private isHiddenCount;
@@ -644,6 +722,8 @@ declare class DocumentStateModule {
644
722
  load: () => void;
645
723
  unsuspend: () => void;
646
724
  getStatistics: () => DocumentStateModulesStatistics;
725
+ get isOnline(): boolean;
726
+ get isVisible(): boolean;
647
727
  private onOnline;
648
728
  private onOffline;
649
729
  private onPageHide;
@@ -656,6 +736,7 @@ interface IncomingDataModuleListeners {
656
736
  }
657
737
  interface IncomingDataModuleEvents {
658
738
  ["no data timeout"]: number;
739
+ ["reconnect"]: string;
659
740
  ["error"]: Readonly<VindralError>;
660
741
  }
661
742
  interface IncomingDataModuleStatistics {
@@ -699,16 +780,20 @@ interface MetadataModuleEvents {
699
780
  interface MetadataModuleListeners {
700
781
  ["buffer state"]: Readonly<BufferState>;
701
782
  }
783
+ interface DriftSource {
784
+ readonly drift: number | undefined;
785
+ }
702
786
  declare class MetadataModule {
703
787
  private static METADATA_TIMEOUT;
704
788
  private logger;
705
789
  private emitter;
706
790
  private waitingMetadata;
707
791
  private isTriggered;
708
- constructor(emitter: Emitter<MetadataModuleListeners, MetadataModuleEvents>, logger: Logger);
792
+ private driftSource;
793
+ constructor(emitter: Emitter<MetadataModuleListeners, MetadataModuleEvents>, logger: Logger, driftSource: DriftSource);
709
794
  load: () => void;
710
795
  unload: () => void;
711
- static create: (emitter: Emitter<MetadataModuleListeners, MetadataModuleEvents>, logger: Logger) => MetadataModule;
796
+ static create: (emitter: Emitter<MetadataModuleListeners, MetadataModuleEvents>, logger: Logger, driftSource: DriftSource) => MetadataModule;
712
797
  addMetadata: (metadata: Metadata) => void;
713
798
  private onBufferedStateChanged;
714
799
  }
@@ -902,7 +987,7 @@ declare class SyncModule {
902
987
  readonly catchupRate: 1.05;
903
988
  readonly slowdownRate: 0.95;
904
989
  };
905
- readonly maxTimeSyncDifferenceTolerance = 150;
990
+ readonly maxTimeSyncDifferenceTolerance = 20;
906
991
  private timers;
907
992
  private rtt;
908
993
  private channelSyncInfo;
@@ -926,7 +1011,9 @@ declare class SyncModule {
926
1011
  getCurrentChannelId: () => string | undefined;
927
1012
  updateChannelSyncInfo(channelId: string, syncInfo: SyncInfo): void;
928
1013
  getLiveEdgeTime: (channelId: string) => number | undefined;
1014
+ getLiveEdgeTimeLatencyAdjusted: (channelId: string) => number | undefined;
929
1015
  getWallclockTime: (channelId: string) => number | undefined;
1016
+ getWallclockTimeLatencyAdjusted: (channelId: string) => number | undefined;
930
1017
  get serverCurrentTime(): number;
931
1018
  processSample: <T extends SyncSample>(sample: T) => T;
932
1019
  getStatistics: () => SyncModuleStatistics;
@@ -990,6 +1077,7 @@ export declare type Statistics = ModuleStatistics & UserAgentInformation & {
990
1077
  };
991
1078
  export declare class Vindral extends Emitter<PublicVindralEvents> {
992
1079
  private static INITIAL_MAX_BIT_RATE;
1080
+ private static PING_TIMEOUT;
993
1081
  readonly pictureInPicture: {
994
1082
  enter: () => Promise<void>;
995
1083
  exit: () => Promise<void>;
@@ -1009,6 +1097,7 @@ export declare class Vindral extends Emitter<PublicVindralEvents> {
1009
1097
  private createdAt;
1010
1098
  private hasCalledConnect;
1011
1099
  private apiClient;
1100
+ private latestEmittedLanguages;
1012
1101
  private durationSessions;
1013
1102
  constructor(options: Options);
1014
1103
  attach: (container: HTMLElement) => void;
@@ -1022,6 +1111,8 @@ export declare class Vindral extends Emitter<PublicVindralEvents> {
1022
1111
  get connectionState(): Readonly<State>;
1023
1112
  get playbackState(): Readonly<PlaybackState>;
1024
1113
  get bufferFullness(): number;
1114
+ get sizeBasedResolutionCapEnabled(): boolean;
1115
+ set sizeBasedResolutionCapEnabled(enabled: boolean);
1025
1116
  get abrEnabled(): boolean;
1026
1117
  set abrEnabled(enabled: boolean);
1027
1118
  get serverEdgeTime(): number | undefined;
@@ -1039,12 +1130,10 @@ export declare class Vindral extends Emitter<PublicVindralEvents> {
1039
1130
  set channelId(channelId: string);
1040
1131
  get maxSize(): Size;
1041
1132
  set maxSize(size: Size);
1042
- get maxBitRate(): number;
1043
- set maxBitRate(bitRate: number);
1044
- get maxVideoBitrate(): number;
1045
- set maxVideoBitrate(bitRate: number);
1046
- get maxAudioBitrate(): number;
1047
- set maxAudioBitrate(bitRate: number);
1133
+ get maxVideoBitRate(): number;
1134
+ set maxVideoBitRate(bitRate: number);
1135
+ get maxAudioBitRate(): number;
1136
+ set maxAudioBitRate(bitRate: number);
1048
1137
  get renditionLevels(): ReadonlyArray<RenditionLevel>;
1049
1138
  get currentRenditionLevel(): Readonly<RenditionLevel> | undefined;
1050
1139
  get targetRenditionLevel(): Readonly<RenditionLevel> | undefined;
@@ -1061,7 +1150,9 @@ export declare class Vindral extends Emitter<PublicVindralEvents> {
1061
1150
  connect: () => void;
1062
1151
  getCastOptions: () => Options;
1063
1152
  private connectionInfo;
1153
+ private estimateRTT;
1064
1154
  private connectHandler;
1155
+ private emitLanguagesIfChanged;
1065
1156
  private filterRenditions;
1066
1157
  private patchSubscription;
1067
1158
  private isSupportedVideoCodecProfile;
@@ -1136,6 +1227,16 @@ declare class TimerModule {
1136
1227
  setInterval: (callback: (...args: unknown[]) => void, interval: number, ...args: unknown[]) => number;
1137
1228
  unload: () => void;
1138
1229
  }
1230
+ declare class UnpauseModule {
1231
+ private logger;
1232
+ private element;
1233
+ private documentState;
1234
+ private timers;
1235
+ private constructor();
1236
+ static create: (logger: Logger, element: MediaElement, documentState: DocumentState) => UnpauseModule;
1237
+ unload: () => void;
1238
+ private unpause;
1239
+ }
1139
1240
  interface VideoPlayerModuleListeners {
1140
1241
  ["decoded frame"]: Readonly<DecodedSample>;
1141
1242
  }
@@ -1185,6 +1286,7 @@ export interface Modules {
1185
1286
  telemetry?: TelemetryModule;
1186
1287
  documentState: DocumentStateModule;
1187
1288
  incomingData: IncomingDataModule;
1289
+ unpause?: UnpauseModule;
1188
1290
  }
1189
1291
  export interface ReconnectState {
1190
1292
  reconnectRetries: number;
@@ -1221,15 +1323,6 @@ export interface Options {
1221
1323
  advanced?: AdvancedOptions;
1222
1324
  media?: Media;
1223
1325
  }
1224
- export interface PlaybackSource {
1225
- volume: number;
1226
- muted: boolean;
1227
- currentTime: number;
1228
- playbackRate?: number;
1229
- readonly seekTime: number;
1230
- readonly isSeeking: boolean;
1231
- play(): Promise<void>;
1232
- }
1233
1326
  export interface PublicVindralEvents {
1234
1327
  ["error"]: Readonly<VindralError>;
1235
1328
  ["needs user input"]: NeedsUserInputContext;
@@ -1240,6 +1333,7 @@ export interface PublicVindralEvents {
1240
1333
  ["rendition level"]: Readonly<RenditionLevel>;
1241
1334
  ["languages"]: ReadonlyArray<string>;
1242
1335
  ["channels"]: ReadonlyArray<Channel>;
1336
+ ["context switch"]: Readonly<ContextSwitchState>;
1243
1337
  ["server wallclock time"]: Readonly<number>;
1244
1338
  ["buffer state event"]: Readonly<BufferStateEvent>;
1245
1339
  ["initialized media"]: void;
@@ -1472,12 +1566,22 @@ export interface PlayerOptions {
1472
1566
  fullscreenButtonEnabled?: boolean;
1473
1567
  pipButtonEnabled?: boolean;
1474
1568
  channelSelectionEnabled?: boolean;
1569
+ channelSelectionOptions?: {
1570
+ barButton?: {
1571
+ enabled?: boolean;
1572
+ thumbnails?: boolean;
1573
+ };
1574
+ list?: {
1575
+ enabled?: boolean;
1576
+ };
1577
+ };
1475
1578
  renditionLevelsEnabled?: boolean;
1476
1579
  languagesButtonEnabled?: boolean;
1477
1580
  oneToOneButtonEnabled?: boolean;
1478
1581
  hideTimeout?: number;
1479
1582
  castBackground?: string;
1480
1583
  castReceiverApplicationId?: string;
1584
+ thumbnailUpdateInterval?: number;
1481
1585
  }
1482
1586
  export interface PlayerState {
1483
1587
  isBuffering: boolean;
@@ -1492,9 +1596,11 @@ export declare class Player {
1492
1596
  private playerElement;
1493
1597
  private bufferingOverlay;
1494
1598
  private playOverlay;
1599
+ private channelSelectionList?;
1495
1600
  private bar;
1496
1601
  private stateInterval?;
1497
1602
  private showBufferingTimeout?;
1603
+ private thumbnailModule?;
1498
1604
  constructor(optionsOrInstance: Options | Vindral, playerOptions?: PlayerOptions);
1499
1605
  unload: () => void;
1500
1606
  attach: (container: HTMLElement) => void;
@@ -1509,6 +1615,7 @@ export declare class Player {
1509
1615
  private lockOrientation;
1510
1616
  private unlockOrientation;
1511
1617
  private checkState;
1618
+ private needsThumbnails;
1512
1619
  private bumpInteractTime;
1513
1620
  }
1514
1621
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vindral/web-sdk",
3
- "version": "2.0.9",
3
+ "version": "2.0.13",
4
4
  "homepage": "https://vindral.com",
5
5
  "description": "Web SDK for viewing Vindral streams",
6
6
  "license": "SEE LICENSE IN https://www.vindral.com/terms-conditions",