@livekit/react-native 0.2.2 → 1.0.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 CHANGED
@@ -1,52 +1,64 @@
1
+ <!--BEGIN_BANNER_IMAGE--><!--END_BANNER_IMAGE-->
2
+
1
3
  # livekit-react-native
2
4
 
5
+ <!--BEGIN_DESCRIPTION-->
3
6
  LiveKit Client SDK for React Native. (beta)
7
+ <!--END_DESCRIPTION-->
8
+
9
+ > **Info**
10
+ > Beta status currently
4
11
 
5
12
  ## Installation
6
13
 
7
14
  ### NPM
15
+
8
16
  ```sh
9
- npm install https://github.com/livekit/client-sdk-react-native
17
+ npm install @livekit/react-native
10
18
  ```
11
19
 
12
20
  ### Yarn
21
+
13
22
  ```sh
14
- yarn add https://github.com/livekit/client-sdk-react-native
23
+ yarn add @livekit/react-native
15
24
  ```
16
25
 
17
- The `react-native-webrtc` library has additional installation instructions found here:
26
+ This library depends on `react-native-webrtc`, which has additional installation instructions found here:
18
27
 
19
- * [iOS Installation Guide](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/iOSInstallation.md)
20
- * [Android Installation Guide](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md)
28
+ - [iOS Installation Guide](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/iOSInstallation.md)
29
+ - [Android Installation Guide](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md)
21
30
 
22
31
  ## Example app
23
32
 
24
33
  We've included an [example app](example/) that you can try out.
25
34
 
35
+ ## Beta limitations
36
+
37
+ This library does not currently support simulcast due to a limitation with `react-native-webrtc`
38
+
26
39
  ## Usage
27
40
 
28
- In your `index.js` file, setup the LiveKit SDK by calling `registerGlobals()`.
41
+ In your `index.js` file, setup the LiveKit SDK by calling `registerGlobals()`.
29
42
  This sets up the required WebRTC libraries for use in Javascript, and is needed for LiveKit to work.
30
43
 
31
44
  ```js
32
- import { registerGlobals } from "livekit-react-native";
45
+ import { registerGlobals } from '@livekit/react-native';
33
46
 
34
47
  // ...
35
48
 
36
- registerGlobals()
49
+ registerGlobals();
37
50
  ```
38
51
 
39
52
  A Room object can then be created and connected to.
40
53
 
41
54
  ```js
42
-
43
55
  import { Participant, Room, Track } from 'livekit-client';
44
- import { useRoom, AudioSession, VideoView } from 'livekit-react-native';
56
+ import { useRoom, AudioSession, VideoView } from '@livekit/react-native';
45
57
 
46
58
  /*...*/
47
59
 
48
60
  // Create a room state
49
- const [room,] = useState(() => new Room());
61
+ const [room] = useState(() => new Room());
50
62
 
51
63
  // Get the participants from the room
52
64
  const { participants } = useRoom(room);
@@ -55,13 +67,16 @@ useEffect(() => {
55
67
  AudioSession.startAudioSession();
56
68
  room.connect(url, token, {});
57
69
  return () => {
58
- room.disconnect()
70
+ room.disconnect();
59
71
  AudioSession.stopAudioSession();
60
- }
72
+ };
61
73
  }, [url, token, room]);
62
74
 
63
75
  const videoView = participants.length > 0 && (
64
- <VideoView style={{flex:1, width:"100%"}} videoTrack={participants[0].getTrack(Track.Source.Camera)?.videoTrack} />
76
+ <VideoView
77
+ style={{ flex: 1, width: '100%' }}
78
+ videoTrack={participants[0].getTrack(Track.Source.Camera)?.videoTrack}
79
+ />
65
80
  );
66
81
  ```
67
82
 
