livekit-client 2.5.8 → 2.5.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- {"version":3,"file":"FrameCryptor.d.ts","sourceRoot":"","sources":["../../../../src/e2ee/worker/FrameCryptor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,iBAAiB,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAG3D,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,WAAW,CAAC;AAChE,OAAO,KAAK,EAAwB,kBAAkB,EAAU,MAAM,UAAU,CAAC;AAEjF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGrE,eAAO,MAAM,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAa,CAAC;AAEpE,MAAM,WAAW,uBAAuB;IACtC,KAAK,IAAI,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,eAAe,CAAC;IAC7B,eAAe,EAAE,eAAe,CAAC;CAClC;+CAEgE,iBAAiB,CAAC,gBAAgB,CAAC;AAApG,qBAAa,gBAAiB,SAAQ,qBAA+D;IACnG,SAAS,CAAC,cAAc,CACtB,YAAY,EAAE,oBAAoB,GAAG,oBAAoB,EACzD,UAAU,EAAE,gCAAgC,GAC3C,OAAO,CAAC,GAAG,CAAC;IAIf,SAAS,CAAC,cAAc,CACtB,YAAY,EAAE,oBAAoB,GAAG,oBAAoB,EACzD,UAAU,EAAE,gCAAgC,GAC3C,OAAO,CAAC,GAAG,CAAC;CAGhB;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,gBAAgB;IAChD,OAAO,CAAC,UAAU,CAAsB;IAExC,OAAO,CAAC,mBAAmB,CAAqB;IAEhD,OAAO,CAAC,OAAO,CAAqB;IAEpC,OAAO,CAAC,IAAI,CAAwB;IAEpC,OAAO,CAAC,UAAU,CAAC,CAAa;IAEhC,OAAO,CAAC,MAAM,CAA0B;IAExC,OAAO,CAAC,kBAAkB,CAAqB;IAE/C;;OAEG;IACH,OAAO,CAAC,UAAU,CAAa;IAE/B,OAAO,CAAC,QAAQ,CAAW;IAE3B,OAAO,CAAC,aAAa,CAAC,CAAa;gBAEvB,IAAI,EAAE;QAChB,IAAI,EAAE,qBAAqB,CAAC;QAC5B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;IAWD,OAAO,KAAK,UAAU,GAMrB;IAED;;;;;OAKG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB;IAkBtD,gBAAgB;IAKhB,SAAS;IAQT,sBAAsB;IAItB,UAAU;IAIV;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,UAAU;IAI/B;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAItC,cAAc,CACZ,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAC9B,QAAQ,EAAE,cAAc,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,EACrE,QAAQ,EAAE,cAAc,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,EACrE,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,UAAU;IAkCpB,aAAa,CAAC,OAAO,EAAE,UAAU;IAKjC;;;;;;;;;;;;;;;;;;;;;OAqBG;cACa,cAAc,CAC5B,YAAY,EAAE,oBAAoB,GAAG,oBAAoB,EACzD,UAAU,EAAE,gCAAgC;IA+F9C;;;;;OAKG;cACa,cAAc,CAC5B,YAAY,EAAE,oBAAoB,GAAG,oBAAoB,EACzD,UAAU,EAAE,gCAAgC;IAiE9C;;;OAGG;YACW,YAAY;IA4H1B;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,MAAM;IAqBd,OAAO,CAAC,mBAAmB;IAgE3B;;OAEG;IACH,OAAO,CAAC,aAAa;CAQtB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CA0B5D;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAEzD;AAID,oBAAY,QAAQ;IAClB,uCAAuC;IACvC,aAAa,IAAI;IACjB,mCAAmC;IACnC,iBAAiB,IAAI;IACrB,mCAAmC;IACnC,iBAAiB,IAAI;IACrB,mCAAmC;IACnC,iBAAiB,IAAI;IACrB,oCAAoC;IACpC,SAAS,IAAI;IACb,2CAA2C;IAC3C,GAAG,IAAI;IACP,6BAA6B;IAC7B,GAAG,IAAI;IACP,4BAA4B;IAC5B,GAAG,IAAI;IACP,4BAA4B;IAC5B,GAAG,IAAI;IACP,sBAAsB;IACtB,OAAO,KAAK;IACZ,oBAAoB;IACpB,UAAU,KAAK;IACf,kBAAkB;IAClB,WAAW,KAAK;IAChB,uCAAuC;IACvC,OAAO,KAAK;IACZ,sBAAsB;IACtB,WAAW,KAAK;IAChB,oCAAoC;IACpC,UAAU,KAAK;IACf,0BAA0B;IAC1B,GAAG,KAAK;IAIR,qEAAqE;IACrE,SAAS,KAAK;IACd,4BAA4B;IAC5B,SAAS,KAAK;IACd,0FAA0F;IAC1F,eAAe,KAAK;CAGrB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,GAAG,OAAO,CAQ/F"}
1
+ {"version":3,"file":"FrameCryptor.d.ts","sourceRoot":"","sources":["../../../../src/e2ee/worker/FrameCryptor.ts"],"names":[],"mappings":"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"}
@@ -13,20 +13,40 @@ declare const ParticipantKeyHandler_base: new () => TypedEventEmitter<Participan
13
13
  export declare class ParticipantKeyHandler extends ParticipantKeyHandler_base {
14
14
  private currentKeyIndex;
15
15
  private cryptoKeyRing;
16
+ private decryptionFailureCounts;
16
17
  private keyProviderOptions;
17
18
  private ratchetPromiseMap;
18
19
  private participantIdentity;
19
- private decryptionFailureCount;
20
- private _hasValidKey;
20
+ /**
21
+ * true if the current key has not been marked as invalid
22
+ */
21
23
  get hasValidKey(): boolean;
22
24
  constructor(participantIdentity: string, keyProviderOptions: KeyProviderOptions);
23
- decryptionFailure(): void;
24
- decryptionSuccess(): void;
25
+ /**
26
+ * Returns true if the key at the given index is marked as invalid.
27
+ *
28
+ * @param keyIndex the index of the key
29
+ */
30
+ hasInvalidKeyAtIndex(keyIndex: number): boolean;
31
+ /**
32
+ * Informs the key handler that a decryption failure occurred for an encryption key.
33
+ * @internal
34
+ * @param keyIndex the key index for which the failure occurred. Defaults to the current key index.
35
+ */
36
+ decryptionFailure(keyIndex?: number): void;
37
+ /**
38
+ * Informs the key handler that a frame was successfully decrypted using an encryption key.
39
+ * @internal
40
+ * @param keyIndex the key index for which the success occurred. Defaults to the current key index.
41
+ */
42
+ decryptionSuccess(keyIndex?: number): void;
25
43
  /**
26
44
  * Call this after user initiated ratchet or a new key has been set in order to make sure to mark potentially
27
45
  * invalid keys as valid again
46
+ *
47
+ * @param keyIndex the index of the key. Defaults to the current key index.
28
48
  */
29
- resetKeyStatus(): void;
49
+ resetKeyStatus(keyIndex?: number): void;
30
50
  /**
31
51
  * Ratchets the current key (or the one at keyIndex if provided) and
32
52
  * returns the ratcheted material
@@ -1 +1 @@
1
- {"version":3,"file":"ParticipantKeyHandler.d.ts","sourceRoot":"","sources":["../../../../src/e2ee/worker/ParticipantKeyHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,iBAAiB,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAmB,KAAK,8BAA8B,EAAE,MAAM,WAAW,CAAC;AACjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;oDAcW,iBAAiB,CAAC,8BAA8B,CAAC;AARvH;;;;;;;GAOG;AACH,qBAAa,qBAAsB,SAAQ,0BAA6E;IACtH,OAAO,CAAC,eAAe,CAAS;IAEhC,OAAO,CAAC,aAAa,CAA4B;IAEjD,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,iBAAiB,CAAkC;IAE3D,OAAO,CAAC,mBAAmB,CAAS;IAEpC,OAAO,CAAC,sBAAsB,CAAK;IAEnC,OAAO,CAAC,YAAY,CAAiB;IAErC,IAAI,WAAW,YAEd;gBAEW,mBAAmB,EAAE,MAAM,EAAE,kBAAkB,EAAE,kBAAkB;IAa/E,iBAAiB;IAYjB,iBAAiB;IAIjB;;;OAGG;IACH,cAAc;IAKd;;;;;;OAMG;IACH,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,UAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IA0ChE;;;;;OAKG;IACG,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,SAAI;IAK9C;;;;;OAKG;IACG,kBAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,UAAQ;IAYxF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,UAAQ;IAQ9D,kBAAkB,CAAC,KAAK,EAAE,MAAM;IAKtC,kBAAkB;IAIlB;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM;CAG5B"}
1
+ {"version":3,"file":"ParticipantKeyHandler.d.ts","sourceRoot":"","sources":["../../../../src/e2ee/worker/ParticipantKeyHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,iBAAiB,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAmB,KAAK,8BAA8B,EAAE,MAAM,WAAW,CAAC;AACjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;oDAcW,iBAAiB,CAAC,8BAA8B,CAAC;AARvH;;;;;;;GAOG;AACH,qBAAa,qBAAsB,SAAQ,0BAA6E;IACtH,OAAO,CAAC,eAAe,CAAS;IAEhC,OAAO,CAAC,aAAa,CAA4B;IAEjD,OAAO,CAAC,uBAAuB,CAAgB;IAE/C,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,iBAAiB,CAAkC;IAE3D,OAAO,CAAC,mBAAmB,CAAS;IAEpC;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;gBAEW,mBAAmB,EAAE,MAAM,EAAE,kBAAkB,EAAE,kBAAkB;IAa/E;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAO/C;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,GAAE,MAA6B,GAAG,IAAI;IAchE;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,GAAE,MAA6B,GAAG,IAAI;IAIhE;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvC;;;;;;OAMG;IACH,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,UAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IA0ChE;;;;;OAKG;IACG,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,SAAI;IAK9C;;;;;OAKG;IACG,kBAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,UAAQ;IAYxF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,UAAQ;IAQ9D,kBAAkB,CAAC,KAAK,EAAE,MAAM;IAKtC,kBAAkB;IAIlB;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM;CAG5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"LocalParticipant.d.ts","sourceRoot":"","sources":["../../../../src/room/participant/LocalParticipant.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LocalParticipant.d.ts","sourceRoot":"","sources":["../../../../src/room/participant/LocalParticipant.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,EAIL,eAAe,EACf,qBAAqB,EAUtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAW1C,OAAO,UAAU,MAAM,qBAAqB,CAAC;AAC7C,OAAO,qBAAqB,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAYhE,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAS/E,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,WAAW;IACvD,sBAAsB,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAE3D,sBAAsB,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAE3D,+CAA+C;IAC/C,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAEtD,gBAAgB;IAChB,MAAM,EAAE,SAAS,CAAC;IAElB,gBAAgB;IAChB,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAE9C,OAAO,CAAC,iBAAiB,CAA2B;IAEpD,OAAO,CAAC,sBAAsB,CAAyD;IAEvF,OAAO,CAAC,gBAAgB,CAA4B;IAEpD,OAAO,CAAC,WAAW,CAAoB;IAEvC,OAAO,CAAC,eAAe,CAAoB;IAE3C,OAAO,CAAC,2BAA2B,CAAyC;IAE5E,OAAO,CAAC,iCAAiC,CAAiB;IAG1D,OAAO,CAAC,WAAW,CAAsB;IAEzC,OAAO,CAAC,cAAc,CAAyC;IAE/D,OAAO,CAAC,eAAe,CAAC,CAAe;IAEvC,OAAO,CAAC,qBAAqB,CAO3B;IAEF,OAAO,CAAC,yBAAyB,CAAe;IAEhD,gBAAgB;gBACJ,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB;IAe1F,IAAI,eAAe,IAAI,KAAK,GAAG,SAAS,CAEvC;IAED,IAAI,mBAAmB,IAAI,KAAK,GAAG,SAAS,CAE3C;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAO5E,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAO1E;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,SAAS;IA0B7B,OAAO,CAAC,kBAAkB,CAIxB;IAEF,OAAO,CAAC,iBAAiB,CAIvB;IAEF,OAAO,CAAC,kBAAkB,CAMxB;IAEF,OAAO,CAAC,2BAA2B,CASjC;IAEF;;;;;OAKG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD;;;;;OAKG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C;;;;;OAKG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;YAIxC,qBAAqB;IAmDnC;;;;;OAKG;IACH,gBAAgB,CACd,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,EAC7B,cAAc,CAAC,EAAE,mBAAmB,GACnC,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAI7C;;;;;OAKG;IACH,oBAAoB,CAClB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,EAC7B,cAAc,CAAC,EAAE,mBAAmB,GACnC,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAI7C;;;OAGG;IACH,qBAAqB,CACnB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,yBAAyB,EACnC,cAAc,CAAC,EAAE,mBAAmB,GACnC,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAI7C,gBAAgB;IAChB,cAAc,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO;IAS3D,gBAAgB;IACV,cAAc,CAAC,OAAO,EAAE,OAAO;IAKrC;;;;OAIG;YACW,eAAe;IA6G7B;;;OAGG;IACG,yBAAyB;IAwB/B;;;;OAIG;IACG,YAAY,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAoE7E;;;;OAIG;IACG,kBAAkB,CAAC,OAAO,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAgDzF;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,EAAE,OAAO,CAAC,EAAE,mBAAmB;YAIxE,uBAAuB;YA+IvB,OAAO;IA2RrB,IAAa,OAAO,IAAI,OAAO,CAE9B;IAED;;OAEG;IACG,8BAA8B,CAClC,KAAK,EAAE,UAAU,GAAG,gBAAgB,EACpC,UAAU,EAAE,gBAAgB,EAC5B,OAAO,CAAC,EAAE,mBAAmB;IAoFzB,cAAc,CAClB,KAAK,EAAE,UAAU,GAAG,gBAAgB,EACpC,eAAe,CAAC,EAAE,OAAO,GACxB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IA4GvC,eAAe,CACnB,MAAM,EAAE,UAAU,EAAE,GAAG,gBAAgB,EAAE,GACxC,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAO7B,kBAAkB,CAAC,OAAO,CAAC,EAAE,mBAAmB,EAAE,aAAa,GAAE,OAAc;IAkDrF;;;;;;OAMG;IACG,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBpF;;;;;OAKG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAevD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBnD,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW;;;;;;IAqBpE;;;;;;;;;;;;;;;;OAgBG;IACH,+BAA+B,CAC7B,sBAAsB,EAAE,OAAO,EAC/B,2BAA2B,GAAE,0BAA0B,EAAO;IAShE,gBAAgB;IAChB,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE;IAMvC,gBAAgB;IAChB,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO;IA+B1C,OAAO,CAAC,kCAAkC,CAUxC;IAEF,gBAAgB;IAChB,OAAO,CAAC,cAAc,CAEpB;IAGF,gBAAgB;IAChB,OAAO,CAAC,YAAY,CAclB;IAEF,OAAO,CAAC,qBAAqB,CAM3B;IAEF,OAAO,CAAC,sBAAsB,CAM5B;IAEF,OAAO,CAAC,oBAAoB,CAU1B;IAEF,OAAO,CAAC,6BAA6B,CA6BnC;IAEF,OAAO,CAAC,2BAA2B,CAUjC;IAEF,OAAO,CAAC,gBAAgB,CA8DtB;IAEF,OAAO,CAAC,sBAAsB;YAwBhB,iCAAiC;CAQhD"}
@@ -13,20 +13,40 @@ declare const ParticipantKeyHandler_base: new () => TypedEventEmitter<Participan
13
13
  export declare class ParticipantKeyHandler extends ParticipantKeyHandler_base {
14
14
  private currentKeyIndex;
15
15
  private cryptoKeyRing;
16
+ private decryptionFailureCounts;
16
17
  private keyProviderOptions;
17
18
  private ratchetPromiseMap;
18
19
  private participantIdentity;
19
- private decryptionFailureCount;
20
- private _hasValidKey;
20
+ /**
21
+ * true if the current key has not been marked as invalid
22
+ */
21
23
  get hasValidKey(): boolean;
22
24
  constructor(participantIdentity: string, keyProviderOptions: KeyProviderOptions);
23
- decryptionFailure(): void;
24
- decryptionSuccess(): void;
25
+ /**
26
+ * Returns true if the key at the given index is marked as invalid.
27
+ *
28
+ * @param keyIndex the index of the key
29
+ */
30
+ hasInvalidKeyAtIndex(keyIndex: number): boolean;
31
+ /**
32
+ * Informs the key handler that a decryption failure occurred for an encryption key.
33
+ * @internal
34
+ * @param keyIndex the key index for which the failure occurred. Defaults to the current key index.
35
+ */
36
+ decryptionFailure(keyIndex?: number): void;
37
+ /**
38
+ * Informs the key handler that a frame was successfully decrypted using an encryption key.
39
+ * @internal
40
+ * @param keyIndex the key index for which the success occurred. Defaults to the current key index.
41
+ */
42
+ decryptionSuccess(keyIndex?: number): void;
25
43
  /**
26
44
  * Call this after user initiated ratchet or a new key has been set in order to make sure to mark potentially
27
45
  * invalid keys as valid again
46
+ *
47
+ * @param keyIndex the index of the key. Defaults to the current key index.
28
48
  */
29
- resetKeyStatus(): void;
49
+ resetKeyStatus(keyIndex?: number): void;
30
50
  /**
31
51
  * Ratchets the current key (or the one at keyIndex if provided) and
32
52
  * returns the ratcheted material
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livekit-client",
3
- "version": "2.5.8",
3
+ "version": "2.5.9",
4
4
  "description": "JavaScript/TypeScript client SDK for LiveKit",
5
5
  "main": "./dist/livekit-client.umd.js",
6
6
  "unpkg": "./dist/livekit-client.umd.js",
@@ -71,7 +71,7 @@
71
71
  "eslint-plugin-ecmascript-compat": "^3.0.0",
72
72
  "eslint-plugin-import": "2.30.0",
73
73
  "gh-pages": "6.1.1",
74
- "jsdom": "^24.0.0",
74
+ "happy-dom": "^15.7.4",
75
75
  "prettier": "^3.0.0",
76
76
  "rollup": "4.24.0",
77
77
  "rollup-plugin-delete": "^2.0.0",
@@ -60,6 +60,21 @@ class TestUnderlyingSink<T> implements UnderlyingSink<T> {
60
60
  function prepareParticipantTestDecoder(
61
61
  participantIdentity: string,
62
62
  partialKeyProviderOptions: Partial<KeyProviderOptions>,
63
+ ) {
64
+ return prepareParticipantTest('decode', participantIdentity, partialKeyProviderOptions);
65
+ }
66
+
67
+ function prepareParticipantTestEncoder(
68
+ participantIdentity: string,
69
+ partialKeyProviderOptions: Partial<KeyProviderOptions>,
70
+ ) {
71
+ return prepareParticipantTest('encode', participantIdentity, partialKeyProviderOptions);
72
+ }
73
+
74
+ function prepareParticipantTest(
75
+ mode: 'encode' | 'decode',
76
+ participantIdentity: string,
77
+ partialKeyProviderOptions: Partial<KeyProviderOptions>,
63
78
  ): {
64
79
  keys: ParticipantKeyHandler;
65
80
  cryptor: FrameCryptor;
@@ -80,12 +95,7 @@ function prepareParticipantTestDecoder(
80
95
 
81
96
  const input = new TestUnderlyingSource<RTCEncodedVideoFrame>();
82
97
  const output = new TestUnderlyingSink<RTCEncodedVideoFrame>();
83
- cryptor.setupTransform(
84
- 'decode',
85
- new ReadableStream(input),
86
- new WritableStream(output),
87
- 'testTrack',
88
- );
98
+ cryptor.setupTransform(mode, new ReadableStream(input), new WritableStream(output), 'testTrack');
89
99
 
90
100
  return { keys, cryptor, input, output };
91
101
  }
@@ -93,10 +103,6 @@ function prepareParticipantTestDecoder(
93
103
  describe('FrameCryptor', () => {
94
104
  const participantIdentity = 'testParticipant';
95
105
 
96
- afterEach(() => {
97
- encryptionEnabledMap.clear();
98
- });
99
-
100
106
  it('identifies server injected frame correctly', () => {
101
107
  const frameTrailer = new TextEncoder().encode('LKROCKS');
102
108
  const frameData = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, ...frameTrailer]).buffer;
@@ -113,154 +119,346 @@ describe('FrameCryptor', () => {
113
119
  expect(isFrameServerInjected(frameData.buffer, frameTrailer)).toBe(false);
114
120
  });
115
121
 
116
- it('passthrough if participant encryption disabled', async () => {
117
- vitest.useFakeTimers();
118
- try {
119
- const { input, output } = prepareParticipantTestDecoder(participantIdentity, {});
122
+ describe('encode', () => {
123
+ afterEach(() => {
124
+ encryptionEnabledMap.clear();
125
+ });
120
126
 
121
- // disable encryption for participant
122
- encryptionEnabledMap.set(participantIdentity, false);
127
+ it('passthrough if participant encryption disabled', async () => {
128
+ vitest.useFakeTimers();
129
+ try {
130
+ const { input, output } = prepareParticipantTestEncoder(participantIdentity, {});
123
131
 
124
- const frame = mockEncryptedRTCEncodedVideoFrame(1);
132
+ // disable encryption for participant
133
+ encryptionEnabledMap.set(participantIdentity, false);
125
134
 
126
- input.write(frame);
127
- await vitest.advanceTimersToNextTimerAsync();
135
+ const frame = mockRTCEncodedVideoFrame(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]));
128
136
 
129
- expect(output.chunks).toEqual([frame]);
130
- } finally {
131
- vitest.useRealTimers();
132
- }
133
- });
137
+ input.write(frame);
138
+ await vitest.advanceTimersToNextTimerAsync();
134
139
 
135
- it('passthrough for empty frame', async () => {
136
- vitest.useFakeTimers();
137
- try {
138
- const { input, output } = prepareParticipantTestDecoder(participantIdentity, {});
140
+ expect(output.chunks).toEqual([frame]);
141
+ } finally {
142
+ vitest.useRealTimers();
143
+ }
144
+ });
139
145
 
140
- // empty frame
141
- const frame = mockRTCEncodedVideoFrame(new Uint8Array(0));
146
+ it('passthrough for empty frame', async () => {
147
+ vitest.useFakeTimers();
148
+ try {
149
+ const { input, output } = prepareParticipantTestEncoder(participantIdentity, {});
142
150
 
143
- input.write(frame);
144
- await vitest.advanceTimersToNextTimerAsync();
151
+ // empty frame
152
+ const frame = mockRTCEncodedVideoFrame(new Uint8Array(0));
145
153
 
146
- expect(output.chunks).toEqual([frame]);
147
- } finally {
148
- vitest.useRealTimers();
149
- }
150
- });
154
+ input.write(frame);
155
+ await vitest.advanceTimersToNextTimerAsync();
156
+
157
+ expect(output.chunks).toEqual([frame]);
158
+ } finally {
159
+ vitest.useRealTimers();
160
+ }
161
+ });
162
+
163
+ it('immediately drops frame and emits error if no key set', async () => {
164
+ vitest.useFakeTimers();
165
+ try {
166
+ const { cryptor, input, output } = prepareParticipantTestEncoder(participantIdentity, {});
167
+
168
+ const errorListener = vitest.fn();
169
+ cryptor.on(CryptorEvent.Error, errorListener);
170
+
171
+ const frame = mockRTCEncodedVideoFrame(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]));
151
172
 
152
- it('drops frames when invalid key', async () => {
153
- vitest.useFakeTimers();
154
- try {
155
- const { keys, input, output } = prepareParticipantTestDecoder(participantIdentity, {
156
- failureTolerance: 0,
157
- });
173
+ input.write(frame);
174
+ await vitest.advanceTimersToNextTimerAsync();
158
175
 
159
- expect(keys.hasValidKey).toBe(true);
176
+ expect(output.chunks).toEqual([]);
177
+ expect(errorListener).toHaveBeenCalled();
178
+ } finally {
179
+ vitest.useRealTimers();
180
+ }
181
+ });
182
+
183
+ it('encrypts frame', async () => {
184
+ vitest.useFakeTimers();
185
+ try {
186
+ const { keys, input, output } = prepareParticipantTestEncoder(participantIdentity, {});
187
+
188
+ await keys.setKey(await createKeyMaterialFromString('key1'), 1);
160
189
 
161
- await keys.setKey(await createKeyMaterialFromString('password'), 0);
190
+ const plainTextData = new Uint8Array([
191
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
192
+ ]);
193
+ const frame = mockRTCEncodedVideoFrame(plainTextData);
162
194
 
163
- input.write(mockEncryptedRTCEncodedVideoFrame(1));
164
- await vitest.advanceTimersToNextTimerAsync();
195
+ input.write(frame);
196
+ await vitest.waitFor(() => expect(output.chunks).toHaveLength(1));
165
197
 
166
- expect(output.chunks).toEqual([]);
167
- expect(keys.hasValidKey).toBe(false);
198
+ expect(output.chunks).toEqual([frame]);
199
+ expect(frame.data.byteLength).toBeGreaterThan(16);
168
200
 
169
- // this should still fail as keys are all marked as invalid
170
- input.write(mockEncryptedRTCEncodedVideoFrame(0));
171
- await vitest.advanceTimersToNextTimerAsync();
201
+ // first bytes are unencrypted
202
+ expect(new Uint8Array(frame.data.slice(0, 10))).toEqual(plainTextData.subarray(0, 10));
172
203
 
173
- expect(output.chunks).toEqual([]);
174
- expect(keys.hasValidKey).toBe(false);
175
- } finally {
176
- vitest.useRealTimers();
177
- }
204
+ // remainder should not be the same
205
+ expect(new Uint8Array(frame.data.slice(10, 16))).not.toEqual(
206
+ plainTextData.subarray(10, 16),
207
+ );
208
+
209
+ const frameTrailer = new Uint8Array(frame.data.slice(frame.data.byteLength - 2));
210
+ // IV length
211
+ expect(frameTrailer[0]).toEqual(IV_LENGTH);
212
+ // key index
213
+ expect(frameTrailer[1]).toEqual(1);
214
+ } finally {
215
+ vitest.useRealTimers();
216
+ }
217
+ });
178
218
  });
179
219
 
180
- it('marks key invalid after too many failures', async () => {
181
- const { keys, cryptor, input } = prepareParticipantTestDecoder(participantIdentity, {
182
- failureTolerance: 1,
220
+ describe('decode', () => {
221
+ afterEach(() => {
222
+ encryptionEnabledMap.clear();
183
223
  });
184
224
 
185
- expect(keys.hasValidKey).toBe(true);
225
+ it('passthrough if participant encryption disabled', async () => {
226
+ vitest.useFakeTimers();
227
+ try {
228
+ const { input, output } = prepareParticipantTestDecoder(participantIdentity, {});
186
229
 
187
- await keys.setKey(await createKeyMaterialFromString('password'), 0);
230
+ // disable encryption for participant
231
+ encryptionEnabledMap.set(participantIdentity, false);
188
232
 
189
- vitest.spyOn(keys, 'getKeySet');
190
- vitest.spyOn(keys, 'decryptionFailure');
233
+ const frame = mockEncryptedRTCEncodedVideoFrame(1);
191
234
 
192
- const errorListener = vitest.fn().mockImplementation((e) => {
193
- console.log('error', e);
235
+ input.write(frame);
236
+ await vitest.advanceTimersToNextTimerAsync();
237
+
238
+ expect(output.chunks).toEqual([frame]);
239
+ } finally {
240
+ vitest.useRealTimers();
241
+ }
194
242
  });
195
- cryptor.on(CryptorEvent.Error, errorListener);
196
243
 
197
- input.write(mockEncryptedRTCEncodedVideoFrame(1));
244
+ it('passthrough for empty frame', async () => {
245
+ vitest.useFakeTimers();
246
+ try {
247
+ const { input, output } = prepareParticipantTestDecoder(participantIdentity, {});
198
248
 
199
- await vitest.waitFor(() => expect(keys.decryptionFailure).toHaveBeenCalled());
200
- expect(errorListener).toHaveBeenCalled();
201
- expect(keys.decryptionFailure).toHaveBeenCalledTimes(1);
202
- expect(keys.getKeySet).toHaveBeenCalled();
203
- expect(keys.getKeySet).toHaveBeenLastCalledWith(1);
204
- expect(keys.hasValidKey).toBe(true);
249
+ // empty frame
250
+ const frame = mockRTCEncodedVideoFrame(new Uint8Array(0));
205
251
 
206
- vitest.clearAllMocks();
252
+ input.write(frame);
253
+ await vitest.advanceTimersToNextTimerAsync();
207
254
 
208
- input.write(mockEncryptedRTCEncodedVideoFrame(1));
255
+ expect(output.chunks).toEqual([frame]);
256
+ } finally {
257
+ vitest.useRealTimers();
258
+ }
259
+ });
209
260
 
210
- await vitest.waitFor(() => expect(keys.decryptionFailure).toHaveBeenCalled());
211
- expect(errorListener).toHaveBeenCalled();
212
- expect(keys.decryptionFailure).toHaveBeenCalledTimes(1);
213
- expect(keys.getKeySet).toHaveBeenCalled();
214
- expect(keys.getKeySet).toHaveBeenLastCalledWith(1);
215
- expect(keys.hasValidKey).toBe(false);
261
+ it('immediately drops frames when key marked invalid', async () => {
262
+ vitest.useFakeTimers();
263
+ try {
264
+ const { keys, input, output } = prepareParticipantTestDecoder(participantIdentity, {
265
+ failureTolerance: 0,
266
+ });
216
267
 
217
- vitest.clearAllMocks();
268
+ keys.decryptionFailure();
218
269
 
219
- // this should still fail as keys are all marked as invalid
220
- input.write(mockEncryptedRTCEncodedVideoFrame(0));
270
+ input.write(mockEncryptedRTCEncodedVideoFrame(1));
271
+ await vitest.advanceTimersToNextTimerAsync();
221
272
 
222
- await vitest.waitFor(() => expect(keys.getKeySet).toHaveBeenCalled());
223
- // decryptionFailure() isn't called in this case
224
- expect(keys.getKeySet).toHaveBeenCalled();
225
- expect(keys.getKeySet).toHaveBeenLastCalledWith(0);
226
- expect(keys.hasValidKey).toBe(false);
227
- });
273
+ expect(output.chunks).toEqual([]);
228
274
 
229
- it('mark as valid when a new key is set on same index', async () => {
230
- const { keys, input } = prepareParticipantTestDecoder(participantIdentity, {
231
- failureTolerance: 0,
232
- });
275
+ keys.decryptionFailure();
233
276
 
234
- const material = await createKeyMaterialFromString('password');
235
- await keys.setKey(material, 0);
277
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
278
+ await vitest.advanceTimersToNextTimerAsync();
236
279
 
237
- expect(keys.hasValidKey).toBe(true);
280
+ expect(output.chunks).toEqual([]);
281
+ } finally {
282
+ vitest.useRealTimers();
283
+ }
284
+ });
238
285
 
239
- input.write(mockEncryptedRTCEncodedVideoFrame(1));
286
+ it('calls decryptionFailure on missing key and emits error', async () => {
287
+ vitest.useFakeTimers();
288
+ try {
289
+ const { cryptor, keys, input } = prepareParticipantTestDecoder(participantIdentity, {});
290
+
291
+ const errorListener = vitest.fn();
292
+ cryptor.on(CryptorEvent.Error, errorListener);
293
+ vitest.spyOn(keys, 'decryptionFailure');
294
+
295
+ // no key is set at this index
296
+ input.write(mockEncryptedRTCEncodedVideoFrame(1));
297
+ await vitest.advanceTimersToNextTimerAsync();
298
+
299
+ expect(keys.decryptionFailure).toHaveBeenCalledTimes(1);
300
+ expect(keys.decryptionFailure).toHaveBeenCalledWith(1);
301
+ expect(errorListener).toHaveBeenCalled();
302
+ } finally {
303
+ vitest.useRealTimers();
304
+ }
305
+ });
240
306
 
241
- expect(keys.hasValidKey).toBe(false);
307
+ it('immediately drops frame if no key', async () => {
308
+ vitest.useFakeTimers();
309
+ try {
310
+ const { input, output } = prepareParticipantTestDecoder(participantIdentity, {});
242
311
 
243
- await keys.setKey(material, 0);
312
+ vitest.spyOn(crypto.subtle, 'decrypt');
244
313
 
245
- expect(keys.hasValidKey).toBe(true);
246
- });
314
+ input.write(mockEncryptedRTCEncodedVideoFrame(1));
315
+ await vitest.advanceTimersToNextTimerAsync();
247
316
 
248
- it('mark as valid when a new key is set on new index', async () => {
249
- const { keys, input } = prepareParticipantTestDecoder(participantIdentity, {
250
- failureTolerance: 0,
317
+ expect(crypto.subtle.decrypt).not.toHaveBeenCalled();
318
+ expect(output.chunks).toEqual([]);
319
+ } finally {
320
+ vitest.useRealTimers();
321
+ }
251
322
  });
252
323
 
253
- const material = await createKeyMaterialFromString('password');
254
- await keys.setKey(material, 0);
324
+ it('calls decryptionFailure with incorrect key and emits error', async () => {
325
+ vitest.useFakeTimers();
326
+ try {
327
+ const { cryptor, keys, input, output } = prepareParticipantTestDecoder(
328
+ participantIdentity,
329
+ { ratchetWindowSize: 0 },
330
+ );
331
+
332
+ vitest.spyOn(crypto.subtle, 'decrypt');
333
+ vitest.spyOn(keys, 'decryptionFailure');
334
+ const errorListener = vitest.fn();
335
+ cryptor.on(CryptorEvent.Error, errorListener);
336
+
337
+ await keys.setKey(await createKeyMaterialFromString('incorrect key'), 1);
338
+
339
+ const frame = mockRTCEncodedVideoFrame(
340
+ new Uint8Array([
341
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 254, 96, 91, 111, 187, 132, 31, 12, 207, 136, 17, 221,
342
+ 233, 116, 174, 6, 50, 37, 214, 71, 119, 196, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255,
343
+ 199, 51, 12, 1,
344
+ ]),
345
+ );
346
+ // global.RTCEncodedAudioFrame = vitest.fn();
347
+ input.write(frame);
348
+ await vitest.waitFor(() => expect(keys.decryptionFailure).toHaveBeenCalled());
349
+
350
+ expect(crypto.subtle.decrypt).toHaveBeenCalled();
351
+ expect(output.chunks).toEqual([]);
352
+ expect(errorListener).toHaveBeenCalled();
353
+ expect(keys.decryptionFailure).toHaveBeenCalledTimes(1);
354
+ expect(keys.decryptionFailure).toHaveBeenCalledWith(1);
355
+ } finally {
356
+ vitest.useRealTimers();
357
+ }
358
+ });
359
+
360
+ it('decrypts frame with correct key', async () => {
361
+ vitest.useFakeTimers();
362
+ try {
363
+ const { keys, input, output } = prepareParticipantTestDecoder(participantIdentity, {});
364
+
365
+ vitest.spyOn(keys, 'decryptionSuccess');
255
366
 
256
- expect(keys.hasValidKey).toBe(true);
367
+ await keys.setKey(await createKeyMaterialFromString('key1'), 1);
257
368
 
258
- input.write(mockEncryptedRTCEncodedVideoFrame(1));
369
+ const frame = mockRTCEncodedVideoFrame(
370
+ new Uint8Array([
371
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 254, 96, 91, 111, 187, 132, 31, 12, 207, 136, 17, 221,
372
+ 233, 116, 174, 6, 50, 37, 214, 71, 119, 196, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255,
373
+ 199, 51, 12, 1,
374
+ ]),
375
+ );
376
+ input.write(frame);
377
+ await vitest.waitFor(() => expect(output.chunks).toHaveLength(1));
259
378
 
260
- expect(keys.hasValidKey).toBe(false);
379
+ expect(output.chunks).toEqual([frame]);
261
380
 
262
- await keys.setKey(material, 1);
381
+ expect(keys.decryptionSuccess).toHaveBeenCalledTimes(1);
382
+ expect(keys.decryptionSuccess).toHaveBeenCalledWith(1);
263
383
 
264
- expect(keys.hasValidKey).toBe(true);
384
+ expect(frame.data.byteLength).toBe(16);
385
+
386
+ expect(new Uint8Array(frame.data)).toEqual(
387
+ new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
388
+ );
389
+ } finally {
390
+ vitest.useRealTimers();
391
+ }
392
+ });
393
+
394
+ it('recovers from delayed use of rotated key', async () => {
395
+ vitest.useFakeTimers();
396
+ try {
397
+ // 1. we (the local participant) have just joined a room and do not have the existing key (index 0) for the existing/remote participant
398
+ const { keys, input, output } = prepareParticipantTestDecoder(participantIdentity, {
399
+ failureTolerance: 1,
400
+ ratchetWindowSize: 0,
401
+ });
402
+ vitest.spyOn(keys, 'decryptionFailure');
403
+
404
+ // 2. we receive some frames from the existing participant encrypted with the existing key 0 that we don't have
405
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
406
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
407
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
408
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
409
+
410
+ // 3. we should have marked key at index 0 as invalid by now and dropped all the frames
411
+ await vitest.waitFor(() => expect(keys.decryptionFailure).toHaveBeenCalledTimes(2));
412
+ expect(keys.hasInvalidKeyAtIndex(0)).toBe(true);
413
+ expect(output.chunks).toEqual([]);
414
+
415
+ // 4. the existing participant then notices that we have joined the room and generates a new key (with a new key index 1)
416
+ // and distributes it out of band to us
417
+ await keys.setKey(await createKeyMaterialFromString('key1'), 1);
418
+
419
+ // 5. the existing participant waits a period of time before using the new key and continues sending media using the previous key 0.
420
+ // we receive these frames and should drop them as we still don't have the key.
421
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
422
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
423
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
424
+ input.write(mockEncryptedRTCEncodedVideoFrame(0));
425
+
426
+ await vitest.advanceTimersToNextTimerAsync();
427
+ expect(output.chunks).toEqual([]);
428
+
429
+ // 6. the existing participant moves over to the new key index 1 and we start to receive frames for index 1 that we
430
+ // should be able to decrypt even though we had the previous failures.
431
+ input.write(
432
+ mockRTCEncodedVideoFrame(
433
+ new Uint8Array([
434
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 254, 96, 91, 111, 187, 132, 31, 12, 207, 136, 17, 221,
435
+ 233, 116, 174, 6, 50, 37, 214, 71, 119, 196, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255,
436
+ 199, 51, 12, 1,
437
+ ]),
438
+ ),
439
+ );
440
+
441
+ input.write(
442
+ mockRTCEncodedVideoFrame(
443
+ new Uint8Array([
444
+ 99, 2, 3, 4, 5, 6, 7, 8, 9, 10, 154, 108, 209, 239, 253, 33, 72, 111, 13, 125, 10,
445
+ 101, 28, 209, 141, 162, 0, 238, 189, 254, 66, 156, 255, 255, 255, 255, 0, 0, 0, 0,
446
+ 255, 255, 96, 247, 12, 1,
447
+ ]),
448
+ ),
449
+ );
450
+
451
+ await vitest.waitFor(() => expect(output.chunks.length).toEqual(2));
452
+
453
+ expect(new Uint8Array(output.chunks[0].data)).toEqual(
454
+ new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
455
+ );
456
+ expect(new Uint8Array(output.chunks[1].data)).toEqual(
457
+ new Uint8Array([99, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
458
+ );
459
+ } finally {
460
+ vitest.useRealTimers();
461
+ }
462
+ });
265
463
  });
266
464
  });