@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.
- package/README.md +7 -7
- package/android/local.properties +8 -0
- package/lib/commonjs/audio/AudioManager.js +20 -12
- package/lib/commonjs/audio/AudioManager.js.map +1 -1
- package/lib/commonjs/components/VideoTrack.js +13 -0
- package/lib/commonjs/components/VideoTrack.js.map +1 -1
- package/lib/commonjs/e2ee/RNE2EEManager.js +115 -0
- package/lib/commonjs/e2ee/RNE2EEManager.js.map +1 -0
- package/lib/commonjs/e2ee/RNKeyProvider.js +104 -0
- package/lib/commonjs/e2ee/RNKeyProvider.js.map +1 -0
- package/lib/commonjs/hooks/useE2EEManager.js +38 -0
- package/lib/commonjs/hooks/useE2EEManager.js.map +1 -0
- package/lib/commonjs/hooks.js +42 -0
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/commonjs/index.js +18 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/audio/AudioManager.js +20 -12
- package/lib/module/audio/AudioManager.js.map +1 -1
- package/lib/module/components/VideoTrack.js +14 -0
- package/lib/module/components/VideoTrack.js.map +1 -1
- package/lib/module/e2ee/RNE2EEManager.js +107 -0
- package/lib/module/e2ee/RNE2EEManager.js.map +1 -0
- package/lib/module/e2ee/RNKeyProvider.js +97 -0
- package/lib/module/e2ee/RNKeyProvider.js.map +1 -0
- package/lib/module/hooks/useE2EEManager.js +31 -0
- package/lib/module/hooks/useE2EEManager.js.map +1 -0
- package/lib/module/hooks.js +1 -0
- package/lib/module/hooks.js.map +1 -1
- package/lib/module/index.js +4 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/lib/commonjs/components/VideoTrack.d.ts +12 -0
- package/lib/typescript/lib/commonjs/e2ee/RNE2EEManager.d.ts +23 -0
- package/lib/typescript/lib/commonjs/e2ee/RNKeyProvider.d.ts +33 -0
- package/lib/typescript/lib/commonjs/hooks/useE2EEManager.d.ts +8 -0
- package/lib/typescript/lib/commonjs/index.d.ts +2 -0
- package/lib/typescript/lib/module/e2ee/RNE2EEManager.d.ts +21 -0
- package/lib/typescript/lib/module/e2ee/RNKeyProvider.d.ts +30 -0
- package/lib/typescript/lib/module/hooks/useE2EEManager.d.ts +9 -0
- package/lib/typescript/lib/module/hooks.d.ts +1 -0
- package/lib/typescript/lib/module/index.d.ts +3 -1
- package/lib/typescript/src/components/VideoTrack.d.ts +46 -0
- package/lib/typescript/src/e2ee/RNE2EEManager.d.ts +27 -0
- package/lib/typescript/src/e2ee/RNKeyProvider.d.ts +35 -0
- package/lib/typescript/src/hooks/useE2EEManager.d.ts +15 -0
- package/lib/typescript/src/hooks.d.ts +2 -0
- package/lib/typescript/src/index.d.ts +4 -2
- package/package.json +5 -4
- package/src/audio/AudioManager.ts +30 -18
- package/src/components/VideoTrack.tsx +48 -0
- package/src/e2ee/RNE2EEManager.ts +199 -0
- package/src/e2ee/RNKeyProvider.ts +116 -0
- package/src/hooks/useE2EEManager.ts +49 -0
- package/src/hooks.ts +2 -0
- package/src/index.tsx +5 -0
package/lib/module/index.js.map
CHANGED
|
@@ -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":"AAAA,SAASA,eAAe,IAAIC,qBAAqB,QAAQ,8BAA8B;AACvF,SAASC,gBAAgB,QAAQ,2BAA2B;AAC5D,OAAO,2CAA2C;AAClD,OAAOC,YAAY,IACjBC,uBAAuB,EAOvBC,wCAAwC,QACnC,sBAAsB;AAE7B,SAASC,UAAU,EAAEC,QAAQ,QAAQ,cAAc;
|
|
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
|
+
}
|
|
@@ -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';
|
|
@@ -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.
|
|
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
|
-
"
|
|
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.
|
|
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.
|
|
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 {
|
|
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
|
-
|
|
58
|
+
let onLocalPublished = (publication: LocalTrackPublication) => {
|
|
59
|
+
if (publication.kind === 'audio') {
|
|
60
|
+
setLocalTrackCount(localTrackCount + 1);
|
|
61
|
+
}
|
|
55
62
|
};
|
|
56
|
-
let onLocalUnpublished = () => {
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
73
|
+
let onRemotePublished = (publication: RemoteTrackPublication) => {
|
|
74
|
+
if (publication.kind === 'audio') {
|
|
75
|
+
setRemoteTrackCount(remoteTrackCount + 1);
|
|
76
|
+
}
|
|
66
77
|
};
|
|
67
|
-
let onRemoteUnpublished = () => {
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
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;
|