@livekit/react-native 2.4.2 → 2.5.0

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.
Files changed (54) hide show
  1. package/README.md +7 -7
  2. package/android/local.properties +8 -0
  3. package/lib/commonjs/audio/AudioManager.js +20 -12
  4. package/lib/commonjs/audio/AudioManager.js.map +1 -1
  5. package/lib/commonjs/components/VideoTrack.js +13 -0
  6. package/lib/commonjs/components/VideoTrack.js.map +1 -1
  7. package/lib/commonjs/e2ee/RNE2EEManager.js +115 -0
  8. package/lib/commonjs/e2ee/RNE2EEManager.js.map +1 -0
  9. package/lib/commonjs/e2ee/RNKeyProvider.js +104 -0
  10. package/lib/commonjs/e2ee/RNKeyProvider.js.map +1 -0
  11. package/lib/commonjs/hooks/useE2EEManager.js +38 -0
  12. package/lib/commonjs/hooks/useE2EEManager.js.map +1 -0
  13. package/lib/commonjs/hooks.js +42 -0
  14. package/lib/commonjs/hooks.js.map +1 -1
  15. package/lib/commonjs/index.js +18 -1
  16. package/lib/commonjs/index.js.map +1 -1
  17. package/lib/module/audio/AudioManager.js +20 -12
  18. package/lib/module/audio/AudioManager.js.map +1 -1
  19. package/lib/module/components/VideoTrack.js +14 -0
  20. package/lib/module/components/VideoTrack.js.map +1 -1
  21. package/lib/module/e2ee/RNE2EEManager.js +107 -0
  22. package/lib/module/e2ee/RNE2EEManager.js.map +1 -0
  23. package/lib/module/e2ee/RNKeyProvider.js +97 -0
  24. package/lib/module/e2ee/RNKeyProvider.js.map +1 -0
  25. package/lib/module/hooks/useE2EEManager.js +31 -0
  26. package/lib/module/hooks/useE2EEManager.js.map +1 -0
  27. package/lib/module/hooks.js +1 -0
  28. package/lib/module/hooks.js.map +1 -1
  29. package/lib/module/index.js +4 -1
  30. package/lib/module/index.js.map +1 -1
  31. package/lib/typescript/lib/commonjs/components/VideoTrack.d.ts +12 -0
  32. package/lib/typescript/lib/commonjs/e2ee/RNE2EEManager.d.ts +23 -0
  33. package/lib/typescript/lib/commonjs/e2ee/RNKeyProvider.d.ts +33 -0
  34. package/lib/typescript/lib/commonjs/hooks/useE2EEManager.d.ts +8 -0
  35. package/lib/typescript/lib/commonjs/index.d.ts +2 -0
  36. package/lib/typescript/lib/module/e2ee/RNE2EEManager.d.ts +21 -0
  37. package/lib/typescript/lib/module/e2ee/RNKeyProvider.d.ts +30 -0
  38. package/lib/typescript/lib/module/hooks/useE2EEManager.d.ts +9 -0
  39. package/lib/typescript/lib/module/hooks.d.ts +1 -0
  40. package/lib/typescript/lib/module/index.d.ts +3 -1
  41. package/lib/typescript/src/components/VideoTrack.d.ts +46 -0
  42. package/lib/typescript/src/e2ee/RNE2EEManager.d.ts +27 -0
  43. package/lib/typescript/src/e2ee/RNKeyProvider.d.ts +35 -0
  44. package/lib/typescript/src/hooks/useE2EEManager.d.ts +15 -0
  45. package/lib/typescript/src/hooks.d.ts +2 -0
  46. package/lib/typescript/src/index.d.ts +4 -2
  47. package/package.json +5 -4
  48. package/src/audio/AudioManager.ts +30 -18
  49. package/src/components/VideoTrack.tsx +48 -0
  50. package/src/e2ee/RNE2EEManager.ts +199 -0
  51. package/src/e2ee/RNKeyProvider.ts +116 -0
  52. package/src/hooks/useE2EEManager.ts +49 -0
  53. package/src/hooks.ts +2 -0
  54. package/src/index.tsx +5 -0
