@livekit/react-native 2.0.1 → 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 +4 -0
- package/android/src/main/java/com/livekit/reactnative/LiveKitReactNative.kt +4 -4
- package/android/src/main/java/com/livekit/reactnative/video/CustomVideoDecoderFactory.kt +67 -0
- package/android/src/main/java/com/livekit/reactnative/video/CustomVideoEncoderFactory.kt +74 -0
- package/lib/commonjs/components/LiveKitRoom.js +43 -0
- package/lib/commonjs/components/LiveKitRoom.js.map +1 -0
- package/lib/commonjs/components/VideoTrack.js +171 -0
- package/lib/commonjs/components/VideoTrack.js.map +1 -0
- package/lib/commonjs/components/VideoView.js +15 -11
- package/lib/commonjs/components/VideoView.js.map +1 -1
- package/lib/commonjs/components/ViewPortDetector.js +134 -39
- package/lib/commonjs/components/ViewPortDetector.js.map +1 -1
- package/lib/commonjs/hooks.js +232 -0
- package/lib/commonjs/hooks.js.map +1 -0
- package/lib/commonjs/index.js +42 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/useParticipant.js +1 -0
- package/lib/commonjs/useParticipant.js.map +1 -1
- package/lib/commonjs/useRoom.js +1 -0
- package/lib/commonjs/useRoom.js.map +1 -1
- package/lib/module/components/LiveKitRoom.js +32 -0
- package/lib/module/components/LiveKitRoom.js.map +1 -0
- package/lib/module/components/VideoTrack.js +152 -0
- package/lib/module/components/VideoTrack.js.map +1 -0
- package/lib/module/components/VideoView.js +20 -12
- package/lib/module/components/VideoView.js.map +1 -1
- package/lib/module/components/ViewPortDetector.js +134 -40
- package/lib/module/components/ViewPortDetector.js.map +1 -1
- package/lib/module/hooks.js +3 -0
- package/lib/module/hooks.js.map +1 -0
- package/lib/module/index.js +9 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/useParticipant.js +3 -0
- package/lib/module/useParticipant.js.map +1 -1
- package/lib/module/useRoom.js +2 -0
- package/lib/module/useRoom.js.map +1 -1
- package/lib/typescript/components/LiveKitRoom.d.ts +90 -0
- package/lib/typescript/components/VideoTrack.d.ts +11 -0
- package/lib/typescript/components/VideoView.d.ts +6 -0
- package/lib/typescript/components/ViewPortDetector.d.ts +11 -4
- package/lib/typescript/hooks.d.ts +2 -0
- package/lib/typescript/index.d.ts +3 -0
- package/lib/typescript/useParticipant.d.ts +2 -0
- package/lib/typescript/useRoom.d.ts +1 -0
- package/livekit-react-native.podspec +5 -0
- package/package.json +2 -1
- package/src/components/LiveKitRoom.tsx +118 -0
- package/src/components/VideoTrack.tsx +150 -0
- package/src/components/VideoView.tsx +26 -13
- package/src/components/ViewPortDetector.tsx +112 -21
- package/src/hooks.ts +40 -0
- package/src/index.tsx +6 -4
- package/src/useParticipant.ts +2 -1
- package/src/useRoom.ts +1 -0
- package/android/local.properties +0 -8
- package/ios/LivekitReactNative.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/LivekitReactNative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/ios/LivekitReactNative.xcodeproj/project.xcworkspace/xcuserdata/davidliu.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/LivekitReactNative.xcodeproj/xcuserdata/davidliu.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
package/README.md
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
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.
|
|
15
15
|
<!--END_DESCRIPTION-->
|
|
16
16
|
|
|
17
|
+
> [!NOTE]
|
|
18
|
+
> This is v2 of the React-Native SDK. When migrating from v1.x to v2.x you might encounter a small set of breaking changes.
|
|
19
|
+
> Read the [migration guide](https://docs.livekit.io/guides/migrate-from-v1/) for a detailed overview of what has changed.
|
|
20
|
+
|
|
17
21
|
## Installation
|
|
18
22
|
|
|
19
23
|
### NPM
|
|
@@ -4,8 +4,8 @@ import android.app.Application
|
|
|
4
4
|
import android.content.Context
|
|
5
5
|
import android.os.Build
|
|
6
6
|
import com.livekit.reactnative.audio.AudioType
|
|
7
|
-
import com.livekit.reactnative.video.
|
|
8
|
-
import com.livekit.reactnative.video.
|
|
7
|
+
import com.livekit.reactnative.video.CustomVideoEncoderFactory
|
|
8
|
+
import com.livekit.reactnative.video.CustomVideoDecoderFactory
|
|
9
9
|
import com.oney.WebRTCModule.WebRTCModuleOptions
|
|
10
10
|
import org.webrtc.audio.JavaAudioDeviceModule
|
|
11
11
|
|
|
@@ -21,8 +21,8 @@ object LiveKitReactNative {
|
|
|
21
21
|
@JvmOverloads
|
|
22
22
|
fun setup(context: Context, audioType: AudioType = AudioType.CommunicationAudioType()) {
|
|
23
23
|
val options = WebRTCModuleOptions.getInstance()
|
|
24
|
-
options.videoEncoderFactory =
|
|
25
|
-
options.videoDecoderFactory =
|
|
24
|
+
options.videoEncoderFactory = CustomVideoEncoderFactory(null, true, true)
|
|
25
|
+
options.videoDecoderFactory = CustomVideoDecoderFactory()
|
|
26
26
|
|
|
27
27
|
val useHardwareAudioProcessing = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
|
28
28
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023-2024 LiveKit, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package com.livekit.reactnative.video
|
|
18
|
+
|
|
19
|
+
import com.oney.WebRTCModule.webrtcutils.SoftwareVideoDecoderFactoryProxy
|
|
20
|
+
import org.webrtc.EglBase
|
|
21
|
+
import org.webrtc.SoftwareVideoDecoderFactory
|
|
22
|
+
import org.webrtc.VideoCodecInfo
|
|
23
|
+
import org.webrtc.VideoDecoder
|
|
24
|
+
import org.webrtc.VideoDecoderFactory
|
|
25
|
+
import org.webrtc.WrappedVideoDecoderFactory
|
|
26
|
+
|
|
27
|
+
open class CustomVideoDecoderFactory(
|
|
28
|
+
private var forceSWCodec: Boolean = false,
|
|
29
|
+
private var forceSWCodecs: List<String> = listOf("VP9"),
|
|
30
|
+
) : VideoDecoderFactory {
|
|
31
|
+
private val softwareVideoDecoderFactory = SoftwareVideoDecoderFactoryProxy()
|
|
32
|
+
private val wrappedVideoDecoderFactory = WrappedVideoDecoderFactoryProxy()
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Set to true to force software codecs.
|
|
36
|
+
*/
|
|
37
|
+
fun setForceSWCodec(forceSWCodec: Boolean) {
|
|
38
|
+
this.forceSWCodec = forceSWCodec
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Set a list of codecs for which to use software codecs.
|
|
43
|
+
*/
|
|
44
|
+
fun setForceSWCodecList(forceSWCodecs: List<String>) {
|
|
45
|
+
this.forceSWCodecs = forceSWCodecs
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override fun createDecoder(videoCodecInfo: VideoCodecInfo): VideoDecoder? {
|
|
49
|
+
if (forceSWCodec) {
|
|
50
|
+
return softwareVideoDecoderFactory.createDecoder(videoCodecInfo)
|
|
51
|
+
}
|
|
52
|
+
if (forceSWCodecs.isNotEmpty()) {
|
|
53
|
+
if (forceSWCodecs.contains(videoCodecInfo.name)) {
|
|
54
|
+
return softwareVideoDecoderFactory.createDecoder(videoCodecInfo)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return wrappedVideoDecoderFactory.createDecoder(videoCodecInfo)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override fun getSupportedCodecs(): Array<VideoCodecInfo> {
|
|
61
|
+
return if (forceSWCodec && forceSWCodecs.isEmpty()) {
|
|
62
|
+
softwareVideoDecoderFactory.supportedCodecs
|
|
63
|
+
} else {
|
|
64
|
+
wrappedVideoDecoderFactory.supportedCodecs
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023-2024 LiveKit, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package com.livekit.reactnative.video
|
|
18
|
+
|
|
19
|
+
import com.oney.WebRTCModule.webrtcutils.SoftwareVideoEncoderFactoryProxy
|
|
20
|
+
import org.webrtc.EglBase
|
|
21
|
+
import org.webrtc.SoftwareVideoEncoderFactory
|
|
22
|
+
import org.webrtc.VideoCodecInfo
|
|
23
|
+
import org.webrtc.VideoEncoder
|
|
24
|
+
import org.webrtc.VideoEncoderFactory
|
|
25
|
+
|
|
26
|
+
open class CustomVideoEncoderFactory(
|
|
27
|
+
sharedContext: EglBase.Context?,
|
|
28
|
+
enableIntelVp8Encoder: Boolean,
|
|
29
|
+
enableH264HighProfile: Boolean,
|
|
30
|
+
private var forceSWCodec: Boolean = false,
|
|
31
|
+
private var forceSWCodecs: List<String> = listOf("VP9"),
|
|
32
|
+
) : VideoEncoderFactory {
|
|
33
|
+
private val softwareVideoEncoderFactory = SoftwareVideoEncoderFactoryProxy()
|
|
34
|
+
private val simulcastVideoEncoderFactoryWrapper: SimulcastVideoEncoderFactoryWrapper
|
|
35
|
+
|
|
36
|
+
init {
|
|
37
|
+
simulcastVideoEncoderFactoryWrapper =
|
|
38
|
+
SimulcastVideoEncoderFactoryWrapper(sharedContext, enableIntelVp8Encoder, enableH264HighProfile)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Set to true to force software codecs.
|
|
43
|
+
*/
|
|
44
|
+
fun setForceSWCodec(forceSWCodec: Boolean) {
|
|
45
|
+
this.forceSWCodec = forceSWCodec
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set a list of codecs for which to use software codecs.
|
|
50
|
+
*/
|
|
51
|
+
fun setForceSWCodecList(forceSWCodecs: List<String>) {
|
|
52
|
+
this.forceSWCodecs = forceSWCodecs
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override fun createEncoder(videoCodecInfo: VideoCodecInfo): VideoEncoder? {
|
|
56
|
+
if (forceSWCodec) {
|
|
57
|
+
return softwareVideoEncoderFactory.createEncoder(videoCodecInfo)
|
|
58
|
+
}
|
|
59
|
+
if (forceSWCodecs.isNotEmpty()) {
|
|
60
|
+
if (forceSWCodecs.contains(videoCodecInfo.name)) {
|
|
61
|
+
return softwareVideoEncoderFactory.createEncoder(videoCodecInfo)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return simulcastVideoEncoderFactoryWrapper.createEncoder(videoCodecInfo)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
override fun getSupportedCodecs(): Array<VideoCodecInfo> {
|
|
68
|
+
return if (forceSWCodec && forceSWCodecs.isEmpty()) {
|
|
69
|
+
softwareVideoEncoderFactory.supportedCodecs
|
|
70
|
+
} else {
|
|
71
|
+
simulcastVideoEncoderFactoryWrapper.supportedCodecs
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.LiveKitRoom = LiveKitRoom;
|
|
7
|
+
|
|
8
|
+
var _componentsReact = require("@livekit/components-react");
|
|
9
|
+
|
|
10
|
+
var React = _interopRequireWildcard(require("react"));
|
|
11
|
+
|
|
12
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
13
|
+
|
|
14
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The `LiveKitRoom` component provides the room context to all its child components.
|
|
18
|
+
* It is generally the starting point of your LiveKit app and the root of the LiveKit component tree.
|
|
19
|
+
* It provides the room state as a React context to all child components, so you don't have to pass it yourself.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* <LiveKitRoom
|
|
24
|
+
* token='<livekit-token>'
|
|
25
|
+
* serverUrl='<url-to-livekit-server>'
|
|
26
|
+
* connect={true}
|
|
27
|
+
* >
|
|
28
|
+
* ...
|
|
29
|
+
* </LiveKitRoom>
|
|
30
|
+
* ```
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
function LiveKitRoom(props) {
|
|
34
|
+
const {
|
|
35
|
+
room
|
|
36
|
+
} = (0, _componentsReact.useLiveKitRoom)(props);
|
|
37
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, room && /*#__PURE__*/React.createElement(_componentsReact.RoomContext.Provider, {
|
|
38
|
+
value: room
|
|
39
|
+
}, /*#__PURE__*/React.createElement(_componentsReact.LKFeatureContext.Provider, {
|
|
40
|
+
value: props.featureFlags
|
|
41
|
+
}, props.children)));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=LiveKitRoom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["LiveKitRoom.tsx"],"names":["LiveKitRoom","props","room","featureFlags","children"],"mappings":";;;;;;;AAAA;;AAcA;;;;;;AAyEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,WAAT,CAAqBC,KAArB,EAAuE;AAC5E,QAAM;AAAEC,IAAAA;AAAF,MAAW,qCAAeD,KAAf,CAAjB;AACA,sBACE,0CACGC,IAAI,iBACH,oBAAC,4BAAD,CAAa,QAAb;AAAsB,IAAA,KAAK,EAAEA;AAA7B,kBACE,oBAAC,iCAAD,CAAkB,QAAlB;AAA2B,IAAA,KAAK,EAAED,KAAK,CAACE;AAAxC,KACGF,KAAK,CAACG,QADT,CADF,CAFJ,CADF;AAWD","sourcesContent":["import {\n FeatureFlags,\n LKFeatureContext,\n RoomContext,\n useLiveKitRoom,\n} from '@livekit/components-react';\nimport type {\n AudioCaptureOptions,\n RoomConnectOptions,\n RoomOptions,\n ScreenShareCaptureOptions,\n VideoCaptureOptions,\n} from 'livekit-client';\nimport type { MediaDeviceFailure, Room } from 'livekit-client';\nimport * as React from 'react';\n\n/** @public */\nexport interface LiveKitRoomProps {\n /**\n * URL to the LiveKit server.\n * For example: `wss://<domain>.livekit.cloud`\n * To simplify the implementation, `undefined` is also accepted as an intermediate value, but only with a valid string url can the connection be established.\n */\n serverUrl: string | undefined;\n /**\n * A user specific access token for a client to authenticate to the room.\n * This token is necessary to establish a connection to the room.\n * To simplify the implementation, `undefined` is also accepted as an intermediate value, but only with a valid string token can the connection be established.\n *\n * @see https://docs.livekit.io/cloud/project-management/keys-and-tokens/#generating-access-tokens\n */\n token: string | undefined;\n /**\n * Publish audio immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/AudioCaptureOptions.html\n */\n audio?: AudioCaptureOptions | boolean;\n /**\n * Publish video immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/VideoCaptureOptions.html\n */\n video?: VideoCaptureOptions | boolean;\n /**\n * Publish screen share immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/ScreenShareCaptureOptions.html\n */\n screen?: ScreenShareCaptureOptions | boolean;\n /**\n * If set to true a connection to LiveKit room is initiated.\n * @defaultValue `false`\n */\n connect?: boolean;\n /**\n * Options for when creating a new room.\n * When you pass your own room instance to this component, these options have no effect.\n * Instead, set the options directly in the room instance.\n *\n * @see https://docs.livekit.io/client-sdk-js/interfaces/RoomOptions.html\n */\n options?: RoomOptions;\n /**\n * Define options how to connect to the LiveKit server.\n *\n * @see https://docs.livekit.io/client-sdk-js/interfaces/RoomConnectOptions.html\n */\n connectOptions?: RoomConnectOptions;\n onConnected?: () => void;\n onDisconnected?: () => void;\n onError?: (error: Error) => void;\n onMediaDeviceFailure?: (failure?: MediaDeviceFailure) => void;\n onEncryptionError?: (error: Error) => void;\n /**\n * Optional room instance.\n * By passing your own room instance you overwrite the `options` parameter,\n * make sure to set the options directly on the room instance itself.\n */\n room?: Room;\n\n simulateParticipants?: number | undefined;\n\n /** @experimental */\n featureFlags?: FeatureFlags | undefined;\n}\n\n/**\n * The `LiveKitRoom` component provides the room context to all its child components.\n * It is generally the starting point of your LiveKit app and the root of the LiveKit component tree.\n * It provides the room state as a React context to all child components, so you don't have to pass it yourself.\n *\n * @example\n * ```tsx\n * <LiveKitRoom\n * token='<livekit-token>'\n * serverUrl='<url-to-livekit-server>'\n * connect={true}\n * >\n * ...\n * </LiveKitRoom>\n * ```\n * @public\n */\nexport function LiveKitRoom(props: React.PropsWithChildren<LiveKitRoomProps>) {\n const { room } = useLiveKitRoom(props);\n return (\n <>\n {room && (\n <RoomContext.Provider value={room}>\n <LKFeatureContext.Provider value={props.featureFlags}>\n {props.children}\n </LKFeatureContext.Provider>\n </RoomContext.Provider>\n )}\n </>\n );\n}\n"]}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.VideoTrack = void 0;
|
|
7
|
+
|
|
8
|
+
var React = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
|
|
12
|
+
var _livekitClient = require("livekit-client");
|
|
13
|
+
|
|
14
|
+
var _reactNativeWebrtc = require("@livekit/react-native-webrtc");
|
|
15
|
+
|
|
16
|
+
var _ViewPortDetector = _interopRequireDefault(require("./ViewPortDetector"));
|
|
17
|
+
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
+
|
|
20
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
|
+
|
|
22
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
23
|
+
|
|
24
|
+
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; }
|
|
25
|
+
|
|
26
|
+
const VideoTrack = _ref => {
|
|
27
|
+
var _mediaStream$toURL;
|
|
28
|
+
|
|
29
|
+
let {
|
|
30
|
+
style = {},
|
|
31
|
+
trackRef,
|
|
32
|
+
objectFit = 'cover',
|
|
33
|
+
zOrder,
|
|
34
|
+
mirror
|
|
35
|
+
} = _ref;
|
|
36
|
+
const [elementInfo] = (0, React.useState)(() => {
|
|
37
|
+
var _trackRef$publication;
|
|
38
|
+
|
|
39
|
+
let info = new VideoTrackElementInfo();
|
|
40
|
+
info.id = trackRef === null || trackRef === void 0 ? void 0 : (_trackRef$publication = trackRef.publication) === null || _trackRef$publication === void 0 ? void 0 : _trackRef$publication.trackSid;
|
|
41
|
+
return info;
|
|
42
|
+
});
|
|
43
|
+
const layoutOnChange = (0, React.useCallback)(event => elementInfo.onLayout(event), [elementInfo]);
|
|
44
|
+
const visibilityOnChange = (0, React.useCallback)(isVisible => elementInfo.onVisibility(isVisible), [elementInfo]);
|
|
45
|
+
const videoTrack = trackRef === null || trackRef === void 0 ? void 0 : trackRef.publication.track;
|
|
46
|
+
const shouldObserveVisibility = (0, React.useMemo)(() => {
|
|
47
|
+
return videoTrack instanceof _livekitClient.RemoteVideoTrack && videoTrack.isAdaptiveStream;
|
|
48
|
+
}, [videoTrack]);
|
|
49
|
+
const [mediaStream, setMediaStream] = (0, React.useState)(videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.mediaStream);
|
|
50
|
+
(0, React.useEffect)(() => {
|
|
51
|
+
setMediaStream(videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.mediaStream);
|
|
52
|
+
|
|
53
|
+
if (videoTrack instanceof _livekitClient.LocalVideoTrack) {
|
|
54
|
+
const onRestarted = track => {
|
|
55
|
+
setMediaStream(track === null || track === void 0 ? void 0 : track.mediaStream);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
videoTrack.on(_livekitClient.TrackEvent.Restarted, onRestarted);
|
|
59
|
+
return () => {
|
|
60
|
+
videoTrack.off(_livekitClient.TrackEvent.Restarted, onRestarted);
|
|
61
|
+
};
|
|
62
|
+
} else {
|
|
63
|
+
return () => {};
|
|
64
|
+
}
|
|
65
|
+
}, [videoTrack]);
|
|
66
|
+
(0, React.useEffect)(() => {
|
|
67
|
+
if (videoTrack instanceof _livekitClient.RemoteVideoTrack && videoTrack.isAdaptiveStream) {
|
|
68
|
+
videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.observeElementInfo(elementInfo);
|
|
69
|
+
return () => {
|
|
70
|
+
videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.stopObservingElementInfo(elementInfo);
|
|
71
|
+
};
|
|
72
|
+
} else {
|
|
73
|
+
return () => {};
|
|
74
|
+
}
|
|
75
|
+
}, [videoTrack, elementInfo]);
|
|
76
|
+
return /*#__PURE__*/React.createElement(_reactNative.View, {
|
|
77
|
+
style: { ...style,
|
|
78
|
+
...styles.container
|
|
79
|
+
},
|
|
80
|
+
onLayout: layoutOnChange
|
|
81
|
+
}, /*#__PURE__*/React.createElement(_ViewPortDetector.default, {
|
|
82
|
+
onChange: visibilityOnChange,
|
|
83
|
+
style: styles.videoTrack,
|
|
84
|
+
disabled: !shouldObserveVisibility,
|
|
85
|
+
propKey: videoTrack
|
|
86
|
+
}, /*#__PURE__*/React.createElement(_reactNativeWebrtc.RTCView, {
|
|
87
|
+
style: styles.videoTrack,
|
|
88
|
+
streamURL: (_mediaStream$toURL = mediaStream === null || mediaStream === void 0 ? void 0 : mediaStream.toURL()) !== null && _mediaStream$toURL !== void 0 ? _mediaStream$toURL : '',
|
|
89
|
+
objectFit: objectFit,
|
|
90
|
+
zOrder: zOrder,
|
|
91
|
+
mirror: mirror
|
|
92
|
+
})));
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
exports.VideoTrack = VideoTrack;
|
|
96
|
+
|
|
97
|
+
const styles = _reactNative.StyleSheet.create({
|
|
98
|
+
container: {},
|
|
99
|
+
videoTrack: {
|
|
100
|
+
flex: 1,
|
|
101
|
+
width: '100%'
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
class VideoTrackElementInfo {
|
|
106
|
+
constructor() {
|
|
107
|
+
_defineProperty(this, "element", {});
|
|
108
|
+
|
|
109
|
+
_defineProperty(this, "something", void 0);
|
|
110
|
+
|
|
111
|
+
_defineProperty(this, "id", void 0);
|
|
112
|
+
|
|
113
|
+
_defineProperty(this, "_width", 0);
|
|
114
|
+
|
|
115
|
+
_defineProperty(this, "_height", 0);
|
|
116
|
+
|
|
117
|
+
_defineProperty(this, "_observing", false);
|
|
118
|
+
|
|
119
|
+
_defineProperty(this, "visible", true);
|
|
120
|
+
|
|
121
|
+
_defineProperty(this, "visibilityChangedAt", void 0);
|
|
122
|
+
|
|
123
|
+
_defineProperty(this, "pictureInPicture", false);
|
|
124
|
+
|
|
125
|
+
_defineProperty(this, "handleResize", void 0);
|
|
126
|
+
|
|
127
|
+
_defineProperty(this, "handleVisibilityChanged", void 0);
|
|
128
|
+
|
|
129
|
+
_defineProperty(this, "width", () => this._width);
|
|
130
|
+
|
|
131
|
+
_defineProperty(this, "height", () => this._height);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
observe() {
|
|
135
|
+
this._observing = true;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
stopObserving() {
|
|
139
|
+
this._observing = false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
onLayout(event) {
|
|
143
|
+
let {
|
|
144
|
+
width,
|
|
145
|
+
height
|
|
146
|
+
} = event.nativeEvent.layout;
|
|
147
|
+
this._width = width;
|
|
148
|
+
this._height = height;
|
|
149
|
+
|
|
150
|
+
if (this._observing) {
|
|
151
|
+
var _this$handleResize;
|
|
152
|
+
|
|
153
|
+
(_this$handleResize = this.handleResize) === null || _this$handleResize === void 0 ? void 0 : _this$handleResize.call(this);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
onVisibility(isVisible) {
|
|
158
|
+
if (this.visible !== isVisible) {
|
|
159
|
+
this.visible = isVisible;
|
|
160
|
+
this.visibilityChangedAt = Date.now();
|
|
161
|
+
|
|
162
|
+
if (this._observing) {
|
|
163
|
+
var _this$handleVisibilit;
|
|
164
|
+
|
|
165
|
+
(_this$handleVisibilit = this.handleVisibilityChanged) === null || _this$handleVisibilit === void 0 ? void 0 : _this$handleVisibilit.call(this);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=VideoTrack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["VideoTrack.tsx"],"names":["VideoTrack","style","trackRef","objectFit","zOrder","mirror","elementInfo","info","VideoTrackElementInfo","id","publication","trackSid","layoutOnChange","event","onLayout","visibilityOnChange","isVisible","onVisibility","videoTrack","track","shouldObserveVisibility","RemoteVideoTrack","isAdaptiveStream","mediaStream","setMediaStream","LocalVideoTrack","onRestarted","on","TrackEvent","Restarted","off","observeElementInfo","stopObservingElementInfo","styles","container","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} from 'livekit-client';\nimport { RTCView } from '@livekit/react-native-webrtc';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\nimport type { TrackReference } from '@livekit/components-react';\n\nexport type VideoTrackProps = {\n trackRef: TrackReference | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\nexport const VideoTrack = ({\n style = {},\n trackRef,\n objectFit = 'cover',\n zOrder,\n mirror,\n}: VideoTrackProps) => {\n const [elementInfo] = useState(() => {\n let info = new VideoTrackElementInfo();\n info.id = trackRef?.publication?.trackSid;\n return info;\n });\n\n const layoutOnChange = useCallback(\n (event: LayoutChangeEvent) => elementInfo.onLayout(event),\n [elementInfo]\n );\n const visibilityOnChange = useCallback(\n (isVisible: boolean) => elementInfo.onVisibility(isVisible),\n [elementInfo]\n );\n\n const videoTrack = trackRef?.publication.track;\n\n const shouldObserveVisibility = useMemo(() => {\n return (\n videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream\n );\n }, [videoTrack]);\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 style={{ ...style, ...styles.container }} onLayout={layoutOnChange}>\n <ViewPortDetector\n onChange={visibilityOnChange}\n style={styles.videoTrack}\n disabled={!shouldObserveVisibility}\n propKey={videoTrack}\n >\n <RTCView\n style={styles.videoTrack}\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 videoTrack: {\n flex: 1,\n width: '100%',\n },\n});\n\nclass VideoTrackElementInfo 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"]}
|
|
@@ -23,6 +23,9 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
23
23
|
|
|
24
24
|
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; }
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* @deprecated use `VideoTrack` and `VideoTrackProps` instead.
|
|
28
|
+
*/
|
|
26
29
|
const VideoView = _ref => {
|
|
27
30
|
var _mediaStream$toURL;
|
|
28
31
|
|
|
@@ -39,6 +42,11 @@ const VideoView = _ref => {
|
|
|
39
42
|
info.something = videoTrack;
|
|
40
43
|
return info;
|
|
41
44
|
});
|
|
45
|
+
const layoutOnChange = (0, React.useCallback)(event => elementInfo.onLayout(event), [elementInfo]);
|
|
46
|
+
const visibilityOnChange = (0, React.useCallback)(isVisible => elementInfo.onVisibility(isVisible), [elementInfo]);
|
|
47
|
+
const shouldObserveVisibility = (0, React.useMemo)(() => {
|
|
48
|
+
return videoTrack instanceof _livekitClient.RemoteVideoTrack && videoTrack.isAdaptiveStream;
|
|
49
|
+
}, [videoTrack]);
|
|
42
50
|
const [mediaStream, setMediaStream] = (0, React.useState)(videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.mediaStream);
|
|
43
51
|
(0, React.useEffect)(() => {
|
|
44
52
|
setMediaStream(videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.mediaStream);
|
|
@@ -70,18 +78,14 @@ const VideoView = _ref => {
|
|
|
70
78
|
style: { ...style,
|
|
71
79
|
...styles.container
|
|
72
80
|
},
|
|
73
|
-
onLayout:
|
|
74
|
-
elementInfo.onLayout(event);
|
|
75
|
-
}
|
|
81
|
+
onLayout: layoutOnChange
|
|
76
82
|
}, /*#__PURE__*/React.createElement(_ViewPortDetector.default, {
|
|
77
|
-
onChange:
|
|
78
|
-
style: styles.videoView
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
width: '100%'
|
|
84
|
-
},
|
|
83
|
+
onChange: visibilityOnChange,
|
|
84
|
+
style: styles.videoView,
|
|
85
|
+
disabled: !shouldObserveVisibility,
|
|
86
|
+
propKey: videoTrack
|
|
87
|
+
}, /*#__PURE__*/React.createElement(_reactNativeWebrtc.RTCView, {
|
|
88
|
+
style: styles.videoView,
|
|
85
89
|
streamURL: (_mediaStream$toURL = mediaStream === null || mediaStream === void 0 ? void 0 : mediaStream.toURL()) !== null && _mediaStream$toURL !== void 0 ? _mediaStream$toURL : '',
|
|
86
90
|
objectFit: objectFit,
|
|
87
91
|
zOrder: zOrder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["VideoView.tsx"],"names":["VideoView","style","videoTrack","objectFit","zOrder","mirror","elementInfo","info","VideoViewElementInfo","id","sid","something","
|
|
1
|
+
{"version":3,"sources":["VideoView.tsx"],"names":["VideoView","style","videoTrack","objectFit","zOrder","mirror","elementInfo","info","VideoViewElementInfo","id","sid","something","layoutOnChange","event","onLayout","visibilityOnChange","isVisible","onVisibility","shouldObserveVisibility","RemoteVideoTrack","isAdaptiveStream","mediaStream","setMediaStream","LocalVideoTrack","onRestarted","track","on","TrackEvent","Restarted","off","observeElementInfo","stopObservingElementInfo","styles","container","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 '@livekit/react-native-webrtc';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\n\n/**\n * @deprecated use `VideoTrack` and `VideoTrackProps` instead.\n */\nexport type Props = {\n videoTrack?: VideoTrack | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\n/**\n * @deprecated use `VideoTrack` and `VideoTrackProps` instead.\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 layoutOnChange = useCallback(\n (event: LayoutChangeEvent) => elementInfo.onLayout(event),\n [elementInfo]\n );\n const visibilityOnChange = useCallback(\n (isVisible: boolean) => elementInfo.onVisibility(isVisible),\n [elementInfo]\n );\n const shouldObserveVisibility = useMemo(() => {\n return (\n videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream\n );\n }, [videoTrack]);\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 style={{ ...style, ...styles.container }} onLayout={layoutOnChange}>\n <ViewPortDetector\n onChange={visibilityOnChange}\n style={styles.videoView}\n disabled={!shouldObserveVisibility}\n propKey={videoTrack}\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"]}
|