@@ -81,7 +96,7 @@ The example app uses [@voximplant/react-native-foreground-service](https://githu
81
96
  Ensure that the service is labelled a `mediaProjection` service like so:
82
97
 
83
98
  ```
84
- <service android:name="com.voximplant.foregroundservice.VIForegroundService"
99
+ <service android:name="com.voximplant.foregroundservice.VIForegroundService"
85
100
  android:foregroundServiceType="mediaProjection" />
86
101
  ```
87
102
 
@@ -93,10 +108,10 @@ iOS screenshare requires adding a Broadcast Extension to your iOS project. Follo
93
108
 
94
109
  https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-ios-sdk/#screen-sharing-integration
95
110
 
96
- It involves copying the files found in this [sample project](https://github.com/jitsi/jitsi-meet-sdk-samples/tree/18c35f7625b38233579ff34f761f4c126ba7e03a/ios/swift-screensharing/JitsiSDKScreenSharingTest/Broadcast%20Extension)
111
+ It involves copying the files found in this [sample project](https://github.com/jitsi/jitsi-meet-sdk-samples/tree/18c35f7625b38233579ff34f761f4c126ba7e03a/ios/swift-screensharing/JitsiSDKScreenSharingTest/Broadcast%20Extension)
97
112
  to your iOS project, and registering a Broadcast Extension in Xcode.
98
113
 
99
- It's also recommended to use [CallKeep](https://github.com/react-native-webrtc/react-native-callkeep),
114
+ It's also recommended to use [CallKeep](https://github.com/react-native-webrtc/react-native-callkeep),
100
115
  to register a call with CallKit (as well as turning on the `voip` background mode).
101
116
  Due to background app processing limitations, screen recording may be interrupted if the app is restricted
102
117
  in the background. Registering with CallKit allows the app to continue processing for the duration of the call.
@@ -105,24 +120,22 @@ Once setup, iOS screenshare can be initiated like so:
105
120
 
106
121
  ```js
107
122
  const screenCaptureRef = React.useRef(null);
108
- const screenCapturePickerView = Platform.OS === "ios" && (
123
+ const screenCapturePickerView = Platform.OS === 'ios' && (
109
124
  <ScreenCapturePickerView ref={screenCaptureRef} />
110
125
  );
111
126
  const startBroadcast = async () => {
112
- if(Platform.OS === "ios") {
127
+ if (Platform.OS === 'ios') {
113
128
  const reactTag = findNodeHandle(screenCaptureRef.current);
114
129
  await NativeModules.ScreenCapturePickerViewManager.show(reactTag);
115
130
  room.localParticipant.setScreenShareEnabled(true);
116
- }
117
- else {
131
+ } else {
118
132
  room.localParticipant.setScreenShareEnabled(true);
119
133
  }
120
134
  };
121
135
 
122
136
  return (
123
137
  <View style={styles.container}>
124
- /*...*/
125
- // Make sure the ScreenCapturePickerView exists in the view tree.
138
+ /*...*/ // Make sure the ScreenCapturePickerView exists in the view tree.
126
139
  {screenCapturePickerView}
127
140
  </View>
128
141
  );
@@ -139,3 +152,5 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
139
152
  ## License
140
153
 
141
154
  Apache License 2.0
155
+
156
+ <!--BEGIN_REPO_NAV--><!--END_REPO_NAV-->
@@ -4,5 +4,5 @@
4
4
  # Location of the SDK. This is only used by Gradle.
5
5
  # For customization when using a Version Control System, please read the
6
6
  # header note.
7
- #Fri Apr 22 01:03:04 JST 2022
7
+ #Mon Jan 23 20:31:14 JST 2023
8
8
  sdk.dir=/Users/davidliu/Library/Android/sdk
@@ -1,4 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Workspace
3
3
  version = "1.0">
4
+ <FileRef
5
+ location = "self:">
6
+ </FileRef>
4
7
  </Workspace>
@@ -9,7 +9,7 @@ var _reactNative = require("react-native");
9
9
 
10
10
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
11
 
12
- const LINKING_ERROR = `The package 'livekit-react-native' doesn't seem to be linked. Make sure: \n\n` + _reactNative.Platform.select({
12
+ const LINKING_ERROR = `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \n\n` + _reactNative.Platform.select({
13
13
  ios: "- You have run 'pod install'\n",
14
14
  default: ''
15
15
  }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo managed workflow\n';
@@ -1 +1 @@
1
- {"version":3,"sources":["AudioSession.ts"],"names":["LINKING_ERROR","Platform","select","ios","default","LivekitReactNative","NativeModules","Proxy","get","Error","AudioSession","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker"],"mappings":";;;;;;;AAAA;;;;AACA,MAAMA,aAAa,GAChB,+EAAD,GACAC,sBAASC,MAAT,CAAgB;AAAEC,EAAAA,GAAG,EAAE,gCAAP;AAAyCC,EAAAA,OAAO,EAAE;AAAlD,CAAhB,CADA,GAEA,sDAFA,GAGA,6CAJF;AAMA,MAAMC,kBAAkB,GAAGC,2BAAcD,kBAAd,GACvBC,2BAAcD,kBADS,GAEvB,IAAIE,KAAJ,CACE,EADF,EAEE;AACEC,EAAAA,GAAG,GAAG;AACJ,UAAM,IAAIC,KAAJ,CAAUT,aAAV,CAAN;AACD;;AAHH,CAFF,CAFJ;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUe,MAAMU,YAAN,CAAmB;;;;gBAAbA,Y,oBAMK,MAAOC,MAAP,IAAsC;AAC5D,QAAMN,kBAAkB,CAACO,cAAnB,CAAkCD,MAAlC,CAAN;AACD,C;;gBARkBD,Y,uBAaQ,YAAY;AACrC,QAAML,kBAAkB,CAACQ,iBAAnB,EAAN;AACD,C;;gBAfkBH,Y,sBAoBO,YAAY;AACpC,QAAML,kBAAkB,CAACS,gBAAnB,EAAN;AACD,C;;gBAtBkBJ,Y,qBAmDM,YAA+B;AACtD,MAAIT,sBAASc,EAAT,KAAgB,KAApB,EAA2B;AACzB,WAAO,CAAC,SAAD,EAAY,eAAZ,CAAP;AACD,GAFD,MAEO,IAAId,sBAASc,EAAT,KAAgB,SAApB,EAA+B;AACpC,WAAQ,MAAMV,kBAAkB,CAACW,eAAnB,EAAd;AACD,GAFM,MAEA;AACL,WAAO,EAAP;AACD;AACF,C;;gBA3DkBN,Y,uBAoEQ,MAAOO,QAAP,IAA4B;AACrD,QAAMZ,kBAAkB,CAACa,iBAAnB,CAAqCD,QAArC,CAAN;AACD,C;;gBAtEkBP,Y,0BA6EW,YAAY;AACxC,MAAIT,sBAASc,EAAT,KAAgB,KAApB,EAA2B;AACzB,UAAMV,kBAAkB,CAACc,oBAAnB,EAAN;AACD;AACF,C","sourcesContent":["import { NativeModules, Platform } from 'react-native';\nconst LINKING_ERROR =\n `The package 'livekit-react-native' doesn't seem to be linked. Make sure: \\n\\n` +\n Platform.select({ ios: \"- You have run 'pod install'\\n\", default: '' }) +\n '- You rebuilt the app after installing the package\\n' +\n '- You are not using Expo managed workflow\\n';\n\nconst LivekitReactNative = NativeModules.LivekitReactNative\n ? NativeModules.LivekitReactNative\n : new Proxy(\n {},\n {\n get() {\n throw new Error(LINKING_ERROR);\n },\n }\n );\n\n/**\n * Configuration for the underlying AudioSession.\n *\n * ----\n * Android specific options:\n *\n * * preferredOutputList - The preferred order in which to automatically select an audio output.\n * This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.\n *\n * By default, the order is set to:\n * 1. `\"speaker\"`\n * 2. `\"earpiece\"`\n * 3. `\"headset\"`\n * 4. `\"bluetooth\"`\n *\n * ----\n * iOS\n *\n * * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.\n *\n * By default, this is set to `\"speaker\"`\n */\nexport type AudioConfiguration = {\n android: {\n preferredOutputList: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];\n };\n ios: {\n defaultOutput: 'speaker' | 'earpiece';\n };\n};\n\nexport default class AudioSession {\n /**\n * Applies the provided audio configuration to the underlying AudioSession.\n *\n * Must be called prior to connecting to a Room for the configuration to apply correctly.\n */\n static configureAudio = async (config: AudioConfiguration) => {\n await LivekitReactNative.configureAudio(config);\n };\n\n /**\n * Starts an AudioSession.\n */\n static startAudioSession = async () => {\n await LivekitReactNative.startAudioSession();\n };\n\n /**\n * Stops the existing AudioSession.\n */\n static stopAudioSession = async () => {\n await LivekitReactNative.stopAudioSession();\n };\n\n /**\n * Gets the available audio outputs for use with {@link selectAudioOutput}.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * For Android, will return if available:\n * * \"speaker\"\n * * \"earpiece\"\n * * \"headset\"\n * * \"bluetooth\"\n *\n * Note: For applications targeting SDK versions over 30, the runtime BLUETOOTH_CONNECT\n * permission must be requested to send audio to bluetooth headsets.\n *\n * ----\n *\n * For iOS, due to OS limitations, the only available types are:\n * * \"default\" - Use default iOS audio routing\n * * \"force_speaker\" - Force audio output through speaker\n *\n * See also {@link showAudioRoutePicker} to display a route picker that\n * can choose between other audio devices (i.e. headset/bluetooth/airplay),\n * or use a library like `react-native-avroutepicker` for a native platform\n * control.\n *\n * @returns the available audio output types\n */\n static getAudioOutputs = async (): Promise<string[]> => {\n if (Platform.OS === 'ios') {\n return ['default', 'force_speaker'];\n } else if (Platform.OS === 'android') {\n return (await LivekitReactNative.getAudioOutputs()) as string[];\n } else {\n return [];\n }\n };\n\n /**\n * Select the provided audio output if available.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * @param deviceId A deviceId retrieved from {@link getAudioOutputs}\n */\n static selectAudioOutput = async (deviceId: string) => {\n await LivekitReactNative.selectAudioOutput(deviceId);\n };\n\n /**\n * iOS only, requires iOS 11+.\n *\n * Displays an AVRoutePickerView for the user to choose their audio output.\n */\n static showAudioRoutePicker = async () => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.showAudioRoutePicker();\n }\n };\n}\n"]}
1
+ {"version":3,"sources":["AudioSession.ts"],"names":["LINKING_ERROR","Platform","select","ios","default","LivekitReactNative","NativeModules","Proxy","get","Error","AudioSession","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker"],"mappings":";;;;;;;AAAA;;;;AACA,MAAMA,aAAa,GAChB,gFAAD,GACAC,sBAASC,MAAT,CAAgB;AAAEC,EAAAA,GAAG,EAAE,gCAAP;AAAyCC,EAAAA,OAAO,EAAE;AAAlD,CAAhB,CADA,GAEA,sDAFA,GAGA,6CAJF;AAMA,MAAMC,kBAAkB,GAAGC,2BAAcD,kBAAd,GACvBC,2BAAcD,kBADS,GAEvB,IAAIE,KAAJ,CACE,EADF,EAEE;AACEC,EAAAA,GAAG,GAAG;AACJ,UAAM,IAAIC,KAAJ,CAAUT,aAAV,CAAN;AACD;;AAHH,CAFF,CAFJ;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUe,MAAMU,YAAN,CAAmB;;;;gBAAbA,Y,oBAMK,MAAOC,MAAP,IAAsC;AAC5D,QAAMN,kBAAkB,CAACO,cAAnB,CAAkCD,MAAlC,CAAN;AACD,C;;gBARkBD,Y,uBAaQ,YAAY;AACrC,QAAML,kBAAkB,CAACQ,iBAAnB,EAAN;AACD,C;;gBAfkBH,Y,sBAoBO,YAAY;AACpC,QAAML,kBAAkB,CAACS,gBAAnB,EAAN;AACD,C;;gBAtBkBJ,Y,qBAmDM,YAA+B;AACtD,MAAIT,sBAASc,EAAT,KAAgB,KAApB,EAA2B;AACzB,WAAO,CAAC,SAAD,EAAY,eAAZ,CAAP;AACD,GAFD,MAEO,IAAId,sBAASc,EAAT,KAAgB,SAApB,EAA+B;AACpC,WAAQ,MAAMV,kBAAkB,CAACW,eAAnB,EAAd;AACD,GAFM,MAEA;AACL,WAAO,EAAP;AACD;AACF,C;;gBA3DkBN,Y,uBAoEQ,MAAOO,QAAP,IAA4B;AACrD,QAAMZ,kBAAkB,CAACa,iBAAnB,CAAqCD,QAArC,CAAN;AACD,C;;gBAtEkBP,Y,0BA6EW,YAAY;AACxC,MAAIT,sBAASc,EAAT,KAAgB,KAApB,EAA2B;AACzB,UAAMV,kBAAkB,CAACc,oBAAnB,EAAN;AACD;AACF,C","sourcesContent":["import { NativeModules, Platform } from 'react-native';\nconst LINKING_ERROR =\n `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \\n\\n` +\n Platform.select({ ios: \"- You have run 'pod install'\\n\", default: '' }) +\n '- You rebuilt the app after installing the package\\n' +\n '- You are not using Expo managed workflow\\n';\n\nconst LivekitReactNative = NativeModules.LivekitReactNative\n ? NativeModules.LivekitReactNative\n : new Proxy(\n {},\n {\n get() {\n throw new Error(LINKING_ERROR);\n },\n }\n );\n\n/**\n * Configuration for the underlying AudioSession.\n *\n * ----\n * Android specific options:\n *\n * * preferredOutputList - The preferred order in which to automatically select an audio output.\n * This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.\n *\n * By default, the order is set to:\n * 1. `\"speaker\"`\n * 2. `\"earpiece\"`\n * 3. `\"headset\"`\n * 4. `\"bluetooth\"`\n *\n * ----\n * iOS\n *\n * * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.\n *\n * By default, this is set to `\"speaker\"`\n */\nexport type AudioConfiguration = {\n android: {\n preferredOutputList: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];\n };\n ios: {\n defaultOutput: 'speaker' | 'earpiece';\n };\n};\n\nexport default class AudioSession {\n /**\n * Applies the provided audio configuration to the underlying AudioSession.\n *\n * Must be called prior to connecting to a Room for the configuration to apply correctly.\n */\n static configureAudio = async (config: AudioConfiguration) => {\n await LivekitReactNative.configureAudio(config);\n };\n\n /**\n * Starts an AudioSession.\n */\n static startAudioSession = async () => {\n await LivekitReactNative.startAudioSession();\n };\n\n /**\n * Stops the existing AudioSession.\n */\n static stopAudioSession = async () => {\n await LivekitReactNative.stopAudioSession();\n };\n\n /**\n * Gets the available audio outputs for use with {@link selectAudioOutput}.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * For Android, will return if available:\n * * \"speaker\"\n * * \"earpiece\"\n * * \"headset\"\n * * \"bluetooth\"\n *\n * Note: For applications targeting SDK versions over 30, the runtime BLUETOOTH_CONNECT\n * permission must be requested to send audio to bluetooth headsets.\n *\n * ----\n *\n * For iOS, due to OS limitations, the only available types are:\n * * \"default\" - Use default iOS audio routing\n * * \"force_speaker\" - Force audio output through speaker\n *\n * See also {@link showAudioRoutePicker} to display a route picker that\n * can choose between other audio devices (i.e. headset/bluetooth/airplay),\n * or use a library like `react-native-avroutepicker` for a native platform\n * control.\n *\n * @returns the available audio output types\n */\n static getAudioOutputs = async (): Promise<string[]> => {\n if (Platform.OS === 'ios') {\n return ['default', 'force_speaker'];\n } else if (Platform.OS === 'android') {\n return (await LivekitReactNative.getAudioOutputs()) as string[];\n } else {\n return [];\n }\n };\n\n /**\n * Select the provided audio output if available.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * @param deviceId A deviceId retrieved from {@link getAudioOutputs}\n */\n static selectAudioOutput = async (deviceId: string) => {\n await LivekitReactNative.selectAudioOutput(deviceId);\n };\n\n /**\n * iOS only, requires iOS 11+.\n *\n * Displays an AVRoutePickerView for the user to choose their audio output.\n */\n static showAudioRoutePicker = async () => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.showAudioRoutePicker();\n }\n };\n}\n"]}
@@ -113,6 +113,8 @@ class VideoViewElementInfo {
113
113
 
114
114
  _defineProperty(this, "visibilityChangedAt", void 0);
115
115
 
116
+ _defineProperty(this, "pictureInPicture", false);
117
+
116
118
  _defineProperty(this, "handleResize", void 0);
117
119
 
118
120
  _defineProperty(this, "handleVisibilityChanged", void 0);
@@ -135,11 +137,8 @@ class VideoViewElementInfo {
135
137
  width,
136
138
  height
137
139
  } = event.nativeEvent.layout;
138
-
139
- const pixelRatio = _reactNative.PixelRatio.get();
140
-
141
- this._width = width * pixelRatio;
142
- this._height = height * pixelRatio;
140
+ this._width = width;
141
+ this._height = height;
143
142
 
144
143
  if (this._observing) {
145
144
  var _this$handleResize;
@@ -1 +1 @@
1
- {"version":3,"sources":["VideoView.tsx"],"names":["VideoView","style","videoTrack","objectFit","zOrder","mirror","elementInfo","info","VideoViewElementInfo","id","sid","something","mediaStream","setMediaStream","LocalVideoTrack","onRestarted","track","on","TrackEvent","Restarted","off","RemoteVideoTrack","isAdaptiveStream","observeElementInfo","stopObservingElementInfo","styles","container","event","onLayout","isVisible","onVisibility","videoView","toURL","StyleSheet","create","flex","width","_width","_height","observe","_observing","stopObserving","height","nativeEvent","layout","pixelRatio","PixelRatio","get","handleResize","visible","visibilityChangedAt","Date","now","handleVisibilityChanged"],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {\n LayoutChangeEvent,\n PixelRatio,\n StyleSheet,\n View,\n ViewStyle,\n} from 'react-native';\nimport {\n ElementInfo,\n LocalVideoTrack,\n Track,\n TrackEvent,\n VideoTrack,\n} from 'livekit-client';\nimport { RTCView } from 'react-native-webrtc';\nimport { useEffect, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\n\nexport type Props = {\n videoTrack?: VideoTrack | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\nexport const VideoView = ({\n style = {},\n videoTrack,\n objectFit = 'cover',\n zOrder,\n mirror,\n}: Props) => {\n const [elementInfo] = useState(() => {\n let info = new VideoViewElementInfo();\n info.id = videoTrack?.sid;\n info.something = videoTrack;\n return info;\n });\n\n const [mediaStream, setMediaStream] = useState(videoTrack?.mediaStream);\n useEffect(() => {\n setMediaStream(videoTrack?.mediaStream);\n if (videoTrack instanceof LocalVideoTrack) {\n const onRestarted = (track: Track | null) => {\n setMediaStream(track?.mediaStream);\n };\n videoTrack.on(TrackEvent.Restarted, onRestarted);\n\n return () => {\n videoTrack.off(TrackEvent.Restarted, onRestarted);\n };\n } else {\n return () => {};\n }\n }, [videoTrack]);\n\n useEffect(() => {\n if (videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream) {\n videoTrack?.observeElementInfo(elementInfo);\n return () => {\n videoTrack?.stopObservingElementInfo(elementInfo);\n };\n } else {\n return () => {};\n }\n }, [videoTrack, elementInfo]);\n\n return (\n <View\n style={{ ...style, ...styles.container }}\n onLayout={(event) => {\n elementInfo.onLayout(event);\n }}\n >\n <ViewPortDetector\n onChange={(isVisible: boolean) => elementInfo.onVisibility(isVisible)}\n style={styles.videoView}\n >\n <RTCView\n style={styles.videoView}\n streamURL={mediaStream?.toURL() ?? ''}\n objectFit={objectFit}\n zOrder={zOrder}\n mirror={mirror}\n />\n </ViewPortDetector>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {},\n videoView: {\n flex: 1,\n width: '100%',\n },\n});\n\nclass VideoViewElementInfo implements ElementInfo {\n element: object = {};\n something?: any;\n id?: string;\n _width = 0;\n _height = 0;\n _observing = false;\n visible: boolean = true;\n visibilityChangedAt: number | undefined;\n handleResize?: (() => void) | undefined;\n handleVisibilityChanged?: (() => void) | undefined;\n width = () => this._width;\n height = () => this._height;\n\n observe(): void {\n this._observing = true;\n }\n stopObserving(): void {\n this._observing = false;\n }\n\n onLayout(event: LayoutChangeEvent) {\n let { width, height } = event.nativeEvent.layout;\n const pixelRatio = PixelRatio.get();\n this._width = width * pixelRatio;\n this._height = height * pixelRatio;\n\n if (this._observing) {\n this.handleResize?.();\n }\n }\n onVisibility(isVisible: boolean) {\n if (this.visible !== isVisible) {\n this.visible = isVisible;\n this.visibilityChangedAt = Date.now();\n if (this._observing) {\n this.handleVisibilityChanged?.();\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["VideoView.tsx"],"names":["VideoView","style","videoTrack","objectFit","zOrder","mirror","elementInfo","info","VideoViewElementInfo","id","sid","something","mediaStream","setMediaStream","LocalVideoTrack","onRestarted","track","on","TrackEvent","Restarted","off","RemoteVideoTrack","isAdaptiveStream","observeElementInfo","stopObservingElementInfo","styles","container","event","onLayout","isVisible","onVisibility","videoView","toURL","StyleSheet","create","flex","width","_width","_height","observe","_observing","stopObserving","height","nativeEvent","layout","handleResize","visible","visibilityChangedAt","Date","now","handleVisibilityChanged"],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport { LayoutChangeEvent, StyleSheet, View, ViewStyle } from 'react-native';\nimport {\n ElementInfo,\n LocalVideoTrack,\n Track,\n TrackEvent,\n VideoTrack,\n} from 'livekit-client';\nimport { RTCView } from 'react-native-webrtc';\nimport { useEffect, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\n\nexport type Props = {\n videoTrack?: VideoTrack | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\nexport const VideoView = ({\n style = {},\n videoTrack,\n objectFit = 'cover',\n zOrder,\n mirror,\n}: Props) => {\n const [elementInfo] = useState(() => {\n let info = new VideoViewElementInfo();\n info.id = videoTrack?.sid;\n info.something = videoTrack;\n return info;\n });\n\n const [mediaStream, setMediaStream] = useState(videoTrack?.mediaStream);\n useEffect(() => {\n setMediaStream(videoTrack?.mediaStream);\n if (videoTrack instanceof LocalVideoTrack) {\n const onRestarted = (track: Track | null) => {\n setMediaStream(track?.mediaStream);\n };\n videoTrack.on(TrackEvent.Restarted, onRestarted);\n\n return () => {\n videoTrack.off(TrackEvent.Restarted, onRestarted);\n };\n } else {\n return () => {};\n }\n }, [videoTrack]);\n\n useEffect(() => {\n if (videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream) {\n videoTrack?.observeElementInfo(elementInfo);\n return () => {\n videoTrack?.stopObservingElementInfo(elementInfo);\n };\n } else {\n return () => {};\n }\n }, [videoTrack, elementInfo]);\n\n return (\n <View\n style={{ ...style, ...styles.container }}\n onLayout={(event) => {\n elementInfo.onLayout(event);\n }}\n >\n <ViewPortDetector\n onChange={(isVisible: boolean) => elementInfo.onVisibility(isVisible)}\n style={styles.videoView}\n >\n <RTCView\n style={styles.videoView}\n streamURL={mediaStream?.toURL() ?? ''}\n objectFit={objectFit}\n zOrder={zOrder}\n mirror={mirror}\n />\n </ViewPortDetector>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {},\n videoView: {\n flex: 1,\n width: '100%',\n },\n});\n\nclass VideoViewElementInfo implements ElementInfo {\n element: object = {};\n something?: any;\n id?: string;\n _width = 0;\n _height = 0;\n _observing = false;\n visible: boolean = true;\n visibilityChangedAt: number | undefined;\n pictureInPicture = false;\n handleResize?: (() => void) | undefined;\n handleVisibilityChanged?: (() => void) | undefined;\n width = () => this._width;\n height = () => this._height;\n\n observe(): void {\n this._observing = true;\n }\n stopObserving(): void {\n this._observing = false;\n }\n\n onLayout(event: LayoutChangeEvent) {\n let { width, height } = event.nativeEvent.layout;\n this._width = width;\n this._height = height;\n\n if (this._observing) {\n this.handleResize?.();\n }\n }\n onVisibility(isVisible: boolean) {\n if (this.visible !== isVisible) {\n this.visible = isVisible;\n this.visibilityChangedAt = Date.now();\n if (this._observing) {\n this.handleVisibilityChanged?.();\n }\n }\n }\n}\n"]}
@@ -21,6 +21,8 @@ var _reactNativeUrlPolyfill = require("react-native-url-polyfill");
21
21
 
22
22
  var _AudioSession = _interopRequireDefault(require("./audio/AudioSession"));
23
23
 
24
+ var _reactNative = require("react-native");
25
+
24
26
  var _VideoView = require("./components/VideoView");
25
27
 
26
28
  Object.keys(_VideoView).forEach(function (key) {
@@ -72,11 +74,21 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
72
74
  */
73
75
  function registerGlobals() {
74
76
  (0, _reactNativeWebrtc.registerGlobals)();
77
+ livekitRegisterGlobals();
75
78
  (0, _reactNativeUrlPolyfill.setupURLPolyfill)();
76
79
  fixWebrtcAdapter();
77
80
  shimPromiseAllSettled();
78
81
  }
79
82
 
83
+ function livekitRegisterGlobals() {
84
+ let lkGlobal = {
85
+ platform: _reactNative.Platform.OS,
86
+ devicePixelRatio: _reactNative.PixelRatio.get()
87
+ }; // @ts-ignore
88
+
89
+ global.LiveKitReactNativeGlobal = lkGlobal;
90
+ }
91
+
80
92
  function fixWebrtcAdapter() {
81
93
  var _window;
82
94
 
@@ -1 +1 @@
1
- {"version":3,"sources":["index.tsx"],"names":["registerGlobals","fixWebrtcAdapter","shimPromiseAllSettled","window","navigator","undefined","userAgent","product","allSettled","require","shim"],"mappings":";;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AA+BA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AA9BA;AACA;AACA;AACA;AACA;AACO,SAASA,eAAT,GAA2B;AAChC;AACA;AACAC,EAAAA,gBAAgB;AAChBC,EAAAA,qBAAqB;AACtB;;AAED,SAASD,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAE,MAAM,UAAN,0CAAQC,SAAR,MAAsBC,SAA1B,EAAqC;AACnC;AACA,UAAM;AAAED,MAAAA;AAAF,QAAgBD,MAAtB;;AACA,QAAIC,SAAS,CAACE,SAAV,KAAwBD,SAA5B,EAAuC;AAAA;;AACrCD,MAAAA,SAAS,CAACE,SAAV,yBAAsBF,SAAS,CAACG,OAAhC,mEAA2C,SAA3C;AACD;AACF;AACF;;AAED,SAASL,qBAAT,GAAiC;AAC/B,MAAIM,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD","sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from 'react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport AudioSession from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\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 setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\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\nexport * from './components/VideoView';\nexport * from './useParticipant';\nexport * from './useRoom';\nexport { AudioSession, AudioConfiguration };\n"]}
1
+ {"version":3,"sources":["index.tsx"],"names":["registerGlobals","livekitRegisterGlobals","fixWebrtcAdapter","shimPromiseAllSettled","lkGlobal","platform","Platform","OS","devicePixelRatio","PixelRatio","get","global","LiveKitReactNativeGlobal","window","navigator","undefined","userAgent","product","allSettled","require","shim"],"mappings":";;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AAEA;;AAyCA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAxCA;AACA;AACA;AACA;AACA;AACO,SAASA,eAAT,GAA2B;AAChC;AACAC,EAAAA,sBAAsB;AACtB;AACAC,EAAAA,gBAAgB;AAChBC,EAAAA,qBAAqB;AACtB;;AACD,SAASF,sBAAT,GAAkC;AAChC,MAAIG,QAAgC,GAAG;AACrCC,IAAAA,QAAQ,EAAEC,sBAASC,EADkB;AAErCC,IAAAA,gBAAgB,EAAEC,wBAAWC,GAAX;AAFmB,GAAvC,CADgC,CAMhC;;AACAC,EAAAA,MAAM,CAACC,wBAAP,GAAkCR,QAAlC;AACD;;AAED,SAASF,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAW,MAAM,UAAN,0CAAQC,SAAR,MAAsBC,SAA1B,EAAqC;AACnC;AACA,UAAM;AAAED,MAAAA;AAAF,QAAgBD,MAAtB;;AACA,QAAIC,SAAS,CAACE,SAAV,KAAwBD,SAA5B,EAAuC;AAAA;;AACrCD,MAAAA,SAAS,CAACE,SAAV,yBAAsBF,SAAS,CAACG,OAAhC,mEAA2C,SAA3C;AACD;AACF;AACF;;AAED,SAASd,qBAAT,GAAiC;AAC/B,MAAIe,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD","sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from 'react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport AudioSession from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\nimport { PixelRatio, Platform } from 'react-native';\nimport type { LiveKitReactNativeInfo } from 'livekit-client';\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 livekitRegisterGlobals();\n setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\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\nexport * from './components/VideoView';\nexport * from './useParticipant';\nexport * from './useRoom';\nexport { AudioSession, AudioConfiguration };\n"]}
@@ -1,7 +1,7 @@
1
1
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
2
 
3
3
  import { NativeModules, Platform } from 'react-native';
4
- const LINKING_ERROR = `The package 'livekit-react-native' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
4
+ const LINKING_ERROR = `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
5
5
  ios: "- You have run 'pod install'\n",
6
6
  default: ''
7
7
  }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo managed workflow\n';
@@ -1 +1 @@
1
- {"version":3,"sources":["AudioSession.ts"],"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","LivekitReactNative","Proxy","get","Error","AudioSession","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker"],"mappings":";;AAAA,SAASA,aAAT,EAAwBC,QAAxB,QAAwC,cAAxC;AACA,MAAMC,aAAa,GAChB,+EAAD,GACAD,QAAQ,CAACE,MAAT,CAAgB;AAAEC,EAAAA,GAAG,EAAE,gCAAP;AAAyCC,EAAAA,OAAO,EAAE;AAAlD,CAAhB,CADA,GAEA,sDAFA,GAGA,6CAJF;AAMA,MAAMC,kBAAkB,GAAGN,aAAa,CAACM,kBAAd,GACvBN,aAAa,CAACM,kBADS,GAEvB,IAAIC,KAAJ,CACE,EADF,EAEE;AACEC,EAAAA,GAAG,GAAG;AACJ,UAAM,IAAIC,KAAJ,CAAUP,aAAV,CAAN;AACD;;AAHH,CAFF,CAFJ;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA,eAAe,MAAMQ,YAAN,CAAmB;;gBAAbA,Y,oBAMK,MAAOC,MAAP,IAAsC;AAC5D,QAAML,kBAAkB,CAACM,cAAnB,CAAkCD,MAAlC,CAAN;AACD,C;;gBARkBD,Y,uBAaQ,YAAY;AACrC,QAAMJ,kBAAkB,CAACO,iBAAnB,EAAN;AACD,C;;gBAfkBH,Y,sBAoBO,YAAY;AACpC,QAAMJ,kBAAkB,CAACQ,gBAAnB,EAAN;AACD,C;;gBAtBkBJ,Y,qBAmDM,YAA+B;AACtD,MAAIT,QAAQ,CAACc,EAAT,KAAgB,KAApB,EAA2B;AACzB,WAAO,CAAC,SAAD,EAAY,eAAZ,CAAP;AACD,GAFD,MAEO,IAAId,QAAQ,CAACc,EAAT,KAAgB,SAApB,EAA+B;AACpC,WAAQ,MAAMT,kBAAkB,CAACU,eAAnB,EAAd;AACD,GAFM,MAEA;AACL,WAAO,EAAP;AACD;AACF,C;;gBA3DkBN,Y,uBAoEQ,MAAOO,QAAP,IAA4B;AACrD,QAAMX,kBAAkB,CAACY,iBAAnB,CAAqCD,QAArC,CAAN;AACD,C;;gBAtEkBP,Y,0BA6EW,YAAY;AACxC,MAAIT,QAAQ,CAACc,EAAT,KAAgB,KAApB,EAA2B;AACzB,UAAMT,kBAAkB,CAACa,oBAAnB,EAAN;AACD;AACF,C","sourcesContent":["import { NativeModules, Platform } from 'react-native';\nconst LINKING_ERROR =\n `The package 'livekit-react-native' doesn't seem to be linked. Make sure: \\n\\n` +\n Platform.select({ ios: \"- You have run 'pod install'\\n\", default: '' }) +\n '- You rebuilt the app after installing the package\\n' +\n '- You are not using Expo managed workflow\\n';\n\nconst LivekitReactNative = NativeModules.LivekitReactNative\n ? NativeModules.LivekitReactNative\n : new Proxy(\n {},\n {\n get() {\n throw new Error(LINKING_ERROR);\n },\n }\n );\n\n/**\n * Configuration for the underlying AudioSession.\n *\n * ----\n * Android specific options:\n *\n * * preferredOutputList - The preferred order in which to automatically select an audio output.\n * This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.\n *\n * By default, the order is set to:\n * 1. `\"speaker\"`\n * 2. `\"earpiece\"`\n * 3. `\"headset\"`\n * 4. `\"bluetooth\"`\n *\n * ----\n * iOS\n *\n * * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.\n *\n * By default, this is set to `\"speaker\"`\n */\nexport type AudioConfiguration = {\n android: {\n preferredOutputList: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];\n };\n ios: {\n defaultOutput: 'speaker' | 'earpiece';\n };\n};\n\nexport default class AudioSession {\n /**\n * Applies the provided audio configuration to the underlying AudioSession.\n *\n * Must be called prior to connecting to a Room for the configuration to apply correctly.\n */\n static configureAudio = async (config: AudioConfiguration) => {\n await LivekitReactNative.configureAudio(config);\n };\n\n /**\n * Starts an AudioSession.\n */\n static startAudioSession = async () => {\n await LivekitReactNative.startAudioSession();\n };\n\n /**\n * Stops the existing AudioSession.\n */\n static stopAudioSession = async () => {\n await LivekitReactNative.stopAudioSession();\n };\n\n /**\n * Gets the available audio outputs for use with {@link selectAudioOutput}.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * For Android, will return if available:\n * * \"speaker\"\n * * \"earpiece\"\n * * \"headset\"\n * * \"bluetooth\"\n *\n * Note: For applications targeting SDK versions over 30, the runtime BLUETOOTH_CONNECT\n * permission must be requested to send audio to bluetooth headsets.\n *\n * ----\n *\n * For iOS, due to OS limitations, the only available types are:\n * * \"default\" - Use default iOS audio routing\n * * \"force_speaker\" - Force audio output through speaker\n *\n * See also {@link showAudioRoutePicker} to display a route picker that\n * can choose between other audio devices (i.e. headset/bluetooth/airplay),\n * or use a library like `react-native-avroutepicker` for a native platform\n * control.\n *\n * @returns the available audio output types\n */\n static getAudioOutputs = async (): Promise<string[]> => {\n if (Platform.OS === 'ios') {\n return ['default', 'force_speaker'];\n } else if (Platform.OS === 'android') {\n return (await LivekitReactNative.getAudioOutputs()) as string[];\n } else {\n return [];\n }\n };\n\n /**\n * Select the provided audio output if available.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * @param deviceId A deviceId retrieved from {@link getAudioOutputs}\n */\n static selectAudioOutput = async (deviceId: string) => {\n await LivekitReactNative.selectAudioOutput(deviceId);\n };\n\n /**\n * iOS only, requires iOS 11+.\n *\n * Displays an AVRoutePickerView for the user to choose their audio output.\n */\n static showAudioRoutePicker = async () => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.showAudioRoutePicker();\n }\n };\n}\n"]}
1
+ {"version":3,"sources":["AudioSession.ts"],"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","LivekitReactNative","Proxy","get","Error","AudioSession","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker"],"mappings":";;AAAA,SAASA,aAAT,EAAwBC,QAAxB,QAAwC,cAAxC;AACA,MAAMC,aAAa,GAChB,gFAAD,GACAD,QAAQ,CAACE,MAAT,CAAgB;AAAEC,EAAAA,GAAG,EAAE,gCAAP;AAAyCC,EAAAA,OAAO,EAAE;AAAlD,CAAhB,CADA,GAEA,sDAFA,GAGA,6CAJF;AAMA,MAAMC,kBAAkB,GAAGN,aAAa,CAACM,kBAAd,GACvBN,aAAa,CAACM,kBADS,GAEvB,IAAIC,KAAJ,CACE,EADF,EAEE;AACEC,EAAAA,GAAG,GAAG;AACJ,UAAM,IAAIC,KAAJ,CAAUP,aAAV,CAAN;AACD;;AAHH,CAFF,CAFJ;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA,eAAe,MAAMQ,YAAN,CAAmB;;gBAAbA,Y,oBAMK,MAAOC,MAAP,IAAsC;AAC5D,QAAML,kBAAkB,CAACM,cAAnB,CAAkCD,MAAlC,CAAN;AACD,C;;gBARkBD,Y,uBAaQ,YAAY;AACrC,QAAMJ,kBAAkB,CAACO,iBAAnB,EAAN;AACD,C;;gBAfkBH,Y,sBAoBO,YAAY;AACpC,QAAMJ,kBAAkB,CAACQ,gBAAnB,EAAN;AACD,C;;gBAtBkBJ,Y,qBAmDM,YAA+B;AACtD,MAAIT,QAAQ,CAACc,EAAT,KAAgB,KAApB,EAA2B;AACzB,WAAO,CAAC,SAAD,EAAY,eAAZ,CAAP;AACD,GAFD,MAEO,IAAId,QAAQ,CAACc,EAAT,KAAgB,SAApB,EAA+B;AACpC,WAAQ,MAAMT,kBAAkB,CAACU,eAAnB,EAAd;AACD,GAFM,MAEA;AACL,WAAO,EAAP;AACD;AACF,C;;gBA3DkBN,Y,uBAoEQ,MAAOO,QAAP,IAA4B;AACrD,QAAMX,kBAAkB,CAACY,iBAAnB,CAAqCD,QAArC,CAAN;AACD,C;;gBAtEkBP,Y,0BA6EW,YAAY;AACxC,MAAIT,QAAQ,CAACc,EAAT,KAAgB,KAApB,EAA2B;AACzB,UAAMT,kBAAkB,CAACa,oBAAnB,EAAN;AACD;AACF,C","sourcesContent":["import { NativeModules, Platform } from 'react-native';\nconst LINKING_ERROR =\n `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \\n\\n` +\n Platform.select({ ios: \"- You have run 'pod install'\\n\", default: '' }) +\n '- You rebuilt the app after installing the package\\n' +\n '- You are not using Expo managed workflow\\n';\n\nconst LivekitReactNative = NativeModules.LivekitReactNative\n ? NativeModules.LivekitReactNative\n : new Proxy(\n {},\n {\n get() {\n throw new Error(LINKING_ERROR);\n },\n }\n );\n\n/**\n * Configuration for the underlying AudioSession.\n *\n * ----\n * Android specific options:\n *\n * * preferredOutputList - The preferred order in which to automatically select an audio output.\n * This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.\n *\n * By default, the order is set to:\n * 1. `\"speaker\"`\n * 2. `\"earpiece\"`\n * 3. `\"headset\"`\n * 4. `\"bluetooth\"`\n *\n * ----\n * iOS\n *\n * * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.\n *\n * By default, this is set to `\"speaker\"`\n */\nexport type AudioConfiguration = {\n android: {\n preferredOutputList: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];\n };\n ios: {\n defaultOutput: 'speaker' | 'earpiece';\n };\n};\n\nexport default class AudioSession {\n /**\n * Applies the provided audio configuration to the underlying AudioSession.\n *\n * Must be called prior to connecting to a Room for the configuration to apply correctly.\n */\n static configureAudio = async (config: AudioConfiguration) => {\n await LivekitReactNative.configureAudio(config);\n };\n\n /**\n * Starts an AudioSession.\n */\n static startAudioSession = async () => {\n await LivekitReactNative.startAudioSession();\n };\n\n /**\n * Stops the existing AudioSession.\n */\n static stopAudioSession = async () => {\n await LivekitReactNative.stopAudioSession();\n };\n\n /**\n * Gets the available audio outputs for use with {@link selectAudioOutput}.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * For Android, will return if available:\n * * \"speaker\"\n * * \"earpiece\"\n * * \"headset\"\n * * \"bluetooth\"\n *\n * Note: For applications targeting SDK versions over 30, the runtime BLUETOOTH_CONNECT\n * permission must be requested to send audio to bluetooth headsets.\n *\n * ----\n *\n * For iOS, due to OS limitations, the only available types are:\n * * \"default\" - Use default iOS audio routing\n * * \"force_speaker\" - Force audio output through speaker\n *\n * See also {@link showAudioRoutePicker} to display a route picker that\n * can choose between other audio devices (i.e. headset/bluetooth/airplay),\n * or use a library like `react-native-avroutepicker` for a native platform\n * control.\n *\n * @returns the available audio output types\n */\n static getAudioOutputs = async (): Promise<string[]> => {\n if (Platform.OS === 'ios') {\n return ['default', 'force_speaker'];\n } else if (Platform.OS === 'android') {\n return (await LivekitReactNative.getAudioOutputs()) as string[];\n } else {\n return [];\n }\n };\n\n /**\n * Select the provided audio output if available.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * @param deviceId A deviceId retrieved from {@link getAudioOutputs}\n */\n static selectAudioOutput = async (deviceId: string) => {\n await LivekitReactNative.selectAudioOutput(deviceId);\n };\n\n /**\n * iOS only, requires iOS 11+.\n *\n * Displays an AVRoutePickerView for the user to choose their audio output.\n */\n static showAudioRoutePicker = async () => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.showAudioRoutePicker();\n }\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
2
 
3
3
  import * as React from 'react';
4
- import { PixelRatio, StyleSheet, View } from 'react-native';
4
+ import { StyleSheet, View } from 'react-native';
5
5
  import { LocalVideoTrack, TrackEvent } from 'livekit-client';
6
6
  import { RTCView } from 'react-native-webrtc';
7
7
  import { useEffect, useState } from 'react';
@@ -94,6 +94,8 @@ class VideoViewElementInfo {
94
94
 
95
95
  _defineProperty(this, "visibilityChangedAt", void 0);
96
96
 
97
+ _defineProperty(this, "pictureInPicture", false);
98
+
97
99
  _defineProperty(this, "handleResize", void 0);
98
100
 
99
101
  _defineProperty(this, "handleVisibilityChanged", void 0);
@@ -116,9 +118,8 @@ class VideoViewElementInfo {
116
118
  width,
117
119
  height
118
120
  } = event.nativeEvent.layout;
119
- const pixelRatio = PixelRatio.get();
120
- this._width = width * pixelRatio;
121
- this._height = height * pixelRatio;
121
+ this._width = width;
122
+ this._height = height;
122
123
 
123
124
  if (this._observing) {
124
125
  var _this$handleResize;
@@ -1 +1 @@
1
- {"version":3,"sources":["VideoView.tsx"],"names":["React","PixelRatio","StyleSheet","View","LocalVideoTrack","TrackEvent","RTCView","useEffect","useState","RemoteVideoTrack","ViewPortDetector","VideoView","style","videoTrack","objectFit","zOrder","mirror","elementInfo","info","VideoViewElementInfo","id","sid","something","mediaStream","setMediaStream","onRestarted","track","on","Restarted","off","isAdaptiveStream","observeElementInfo","stopObservingElementInfo","styles","container","event","onLayout","isVisible","onVisibility","videoView","toURL","create","flex","width","_width","_height","observe","_observing","stopObserving","height","nativeEvent","layout","pixelRatio","get","handleResize","visible","visibilityChangedAt","Date","now","handleVisibilityChanged"],"mappings":";;AAAA,OAAO,KAAKA,KAAZ,MAAuB,OAAvB;AAEA,SAEEC,UAFF,EAGEC,UAHF,EAIEC,IAJF,QAMO,cANP;AAOA,SAEEC,eAFF,EAIEC,UAJF,QAMO,gBANP;AAOA,SAASC,OAAT,QAAwB,qBAAxB;AACA,SAASC,SAAT,EAAoBC,QAApB,QAAoC,OAApC;AACA,SAASC,gBAAT,QAAiC,gBAAjC;AACA,OAAOC,gBAAP,MAA6B,oBAA7B;AAUA,OAAO,MAAMC,SAAS,GAAG,QAMZ;AAAA;;AAAA,MANa;AACxBC,IAAAA,KAAK,GAAG,EADgB;AAExBC,IAAAA,UAFwB;AAGxBC,IAAAA,SAAS,GAAG,OAHY;AAIxBC,IAAAA,MAJwB;AAKxBC,IAAAA;AALwB,GAMb;AACX,QAAM,CAACC,WAAD,IAAgBT,QAAQ,CAAC,MAAM;AACnC,QAAIU,IAAI,GAAG,IAAIC,oBAAJ,EAAX;AACAD,IAAAA,IAAI,CAACE,EAAL,GAAUP,UAAV,aAAUA,UAAV,uBAAUA,UAAU,CAAEQ,GAAtB;AACAH,IAAAA,IAAI,CAACI,SAAL,GAAiBT,UAAjB;AACA,WAAOK,IAAP;AACD,GAL6B,CAA9B;AAOA,QAAM,CAACK,WAAD,EAAcC,cAAd,IAAgChB,QAAQ,CAACK,UAAD,aAACA,UAAD,uBAACA,UAAU,CAAEU,WAAb,CAA9C;AACAhB,EAAAA,SAAS,CAAC,MAAM;AACdiB,IAAAA,cAAc,CAACX,UAAD,aAACA,UAAD,uBAACA,UAAU,CAAEU,WAAb,CAAd;;AACA,QAAIV,UAAU,YAAYT,eAA1B,EAA2C;AACzC,YAAMqB,WAAW,GAAIC,KAAD,IAAyB;AAC3CF,QAAAA,cAAc,CAACE,KAAD,aAACA,KAAD,uBAACA,KAAK,CAAEH,WAAR,CAAd;AACD,OAFD;;AAGAV,MAAAA,UAAU,CAACc,EAAX,CAActB,UAAU,CAACuB,SAAzB,EAAoCH,WAApC;AAEA,aAAO,MAAM;AACXZ,QAAAA,UAAU,CAACgB,GAAX,CAAexB,UAAU,CAACuB,SAA1B,EAAqCH,WAArC;AACD,OAFD;AAGD,KATD,MASO;AACL,aAAO,MAAM,CAAE,CAAf;AACD;AACF,GAdQ,EAcN,CAACZ,UAAD,CAdM,CAAT;AAgBAN,EAAAA,SAAS,CAAC,MAAM;AACd,QAAIM,UAAU,YAAYJ,gBAAtB,IAA0CI,UAAU,CAACiB,gBAAzD,EAA2E;AACzEjB,MAAAA,UAAU,SAAV,IAAAA,UAAU,WAAV,YAAAA,UAAU,CAAEkB,kBAAZ,CAA+Bd,WAA/B;AACA,aAAO,MAAM;AACXJ,QAAAA,UAAU,SAAV,IAAAA,UAAU,WAAV,YAAAA,UAAU,CAAEmB,wBAAZ,CAAqCf,WAArC;AACD,OAFD;AAGD,KALD,MAKO;AACL,aAAO,MAAM,CAAE,CAAf;AACD;AACF,GATQ,EASN,CAACJ,UAAD,EAAaI,WAAb,CATM,CAAT;AAWA,sBACE,oBAAC,IAAD;AACE,IAAA,KAAK,EAAE,EAAE,GAAGL,KAAL;AAAY,SAAGqB,MAAM,CAACC;AAAtB,KADT;AAEE,IAAA,QAAQ,EAAGC,KAAD,IAAW;AACnBlB,MAAAA,WAAW,CAACmB,QAAZ,CAAqBD,KAArB;AACD;AAJH,kBAME,oBAAC,gBAAD;AACE,IAAA,QAAQ,EAAGE,SAAD,IAAwBpB,WAAW,CAACqB,YAAZ,CAAyBD,SAAzB,CADpC;AAEE,IAAA,KAAK,EAAEJ,MAAM,CAACM;AAFhB,kBAIE,oBAAC,OAAD;AACE,IAAA,KAAK,EAAEN,MAAM,CAACM,SADhB;AAEE,IAAA,SAAS,wBAAEhB,WAAF,aAAEA,WAAF,uBAAEA,WAAW,CAAEiB,KAAb,EAAF,mEAA0B,EAFrC;AAGE,IAAA,SAAS,EAAE1B,SAHb;AAIE,IAAA,MAAM,EAAEC,MAJV;AAKE,IAAA,MAAM,EAAEC;AALV,IAJF,CANF,CADF;AAqBD,CA/DM;AAiEP,MAAMiB,MAAM,GAAG/B,UAAU,CAACuC,MAAX,CAAkB;AAC/BP,EAAAA,SAAS,EAAE,EADoB;AAE/BK,EAAAA,SAAS,EAAE;AACTG,IAAAA,IAAI,EAAE,CADG;AAETC,IAAAA,KAAK,EAAE;AAFE;AAFoB,CAAlB,CAAf;;AAQA,MAAMxB,oBAAN,CAAkD;AAAA;AAAA,qCAC9B,EAD8B;;AAAA;;AAAA;;AAAA,oCAIvC,CAJuC;;AAAA,qCAKtC,CALsC;;AAAA,wCAMnC,KANmC;;AAAA,qCAO7B,IAP6B;;AAAA;;AAAA;;AAAA;;AAAA,mCAWxC,MAAM,KAAKyB,MAX6B;;AAAA,oCAYvC,MAAM,KAAKC,OAZ4B;AAAA;;AAchDC,EAAAA,OAAO,GAAS;AACd,SAAKC,UAAL,GAAkB,IAAlB;AACD;;AACDC,EAAAA,aAAa,GAAS;AACpB,SAAKD,UAAL,GAAkB,KAAlB;AACD;;AAEDX,EAAAA,QAAQ,CAACD,KAAD,EAA2B;AACjC,QAAI;AAAEQ,MAAAA,KAAF;AAASM,MAAAA;AAAT,QAAoBd,KAAK,CAACe,WAAN,CAAkBC,MAA1C;AACA,UAAMC,UAAU,GAAGnD,UAAU,CAACoD,GAAX,EAAnB;AACA,SAAKT,MAAL,GAAcD,KAAK,GAAGS,UAAtB;AACA,SAAKP,OAAL,GAAeI,MAAM,GAAGG,UAAxB;;AAEA,QAAI,KAAKL,UAAT,EAAqB;AAAA;;AACnB,iCAAKO,YAAL;AACD;AACF;;AACDhB,EAAAA,YAAY,CAACD,SAAD,EAAqB;AAC/B,QAAI,KAAKkB,OAAL,KAAiBlB,SAArB,EAAgC;AAC9B,WAAKkB,OAAL,GAAelB,SAAf;AACA,WAAKmB,mBAAL,GAA2BC,IAAI,CAACC,GAAL,EAA3B;;AACA,UAAI,KAAKX,UAAT,EAAqB;AAAA;;AACnB,sCAAKY,uBAAL;AACD;AACF;AACF;;AAvC+C","sourcesContent":["import * as React from 'react';\n\nimport {\n LayoutChangeEvent,\n PixelRatio,\n StyleSheet,\n View,\n ViewStyle,\n} from 'react-native';\nimport {\n ElementInfo,\n LocalVideoTrack,\n Track,\n TrackEvent,\n VideoTrack,\n} from 'livekit-client';\nimport { RTCView } from 'react-native-webrtc';\nimport { useEffect, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\n\nexport type Props = {\n videoTrack?: VideoTrack | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\nexport const VideoView = ({\n style = {},\n videoTrack,\n objectFit = 'cover',\n zOrder,\n mirror,\n}: Props) => {\n const [elementInfo] = useState(() => {\n let info = new VideoViewElementInfo();\n info.id = videoTrack?.sid;\n info.something = videoTrack;\n return info;\n });\n\n const [mediaStream, setMediaStream] = useState(videoTrack?.mediaStream);\n useEffect(() => {\n setMediaStream(videoTrack?.mediaStream);\n if (videoTrack instanceof LocalVideoTrack) {\n const onRestarted = (track: Track | null) => {\n setMediaStream(track?.mediaStream);\n };\n videoTrack.on(TrackEvent.Restarted, onRestarted);\n\n return () => {\n videoTrack.off(TrackEvent.Restarted, onRestarted);\n };\n } else {\n return () => {};\n }\n }, [videoTrack]);\n\n useEffect(() => {\n if (videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream) {\n videoTrack?.observeElementInfo(elementInfo);\n return () => {\n videoTrack?.stopObservingElementInfo(elementInfo);\n };\n } else {\n return () => {};\n }\n }, [videoTrack, elementInfo]);\n\n return (\n <View\n style={{ ...style, ...styles.container }}\n onLayout={(event) => {\n elementInfo.onLayout(event);\n }}\n >\n <ViewPortDetector\n onChange={(isVisible: boolean) => elementInfo.onVisibility(isVisible)}\n style={styles.videoView}\n >\n <RTCView\n style={styles.videoView}\n streamURL={mediaStream?.toURL() ?? ''}\n objectFit={objectFit}\n zOrder={zOrder}\n mirror={mirror}\n />\n </ViewPortDetector>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {},\n videoView: {\n flex: 1,\n width: '100%',\n },\n});\n\nclass VideoViewElementInfo implements ElementInfo {\n element: object = {};\n something?: any;\n id?: string;\n _width = 0;\n _height = 0;\n _observing = false;\n visible: boolean = true;\n visibilityChangedAt: number | undefined;\n handleResize?: (() => void) | undefined;\n handleVisibilityChanged?: (() => void) | undefined;\n width = () => this._width;\n height = () => this._height;\n\n observe(): void {\n this._observing = true;\n }\n stopObserving(): void {\n this._observing = false;\n }\n\n onLayout(event: LayoutChangeEvent) {\n let { width, height } = event.nativeEvent.layout;\n const pixelRatio = PixelRatio.get();\n this._width = width * pixelRatio;\n this._height = height * pixelRatio;\n\n if (this._observing) {\n this.handleResize?.();\n }\n }\n onVisibility(isVisible: boolean) {\n if (this.visible !== isVisible) {\n this.visible = isVisible;\n this.visibilityChangedAt = Date.now();\n if (this._observing) {\n this.handleVisibilityChanged?.();\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["VideoView.tsx"],"names":["React","StyleSheet","View","LocalVideoTrack","TrackEvent","RTCView","useEffect","useState","RemoteVideoTrack","ViewPortDetector","VideoView","style","videoTrack","objectFit","zOrder","mirror","elementInfo","info","VideoViewElementInfo","id","sid","something","mediaStream","setMediaStream","onRestarted","track","on","Restarted","off","isAdaptiveStream","observeElementInfo","stopObservingElementInfo","styles","container","event","onLayout","isVisible","onVisibility","videoView","toURL","create","flex","width","_width","_height","observe","_observing","stopObserving","height","nativeEvent","layout","handleResize","visible","visibilityChangedAt","Date","now","handleVisibilityChanged"],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport { LayoutChangeEvent, StyleSheet, View, ViewStyle } from 'react-native';\nimport {\n ElementInfo,\n LocalVideoTrack,\n Track,\n TrackEvent,\n VideoTrack,\n} from 'livekit-client';\nimport { RTCView } from 'react-native-webrtc';\nimport { useEffect, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\n\nexport type Props = {\n videoTrack?: VideoTrack | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\nexport const VideoView = ({\n style = {},\n videoTrack,\n objectFit = 'cover',\n zOrder,\n mirror,\n}: Props) => {\n const [elementInfo] = useState(() => {\n let info = new VideoViewElementInfo();\n info.id = videoTrack?.sid;\n info.something = videoTrack;\n return info;\n });\n\n const [mediaStream, setMediaStream] = useState(videoTrack?.mediaStream);\n useEffect(() => {\n setMediaStream(videoTrack?.mediaStream);\n if (videoTrack instanceof LocalVideoTrack) {\n const onRestarted = (track: Track | null) => {\n setMediaStream(track?.mediaStream);\n };\n videoTrack.on(TrackEvent.Restarted, onRestarted);\n\n return () => {\n videoTrack.off(TrackEvent.Restarted, onRestarted);\n };\n } else {\n return () => {};\n }\n }, [videoTrack]);\n\n useEffect(() => {\n if (videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream) {\n videoTrack?.observeElementInfo(elementInfo);\n return () => {\n videoTrack?.stopObservingElementInfo(elementInfo);\n };\n } else {\n return () => {};\n }\n }, [videoTrack, elementInfo]);\n\n return (\n <View\n style={{ ...style, ...styles.container }}\n onLayout={(event) => {\n elementInfo.onLayout(event);\n }}\n >\n <ViewPortDetector\n onChange={(isVisible: boolean) => elementInfo.onVisibility(isVisible)}\n style={styles.videoView}\n >\n <RTCView\n style={styles.videoView}\n streamURL={mediaStream?.toURL() ?? ''}\n objectFit={objectFit}\n zOrder={zOrder}\n mirror={mirror}\n />\n </ViewPortDetector>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {},\n videoView: {\n flex: 1,\n width: '100%',\n },\n});\n\nclass VideoViewElementInfo implements ElementInfo {\n element: object = {};\n something?: any;\n id?: string;\n _width = 0;\n _height = 0;\n _observing = false;\n visible: boolean = true;\n visibilityChangedAt: number | undefined;\n pictureInPicture = false;\n handleResize?: (() => void) | undefined;\n handleVisibilityChanged?: (() => void) | undefined;\n width = () => this._width;\n height = () => this._height;\n\n observe(): void {\n this._observing = true;\n }\n stopObserving(): void {\n this._observing = false;\n }\n\n onLayout(event: LayoutChangeEvent) {\n let { width, height } = event.nativeEvent.layout;\n this._width = width;\n this._height = height;\n\n if (this._observing) {\n this.handleResize?.();\n }\n }\n onVisibility(isVisible: boolean) {\n if (this.visible !== isVisible) {\n this.visible = isVisible;\n this.visibilityChangedAt = Date.now();\n if (this._observing) {\n this.handleVisibilityChanged?.();\n }\n }\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { registerGlobals as webrtcRegisterGlobals } from 'react-native-webrtc';
2
2
  import { setupURLPolyfill } from 'react-native-url-polyfill';
3
3
  import AudioSession from './audio/AudioSession';
4
+ import { PixelRatio, Platform } from 'react-native';
4
5
 
5
6
  /**
6
7
  * Registers the required globals needed for LiveKit to work.
@@ -9,11 +10,21 @@ import AudioSession from './audio/AudioSession';
9
10
  */
10
11
  export function registerGlobals() {
11
12
  webrtcRegisterGlobals();
13
+ livekitRegisterGlobals();
12
14
  setupURLPolyfill();
13
15
  fixWebrtcAdapter();
14
16
  shimPromiseAllSettled();
15
17
  }
16
18
 
19
+ function livekitRegisterGlobals() {
20
+ let lkGlobal = {
21
+ platform: Platform.OS,
22
+ devicePixelRatio: PixelRatio.get()
23
+ }; // @ts-ignore
24
+
25
+ global.LiveKitReactNativeGlobal = lkGlobal;
26
+ }
27
+
17
28
  function fixWebrtcAdapter() {
18
29
  var _window;
19
30
 
@@ -1 +1 @@
1
- {"version":3,"sources":["index.tsx"],"names":["registerGlobals","webrtcRegisterGlobals","setupURLPolyfill","AudioSession","fixWebrtcAdapter","shimPromiseAllSettled","window","navigator","undefined","userAgent","product","allSettled","require","shim"],"mappings":"AAAA,SAASA,eAAe,IAAIC,qBAA5B,QAAyD,qBAAzD;AACA,SAASC,gBAAT,QAAiC,2BAAjC;AACA,OAAOC,YAAP,MAAyB,sBAAzB;;AAGA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASH,eAAT,GAA2B;AAChCC,EAAAA,qBAAqB;AACrBC,EAAAA,gBAAgB;AAChBE,EAAAA,gBAAgB;AAChBC,EAAAA,qBAAqB;AACtB;;AAED,SAASD,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAE,MAAM,UAAN,0CAAQC,SAAR,MAAsBC,SAA1B,EAAqC;AACnC;AACA,UAAM;AAAED,MAAAA;AAAF,QAAgBD,MAAtB;;AACA,QAAIC,SAAS,CAACE,SAAV,KAAwBD,SAA5B,EAAuC;AAAA;;AACrCD,MAAAA,SAAS,CAACE,SAAV,yBAAsBF,SAAS,CAACG,OAAhC,mEAA2C,SAA3C;AACD;AACF;AACF;;AAED,SAASL,qBAAT,GAAiC;AAC/B,MAAIM,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD;;AAED,cAAc,wBAAd;AACA,cAAc,kBAAd;AACA,cAAc,WAAd;AACA,SAASV,YAAT","sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from 'react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport AudioSession from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\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 setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\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\nexport * from './components/VideoView';\nexport * from './useParticipant';\nexport * from './useRoom';\nexport { AudioSession, AudioConfiguration };\n"]}
1
+ {"version":3,"sources":["index.tsx"],"names":["registerGlobals","webrtcRegisterGlobals","setupURLPolyfill","AudioSession","PixelRatio","Platform","livekitRegisterGlobals","fixWebrtcAdapter","shimPromiseAllSettled","lkGlobal","platform","OS","devicePixelRatio","get","global","LiveKitReactNativeGlobal","window","navigator","undefined","userAgent","product","allSettled","require","shim"],"mappings":"AAAA,SAASA,eAAe,IAAIC,qBAA5B,QAAyD,qBAAzD;AACA,SAASC,gBAAT,QAAiC,2BAAjC;AACA,OAAOC,YAAP,MAAyB,sBAAzB;AAEA,SAASC,UAAT,EAAqBC,QAArB,QAAqC,cAArC;;AAGA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASL,eAAT,GAA2B;AAChCC,EAAAA,qBAAqB;AACrBK,EAAAA,sBAAsB;AACtBJ,EAAAA,gBAAgB;AAChBK,EAAAA,gBAAgB;AAChBC,EAAAA,qBAAqB;AACtB;;AACD,SAASF,sBAAT,GAAkC;AAChC,MAAIG,QAAgC,GAAG;AACrCC,IAAAA,QAAQ,EAAEL,QAAQ,CAACM,EADkB;AAErCC,IAAAA,gBAAgB,EAAER,UAAU,CAACS,GAAX;AAFmB,GAAvC,CADgC,CAMhC;;AACAC,EAAAA,MAAM,CAACC,wBAAP,GAAkCN,QAAlC;AACD;;AAED,SAASF,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAS,MAAM,UAAN,0CAAQC,SAAR,MAAsBC,SAA1B,EAAqC;AACnC;AACA,UAAM;AAAED,MAAAA;AAAF,QAAgBD,MAAtB;;AACA,QAAIC,SAAS,CAACE,SAAV,KAAwBD,SAA5B,EAAuC;AAAA;;AACrCD,MAAAA,SAAS,CAACE,SAAV,yBAAsBF,SAAS,CAACG,OAAhC,mEAA2C,SAA3C;AACD;AACF;AACF;;AAED,SAASZ,qBAAT,GAAiC;AAC/B,MAAIa,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD;;AAED,cAAc,wBAAd;AACA,cAAc,kBAAd;AACA,cAAc,WAAd;AACA,SAASpB,YAAT","sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from 'react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport AudioSession from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\nimport { PixelRatio, Platform } from 'react-native';\nimport type { LiveKitReactNativeInfo } from 'livekit-client';\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 livekitRegisterGlobals();\n setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\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\nexport * from './components/VideoView';\nexport * from './useParticipant';\nexport * from './useRoom';\nexport { AudioSession, AudioConfiguration };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livekit/react-native",
3
- "version": "0.2.2",
3
+ "version": "1.0.0",
4
4
  "description": "LiveKit for React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -39,7 +39,7 @@
39
39
  "android"
40
40
  ],
41
41
  "dependencies": {
42
- "livekit-client": "^1.6.0",
42
+ "livekit-client": "^1.8.0",
43
43
  "promise.allsettled": "^1.0.5",
44
44
  "react-native-url-polyfill": "^1.3.0"
45
45
  },
@@ -72,7 +72,7 @@
72
72
  "peerDependencies": {
73
73
  "react": "*",
74
74
  "react-native": "*",
75
- "react-native-webrtc": "^106.0.0"
75
+ "react-native-webrtc": "^111.0.0"
76
76
  },
77
77
  "scripts": {
78
78
  "test": "jest",
@@ -98,6 +98,18 @@
98
98
  ]
99
99
  },
100
100
  "release-it": {
101
+ "hooks": {
102
+ "before:init": [
103
+ "yarn lint",
104
+ "yarn test",
105
+ "yarn typescript"
106
+ ],
107
+ "after:bump": [
108
+ "yarn pods",
109
+ "yarn build-docs"
110
+ ],
111
+ "after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
112
+ },
101
113
  "git": {
102
114
  "commitMessage": "chore: release ${version}",
103
115
  "tagName": "v${version}"
@@ -1,6 +1,6 @@
1
1
  import { NativeModules, Platform } from 'react-native';
2
2
  const LINKING_ERROR =
3
- `The package 'livekit-react-native' doesn't seem to be linked. Make sure: \n\n` +
3
+ `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \n\n` +
4
4
  Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
5
5
  '- You rebuilt the app after installing the package\n' +
6
6
  '- You are not using Expo managed workflow\n';
@@ -1,12 +1,6 @@
1
1
  import * as React from 'react';
2
2
 
3
- import {
4
- LayoutChangeEvent,
5
- PixelRatio,
6
- StyleSheet,
7
- View,
8
- ViewStyle,
9
- } from 'react-native';
3
+ import { LayoutChangeEvent, StyleSheet, View, ViewStyle } from 'react-native';
10
4
  import {
11
5
  ElementInfo,
12
6
  LocalVideoTrack,
@@ -109,6 +103,7 @@ class VideoViewElementInfo implements ElementInfo {
109
103
  _observing = false;
110
104
  visible: boolean = true;
111
105
  visibilityChangedAt: number | undefined;
106
+ pictureInPicture = false;
112
107
  handleResize?: (() => void) | undefined;
113
108
  handleVisibilityChanged?: (() => void) | undefined;
114
109
  width = () => this._width;
@@ -123,9 +118,8 @@ class VideoViewElementInfo implements ElementInfo {
123
118
 
124
119
  onLayout(event: LayoutChangeEvent) {
125
120
  let { width, height } = event.nativeEvent.layout;
126
- const pixelRatio = PixelRatio.get();
127
- this._width = width * pixelRatio;
128
- this._height = height * pixelRatio;
121
+ this._width = width;
122
+ this._height = height;
129
123
 
130
124
  if (this._observing) {
131
125
  this.handleResize?.();
package/src/index.tsx CHANGED
@@ -2,6 +2,8 @@ import { registerGlobals as webrtcRegisterGlobals } from 'react-native-webrtc';
2
2
  import { setupURLPolyfill } from 'react-native-url-polyfill';
3
3
  import AudioSession from './audio/AudioSession';
4
4
  import type { AudioConfiguration } from './audio/AudioSession';
5
+ import { PixelRatio, Platform } from 'react-native';
6
+ import type { LiveKitReactNativeInfo } from 'livekit-client';
5
7
 
6
8
  /**
7
9
  * Registers the required globals needed for LiveKit to work.
@@ -10,10 +12,20 @@ import type { AudioConfiguration } from './audio/AudioSession';
10
12
  */
11
13
  export function registerGlobals() {
12
14
  webrtcRegisterGlobals();
15
+ livekitRegisterGlobals();
13
16
  setupURLPolyfill();
14
17
  fixWebrtcAdapter();
15
18
  shimPromiseAllSettled();
16
19
  }
20
+ function livekitRegisterGlobals() {
21
+ let lkGlobal: LiveKitReactNativeInfo = {
22
+ platform: Platform.OS,
23
+ devicePixelRatio: PixelRatio.get(),
24
+ };
25
+
26
+ // @ts-ignore
27
+ global.LiveKitReactNativeGlobal = lkGlobal;
28
+ }
17
29
 
18
30
  function fixWebrtcAdapter() {
19
31
  // @ts-ignore