@@ -1 +1 @@
1
- {"version":3,"names":["registerGlobals","webrtcRegisterGlobals","setupURLPolyfill","AudioSession","AndroidAudioTypePresets","getDefaultAppleAudioConfigurationForMode","PixelRatio","Platform","iosCategoryEnforce","livekitRegisterGlobals","fixWebrtcAdapter","shimPromiseAllSettled","shimArrayAt","shimAsyncIterator","shimIterator","OS","getUserMediaFunc","global","navigator","mediaDevices","getUserMedia","constraints","audio","setAppleAudioConfiguration","audioCategory","lkGlobal","platform","devicePixelRatio","get","LiveKitReactNativeGlobal","_window","window","undefined","userAgent","product","allSettled","require","shim","Array","prototype","at"],"sources":["index.tsx"],"sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from '@livekit/react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport './polyfills/EncoderDecoderTogether.min.js';\nimport AudioSession, {\n AndroidAudioTypePresets,\n type AndroidAudioTypeOptions,\n type AppleAudioCategory,\n type AppleAudioCategoryOption,\n type AppleAudioConfiguration,\n type AppleAudioMode,\n type AudioTrackState,\n getDefaultAppleAudioConfigurationForMode,\n} from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\nimport { PixelRatio, Platform } from 'react-native';\nimport { type LiveKitReactNativeInfo } from 'livekit-client';\nimport type { LogLevel, SetLogLevelOptions } from './logger';\n\n/**\n * Registers the required globals needed for LiveKit to work.\n *\n * Must be called before using LiveKit.\n */\nexport function registerGlobals() {\n webrtcRegisterGlobals();\n iosCategoryEnforce();\n livekitRegisterGlobals();\n setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\n shimArrayAt();\n shimAsyncIterator();\n shimIterator();\n}\n\n/**\n * Enforces changing to playAndRecord category prior to obtaining microphone.\n */\nfunction iosCategoryEnforce() {\n if (Platform.OS === 'ios') {\n // @ts-ignore\n let getUserMediaFunc = global.navigator.mediaDevices.getUserMedia;\n // @ts-ignore\n global.navigator.mediaDevices.getUserMedia = async (constraints: any) => {\n if (constraints.audio) {\n await AudioSession.setAppleAudioConfiguration({\n audioCategory: 'playAndRecord',\n });\n }\n\n return await getUserMediaFunc(constraints);\n };\n }\n}\n\nfunction livekitRegisterGlobals() {\n let lkGlobal: LiveKitReactNativeInfo = {\n platform: Platform.OS,\n devicePixelRatio: PixelRatio.get(),\n };\n\n // @ts-ignore\n global.LiveKitReactNativeGlobal = lkGlobal;\n}\n\nfunction fixWebrtcAdapter() {\n // @ts-ignore\n if (window?.navigator !== undefined) {\n // @ts-ignore\n const { navigator } = window;\n if (navigator.userAgent === undefined) {\n navigator.userAgent = navigator.product ?? 'Unknown';\n }\n }\n}\n\nfunction shimPromiseAllSettled() {\n var allSettled = require('promise.allsettled');\n allSettled.shim();\n}\n\nfunction shimArrayAt() {\n // Some versions of RN don't have Array.prototype.at, which is used by sdp-transform\n if (!Array.prototype.at) {\n var at = require('array.prototype.at');\n at.shim();\n }\n}\n\nfunction shimAsyncIterator() {\n var shim = require('well-known-symbols/Symbol.asyncIterator/shim');\n shim();\n}\n\nfunction shimIterator() {\n var shim = require('well-known-symbols/Symbol.iterator/shim');\n shim();\n}\nexport * from './hooks';\nexport * from './components/LiveKitRoom';\nexport * from './components/VideoTrack';\nexport * from './components/VideoView'; // deprecated\nexport * from './useParticipant'; // deprecated\nexport * from './useRoom'; // deprecated\nexport * from './logger';\nexport * from './audio/AudioManager';\n\nexport {\n AudioSession,\n AndroidAudioTypePresets,\n getDefaultAppleAudioConfigurationForMode,\n};\nexport type {\n AudioConfiguration,\n AndroidAudioTypeOptions,\n AppleAudioCategory,\n AppleAudioCategoryOption,\n AppleAudioConfiguration,\n AppleAudioMode,\n AudioTrackState,\n LogLevel,\n SetLogLevelOptions,\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["registerGlobals","webrtcRegisterGlobals","setupURLPolyfill","AudioSession","AndroidAudioTypePresets","getDefaultAppleAudioConfigurationForMode","PixelRatio","Platform","RNE2EEManager","RNKeyProvider","iosCategoryEnforce","livekitRegisterGlobals","fixWebrtcAdapter","shimPromiseAllSettled","shimArrayAt","shimAsyncIterator","shimIterator","OS","getUserMediaFunc","global","navigator","mediaDevices","getUserMedia","constraints","audio","setAppleAudioConfiguration","audioCategory","lkGlobal","platform","devicePixelRatio","get","LiveKitReactNativeGlobal","_window","window","undefined","userAgent","product","allSettled","require","shim","Array","prototype","at"],"sources":["index.tsx"],"sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from '@livekit/react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport './polyfills/EncoderDecoderTogether.min.js';\nimport AudioSession, {\n AndroidAudioTypePresets,\n type AndroidAudioTypeOptions,\n type AppleAudioCategory,\n type AppleAudioCategoryOption,\n type AppleAudioConfiguration,\n type AppleAudioMode,\n type AudioTrackState,\n getDefaultAppleAudioConfigurationForMode,\n} from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\nimport { PixelRatio, Platform } from 'react-native';\nimport { type LiveKitReactNativeInfo } from 'livekit-client';\nimport type { LogLevel, SetLogLevelOptions } from './logger';\nimport RNE2EEManager from './e2ee/RNE2EEManager';\nimport RNKeyProvider, { type RNKeyProviderOptions } from './e2ee/RNKeyProvider';\n\n/**\n * Registers the required globals needed for LiveKit to work.\n *\n * Must be called before using LiveKit.\n */\nexport function registerGlobals() {\n webrtcRegisterGlobals();\n iosCategoryEnforce();\n livekitRegisterGlobals();\n setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\n shimArrayAt();\n shimAsyncIterator();\n shimIterator();\n}\n\n/**\n * Enforces changing to playAndRecord category prior to obtaining microphone.\n */\nfunction iosCategoryEnforce() {\n if (Platform.OS === 'ios') {\n // @ts-ignore\n let getUserMediaFunc = global.navigator.mediaDevices.getUserMedia;\n // @ts-ignore\n global.navigator.mediaDevices.getUserMedia = async (constraints: any) => {\n if (constraints.audio) {\n await AudioSession.setAppleAudioConfiguration({\n audioCategory: 'playAndRecord',\n });\n }\n\n return await getUserMediaFunc(constraints);\n };\n }\n}\n\nfunction livekitRegisterGlobals() {\n let lkGlobal: LiveKitReactNativeInfo = {\n platform: Platform.OS,\n devicePixelRatio: PixelRatio.get(),\n };\n\n // @ts-ignore\n global.LiveKitReactNativeGlobal = lkGlobal;\n}\n\nfunction fixWebrtcAdapter() {\n // @ts-ignore\n if (window?.navigator !== undefined) {\n // @ts-ignore\n const { navigator } = window;\n if (navigator.userAgent === undefined) {\n navigator.userAgent = navigator.product ?? 'Unknown';\n }\n }\n}\n\nfunction shimPromiseAllSettled() {\n var allSettled = require('promise.allsettled');\n allSettled.shim();\n}\n\nfunction shimArrayAt() {\n // Some versions of RN don't have Array.prototype.at, which is used by sdp-transform\n if (!Array.prototype.at) {\n var at = require('array.prototype.at');\n at.shim();\n }\n}\n\nfunction shimAsyncIterator() {\n var shim = require('well-known-symbols/Symbol.asyncIterator/shim');\n shim();\n}\n\nfunction shimIterator() {\n var shim = require('well-known-symbols/Symbol.iterator/shim');\n shim();\n}\nexport * from './hooks';\nexport * from './components/LiveKitRoom';\nexport * from './components/VideoTrack';\nexport * from './components/VideoView'; // deprecated\nexport * from './useParticipant'; // deprecated\nexport * from './useRoom'; // deprecated\nexport * from './logger';\nexport * from './audio/AudioManager';\n\nexport {\n AudioSession,\n RNE2EEManager,\n RNKeyProvider,\n AndroidAudioTypePresets,\n getDefaultAppleAudioConfigurationForMode,\n};\nexport type {\n AudioConfiguration,\n AndroidAudioTypeOptions,\n AppleAudioCategory,\n AppleAudioCategoryOption,\n AppleAudioConfiguration,\n AppleAudioMode,\n AudioTrackState,\n LogLevel,\n SetLogLevelOptions,\n RNKeyProviderOptions,\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1,4 +1,16 @@
1
1
  export const __esModule: boolean;
