@livekit/react-native 0.3.0 → 1.0.1

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,23 +1,37 @@
1
+ <!--BEGIN_BANNER_IMAGE-->
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="/.github/banner_dark.png">
4
+ <source media="(prefers-color-scheme: light)" srcset="/.github/banner_light.png">
5
+ <img style="width:100%;" alt="The LiveKit icon, the name of the repository and some sample code in the background." src="/.github/banner_light.png">
6
+ </picture>
7
+ <!--END_BANNER_IMAGE-->
8
+
1
9
  # livekit-react-native
2
10
 
3
- LiveKit Client SDK for React Native. (beta)
11
+ <!--BEGIN_DESCRIPTION-->Use this SDK to add real-time video, audio and data features to your React Native app. By connecting to a self- or cloud-hosted <a href="https://livekit.io/">LiveKit</a> server, you can quickly build applications like interactive live streaming or video calls with just a few lines of code.<!--END_DESCRIPTION-->
4
12
 
5
13
  ## Installation
6
14
 
7
15
  ### NPM
16
+
8
17
  ```sh
9
- npm install https://github.com/livekit/client-sdk-react-native
18
+ npm install @livekit/react-native react-native-webrtc
10
19
  ```
11
20
 
12
21
  ### Yarn
22
+
13
23
  ```sh
14
- yarn add https://github.com/livekit/client-sdk-react-native
24
+ yarn add @livekit/react-native react-native-webrtc
15
25
  ```
16
26
 