2
+ /**
3
+ * Props for the VideoTrack component.
4
+ * @public
5
+ */
6
+ /**
7
+ * VideoTrack component for displaying video tracks in a React Native application.
8
+ * It supports both local and remote video tracks from LiveKit, and handles adaptive streaming for remote tracks.
9
+ *
10
+ * @param props - See VideoTrackProps for details.
11
+ * @returns A React component that renders the given video track.
12
+ * @public
13
+ */
2
14
  export function VideoTrack({ style, trackRef, objectFit, zOrder, mirror }: {
3
15
  style?: {} | undefined;
4
16
  trackRef: any;
@@ -0,0 +1,23 @@
1
+ export const __esModule: boolean;
2
+ export default RNE2EEManager;
3
+ declare const RNE2EEManager_base: any;
4
+ /**
5
+ * @experimental
6
+ */
7
+ declare class RNE2EEManager extends RNE2EEManager_base {
8
+ [x: string]: any;
9
+ constructor(keyProvider: any);
10
+ keyProvider: any;
11
+ encryptionEnabled: boolean;
12
+ setup(room: any): void;
13
+ room: any;
14
+ setupEventListeners(room: any): void;
15
+ setupE2EESender(publication: any, participant: any): Promise<void>;
16
+ setupE2EEReceiver(publication: any, participant: any): Promise<void>;
17
+ setSifTrailer(trailer: any): void;
18
+ findTrackCryptor(trackId: any): any;
19
+ createFrameCryptorForSender(sender: any, participantId: any): any;
20
+ createFrameCryptorForReceiver(receiver: any, participantId: any): any;
21
+ setupEngine(_engine: any): void;
22
+ setParticipantCryptorEnabled(enabled: any, participantIdentity: any): void;
23
+ }
@@ -0,0 +1,33 @@
1
+ export const __esModule: boolean;
2
+ export default RNKeyProvider;
3
+ declare const RNKeyProvider_base: any;
4
+ /**
5
+ * Options for construction an RNKeyProvider
6
+ */
7
+ /**
8
+ * @experimental
9
+ */
10
+ declare class RNKeyProvider extends RNKeyProvider_base {
11
+ [x: string]: any;
12
+ constructor(options: any);
13
+ nativeKeyProvider: any;
14
+ getLatestKeyIndex(participantId: any): any;
15
+ /**
16
+ * Accepts a passphrase that's used to create the crypto keys.
17
+ * @param key
18
+ */
19
+ setSharedKey(key: any, keyIndex: any): Promise<any>;
20
+ ratchetSharedKey(keyIndex: any): Promise<void>;
21
+ /**
22
+ * Accepts a passphrase that's used to create the crypto keys for a participant's stream.
23
+ * @param key
24
+ */
25
+ setKey(participantId: any, key: any, keyIndex: any): Promise<any>;
26
+ ratchetKey(participantIdentity: any, keyIndex: any): Promise<void>;
27
+ setSifTrailer(trailer: any): Promise<any>;
28
+ /**
29
+ * @internal
30
+ */
31
+ get rtcKeyProvider(): any;
32
+ dispose(): void;
33
+ }
@@ -0,0 +1,8 @@
1
+ export const __esModule: boolean;
2
+ /**
3
+ * @experimental
4
+ */
5
+ export function useRNE2EEManager(options: any): {
6
+ keyProvider: any;
7
+ e2eeManager: any;
8
+ };
@@ -1,6 +1,8 @@
1
1
  export const __esModule: boolean;
2
2
  export const AndroidAudioTypePresets: any;
3
3
  export const AudioSession: any;
4
+ export const RNE2EEManager: any;
5
+ export const RNKeyProvider: any;
4
6
  export const getDefaultAppleAudioConfigurationForMode: any;
5
7
  /**
6
8
  * Registers the required globals needed for LiveKit to work.
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * @experimental
4
+ */
5
+ export default class RNE2EEManager extends EventEmitter<[never]> {
6
+ constructor(keyProvider: any);
7
+ keyProvider: any;
8
+ encryptionEnabled: boolean;
9
+ setup(room: any): void;
10
+ room: any;
11
+ setupEventListeners(room: any): void;
12
+ setupE2EESender(publication: any, participant: any): Promise<void>;
13
+ setupE2EEReceiver(publication: any, participant: any): Promise<void>;
14
+ setSifTrailer(trailer: any): void;
15
+ findTrackCryptor(trackId: any): any;
16
+ createFrameCryptorForSender(sender: any, participantId: any): import("@livekit/react-native-webrtc").RTCFrameCryptor;
17
+ createFrameCryptorForReceiver(receiver: any, participantId: any): import("@livekit/react-native-webrtc").RTCFrameCryptor;
18
+ setupEngine(_engine: any): void;
19
+ setParticipantCryptorEnabled(enabled: any, participantIdentity: any): void;
20
+ }
21
+ import EventEmitter from 'events';
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Options for construction an RNKeyProvider
3
+ */
4
+ /**
5
+ * @experimental
6
+ */
7
+ export default class RNKeyProvider extends BaseKeyProvider {
8
+ constructor(options: any);
9
+ nativeKeyProvider: import("@livekit/react-native-webrtc").RTCKeyProvider;
10
+ getLatestKeyIndex(participantId: any): any;
11
+ /**
12
+ * Accepts a passphrase that's used to create the crypto keys.
13
+ * @param key
14
+ */
15
+ setSharedKey(key: any, keyIndex: any): Promise<any>;
16
+ ratchetSharedKey(keyIndex: any): Promise<void>;
17
+ /**
18
+ * Accepts a passphrase that's used to create the crypto keys for a participant's stream.
19
+ * @param key
20
+ */
21
+ setKey(participantId: any, key: any, keyIndex: any): Promise<any>;
22
+ ratchetKey(participantIdentity: any, keyIndex: any): Promise<void>;
23
+ setSifTrailer(trailer: any): Promise<any>;
24
+ /**
25
+ * @internal
26
+ */
27
+ get rtcKeyProvider(): import("@livekit/react-native-webrtc").RTCKeyProvider;
28
+ dispose(): void;
29
+ }
30
+ import { BaseKeyProvider } from 'livekit-client';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @experimental
3
+ */
4
+ export function useRNE2EEManager(options: any): {
5
+ keyProvider: RNKeyProvider;
6
+ e2eeManager: RNE2EEManager;
7
+ };
8
+ import { RNKeyProvider } from '..';
9
+ import RNE2EEManager from '../e2ee/RNE2EEManager';
@@ -1 +1,2 @@
1
+ export * from "./hooks/useE2EEManager";
1
2
  export { useConnectionState, useDataChannel, useIsSpeaking, useLocalParticipant, useLocalParticipantPermissions, useParticipantInfo, useParticipants, useRemoteParticipants, useRemoteParticipant, useSpeakingParticipants, useSortedParticipants, useChat, useIsEncrypted, useRoomInfo, useIsMuted, useParticipantTracks, useLiveKitRoom, RoomContext, useRoomContext, ParticipantContext, useParticipantContext, TrackRefContext, useTrackRefContext, useTracks, isTrackReference, useEnsureTrackRef, useTrackMutedIndicator, useVisualStableUpdate } from "@livekit/components-react";
@@ -13,6 +13,8 @@ export * from "./useRoom";
13
13
  export * from "./logger";
14
14
  export * from "./audio/AudioManager";
15
15
  import AudioSession from './audio/AudioSession';
16
+ import RNE2EEManager from './e2ee/RNE2EEManager';
17
+ import RNKeyProvider from './e2ee/RNKeyProvider';
16
18
  import { AndroidAudioTypePresets } from './audio/AudioSession';
17
19
  import { getDefaultAppleAudioConfigurationForMode } from './audio/AudioSession';
18
- export { AudioSession, AndroidAudioTypePresets, getDefaultAppleAudioConfigurationForMode };
20
+ export { AudioSession, RNE2EEManager, RNKeyProvider, AndroidAudioTypePresets, getDefaultAppleAudioConfigurationForMode };
@@ -1,11 +1,57 @@
1
1
  import * as React from 'react';
2
2
  import { type ViewStyle } from 'react-native';
3
3
  import type { TrackReference } from '@livekit/components-react';
4
+ /**
5
+ * Props for the VideoTrack component.
6
+ * @public
7
+ */
4
8
  export type VideoTrackProps = {
9
+ /**
10
+ * The track reference to display. This should be a TrackReference object
11
+ * or undefined if no track is available.
12
+ */
5
13
  trackRef: TrackReference | undefined;
14
+ /**
15
+ * Custom React Native styles for the video container.
16
+ */
6
17
  style?: ViewStyle;
18
+ /**
19
+ * Specifies how the video content should be resized to fit its container.
20
+ * 'cover' (default): The video will fill the entire container, potentially cropping the video.
21
+ * 'contain': The entire video will be visible within the container, potentially leaving empty space.
22
+ */
7
23
  objectFit?: 'cover' | 'contain' | undefined;
24
+ /**
25
+ * Indicates whether the video should be mirrored during rendering.
26
+ * This is commonly used for front-facing cameras.
27
+ */
8
28
  mirror?: boolean;
29
+ /**
30
+ * Specifies the depth-stacking order of this video view in the stacking space of all video views.
31
+ * A larger zOrder value generally causes the view to cover those with lower values.
32
+ *
33
+ * The support for zOrder is platform-dependent and/or
34
+ * implementation-specific. Thus, specifying a value for zOrder is to be
35
+ * thought of as giving a hint rather than as imposing a requirement. For
36
+ * example, video renderers such as RTCView are commonly implemented using
37
+ * OpenGL and OpenGL views may have different numbers of layers in their
38
+ * stacking space. Android has three: a layer bellow the window (aka
39
+ * default), a layer bellow the window again but above the previous layer
40
+ * (aka media overlay), and above the window. Consequently, it is advisable
41
+ * to limit the number of utilized layers in the stacking space to the
42
+ * minimum sufficient for the desired display. For example, a video call
43
+ * application usually needs a maximum of two zOrder values: 0 for the
44
+ * remote video(s) which appear in the background, and 1 for the local
45
+ * video(s) which appear above the remote video(s).
46
+ */
9
47
  zOrder?: number;
10
48
  };
49
+ /**
50
+ * VideoTrack component for displaying video tracks in a React Native application.
51
+ * It supports both local and remote video tracks from LiveKit, and handles adaptive streaming for remote tracks.
52
+ *
53
+ * @param props - See VideoTrackProps for details.
54
+ * @returns A React component that renders the given video track.
55
+ * @public
56
+ */
11
57
  export declare const VideoTrack: ({ style, trackRef, objectFit, zOrder, mirror, }: VideoTrackProps) => React.JSX.Element;
@@ -0,0 +1,27 @@
1
+ import { type Room, type BaseE2EEManager, type E2EEManagerCallbacks } from 'livekit-client';
2
+ import type RNKeyProvider from './RNKeyProvider';
3
+ import type RTCEngine from 'livekit-client/dist/src/room/RTCEngine';
4
+ import type TypedEventEmitter from 'typed-emitter';
5
+ declare const RNE2EEManager_base: new () => TypedEventEmitter<E2EEManagerCallbacks>;
6
+ /**
7
+ * @experimental
8
+ */
9
+ export default class RNE2EEManager extends RNE2EEManager_base implements BaseE2EEManager {
10
+ private room?;
11
+ private frameCryptors;
12
+ private keyProvider;
13
+ private algorithm;
14
+ private encryptionEnabled;
15
+ constructor(keyProvider: RNKeyProvider);
16
+ setup(room: Room): void;
17
+ private setupEventListeners;
18
+ private setupE2EESender;
19
+ private setupE2EEReceiver;
20
+ setSifTrailer(trailer: Uint8Array): void;
21
+ private findTrackCryptor;
22
+ private createFrameCryptorForSender;
23
+ private createFrameCryptorForReceiver;
24
+ setupEngine(_engine: RTCEngine): void;
25
+ setParticipantCryptorEnabled(enabled: boolean, participantIdentity: string): void;
26
+ }
27
+ export {};
@@ -0,0 +1,35 @@
1
+ import { BaseKeyProvider, type KeyProviderOptions } from 'livekit-client';
2
+ import { RTCKeyProvider } from '@livekit/react-native-webrtc';
3
+ /**
4
+ * Options for construction an RNKeyProvider
5
+ */
6
+ export type RNKeyProviderOptions = KeyProviderOptions & {
7
+ uncryptedMagicBytes?: string | Uint8Array;
8
+ };
9
+ /**
10
+ * @experimental
11
+ */
12
+ export default class RNKeyProvider extends BaseKeyProvider {
13
+ private latestSetIndex;
14
+ private nativeKeyProvider;
15
+ constructor(options: Partial<RNKeyProviderOptions>);
16
+ getLatestKeyIndex(participantId: string): number;
17
+ /**
18
+ * Accepts a passphrase that's used to create the crypto keys.
19
+ * @param key
20
+ */
21
+ setSharedKey(key: string | Uint8Array, keyIndex?: number): Promise<any>;
22
+ ratchetSharedKey(keyIndex?: number): Promise<void>;
23
+ /**
24
+ * Accepts a passphrase that's used to create the crypto keys for a participant's stream.
25
+ * @param key
26
+ */
27
+ setKey(participantId: string, key: string | Uint8Array, keyIndex?: number): Promise<any>;
28
+ ratchetKey(participantIdentity?: string, keyIndex?: number): Promise<void>;
29
+ setSifTrailer(trailer: Uint8Array): Promise<any>;
30
+ /**
31
+ * @internal
32
+ */
33
+ get rtcKeyProvider(): RTCKeyProvider;
34
+ dispose(): void;
35
+ }
@@ -0,0 +1,15 @@
1
+ import RNE2EEManager from '../e2ee/RNE2EEManager';
2
+ import { RNKeyProvider } from '..';
3
+ import type { RNKeyProviderOptions } from '../e2ee/RNKeyProvider';
4
+ export type UseRNE2EEManagerOptions = {
5
+ keyProviderOptions?: RNKeyProviderOptions;
6
+ sharedKey: string | Uint8Array;
7
+ };
8
+ export interface RNE2EEManagerState {
9
+ keyProvider: RNKeyProvider;
10
+ e2eeManager: RNE2EEManager;
11
+ }
12
+ /**
13
+ * @experimental
14
+ */
15
+ export declare function useRNE2EEManager(options: UseRNE2EEManagerOptions): RNE2EEManagerState;
@@ -1,3 +1,5 @@
1
1
  export { useConnectionState, useDataChannel, useIsSpeaking, useLocalParticipant, useLocalParticipantPermissions, useParticipantInfo, useParticipants, useRemoteParticipants, useRemoteParticipant, useSpeakingParticipants, useSortedParticipants, useChat, useIsEncrypted, useRoomInfo, useIsMuted, useParticipantTracks, useLiveKitRoom, RoomContext, useRoomContext, ParticipantContext, useParticipantContext, TrackRefContext, useTrackRefContext, useTracks, isTrackReference, useEnsureTrackRef, useTrackMutedIndicator, useVisualStableUpdate, } from '@livekit/components-react';
2
2
  export type { UseLocalParticipantOptions, UseParticipantInfoOptions, UseParticipantsOptions, UseRemoteParticipantOptions, UseRemoteParticipantsOptions, UseTracksOptions, TrackReference, TrackReferenceOrPlaceholder, UseVisualStableUpdateOptions, } from '@livekit/components-react';
3
3
  export type { ReceivedDataMessage } from '@livekit/components-core';
4
+ export * from './hooks/useE2EEManager';
5
+ export type { UseRNE2EEManagerOptions } from './hooks/useE2EEManager';
@@ -2,6 +2,8 @@ import './polyfills/EncoderDecoderTogether.min.js';
2
2
  import AudioSession, { AndroidAudioTypePresets, type AndroidAudioTypeOptions, type AppleAudioCategory, type AppleAudioCategoryOption, type AppleAudioConfiguration, type AppleAudioMode, type AudioTrackState, getDefaultAppleAudioConfigurationForMode } from './audio/AudioSession';
3
3
  import type { AudioConfiguration } from './audio/AudioSession';
4
4
  import type { LogLevel, SetLogLevelOptions } from './logger';
5
+ import RNE2EEManager from './e2ee/RNE2EEManager';
6
+ import RNKeyProvider, { type RNKeyProviderOptions } from './e2ee/RNKeyProvider';
5
7
  /**
6
8
  * Registers the required globals needed for LiveKit to work.
7
9
  *
@@ -16,5 +18,5 @@ export * from './useParticipant';
16
18
  export * from './useRoom';
17
19
  export * from './logger';
18
20
  export * from './audio/AudioManager';
19
- export { AudioSession, AndroidAudioTypePresets, getDefaultAppleAudioConfigurationForMode, };
20
- export type { AudioConfiguration, AndroidAudioTypeOptions, AppleAudioCategory, AppleAudioCategoryOption, AppleAudioConfiguration, AppleAudioMode, AudioTrackState, LogLevel, SetLogLevelOptions, };
21
+ export { AudioSession, RNE2EEManager, RNKeyProvider, AndroidAudioTypePresets, getDefaultAppleAudioConfigurationForMode, };
22
+ export type { AudioConfiguration, AndroidAudioTypeOptions, AppleAudioCategory, AppleAudioCategoryOption, AppleAudioConfiguration, AppleAudioMode, AudioTrackState, LogLevel, SetLogLevelOptions, RNKeyProviderOptions, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livekit/react-native",
3
- "version": "2.4.2",
3
+ "version": "2.5.0",
4
4
  "description": "LiveKit for React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -44,7 +44,8 @@
44
44
  "dependencies": {
45
45
  "@livekit/components-react": "^2.0.6",
46
46
  "array.prototype.at": "^1.1.1",
47
- "livekit-client": "^2.4.2",
47
+ "event-target-shim": "6.0.2",
48
+ "livekit-client": "^2.7.5",
48
49
  "loglevel": "^1.8.0",
49
50
  "promise.allsettled": "^1.0.5",
50
51
  "react-native-url-polyfill": "^1.3.0",
@@ -55,7 +56,7 @@
55
56
  "@babel/preset-env": "^7.20.0",
56
57
  "@babel/runtime": "^7.20.0",
57
58
  "@commitlint/config-conventional": "^16.2.1",
58
- "@livekit/react-native-webrtc": "^125.0.4",
59
+ "@livekit/react-native-webrtc": "^125.0.6",
59
60
  "@react-native/babel-preset": "0.74.84",
60
61
  "@react-native/eslint-config": "0.74.84",
61
62
  "@react-native/metro-config": "0.74.84",
@@ -81,7 +82,7 @@
81
82
  "typescript": "5.0.4"
82
83
  },
83
84
  "peerDependencies": {
84
- "@livekit/react-native-webrtc": "^125.0.4",
85
+ "@livekit/react-native-webrtc": "^125.0.6",
85
86
  "react": "*",
86
87
  "react-native": "*"
87
88
  },
@@ -1,6 +1,11 @@
1
1
  import { useState, useEffect, useMemo } from 'react';
2
2
  import { Platform } from 'react-native';
3
- import { RoomEvent, Room } from 'livekit-client';
3
+ import {
4
+ RoomEvent,
5
+ Room,
6
+ type LocalTrackPublication,
7
+ type RemoteTrackPublication,
8
+ } from 'livekit-client';
4
9
  import AudioSession, {
5
10
  getDefaultAppleAudioConfigurationForMode,
6
11
  type AppleAudioConfiguration,
@@ -50,27 +55,35 @@ export function useIOSAudioManagement(
50
55
  return () => {};
51
56
  }
52
57
 
53
- let onLocalPublished = () => {
54
- setLocalTrackCount(localTrackCount + 1);
58
+ let onLocalPublished = (publication: LocalTrackPublication) => {
59
+ if (publication.kind === 'audio') {
60
+ setLocalTrackCount(localTrackCount + 1);
61
+ }
55
62
  };
56
- let onLocalUnpublished = () => {
57
- if (localTrackCount - 1 < 0) {
58
- log.warn(
59
- 'mismatched local audio track count! attempted to reduce track count below zero.'
60
- );
63
+ let onLocalUnpublished = (publication: LocalTrackPublication) => {
64
+ if (publication.kind === 'audio') {
65
+ if (localTrackCount - 1 < 0) {
66
+ log.warn(
67
+ 'mismatched local audio track count! attempted to reduce track count below zero.'
68
+ );
69
+ }
70
+ setLocalTrackCount(Math.max(localTrackCount - 1, 0));
61
71
  }
62
- setLocalTrackCount(Math.max(localTrackCount - 1, 0));
63
72
  };
64
- let onRemotePublished = () => {
65
- setRemoteTrackCount(remoteTrackCount + 1);
73
+ let onRemotePublished = (publication: RemoteTrackPublication) => {
74
+ if (publication.kind === 'audio') {
75
+ setRemoteTrackCount(remoteTrackCount + 1);
76
+ }
66
77
  };
67
- let onRemoteUnpublished = () => {
68
- if (remoteTrackCount - 1 < 0) {
69
- log.warn(
70
- 'mismatched remote audio track count! attempted to reduce track count below zero.'
71
- );
78
+ let onRemoteUnpublished = (publication: RemoteTrackPublication) => {
79
+ if (publication.kind === 'audio') {
80
+ if (remoteTrackCount - 1 < 0) {
81
+ log.warn(
82
+ 'mismatched remote audio track count! attempted to reduce track count below zero.'
83
+ );
84
+ }
85
+ setRemoteTrackCount(Math.max(remoteTrackCount - 1, 0));
72
86
  }
73
- setRemoteTrackCount(Math.max(remoteTrackCount - 1, 0));
74
87
  };
75
88
 
76
89
  room
@@ -124,6 +137,5 @@ function getRemoteAudioTrackCount(room: Room): number {
124
137
  room.remoteParticipants.forEach((participant) => {
125
138
  audioTracks += participant.audioTrackPublications.size;
126
139
  });
127
-
128
140
  return audioTracks;
129
141
  }
@@ -18,14 +18,60 @@ import { RemoteVideoTrack } from 'livekit-client';
18
18
  import ViewPortDetector from './ViewPortDetector';
19
19
  import type { TrackReference } from '@livekit/components-react';
20
20
 
21
+ /**
22
+ * Props for the VideoTrack component.
23
+ * @public
24
+ */
21
25
  export type VideoTrackProps = {
26
+ /**
27
+ * The track reference to display. This should be a TrackReference object
28
+ * or undefined if no track is available.
29
+ */
22
30
  trackRef: TrackReference | undefined;
31
+ /**
32
+ * Custom React Native styles for the video container.
33
+ */
23
34
  style?: ViewStyle;
35
+ /**
36
+ * Specifies how the video content should be resized to fit its container.
37
+ * 'cover' (default): The video will fill the entire container, potentially cropping the video.
38
+ * 'contain': The entire video will be visible within the container, potentially leaving empty space.
39
+ */
24
40
  objectFit?: 'cover' | 'contain' | undefined;
41
+ /**
42
+ * Indicates whether the video should be mirrored during rendering.
43
+ * This is commonly used for front-facing cameras.
44
+ */
25
45
  mirror?: boolean;
46
+ /**
47
+ * Specifies the depth-stacking order of this video view in the stacking space of all video views.
48
+ * A larger zOrder value generally causes the view to cover those with lower values.
49
+ *
50
+ * The support for zOrder is platform-dependent and/or
51
+ * implementation-specific. Thus, specifying a value for zOrder is to be
52
+ * thought of as giving a hint rather than as imposing a requirement. For
53
+ * example, video renderers such as RTCView are commonly implemented using
54
+ * OpenGL and OpenGL views may have different numbers of layers in their
55
+ * stacking space. Android has three: a layer bellow the window (aka
56
+ * default), a layer bellow the window again but above the previous layer
57
+ * (aka media overlay), and above the window. Consequently, it is advisable
58
+ * to limit the number of utilized layers in the stacking space to the
59
+ * minimum sufficient for the desired display. For example, a video call
60
+ * application usually needs a maximum of two zOrder values: 0 for the
61
+ * remote video(s) which appear in the background, and 1 for the local
62
+ * video(s) which appear above the remote video(s).
63
+ */
26
64
  zOrder?: number;
27
65
  };
28
66
 
67
+ /**
68
+ * VideoTrack component for displaying video tracks in a React Native application.
69
+ * It supports both local and remote video tracks from LiveKit, and handles adaptive streaming for remote tracks.
70
+ *
71
+ * @param props - See VideoTrackProps for details.
72
+ * @returns A React component that renders the given video track.
73
+ * @public
74
+ */
29
75
  export const VideoTrack = ({
30
76
  style = {},
31
77
  trackRef,
@@ -130,6 +176,7 @@ class VideoTrackElementInfo implements ElementInfo {
130
176
  observe(): void {
131
177
  this._observing = true;
132
178
  }
179
+
133
180
  stopObserving(): void {
134
181
  this._observing = false;
135
182
  }
@@ -143,6 +190,7 @@ class VideoTrackElementInfo implements ElementInfo {
143
190
  this.handleResize?.();
144
191
  }
145
192
  }
193
+
146
194
  onVisibility(isVisible: boolean) {
147
195
  if (this.visible !== isVisible) {
148
196
  this.visible = isVisible;