17
- The `react-native-webrtc` library has additional installation instructions found here:
27
+ This library depends on `react-native-webrtc`, which has additional installation instructions found here:
28
+
29
+ - [iOS Installation Guide](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/iOSInstallation.md)
30
+ - [Android Installation Guide](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/AndroidInstallation.md)
31
+
32
+ ### Expo
18
33
 
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)
34
+ LiveKit is available on Expo through development builds. [See the instructions found here](https://github.com/livekit/client-sdk-react-native/wiki/Expo-Development-Build-Instructions).
21
35
 
22
36
  ## Example app
23
37
 
@@ -25,28 +39,27 @@ We've included an [example app](example/) that you can try out.
25
39
 
26
40
  ## Usage
27
41
 
28
- In your `index.js` file, setup the LiveKit SDK by calling `registerGlobals()`.
42
+ In your `index.js` file, setup the LiveKit SDK by calling `registerGlobals()`.
29
43
  This sets up the required WebRTC libraries for use in Javascript, and is needed for LiveKit to work.
30
44
 
31
45
  ```js
32
- import { registerGlobals } from "@livekit/react-native";
46
+ import { registerGlobals } from '@livekit/react-native';
33
47
 
34
48
  // ...
35
49
 
36
- registerGlobals()
50
+ registerGlobals();
37
51
  ```
38
52
 
39
53
  A Room object can then be created and connected to.
40
54
 
41
55
  ```js
42
-
43
56
  import { Participant, Room, Track } from 'livekit-client';
44
57
  import { useRoom, AudioSession, VideoView } from '@livekit/react-native';
45
58
 
46
59
  /*...*/
47
60
 
48
61
  // Create a room state
49
- const [room,] = useState(() => new Room());
62
+ const [room] = useState(() => new Room());
50
63
 
51
64
  // Get the participants from the room
52
65
  const { participants } = useRoom(room);
@@ -55,13 +68,16 @@ useEffect(() => {
55
68
  AudioSession.startAudioSession();
56
69
  room.connect(url, token, {});
57
70
  return () => {
58
- room.disconnect()
71
+ room.disconnect();
59
72
  AudioSession.stopAudioSession();
60
- }
73
+ };
61
74
  }, [url, token, room]);
62
75
 
63
76
  const videoView = participants.length > 0 && (
64
- <VideoView style={{flex:1, width:"100%"}} videoTrack={participants[0].getTrack(Track.Source.Camera)?.videoTrack} />
77
+ <VideoView
78
+ style={{ flex: 1, width: '100%' }}
79
+ videoTrack={participants[0].getTrack(Track.Source.Camera)?.videoTrack}
80
+ />
65
81
  );
66
82
  ```
67
83
 
@@ -81,7 +97,7 @@ The example app uses [@voximplant/react-native-foreground-service](https://githu
81
97
  Ensure that the service is labelled a `mediaProjection` service like so:
82
98
 
83
99
  ```
84
- <service android:name="com.voximplant.foregroundservice.VIForegroundService"
100
+ <service android:name="com.voximplant.foregroundservice.VIForegroundService"
85
101
  android:foregroundServiceType="mediaProjection" />
86
102
  ```
87
103
 
@@ -93,10 +109,10 @@ iOS screenshare requires adding a Broadcast Extension to your iOS project. Follo
93
109
 
94
110
  https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-ios-sdk/#screen-sharing-integration
95
111
 
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)
112
+ 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
113
  to your iOS project, and registering a Broadcast Extension in Xcode.
98
114
 
99
- It's also recommended to use [CallKeep](https://github.com/react-native-webrtc/react-native-callkeep),
115
+ It's also recommended to use [CallKeep](https://github.com/react-native-webrtc/react-native-callkeep),
100
116
  to register a call with CallKit (as well as turning on the `voip` background mode).
101
117
  Due to background app processing limitations, screen recording may be interrupted if the app is restricted
102
118
  in the background. Registering with CallKit allows the app to continue processing for the duration of the call.
@@ -105,24 +121,22 @@ Once setup, iOS screenshare can be initiated like so:
105
121
 
106
122
  ```js
107
123
  const screenCaptureRef = React.useRef(null);
108
- const screenCapturePickerView = Platform.OS === "ios" && (
124
+ const screenCapturePickerView = Platform.OS === 'ios' && (
109
125
  <ScreenCapturePickerView ref={screenCaptureRef} />
110
126
  );
111
127
  const startBroadcast = async () => {
112
- if(Platform.OS === "ios") {
128
+ if (Platform.OS === 'ios') {
113
129
  const reactTag = findNodeHandle(screenCaptureRef.current);
114
130
  await NativeModules.ScreenCapturePickerViewManager.show(reactTag);
115
131
  room.localParticipant.setScreenShareEnabled(true);
116
- }
117
- else {
132
+ } else {
118
133
  room.localParticipant.setScreenShareEnabled(true);
119
134
  }
120
135
  };
121
136
 
122
137
  return (
123
138
  <View style={styles.container}>
124
- /*...*/
125
- // Make sure the ScreenCapturePickerView exists in the view tree.
139
+ /*...*/ // Make sure the ScreenCapturePickerView exists in the view tree.
126
140
  {screenCapturePickerView}
127
141
  </View>
128
142
  );
@@ -139,3 +153,15 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
139
153
  ## License
140
154
 
141
155
  Apache License 2.0
156
+
157
+ <!--BEGIN_REPO_NAV-->
158
+ <br/><table>
159
+ <thead><tr><th colspan="2">LiveKit Ecosystem</th></tr></thead>
160
+ <tbody>
161
+ <tr><td>Client SDKs</td><td><a href="https://github.com/livekit/components-js">Components</a> · <a href="https://github.com/livekit/client-sdk-js">JavaScript</a> · <a href="https://github.com/livekit/client-sdk-rust">Rust</a> · <a href="https://github.com/livekit/client-sdk-swift">iOS/macOS</a> · <a href="https://github.com/livekit/client-sdk-android">Android</a> · <a href="https://github.com/livekit/client-sdk-flutter">Flutter</a> · <a href="https://github.com/livekit/client-sdk-unity-web">Unity (web)</a> · <b>React Native (beta)</b></td></tr><tr></tr>
162
+ <tr><td>Server SDKs</td><td><a href="https://github.com/livekit/server-sdk-js">Node.js</a> · <a href="https://github.com/livekit/server-sdk-go">Golang</a> · <a href="https://github.com/livekit/server-sdk-ruby">Ruby</a> · <a href="https://github.com/livekit/server-sdk-kotlin">Java/Kotlin</a> · <a href="https://github.com/agence104/livekit-server-sdk-php">PHP (community)</a> · <a href="https://github.com/tradablebits/livekit-server-sdk-python">Python (community)</a></td></tr><tr></tr>
163
+ <tr><td>Services</td><td><a href="https://github.com/livekit/livekit">Livekit server</a> · <a href="https://github.com/livekit/egress">Egress</a> · <a href="https://github.com/livekit/ingress">Ingress</a></td></tr><tr></tr>
164
+ <tr><td>Resources</td><td><a href="https://docs.livekit.io">Docs</a> · <a href="https://github.com/livekit-examples">Example apps</a> · <a href="https://livekit.io/cloud">Cloud</a> · <a href="https://docs.livekit.io/oss/deployment">Self-hosting</a> · <a href="https://github.com/livekit/livekit-cli">CLI</a></td></tr>
165
+ </tbody>
166
+ </table>
167
+ <!--END_REPO_NAV-->
@@ -0,0 +1,8 @@
1
+ ## This file must *NOT* be checked into Version Control Systems,
2
+ # as it contains information specific to your local configuration.
3
+ #
4
+ # Location of the SDK. This is only used by Gradle.
5
+ # For customization when using a Version Control System, please read the
6
+ # header note.
7
+ #Mon Jan 23 20:31:14 JST 2023
8
+ sdk.dir=/Users/davidliu/Library/Android/sdk
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "self:">
6
+ </FileRef>
7
+ </Workspace>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+ </dict>
8
+ </plist>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>SchemeUserState</key>
6
+ <dict>
7
+ <key>LivekitReactNative.xcscheme_^#shared#^_</key>
8
+ <dict>
9
+ <key>orderHint</key>
10
+ <integer>0</integer>
11
+ </dict>
12
+ </dict>
13
+ </dict>
14
+ </plist>
@@ -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":";;;;;;;AAAA;;AAEA;;AACA;;AAOA;;AAGA;;;;;;;;;;AAUO,MAAMA,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,IAAgB,oBAAS,MAAM;AACnC,QAAIC,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,GALqB,CAAtB;AAOA,QAAM,CAACK,WAAD,EAAcC,cAAd,IAAgC,oBAASX,UAAT,aAASA,UAAT,uBAASA,UAAU,CAAEU,WAArB,CAAtC;AACA,uBAAU,MAAM;AACdC,IAAAA,cAAc,CAACX,UAAD,aAACA,UAAD,uBAACA,UAAU,CAAEU,WAAb,CAAd;;AACA,QAAIV,UAAU,YAAYY,8BAA1B,EAA2C;AACzC,YAAMC,WAAW,GAAIC,KAAD,IAAyB;AAC3CH,QAAAA,cAAc,CAACG,KAAD,aAACA,KAAD,uBAACA,KAAK,CAAEJ,WAAR,CAAd;AACD,OAFD;;AAGAV,MAAAA,UAAU,CAACe,EAAX,CAAcC,0BAAWC,SAAzB,EAAoCJ,WAApC;AAEA,aAAO,MAAM;AACXb,QAAAA,UAAU,CAACkB,GAAX,CAAeF,0BAAWC,SAA1B,EAAqCJ,WAArC;AACD,OAFD;AAGD,KATD,MASO;AACL,aAAO,MAAM,CAAE,CAAf;AACD;AACF,GAdD,EAcG,CAACb,UAAD,CAdH;AAgBA,uBAAU,MAAM;AACd,QAAIA,UAAU,YAAYmB,+BAAtB,IAA0CnB,UAAU,CAACoB,gBAAzD,EAA2E;AACzEpB,MAAAA,UAAU,SAAV,IAAAA,UAAU,WAAV,YAAAA,UAAU,CAAEqB,kBAAZ,CAA+BjB,WAA/B;AACA,aAAO,MAAM;AACXJ,QAAAA,UAAU,SAAV,IAAAA,UAAU,WAAV,YAAAA,UAAU,CAAEsB,wBAAZ,CAAqClB,WAArC;AACD,OAFD;AAGD,KALD,MAKO;AACL,aAAO,MAAM,CAAE,CAAf;AACD;AACF,GATD,EASG,CAACJ,UAAD,EAAaI,WAAb,CATH;AAWA,sBACE,oBAAC,iBAAD;AACE,IAAA,KAAK,EAAE,EAAE,GAAGL,KAAL;AAAY,SAAGwB,MAAM,CAACC;AAAtB,KADT;AAEE,IAAA,QAAQ,EAAGC,KAAD,IAAW;AACnBrB,MAAAA,WAAW,CAACsB,QAAZ,CAAqBD,KAArB;AACD;AAJH,kBAME,oBAAC,yBAAD;AACE,IAAA,QAAQ,EAAGE,SAAD,IAAwBvB,WAAW,CAACwB,YAAZ,CAAyBD,SAAzB,CADpC;AAEE,IAAA,KAAK,EAAEJ,MAAM,CAACM;AAFhB,kBAIE,oBAAC,0BAAD;AACE,IAAA,KAAK,EAAEN,MAAM,CAACM,SADhB;AAEE,IAAA,SAAS,wBAAEnB,WAAF,aAAEA,WAAF,uBAAEA,WAAW,CAAEoB,KAAb,EAAF,mEAA0B,EAFrC;AAGE,IAAA,SAAS,EAAE7B,SAHb;AAIE,IAAA,MAAM,EAAEC,MAJV;AAKE,IAAA,MAAM,EAAEC;AALV,IAJF,CANF,CADF;AAqBD,CA/DM;;;;AAiEP,MAAMoB,MAAM,GAAGQ,wBAAWC,MAAX,CAAkB;AAC/BR,EAAAA,SAAS,EAAE,EADoB;AAE/BK,EAAAA,SAAS,EAAE;AACTI,IAAAA,IAAI,EAAE,CADG;AAETC,IAAAA,KAAK,EAAE;AAFE;AAFoB,CAAlB,CAAf;;AAQA,MAAM5B,oBAAN,CAAkD;AAAA;AAAA,qCAC9B,EAD8B;;AAAA;;AAAA;;AAAA,oCAIvC,CAJuC;;AAAA,qCAKtC,CALsC;;AAAA,wCAMnC,KANmC;;AAAA,qCAO7B,IAP6B;;AAAA;;AAAA,8CAS7B,KAT6B;;AAAA;;AAAA;;AAAA,mCAYxC,MAAM,KAAK6B,MAZ6B;;AAAA,oCAavC,MAAM,KAAKC,OAb4B;AAAA;;AAehDC,EAAAA,OAAO,GAAS;AACd,SAAKC,UAAL,GAAkB,IAAlB;AACD;;AACDC,EAAAA,aAAa,GAAS;AACpB,SAAKD,UAAL,GAAkB,KAAlB;AACD;;AAEDZ,EAAAA,QAAQ,CAACD,KAAD,EAA2B;AACjC,QAAI;AAAES,MAAAA,KAAF;AAASM,MAAAA;AAAT,QAAoBf,KAAK,CAACgB,WAAN,CAAkBC,MAA1C;AACA,SAAKP,MAAL,GAAcD,KAAd;AACA,SAAKE,OAAL,GAAeI,MAAf;;AAEA,QAAI,KAAKF,UAAT,EAAqB;AAAA;;AACnB,iCAAKK,YAAL;AACD;AACF;;AACDf,EAAAA,YAAY,CAACD,SAAD,EAAqB;AAC/B,QAAI,KAAKiB,OAAL,KAAiBjB,SAArB,EAAgC;AAC9B,WAAKiB,OAAL,GAAejB,SAAf;AACA,WAAKkB,mBAAL,GAA2BC,IAAI,CAACC,GAAL,EAA3B;;AACA,UAAI,KAAKT,UAAT,EAAqB;AAAA;;AACnB,sCAAKU,uBAAL;AACD;AACF;AACF;;AAvC+C","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,9 +74,20 @@ 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();
81
+ shimArrayAt();
82
+ }
83
+
84
+ function livekitRegisterGlobals() {
85
+ let lkGlobal = {
86
+ platform: _reactNative.Platform.OS,
87
+ devicePixelRatio: _reactNative.PixelRatio.get()
88
+ }; // @ts-ignore
89
+
90
+ global.LiveKitReactNativeGlobal = lkGlobal;
78
91
  }
79
92
 
80
93
  function fixWebrtcAdapter() {
@@ -100,4 +113,13 @@ function shimPromiseAllSettled() {
100
113
 
101
114
  allSettled.shim();
102
115
  }
116
+
117
+ function shimArrayAt() {
118
+ // Some versions of RN don't have Array.prototype.at, which is used by sdp-transform
119
+ if (!Array.prototype.at) {
120
+ var at = require('array.prototype.at');
121
+
122
+ at.shim();
123
+ }
124
+ }
103
125
  //# sourceMappingURL=index.js.map
@@ -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","shimArrayAt","lkGlobal","platform","Platform","OS","devicePixelRatio","PixelRatio","get","global","LiveKitReactNativeGlobal","window","navigator","undefined","userAgent","product","allSettled","require","shim","Array","prototype","at"],"mappings":";;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AAEA;;AAkDA;;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;;;;AAjDA;AACA;AACA;AACA;AACA;AACO,SAASA,eAAT,GAA2B;AAChC;AACAC,EAAAA,sBAAsB;AACtB;AACAC,EAAAA,gBAAgB;AAChBC,EAAAA,qBAAqB;AACrBC,EAAAA,WAAW;AACZ;;AACD,SAASH,sBAAT,GAAkC;AAChC,MAAII,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,SAASH,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAY,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,SAASf,qBAAT,GAAiC;AAC/B,MAAIgB,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD;;AAED,SAASjB,WAAT,GAAuB;AACrB;AACA,MAAI,CAACkB,KAAK,CAACC,SAAN,CAAgBC,EAArB,EAAyB;AACvB,QAAIA,EAAE,GAAGJ,OAAO,CAAC,oBAAD,CAAhB;;AACAI,IAAAA,EAAE,CAACH,IAAH;AACD;AACF","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 shimArrayAt();\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\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 * 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":"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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":["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,9 +10,20 @@ 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();
17
+ shimArrayAt();
18
+ }
19
+
20
+ function livekitRegisterGlobals() {
21
+ let lkGlobal = {
22
+ platform: Platform.OS,
23
+ devicePixelRatio: PixelRatio.get()
24
+ }; // @ts-ignore
25
+
26
+ global.LiveKitReactNativeGlobal = lkGlobal;
15
27
  }
16
28
 
17
29
  function fixWebrtcAdapter() {
@@ -38,6 +50,15 @@ function shimPromiseAllSettled() {
38
50
  allSettled.shim();
39
51
  }
40
52
 
53
+ function shimArrayAt() {
54
+ // Some versions of RN don't have Array.prototype.at, which is used by sdp-transform
55
+ if (!Array.prototype.at) {
56
+ var at = require('array.prototype.at');
57
+
58
+ at.shim();
59
+ }
60
+ }
61
+
41
62
  export * from './components/VideoView';
42
63
  export * from './useParticipant';
43
64
  export * from './useRoom';
@@ -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","shimArrayAt","lkGlobal","platform","OS","devicePixelRatio","get","global","LiveKitReactNativeGlobal","window","navigator","undefined","userAgent","product","allSettled","require","shim","Array","prototype","at"],"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;AACrBC,EAAAA,WAAW;AACZ;;AACD,SAASH,sBAAT,GAAkC;AAChC,MAAII,QAAgC,GAAG;AACrCC,IAAAA,QAAQ,EAAEN,QAAQ,CAACO,EADkB;AAErCC,IAAAA,gBAAgB,EAAET,UAAU,CAACU,GAAX;AAFmB,GAAvC,CADgC,CAMhC;;AACAC,EAAAA,MAAM,CAACC,wBAAP,GAAkCN,QAAlC;AACD;;AAED,SAASH,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAU,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,SAASb,qBAAT,GAAiC;AAC/B,MAAIc,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD;;AAED,SAASf,WAAT,GAAuB;AACrB;AACA,MAAI,CAACgB,KAAK,CAACC,SAAN,CAAgBC,EAArB,EAAyB;AACvB,QAAIA,EAAE,GAAGJ,OAAO,CAAC,oBAAD,CAAhB;;AACAI,IAAAA,EAAE,CAACH,IAAH;AACD;AACF;;AAED,cAAc,wBAAd;AACA,cAAc,kBAAd;AACA,cAAc,WAAd;AACA,SAASrB,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 shimArrayAt();\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\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.3.0",
3
+ "version": "1.0.1",
4
4
  "description": "LiveKit for React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -39,7 +39,8 @@
39
39
  "android"
40
40
  ],
41
41
  "dependencies": {
42
- "livekit-client": "^1.6.0",
42
+ "array.prototype.at": "^1.1.1",
43
+ "livekit-client": "^1.8.0",
43
44
  "promise.allsettled": "^1.0.5",
44
45
  "react-native-url-polyfill": "^1.3.0"
45
46
  },
@@ -72,7 +73,7 @@
72
73
  "peerDependencies": {
73
74
  "react": "*",
74
75
  "react-native": "*",
75
- "react-native-webrtc": "^106.0.0"
76
+ "react-native-webrtc": "^111.0.0"
76
77
  },
77
78
  "scripts": {
78
79
  "test": "jest",
@@ -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,9 +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();
19
+ shimArrayAt();
20
+ }
21
+ function livekitRegisterGlobals() {
22
+ let lkGlobal: LiveKitReactNativeInfo = {
23
+ platform: Platform.OS,
24
+ devicePixelRatio: PixelRatio.get(),
25
+ };
26
+
27
+ // @ts-ignore
28
+ global.LiveKitReactNativeGlobal = lkGlobal;
16
29
  }
17
30
 
18
31
  function fixWebrtcAdapter() {
@@ -31,6 +44,14 @@ function shimPromiseAllSettled() {
31
44
  allSettled.shim();
32
45
  }
33
46
 
47
+ function shimArrayAt() {
48
+ // Some versions of RN don't have Array.prototype.at, which is used by sdp-transform
49
+ if (!Array.prototype.at) {
50
+ var at = require('array.prototype.at');
51
+ at.shim();
52
+ }
53
+ }
54
+
34
55
  export * from './components/VideoView';
35
56
  export * from './useParticipant';
36
57
  export * from './useRoom';