@livekit/react-native 1.3.0 → 1.4.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 +53 -10
- package/android/build.gradle +2 -2
- package/android/src/main/java/com/livekit/reactnative/video/SimulcastVideoEncoderFactoryWrapper.kt +2 -1
- package/ios/AudioUtils.h +9 -0
- package/ios/AudioUtils.m +48 -0
- package/ios/LivekitReactNative.m +45 -0
- package/ios/LivekitReactNative.xcodeproj/project.xcworkspace/xcuserdata/davidliu.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/lib/commonjs/audio/AudioManager.js +108 -0
- package/lib/commonjs/audio/AudioManager.js.map +1 -0
- package/lib/commonjs/audio/AudioSession.js +31 -0
- package/lib/commonjs/audio/AudioSession.js.map +1 -1
- package/lib/commonjs/index.js +71 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/logger.js +32 -0
- package/lib/commonjs/logger.js.map +1 -0
- package/lib/module/audio/AudioManager.js +92 -0
- package/lib/module/audio/AudioManager.js.map +1 -0
- package/lib/module/audio/AudioSession.js +29 -0
- package/lib/module/audio/AudioSession.js.map +1 -1
- package/lib/module/index.js +4 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/logger.js +18 -0
- package/lib/module/logger.js.map +1 -0
- package/lib/typescript/audio/AudioManager.d.ts +11 -0
- package/lib/typescript/audio/AudioSession.d.ts +11 -0
- package/lib/typescript/index.d.ts +5 -2
- package/lib/typescript/logger.d.ts +13 -0
- package/package.json +5 -4
- package/src/audio/AudioManager.ts +119 -0
- package/src/audio/AudioSession.ts +72 -0
- package/src/index.tsx +18 -0
- package/src/logger.ts +23 -0
package/README.md
CHANGED
|
@@ -39,13 +39,16 @@ In your [MainApplication.java](https://github.com/livekit/client-sdk-react-nativ
|
|
|
39
39
|
|
|
40
40
|
```
|
|
41
41
|
import com.livekit.reactnative.LiveKitReactNative;
|
|
42
|
+
import com.livekit.reactnative.audio.AudioType;
|
|
42
43
|
|
|
43
44
|
public class MainApplication extends Application implements ReactApplication {
|
|
44
45
|
|
|
45
46
|
@Override
|
|
46
47
|
public void onCreate() {
|
|
47
48
|
// Place this above any other RN related initialization
|
|
48
|
-
|
|
49
|
+
// When AudioType is omitted, it'll default to CommunicationAudioType
|
|
50
|
+
// use MediaAudioType if user is only consuming audio, and not publishing
|
|
51
|
+
LiveKitReactNative.setup(this, new AudioType.CommunicationAudioType());
|
|
49
52
|
|
|
50
53
|
//...
|
|
51
54
|
}
|
|
@@ -137,20 +140,26 @@ to manage the audio session on native platforms. This class wraps either [AudioM
|
|
|
137
140
|
|
|
138
141
|
You can customize the configuration of the audio session with `configureAudio`.
|
|
139
142
|
|
|
143
|
+
### Media playback
|
|
144
|
+
|
|
145
|
+
By default, the audio session is set up for bidirectional communication. In this mode, the audio framework exhibits the following behaviors:
|
|
146
|
+
|
|
147
|
+
- The volume cannot be reduced to 0.
|
|
148
|
+
- Echo cancellation is available and is enabled by default.
|
|
149
|
+
- A microphone indicator can be displayed, depending on the platform.
|
|
150
|
+
|
|
151
|
+
If you're leveraging LiveKit primarily for media playback, you have the option to reconfigure the audio session to better suit media playback. Here's how:
|
|
152
|
+
|
|
153
|
+
Note: iOS audio session customization is in development, and will be documented here when released.
|
|
154
|
+
|
|
140
155
|
```js
|
|
141
156
|
useEffect(() => {
|
|
142
157
|
let connect = async () => {
|
|
143
158
|
// configure audio session prior to starting it.
|
|
144
159
|
await AudioSession.configureAudio({
|
|
145
160
|
android: {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
// for details on audio and focus modes.
|
|
149
|
-
audioMode: 'normal',
|
|
150
|
-
audioFocusMode: 'gain',
|
|
151
|
-
},
|
|
152
|
-
ios: {
|
|
153
|
-
defaultOutput: 'earpiece',
|
|
161
|
+
// currently supports .media and .communication presets
|
|
162
|
+
audioTypeOptions: AndroidAudioTypePresets.media,
|
|
154
163
|
},
|
|
155
164
|
});
|
|
156
165
|
await AudioSession.startAudioSession();
|
|
@@ -164,6 +173,29 @@ useEffect(() => {
|
|
|
164
173
|
}, [url, token, room]);
|
|
165
174
|
```
|
|
166
175
|
|
|
176
|
+
### Customizing audio session
|
|
177
|
+
|
|
178
|
+
Instead of using our presets, you can further customize the audio session to suit your specific needs.
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
await AudioSession.configureAudio({
|
|
182
|
+
android: {
|
|
183
|
+
preferredOutputList: ['earpiece'],
|
|
184
|
+
// See [AudioManager](https://developer.android.com/reference/android/media/AudioManager)
|
|
185
|
+
// for details on audio and focus modes.
|
|
186
|
+
audioTypeOptions: {
|
|
187
|
+
manageAudioFocus: true,
|
|
188
|
+
audioMode: 'normal',
|
|
189
|
+
audioFocusMode: 'gain',
|
|
190
|
+
audioStreamType: 'music',
|
|
191
|
+
audioAttributesUsageType: 'media',
|
|
192
|
+
audioAttributesContentType: 'unknown',
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
await AudioSession.startAudioSession();
|
|
197
|
+
```
|
|
198
|
+
|
|
167
199
|
## Screenshare
|
|
168
200
|
|
|
169
201
|
Enabling screenshare requires extra installation steps:
|
|
@@ -223,7 +255,18 @@ return (
|
|
|
223
255
|
|
|
224
256
|
### Note
|
|
225
257
|
|
|
226
|
-
|
|
258
|
+
You will not be able to publish camera or microphone tracks on iOS Simulator.
|
|
259
|
+
|
|
260
|
+
## Troubleshooting
|
|
261
|
+
|
|
262
|
+
#### Cannot read properties of undefined (reading 'split')
|
|
263
|
+
|
|
264
|
+
This error could happen if you are using yarn and have incompatible versions of dependencies with livekit-client.
|
|
265
|
+
|
|
266
|
+
To fix this, you can either:
|
|
267
|
+
|
|
268
|
+
- use another package manager, like npm
|
|
269
|
+
- use [yarn-deduplicate](https://www.npmjs.com/package/yarn-deduplicate) to deduplicate dependencies
|
|
227
270
|
|
|
228
271
|
## Contributing
|
|
229
272
|
|
package/android/build.gradle
CHANGED
|
@@ -129,8 +129,8 @@ dependencies {
|
|
|
129
129
|
// noinspection GradleDynamicVersion
|
|
130
130
|
api 'com.facebook.react:react-native:+'
|
|
131
131
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
132
|
-
api 'com.github.davidliu:audioswitch:
|
|
133
|
-
api 'io.github.webrtc-sdk:android:
|
|
132
|
+
api 'com.github.davidliu:audioswitch:89582c47c9a04c62f90aa5e57251af4800a62c9a'
|
|
133
|
+
api 'io.github.webrtc-sdk:android:114.5735.05'
|
|
134
134
|
implementation project(':livekit_react-native-webrtc')
|
|
135
135
|
implementation "androidx.annotation:annotation:1.4.0"
|
|
136
136
|
}
|
package/android/src/main/java/com/livekit/reactnative/video/SimulcastVideoEncoderFactoryWrapper.kt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.livekit.reactnative.video
|
|
2
2
|
|
|
3
3
|
import android.util.Log
|
|
4
|
+
import com.oney.WebRTCModule.webrtcutils.SoftwareVideoEncoderFactoryProxy
|
|
4
5
|
import org.webrtc.EglBase
|
|
5
6
|
import org.webrtc.HardwareVideoEncoderFactory
|
|
6
7
|
import org.webrtc.SimulcastVideoEncoderFactory
|
|
@@ -64,7 +65,7 @@ open class SimulcastVideoEncoderFactoryWrapper(
|
|
|
64
65
|
private class FallbackFactory(private val hardwareVideoEncoderFactory: VideoEncoderFactory) :
|
|
65
66
|
VideoEncoderFactory {
|
|
66
67
|
|
|
67
|
-
private val softwareVideoEncoderFactory: VideoEncoderFactory =
|
|
68
|
+
private val softwareVideoEncoderFactory: VideoEncoderFactory = SoftwareVideoEncoderFactoryProxy()
|
|
68
69
|
|
|
69
70
|
override fun createEncoder(info: VideoCodecInfo): VideoEncoder? {
|
|
70
71
|
val softwareEncoder = softwareVideoEncoderFactory.createEncoder(info)
|
package/ios/AudioUtils.h
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#if TARGET_OS_IPHONE
|
|
2
|
+
#import <AVFoundation/AVFoundation.h>
|
|
3
|
+
|
|
4
|
+
@interface AudioUtils : NSObject
|
|
5
|
+
+ (AVAudioSessionMode)audioSessionModeFromString:(NSString*)mode;
|
|
6
|
+
+ (AVAudioSessionCategory)audioSessionCategoryFromString:(NSString *)category;
|
|
7
|
+
@end
|
|
8
|
+
|
|
9
|
+
#endif
|
package/ios/AudioUtils.m
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#if TARGET_OS_IPHONE
|
|
2
|
+
#import "AudioUtils.h"
|
|
3
|
+
#import <AVFoundation/AVFoundation.h>
|
|
4
|
+
|
|
5
|
+
@implementation AudioUtils
|
|
6
|
+
|
|
7
|
+
+ (AVAudioSessionMode)audioSessionModeFromString:(NSString*)mode {
|
|
8
|
+
if([@"default_" isEqualToString:mode]) {
|
|
9
|
+
return AVAudioSessionModeDefault;
|
|
10
|
+
} else if([@"voicePrompt" isEqualToString:mode]) {
|
|
11
|
+
return AVAudioSessionModeVoicePrompt;
|
|
12
|
+
} else if([@"videoRecording" isEqualToString:mode]) {
|
|
13
|
+
return AVAudioSessionModeVideoRecording;
|
|
14
|
+
} else if([@"videoChat" isEqualToString:mode]) {
|
|
15
|
+
return AVAudioSessionModeVideoChat;
|
|
16
|
+
} else if([@"voiceChat" isEqualToString:mode]) {
|
|
17
|
+
return AVAudioSessionModeVoiceChat;
|
|
18
|
+
} else if([@"gameChat" isEqualToString:mode]) {
|
|
19
|
+
return AVAudioSessionModeGameChat;
|
|
20
|
+
} else if([@"measurement" isEqualToString:mode]) {
|
|
21
|
+
return AVAudioSessionModeMeasurement;
|
|
22
|
+
} else if([@"moviePlayback" isEqualToString:mode]) {
|
|
23
|
+
return AVAudioSessionModeMoviePlayback;
|
|
24
|
+
} else if([@"spokenAudio" isEqualToString:mode]) {
|
|
25
|
+
return AVAudioSessionModeSpokenAudio;
|
|
26
|
+
}
|
|
27
|
+
return AVAudioSessionModeDefault;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
+ (AVAudioSessionCategory)audioSessionCategoryFromString:(NSString *)category {
|
|
31
|
+
if([@"ambient" isEqualToString:category]) {
|
|
32
|
+
return AVAudioSessionCategoryAmbient;
|
|
33
|
+
} else if([@"soloAmbient" isEqualToString:category]) {
|
|
34
|
+
return AVAudioSessionCategorySoloAmbient;
|
|
35
|
+
} else if([@"playback" isEqualToString:category]) {
|
|
36
|
+
return AVAudioSessionCategoryPlayback;
|
|
37
|
+
} else if([@"record" isEqualToString:category]) {
|
|
38
|
+
return AVAudioSessionCategoryRecord;
|
|
39
|
+
} else if([@"playAndRecord" isEqualToString:category]) {
|
|
40
|
+
return AVAudioSessionCategoryPlayAndRecord;
|
|
41
|
+
} else if([@"multiRoute" isEqualToString:category]) {
|
|
42
|
+
return AVAudioSessionCategoryMultiRoute;
|
|
43
|
+
}
|
|
44
|
+
return AVAudioSessionCategoryAmbient;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@end
|
|
48
|
+
#endif
|
package/ios/LivekitReactNative.m
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import "AudioUtils.h"
|
|
2
3
|
#import "LivekitReactNative.h"
|
|
3
4
|
#import "WebRTCModule.h"
|
|
4
5
|
#import "WebRTCModuleOptions.h"
|
|
@@ -117,4 +118,48 @@ RCT_EXPORT_METHOD(selectAudioOutput:(NSString *)deviceId
|
|
|
117
118
|
resolve(nil);
|
|
118
119
|
}
|
|
119
120
|
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
/// Configure audio config for WebRTC
|
|
124
|
+
RCT_EXPORT_METHOD(setAppleAudioConfiguration:(NSDictionary *) configuration){
|
|
125
|
+
RTCAudioSession* session = [RTCAudioSession sharedInstance];
|
|
126
|
+
RTCAudioSessionConfiguration* config = [RTCAudioSessionConfiguration webRTCConfiguration];
|
|
127
|
+
|
|
128
|
+
NSString* appleAudioCategory = configuration[@"audioCategory"];
|
|
129
|
+
NSArray* appleAudioCategoryOptions = configuration[@"audioCategoryOptions"];
|
|
130
|
+
NSString* appleAudioMode = configuration[@"audioMode"];
|
|
131
|
+
|
|
132
|
+
[session lockForConfiguration];
|
|
133
|
+
|
|
134
|
+
if(appleAudioCategoryOptions != nil) {
|
|
135
|
+
config.categoryOptions = 0;
|
|
136
|
+
for(NSString* option in appleAudioCategoryOptions) {
|
|
137
|
+
if([@"mixWithOthers" isEqualToString:option]) {
|
|
138
|
+
config.categoryOptions |= AVAudioSessionCategoryOptionMixWithOthers;
|
|
139
|
+
} else if([@"duckOthers" isEqualToString:option]) {
|
|
140
|
+
config.categoryOptions |= AVAudioSessionCategoryOptionDuckOthers;
|
|
141
|
+
} else if([@"allowBluetooth" isEqualToString:option]) {
|
|
142
|
+
config.categoryOptions |= AVAudioSessionCategoryOptionAllowBluetooth;
|
|
143
|
+
} else if([@"allowBluetoothA2DP" isEqualToString:option]) {
|
|
144
|
+
config.categoryOptions |= AVAudioSessionCategoryOptionAllowBluetoothA2DP;
|
|
145
|
+
} else if([@"allowAirPlay" isEqualToString:option]) {
|
|
146
|
+
config.categoryOptions |= AVAudioSessionCategoryOptionAllowAirPlay;
|
|
147
|
+
} else if([@"defaultToSpeaker" isEqualToString:option]) {
|
|
148
|
+
config.categoryOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if(appleAudioCategory != nil) {
|
|
154
|
+
config.category = [AudioUtils audioSessionCategoryFromString:appleAudioCategory];
|
|
155
|
+
[session setCategory:config.category withOptions:config.categoryOptions error:nil];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if(appleAudioMode != nil) {
|
|
159
|
+
config.mode = [AudioUtils audioSessionModeFromString:appleAudioMode];
|
|
160
|
+
[session setMode:config.mode error:nil];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
[session unlockForConfiguration];
|
|
164
|
+
}
|
|
120
165
|
@end
|
|
Binary file
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useIOSAudioManagement = useIOSAudioManagement;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
|
|
12
|
+
var _livekitClient = require("livekit-client");
|
|
13
|
+
|
|
14
|
+
var _AudioSession = _interopRequireWildcard(require("./AudioSession"));
|
|
15
|
+
|
|
16
|
+
var _ = require("..");
|
|
17
|
+
|
|
18
|
+
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); }
|
|
19
|
+
|
|
20
|
+
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; }
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Handles setting the appropriate AVAudioSession options automatically
|
|
24
|
+
* depending on the audio track states of the Room.
|
|
25
|
+
*
|
|
26
|
+
* @param room
|
|
27
|
+
* @param preferSpeakerOutput
|
|
28
|
+
* @param onConfigureNativeAudio
|
|
29
|
+
*/
|
|
30
|
+
function useIOSAudioManagement(room) {
|
|
31
|
+
let preferSpeakerOutput = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
32
|
+
let onConfigureNativeAudio = arguments.length > 2 ? arguments[2] : undefined;
|
|
33
|
+
const [localTrackCount, setLocalTrackCount] = (0, _react.useState)(0);
|
|
34
|
+
const [remoteTrackCount, setRemoteTrackCount] = (0, _react.useState)(0);
|
|
35
|
+
const trackState = (0, _react.useMemo)(() => computeAudioTrackState(localTrackCount, remoteTrackCount), [localTrackCount, remoteTrackCount]);
|
|
36
|
+
(0, _react.useEffect)(() => {
|
|
37
|
+
if (_reactNative.Platform.OS !== 'ios') {
|
|
38
|
+
return () => {};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setLocalTrackCount(getLocalAudioTrackCount(room));
|
|
42
|
+
setRemoteTrackCount(getRemoteAudioTrackCount(room));
|
|
43
|
+
|
|
44
|
+
let onLocalPublished = () => {
|
|
45
|
+
setLocalTrackCount(localTrackCount + 1);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
let onLocalUnpublished = () => {
|
|
49
|
+
if (localTrackCount - 1 < 0) {
|
|
50
|
+
_.log.warn('mismatched local audio track count! attempted to reduce track count below zero.');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setLocalTrackCount(Math.max(localTrackCount - 1, 0));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
let onRemotePublished = () => {
|
|
57
|
+
setRemoteTrackCount(remoteTrackCount + 1);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
let onRemoteUnpublished = () => {
|
|
61
|
+
if (remoteTrackCount - 1 < 0) {
|
|
62
|
+
_.log.warn('mismatched remote audio track count! attempted to reduce track count below zero.');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
setRemoteTrackCount(Math.max(remoteTrackCount - 1, 0));
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
room.on(_livekitClient.RoomEvent.LocalTrackPublished, onLocalPublished).on(_livekitClient.RoomEvent.LocalTrackUnpublished, onLocalUnpublished).on(_livekitClient.RoomEvent.TrackPublished, onRemotePublished).on(_livekitClient.RoomEvent.TrackUnpublished, onRemoteUnpublished);
|
|
69
|
+
return () => {
|
|
70
|
+
room.off(_livekitClient.RoomEvent.LocalTrackPublished, onLocalPublished).off(_livekitClient.RoomEvent.LocalTrackUnpublished, onLocalUnpublished).off(_livekitClient.RoomEvent.TrackPublished, onRemotePublished).off(_livekitClient.RoomEvent.TrackUnpublished, onRemoteUnpublished);
|
|
71
|
+
};
|
|
72
|
+
}, [room, localTrackCount, remoteTrackCount]);
|
|
73
|
+
(0, _react.useEffect)(() => {
|
|
74
|
+
if (_reactNative.Platform.OS !== 'ios') {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let configFunc = onConfigureNativeAudio !== null && onConfigureNativeAudio !== void 0 ? onConfigureNativeAudio : _AudioSession.getDefaultAppleAudioConfigurationForMode;
|
|
79
|
+
let audioConfig = configFunc(trackState, preferSpeakerOutput);
|
|
80
|
+
|
|
81
|
+
_AudioSession.default.setAppleAudioConfiguration(audioConfig);
|
|
82
|
+
}, [trackState, onConfigureNativeAudio, preferSpeakerOutput]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function computeAudioTrackState(localTracks, remoteTracks) {
|
|
86
|
+
if (localTracks > 0 && remoteTracks > 0) {
|
|
87
|
+
return 'localAndRemote';
|
|
88
|
+
} else if (localTracks > 0 && remoteTracks === 0) {
|
|
89
|
+
return 'localOnly';
|
|
90
|
+
} else if (localTracks === 0 && remoteTracks > 0) {
|
|
91
|
+
return 'remoteOnly';
|
|
92
|
+
} else {
|
|
93
|
+
return 'none';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getLocalAudioTrackCount(room) {
|
|
98
|
+
return room.localParticipant.audioTracks.entries.length;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getRemoteAudioTrackCount(room) {
|
|
102
|
+
var audioTracks = 0;
|
|
103
|
+
room.participants.forEach(participant => {
|
|
104
|
+
audioTracks += participant.audioTracks.entries.length;
|
|
105
|
+
});
|
|
106
|
+
return audioTracks;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=AudioManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["AudioManager.ts"],"names":["useIOSAudioManagement","room","preferSpeakerOutput","onConfigureNativeAudio","localTrackCount","setLocalTrackCount","remoteTrackCount","setRemoteTrackCount","trackState","computeAudioTrackState","Platform","OS","getLocalAudioTrackCount","getRemoteAudioTrackCount","onLocalPublished","onLocalUnpublished","log","warn","Math","max","onRemotePublished","onRemoteUnpublished","on","RoomEvent","LocalTrackPublished","LocalTrackUnpublished","TrackPublished","TrackUnpublished","off","configFunc","getDefaultAppleAudioConfigurationForMode","audioConfig","AudioSession","setAppleAudioConfiguration","localTracks","remoteTracks","localParticipant","audioTracks","entries","length","participants","forEach","participant"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AAKA;;;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,qBAAT,CACLC,IADK,EAOL;AAAA,MALAC,mBAKA,uEAL+B,IAK/B;AAAA,MAJAC,sBAIA;AACA,QAAM,CAACC,eAAD,EAAkBC,kBAAlB,IAAwC,qBAAS,CAAT,CAA9C;AACA,QAAM,CAACC,gBAAD,EAAmBC,mBAAnB,IAA0C,qBAAS,CAAT,CAAhD;AACA,QAAMC,UAAU,GAAG,oBACjB,MAAMC,sBAAsB,CAACL,eAAD,EAAkBE,gBAAlB,CADX,EAEjB,CAACF,eAAD,EAAkBE,gBAAlB,CAFiB,CAAnB;AAKA,wBAAU,MAAM;AACd,QAAII,sBAASC,EAAT,KAAgB,KAApB,EAA2B;AACzB,aAAO,MAAM,CAAE,CAAf;AACD;;AAEDN,IAAAA,kBAAkB,CAACO,uBAAuB,CAACX,IAAD,CAAxB,CAAlB;AACAM,IAAAA,mBAAmB,CAACM,wBAAwB,CAACZ,IAAD,CAAzB,CAAnB;;AAEA,QAAIa,gBAAgB,GAAG,MAAM;AAC3BT,MAAAA,kBAAkB,CAACD,eAAe,GAAG,CAAnB,CAAlB;AACD,KAFD;;AAGA,QAAIW,kBAAkB,GAAG,MAAM;AAC7B,UAAIX,eAAe,GAAG,CAAlB,GAAsB,CAA1B,EAA6B;AAC3BY,cAAIC,IAAJ,CACE,iFADF;AAGD;;AACDZ,MAAAA,kBAAkB,CAACa,IAAI,CAACC,GAAL,CAASf,eAAe,GAAG,CAA3B,EAA8B,CAA9B,CAAD,CAAlB;AACD,KAPD;;AAQA,QAAIgB,iBAAiB,GAAG,MAAM;AAC5Bb,MAAAA,mBAAmB,CAACD,gBAAgB,GAAG,CAApB,CAAnB;AACD,KAFD;;AAGA,QAAIe,mBAAmB,GAAG,MAAM;AAC9B,UAAIf,gBAAgB,GAAG,CAAnB,GAAuB,CAA3B,EAA8B;AAC5BU,cAAIC,IAAJ,CACE,kFADF;AAGD;;AACDV,MAAAA,mBAAmB,CAACW,IAAI,CAACC,GAAL,CAASb,gBAAgB,GAAG,CAA5B,EAA+B,CAA/B,CAAD,CAAnB;AACD,KAPD;;AASAL,IAAAA,IAAI,CACDqB,EADH,CACMC,yBAAUC,mBADhB,EACqCV,gBADrC,EAEGQ,EAFH,CAEMC,yBAAUE,qBAFhB,EAEuCV,kBAFvC,EAGGO,EAHH,CAGMC,yBAAUG,cAHhB,EAGgCN,iBAHhC,EAIGE,EAJH,CAIMC,yBAAUI,gBAJhB,EAIkCN,mBAJlC;AAMA,WAAO,MAAM;AACXpB,MAAAA,IAAI,CACD2B,GADH,CACOL,yBAAUC,mBADjB,EACsCV,gBADtC,EAEGc,GAFH,CAEOL,yBAAUE,qBAFjB,EAEwCV,kBAFxC,EAGGa,GAHH,CAGOL,yBAAUG,cAHjB,EAGiCN,iBAHjC,EAIGQ,GAJH,CAIOL,yBAAUI,gBAJjB,EAImCN,mBAJnC;AAKD,KAND;AAOD,GA5CD,EA4CG,CAACpB,IAAD,EAAOG,eAAP,EAAwBE,gBAAxB,CA5CH;AA8CA,wBAAU,MAAM;AACd,QAAII,sBAASC,EAAT,KAAgB,KAApB,EAA2B;AACzB;AACD;;AAED,QAAIkB,UAAU,GACZ1B,sBADY,aACZA,sBADY,cACZA,sBADY,GACc2B,sDAD5B;AAEA,QAAIC,WAAW,GAAGF,UAAU,CAACrB,UAAD,EAAaN,mBAAb,CAA5B;;AAEA8B,0BAAaC,0BAAb,CAAwCF,WAAxC;AACD,GAVD,EAUG,CAACvB,UAAD,EAAaL,sBAAb,EAAqCD,mBAArC,CAVH;AAWD;;AAED,SAASO,sBAAT,CACEyB,WADF,EAEEC,YAFF,EAGmB;AACjB,MAAID,WAAW,GAAG,CAAd,IAAmBC,YAAY,GAAG,CAAtC,EAAyC;AACvC,WAAO,gBAAP;AACD,GAFD,MAEO,IAAID,WAAW,GAAG,CAAd,IAAmBC,YAAY,KAAK,CAAxC,EAA2C;AAChD,WAAO,WAAP;AACD,GAFM,MAEA,IAAID,WAAW,KAAK,CAAhB,IAAqBC,YAAY,GAAG,CAAxC,EAA2C;AAChD,WAAO,YAAP;AACD,GAFM,MAEA;AACL,WAAO,MAAP;AACD;AACF;;AAED,SAASvB,uBAAT,CAAiCX,IAAjC,EAAqD;AACnD,SAAOA,IAAI,CAACmC,gBAAL,CAAsBC,WAAtB,CAAkCC,OAAlC,CAA0CC,MAAjD;AACD;;AAED,SAAS1B,wBAAT,CAAkCZ,IAAlC,EAAsD;AACpD,MAAIoC,WAAW,GAAG,CAAlB;AACApC,EAAAA,IAAI,CAACuC,YAAL,CAAkBC,OAAlB,CAA2BC,WAAD,IAAiB;AACzCL,IAAAA,WAAW,IAAIK,WAAW,CAACL,WAAZ,CAAwBC,OAAxB,CAAgCC,MAA/C;AACD,GAFD;AAIA,SAAOF,WAAP;AACD","sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { Platform } from 'react-native';\nimport { RoomEvent, type Room } from 'livekit-client';\nimport AudioSession, {\n getDefaultAppleAudioConfigurationForMode,\n type AppleAudioConfiguration,\n type AudioTrackState,\n} from './AudioSession';\nimport { log } from '..';\n\n/**\n * Handles setting the appropriate AVAudioSession options automatically\n * depending on the audio track states of the Room.\n *\n * @param room\n * @param preferSpeakerOutput\n * @param onConfigureNativeAudio\n */\nexport function useIOSAudioManagement(\n room: Room,\n preferSpeakerOutput: boolean = true,\n onConfigureNativeAudio?: (\n trackState: AudioTrackState,\n preferSpeakerOutput: boolean\n ) => AppleAudioConfiguration\n) {\n const [localTrackCount, setLocalTrackCount] = useState(0);\n const [remoteTrackCount, setRemoteTrackCount] = useState(0);\n const trackState = useMemo(\n () => computeAudioTrackState(localTrackCount, remoteTrackCount),\n [localTrackCount, remoteTrackCount]\n );\n\n useEffect(() => {\n if (Platform.OS !== 'ios') {\n return () => {};\n }\n\n setLocalTrackCount(getLocalAudioTrackCount(room));\n setRemoteTrackCount(getRemoteAudioTrackCount(room));\n\n let onLocalPublished = () => {\n setLocalTrackCount(localTrackCount + 1);\n };\n let onLocalUnpublished = () => {\n if (localTrackCount - 1 < 0) {\n log.warn(\n 'mismatched local audio track count! attempted to reduce track count below zero.'\n );\n }\n setLocalTrackCount(Math.max(localTrackCount - 1, 0));\n };\n let onRemotePublished = () => {\n setRemoteTrackCount(remoteTrackCount + 1);\n };\n let onRemoteUnpublished = () => {\n if (remoteTrackCount - 1 < 0) {\n log.warn(\n 'mismatched remote audio track count! attempted to reduce track count below zero.'\n );\n }\n setRemoteTrackCount(Math.max(remoteTrackCount - 1, 0));\n };\n\n room\n .on(RoomEvent.LocalTrackPublished, onLocalPublished)\n .on(RoomEvent.LocalTrackUnpublished, onLocalUnpublished)\n .on(RoomEvent.TrackPublished, onRemotePublished)\n .on(RoomEvent.TrackUnpublished, onRemoteUnpublished);\n\n return () => {\n room\n .off(RoomEvent.LocalTrackPublished, onLocalPublished)\n .off(RoomEvent.LocalTrackUnpublished, onLocalUnpublished)\n .off(RoomEvent.TrackPublished, onRemotePublished)\n .off(RoomEvent.TrackUnpublished, onRemoteUnpublished);\n };\n }, [room, localTrackCount, remoteTrackCount]);\n\n useEffect(() => {\n if (Platform.OS !== 'ios') {\n return;\n }\n\n let configFunc =\n onConfigureNativeAudio ?? getDefaultAppleAudioConfigurationForMode;\n let audioConfig = configFunc(trackState, preferSpeakerOutput);\n\n AudioSession.setAppleAudioConfiguration(audioConfig);\n }, [trackState, onConfigureNativeAudio, preferSpeakerOutput]);\n}\n\nfunction computeAudioTrackState(\n localTracks: number,\n remoteTracks: number\n): AudioTrackState {\n if (localTracks > 0 && remoteTracks > 0) {\n return 'localAndRemote';\n } else if (localTracks > 0 && remoteTracks === 0) {\n return 'localOnly';\n } else if (localTracks === 0 && remoteTracks > 0) {\n return 'remoteOnly';\n } else {\n return 'none';\n }\n}\n\nfunction getLocalAudioTrackCount(room: Room): number {\n return room.localParticipant.audioTracks.entries.length;\n}\n\nfunction getRemoteAudioTrackCount(room: Room): number {\n var audioTracks = 0;\n room.participants.forEach((participant) => {\n audioTracks += participant.audioTracks.entries.length;\n });\n\n return audioTracks;\n}\n"]}
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.AndroidAudioTypePresets = void 0;
|
|
7
|
+
exports.getDefaultAppleAudioConfigurationForMode = getDefaultAppleAudioConfigurationForMode;
|
|
7
8
|
|
|
8
9
|
var _reactNative = require("react-native");
|
|
9
10
|
|
|
@@ -67,6 +68,30 @@ const AndroidAudioTypePresets = {
|
|
|
67
68
|
};
|
|
68
69
|
exports.AndroidAudioTypePresets = AndroidAudioTypePresets;
|
|
69
70
|
|
|
71
|
+
function getDefaultAppleAudioConfigurationForMode(mode) {
|
|
72
|
+
let preferSpeakerOutput = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
73
|
+
|
|
74
|
+
if (mode === 'remoteOnly') {
|
|
75
|
+
return {
|
|
76
|
+
audioCategory: 'playback',
|
|
77
|
+
audioCategoryOptions: ['mixWithOthers'],
|
|
78
|
+
audioMode: 'spokenAudio'
|
|
79
|
+
};
|
|
80
|
+
} else if (mode === 'localAndRemote' || mode === 'localOnly') {
|
|
81
|
+
return {
|
|
82
|
+
audioCategory: 'playAndRecord',
|
|
83
|
+
audioCategoryOptions: ['allowBluetooth', 'mixWithOthers'],
|
|
84
|
+
audioMode: preferSpeakerOutput ? 'videoChat' : 'voiceChat'
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
audioCategory: 'soloAmbient',
|
|
90
|
+
audioCategoryOptions: [],
|
|
91
|
+
audioMode: 'default'
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
70
95
|
class AudioSession {}
|
|
71
96
|
|
|
72
97
|
exports.default = AudioSession;
|
|
@@ -102,4 +127,10 @@ _defineProperty(AudioSession, "showAudioRoutePicker", async () => {
|
|
|
102
127
|
await LivekitReactNative.showAudioRoutePicker();
|
|
103
128
|
}
|
|
104
129
|
});
|
|
130
|
+
|
|
131
|
+
_defineProperty(AudioSession, "setAppleAudioConfiguration", async config => {
|
|
132
|
+
if (_reactNative.Platform.OS === 'ios') {
|
|
133
|
+
await LivekitReactNative.setAppleAudioConfiguration(config);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
105
136
|
//# sourceMappingURL=AudioSession.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["AudioSession.ts"],"names":["LINKING_ERROR","Platform","select","ios","default","LivekitReactNative","NativeModules","Proxy","get","Error","AndroidAudioTypePresets","communication","manageAudioFocus","audioMode","audioFocusMode","audioStreamType","audioAttributesUsageType","audioAttributesContentType","media","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;AACA;AACA;AACA;AACA;AACA;;AA6GO,MAAMU,uBASZ,GAAG;AACFC,EAAAA,aAAa,EAAE;AACbC,IAAAA,gBAAgB,EAAE,IADL;AAEbC,IAAAA,SAAS,EAAE,iBAFE;AAGbC,IAAAA,cAAc,EAAE,MAHH;AAIbC,IAAAA,eAAe,EAAE,WAJJ;AAKbC,IAAAA,wBAAwB,EAAE,oBALb;AAMbC,IAAAA,0BAA0B,EAAE;AANf,GADb;AASFC,EAAAA,KAAK,EAAE;AACLN,IAAAA,gBAAgB,EAAE,IADb;AAELC,IAAAA,SAAS,EAAE,QAFN;AAGLC,IAAAA,cAAc,EAAE,MAHX;AAILC,IAAAA,eAAe,EAAE,OAJZ;AAKLC,IAAAA,wBAAwB,EAAE,OALrB;AAMLC,IAAAA,0BAA0B,EAAE;AANvB;AATL,CATG;;;AA4BQ,MAAME,YAAN,CAAmB;;;;gBAAbA,Y,oBAMK,MAAOC,MAAP,IAAsC;AAC5D,QAAMf,kBAAkB,CAACgB,cAAnB,CAAkCD,MAAlC,CAAN;AACD,C;;gBARkBD,Y,uBAaQ,YAAY;AACrC,QAAMd,kBAAkB,CAACiB,iBAAnB,EAAN;AACD,C;;gBAfkBH,Y,sBAoBO,YAAY;AACpC,QAAMd,kBAAkB,CAACkB,gBAAnB,EAAN;AACD,C;;gBAtBkBJ,Y,qBAgDM,YAA+B;AACtD,MAAIlB,sBAASuB,EAAT,KAAgB,KAApB,EAA2B;AACzB,WAAO,CAAC,SAAD,EAAY,eAAZ,CAAP;AACD,GAFD,MAEO,IAAIvB,sBAASuB,EAAT,KAAgB,SAApB,EAA+B;AACpC,WAAQ,MAAMnB,kBAAkB,CAACoB,eAAnB,EAAd;AACD,GAFM,MAEA;AACL,WAAO,EAAP;AACD;AACF,C;;gBAxDkBN,Y,uBAiEQ,MAAOO,QAAP,IAA4B;AACrD,QAAMrB,kBAAkB,CAACsB,iBAAnB,CAAqCD,QAArC,CAAN;AACD,C;;gBAnEkBP,Y,0BA0EW,YAAY;AACxC,MAAIlB,sBAASuB,EAAT,KAAgB,KAApB,EAA2B;AACzB,UAAMnB,kBAAkB,CAACuB,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. `\"bluetooth\"\n * 2. `\"headset\"``\n * 3. `\"speaker\"`\n * 4. `\"earpiece\"`\n *\n * * audioTypeOptions - An {@link AndroidAudioTypeOptions} object which provides the\n * audio options to use on Android.\n *\n * See {@link AndroidAudioTypePresets} for pre-configured values.\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 audioTypeOptions: AndroidAudioTypeOptions;\n };\n ios?: {\n defaultOutput?: 'speaker' | 'earpiece';\n };\n};\n\nexport type AndroidAudioTypeOptions = {\n /**\n * Whether LiveKit should handle managing the audio focus or not.\n *\n * Defaults to true.\n */\n manageAudioFocus?: boolean;\n\n /**\n * Corresponds to {@link https://developer.android.com/reference/android/media/AudioManager#setMode(int)}\n *\n * Defaults to 'inCommunication'.\n */\n audioMode?:\n | 'normal'\n | 'callScreening'\n | 'inCall'\n | 'inCommunication'\n | 'ringtone';\n\n /**\n * Corresponds to the duration hint when requesting audio focus.\n *\n * Defaults to 'gain'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#AUDIOFOCUS_GAIN}\n */\n audioFocusMode?:\n | 'gain'\n | 'gainTransient'\n | 'gainTransientExclusive'\n | 'gainTransientMayDuck';\n\n /**\n * Corresponds to Android's AudioAttributes usage type.\n *\n * Defaults to 'voiceCommunication'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesUsageType?:\n | 'alarm'\n | 'assistanceAccessibility'\n | 'assistanceNavigationGuidance'\n | 'assistanceSonification'\n | 'assistant'\n | 'game'\n | 'media'\n | 'notification'\n | 'notificationEvent'\n | 'notificationRingtone'\n | 'unknown'\n | 'voiceCommunication'\n | 'voiceCommunicationSignalling';\n\n /**\n * Corresponds to Android's AndroidAttributes content type.\n *\n * Defaults to 'speech'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesContentType?:\n | 'movie'\n | 'music'\n | 'sonification'\n | 'speech'\n | 'unknown';\n\n /**\n * Corresponds to the stream type when requesting audio focus. Used on pre-O devices.\n *\n * Defaults to 'voiceCall'\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#STREAM_VOICE_CALL}\n */\n audioStreamType?:\n | 'accessibility'\n | 'alarm'\n | 'dtmf'\n | 'music'\n | 'notification'\n | 'ring'\n | 'system'\n | 'voiceCall';\n\n /**\n * On certain Android devices, audio routing does not function properly and\n * bluetooth microphones will not work unless audio mode is set to\n * `inCommunication` or `inCall`. Audio routing is turned off those cases.\n *\n * If this set to true, will attempt to do audio routing regardless of audio mode.\n *\n * Defaults to false.\n */\n forceHandleAudioRouting?: boolean;\n};\n\nexport const AndroidAudioTypePresets: {\n /**\n * A pre-configured AndroidAudioConfiguration for voice communication.\n */\n communication: AndroidAudioTypeOptions;\n /**\n * A pre-configured AndroidAudioConfiguration for media playback.\n */\n media: AndroidAudioTypeOptions;\n} = {\n communication: {\n manageAudioFocus: true,\n audioMode: 'inCommunication',\n audioFocusMode: 'gain',\n audioStreamType: 'voiceCall',\n audioAttributesUsageType: 'voiceCommunication',\n audioAttributesContentType: 'speech',\n },\n media: {\n manageAudioFocus: true,\n audioMode: 'normal',\n audioFocusMode: 'gain',\n audioStreamType: 'music',\n audioAttributesUsageType: 'media',\n audioAttributesContentType: 'unknown',\n },\n} as const;\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 * ----\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","AndroidAudioTypePresets","communication","manageAudioFocus","audioMode","audioFocusMode","audioStreamType","audioAttributesUsageType","audioAttributesContentType","media","getDefaultAppleAudioConfigurationForMode","mode","preferSpeakerOutput","audioCategory","audioCategoryOptions","AudioSession","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker","setAppleAudioConfiguration"],"mappings":"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","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. `\"bluetooth\"\n * 2. `\"headset\"``\n * 3. `\"speaker\"`\n * 4. `\"earpiece\"`\n *\n * * audioTypeOptions - An {@link AndroidAudioTypeOptions} object which provides the\n * audio options to use on Android.\n *\n * See {@link AndroidAudioTypePresets} for pre-configured values.\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 audioTypeOptions: AndroidAudioTypeOptions;\n };\n ios?: {\n defaultOutput?: 'speaker' | 'earpiece';\n };\n};\n\nexport type AndroidAudioTypeOptions = {\n /**\n * Whether LiveKit should handle managing the audio focus or not.\n *\n * Defaults to true.\n */\n manageAudioFocus?: boolean;\n\n /**\n * Corresponds to {@link https://developer.android.com/reference/android/media/AudioManager#setMode(int)}\n *\n * Defaults to 'inCommunication'.\n */\n audioMode?:\n | 'normal'\n | 'callScreening'\n | 'inCall'\n | 'inCommunication'\n | 'ringtone';\n\n /**\n * Corresponds to the duration hint when requesting audio focus.\n *\n * Defaults to 'gain'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#AUDIOFOCUS_GAIN}\n */\n audioFocusMode?:\n | 'gain'\n | 'gainTransient'\n | 'gainTransientExclusive'\n | 'gainTransientMayDuck';\n\n /**\n * Corresponds to Android's AudioAttributes usage type.\n *\n * Defaults to 'voiceCommunication'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesUsageType?:\n | 'alarm'\n | 'assistanceAccessibility'\n | 'assistanceNavigationGuidance'\n | 'assistanceSonification'\n | 'assistant'\n | 'game'\n | 'media'\n | 'notification'\n | 'notificationEvent'\n | 'notificationRingtone'\n | 'unknown'\n | 'voiceCommunication'\n | 'voiceCommunicationSignalling';\n\n /**\n * Corresponds to Android's AndroidAttributes content type.\n *\n * Defaults to 'speech'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesContentType?:\n | 'movie'\n | 'music'\n | 'sonification'\n | 'speech'\n | 'unknown';\n\n /**\n * Corresponds to the stream type when requesting audio focus. Used on pre-O devices.\n *\n * Defaults to 'voiceCall'\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#STREAM_VOICE_CALL}\n */\n audioStreamType?:\n | 'accessibility'\n | 'alarm'\n | 'dtmf'\n | 'music'\n | 'notification'\n | 'ring'\n | 'system'\n | 'voiceCall';\n\n /**\n * On certain Android devices, audio routing does not function properly and\n * bluetooth microphones will not work unless audio mode is set to\n * `inCommunication` or `inCall`. Audio routing is turned off those cases.\n *\n * If this set to true, will attempt to do audio routing regardless of audio mode.\n *\n * Defaults to false.\n */\n forceHandleAudioRouting?: boolean;\n};\n\nexport const AndroidAudioTypePresets: {\n /**\n * A pre-configured AndroidAudioConfiguration for voice communication.\n */\n communication: AndroidAudioTypeOptions;\n /**\n * A pre-configured AndroidAudioConfiguration for media playback.\n */\n media: AndroidAudioTypeOptions;\n} = {\n communication: {\n manageAudioFocus: true,\n audioMode: 'inCommunication',\n audioFocusMode: 'gain',\n audioStreamType: 'voiceCall',\n audioAttributesUsageType: 'voiceCommunication',\n audioAttributesContentType: 'speech',\n },\n media: {\n manageAudioFocus: true,\n audioMode: 'normal',\n audioFocusMode: 'gain',\n audioStreamType: 'music',\n audioAttributesUsageType: 'media',\n audioAttributesContentType: 'unknown',\n },\n} as const;\n\nexport type AppleAudioMode =\n | 'default'\n | 'gameChat'\n | 'measurement'\n | 'moviePlayback'\n | 'spokenAudio'\n | 'videoChat'\n | 'videoRecording'\n | 'voiceChat'\n | 'voicePrompt';\n\nexport type AppleAudioCategory =\n | 'soloAmbient'\n | 'playback'\n | 'record'\n | 'playAndRecord'\n | 'multiRoute';\n\nexport type AppleAudioCategoryOption =\n | 'mixWithOthers'\n | 'duckOthers'\n | 'interruptSpokenAudioAndMixWithOthers'\n | 'allowBluetooth'\n | 'allowBluetoothA2DP'\n | 'allowAirPlay'\n | 'defaultToSpeaker';\n\nexport type AppleAudioConfiguration = {\n audioCategory?: AppleAudioCategory;\n audioCategoryOptions?: AppleAudioCategoryOption[];\n audioMode?: AppleAudioMode;\n};\n\nexport type AudioTrackState =\n | 'none'\n | 'remoteOnly'\n | 'localOnly'\n | 'localAndRemote';\n\nexport function getDefaultAppleAudioConfigurationForMode(\n mode: AudioTrackState,\n preferSpeakerOutput: boolean = true\n): AppleAudioConfiguration {\n if (mode === 'remoteOnly') {\n return {\n audioCategory: 'playback',\n audioCategoryOptions: ['mixWithOthers'],\n audioMode: 'spokenAudio',\n };\n } else if (mode === 'localAndRemote' || mode === 'localOnly') {\n return {\n audioCategory: 'playAndRecord',\n audioCategoryOptions: ['allowBluetooth', 'mixWithOthers'],\n audioMode: preferSpeakerOutput ? 'videoChat' : 'voiceChat',\n };\n }\n\n return {\n audioCategory: 'soloAmbient',\n audioCategoryOptions: [],\n audioMode: 'default',\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 * ----\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 static setAppleAudioConfiguration = async (\n config: AppleAudioConfiguration\n ) => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.setAppleAudioConfiguration(config);\n }\n };\n}\n"]}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -7,7 +7,13 @@ var _exportNames = {
|
|
|
7
7
|
registerGlobals: true,
|
|
8
8
|
AudioSession: true,
|
|
9
9
|
AndroidAudioTypePresets: true,
|
|
10
|
-
AndroidAudioTypeOptions: true
|
|
10
|
+
AndroidAudioTypeOptions: true,
|
|
11
|
+
AppleAudioCategory: true,
|
|
12
|
+
AppleAudioCategoryOption: true,
|
|
13
|
+
AppleAudioConfiguration: true,
|
|
14
|
+
AppleAudioMode: true,
|
|
15
|
+
AudioTrackState: true,
|
|
16
|
+
getDefaultAppleAudioConfigurationForMode: true
|
|
11
17
|
};
|
|
12
18
|
Object.defineProperty(exports, "AndroidAudioTypeOptions", {
|
|
13
19
|
enumerable: true,
|
|
@@ -21,12 +27,48 @@ Object.defineProperty(exports, "AndroidAudioTypePresets", {
|
|
|
21
27
|
return _AudioSession.AndroidAudioTypePresets;
|
|
22
28
|
}
|
|
23
29
|
});
|
|
30
|
+
Object.defineProperty(exports, "AppleAudioCategory", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _AudioSession.AppleAudioCategory;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "AppleAudioCategoryOption", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _AudioSession.AppleAudioCategoryOption;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "AppleAudioConfiguration", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _AudioSession.AppleAudioConfiguration;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "AppleAudioMode", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _AudioSession.AppleAudioMode;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
24
54
|
Object.defineProperty(exports, "AudioSession", {
|
|
25
55
|
enumerable: true,
|
|
26
56
|
get: function () {
|
|
27
57
|
return _AudioSession.default;
|
|
28
58
|
}
|
|
29
59
|
});
|
|
60
|
+
Object.defineProperty(exports, "AudioTrackState", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _AudioSession.AudioTrackState;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "getDefaultAppleAudioConfigurationForMode", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _AudioSession.getDefaultAppleAudioConfigurationForMode;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
30
72
|
exports.registerGlobals = registerGlobals;
|
|
31
73
|
|
|
32
74
|
var _reactNativeWebrtc = require("@livekit/react-native-webrtc");
|
|
@@ -81,6 +123,34 @@ Object.keys(_useRoom).forEach(function (key) {
|
|
|
81
123
|
});
|
|
82
124
|
});
|
|
83
125
|
|
|
126
|
+
var _logger = require("./logger");
|
|
127
|
+
|
|
128
|
+
Object.keys(_logger).forEach(function (key) {
|
|
129
|
+
if (key === "default" || key === "__esModule") return;
|
|
130
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
131
|
+
if (key in exports && exports[key] === _logger[key]) return;
|
|
132
|
+
Object.defineProperty(exports, key, {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
get: function () {
|
|
135
|
+
return _logger[key];
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
var _AudioManager = require("./audio/AudioManager");
|
|
141
|
+
|
|
142
|
+
Object.keys(_AudioManager).forEach(function (key) {
|
|
143
|
+
if (key === "default" || key === "__esModule") return;
|
|
144
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
145
|
+
if (key in exports && exports[key] === _AudioManager[key]) return;
|
|
146
|
+
Object.defineProperty(exports, key, {
|
|
147
|
+
enumerable: true,
|
|
148
|
+
get: function () {
|
|
149
|
+
return _AudioManager[key];
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
84
154
|
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); }
|
|
85
155
|
|
|
86
156
|
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; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.tsx"],"names":["registerGlobals","livekitRegisterGlobals","fixWebrtcAdapter","shimPromiseAllSettled","shimArrayAt","shimAsyncIterator","shimIterator","lkGlobal","platform","Platform","OS","devicePixelRatio","PixelRatio","get","global","LiveKitReactNativeGlobal","window","navigator","undefined","userAgent","product","allSettled","require","shim","Array","prototype","at"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["index.tsx"],"names":["registerGlobals","livekitRegisterGlobals","fixWebrtcAdapter","shimPromiseAllSettled","shimArrayAt","shimAsyncIterator","shimIterator","lkGlobal","platform","Platform","OS","devicePixelRatio","PixelRatio","get","global","LiveKitReactNativeGlobal","window","navigator","undefined","userAgent","product","allSettled","require","shim","Array","prototype","at"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AAWA;;AA+DA;;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;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AA/DA;AACA;AACA;AACA;AACA;AACO,SAASA,eAAT,GAA2B;AAChC;AACAC,EAAAA,sBAAsB;AACtB;AACAC,EAAAA,gBAAgB;AAChBC,EAAAA,qBAAqB;AACrBC,EAAAA,WAAW;AACXC,EAAAA,iBAAiB;AACjBC,EAAAA,YAAY;AACb;;AACD,SAASL,sBAAT,GAAkC;AAChC,MAAIM,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,SAASL,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAc,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,SAASjB,qBAAT,GAAiC;AAC/B,MAAIkB,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD;;AAED,SAASnB,WAAT,GAAuB;AACrB;AACA,MAAI,CAACoB,KAAK,CAACC,SAAN,CAAgBC,EAArB,EAAyB;AACvB,QAAIA,EAAE,GAAGJ,OAAO,CAAC,oBAAD,CAAhB;;AACAI,IAAAA,EAAE,CAACH,IAAH;AACD;AACF;;AAED,SAASlB,iBAAT,GAA6B;AAC3B,MAAIkB,IAAI,GAAGD,OAAO,CAAC,8CAAD,CAAlB;;AACAC,EAAAA,IAAI;AACL;;AAED,SAASjB,YAAT,GAAwB;AACtB,MAAIiB,IAAI,GAAGD,OAAO,CAAC,yCAAD,CAAlB;;AACAC,EAAAA,IAAI;AACL","sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from '@livekit/react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport 'fastestsmallesttextencoderdecoder';\nimport AudioSession, {\n AndroidAudioTypePresets,\n AndroidAudioTypeOptions,\n AppleAudioCategory,\n AppleAudioCategoryOption,\n AppleAudioConfiguration,\n AppleAudioMode,\n AudioTrackState,\n getDefaultAppleAudioConfigurationForMode,\n} from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\nimport { PixelRatio, Platform } from 'react-native';\nimport type { LiveKitReactNativeInfo } from 'livekit-client';\nimport type { LogLevel, SetLogLevelOptions } from './logger';\n\n/**\n * Registers the required globals needed for LiveKit to work.\n *\n * Must be called before using LiveKit.\n */\nexport function registerGlobals() {\n webrtcRegisterGlobals();\n livekitRegisterGlobals();\n setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\n shimArrayAt();\n shimAsyncIterator();\n shimIterator();\n}\nfunction livekitRegisterGlobals() {\n let lkGlobal: LiveKitReactNativeInfo = {\n platform: Platform.OS,\n devicePixelRatio: PixelRatio.get(),\n };\n\n // @ts-ignore\n global.LiveKitReactNativeGlobal = lkGlobal;\n}\n\nfunction fixWebrtcAdapter() {\n // @ts-ignore\n if (window?.navigator !== undefined) {\n // @ts-ignore\n const { navigator } = window;\n if (navigator.userAgent === undefined) {\n navigator.userAgent = navigator.product ?? 'Unknown';\n }\n }\n}\n\nfunction shimPromiseAllSettled() {\n var allSettled = require('promise.allsettled');\n allSettled.shim();\n}\n\nfunction shimArrayAt() {\n // Some versions of RN don't have Array.prototype.at, which is used by sdp-transform\n if (!Array.prototype.at) {\n var at = require('array.prototype.at');\n at.shim();\n }\n}\n\nfunction shimAsyncIterator() {\n var shim = require('well-known-symbols/Symbol.asyncIterator/shim');\n shim();\n}\n\nfunction shimIterator() {\n var shim = require('well-known-symbols/Symbol.iterator/shim');\n shim();\n}\n\nexport * from './components/VideoView';\nexport * from './useParticipant';\nexport * from './useRoom';\nexport * from './logger';\nexport * from './audio/AudioManager';\n\nexport {\n AudioSession,\n AudioConfiguration,\n AndroidAudioTypeOptions,\n AndroidAudioTypePresets,\n AppleAudioCategory,\n AppleAudioCategoryOption,\n AppleAudioConfiguration,\n AppleAudioMode,\n AudioTrackState,\n getDefaultAppleAudioConfigurationForMode,\n LogLevel,\n SetLogLevelOptions,\n};\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.log = void 0;
|
|
7
|
+
exports.setLogLevel = setLogLevel;
|
|
8
|
+
|
|
9
|
+
var _livekitClient = require("livekit-client");
|
|
10
|
+
|
|
11
|
+
var _loglevel = _interopRequireDefault(require("loglevel"));
|
|
12
|
+
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
|
|
15
|
+
const log = _loglevel.default.getLogger('lk-react-native');
|
|
16
|
+
|
|
17
|
+
exports.log = log;
|
|
18
|
+
log.setDefaultLevel('WARN');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Set the log level for both the `@livekit/react-native` package and the `@livekit-client` package.
|
|
22
|
+
* To set the `@livekit-client` log independently, use the `liveKitClientLogLevel` prop on the `options` object.
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
function setLogLevel(level) {
|
|
26
|
+
var _options$liveKitClien;
|
|
27
|
+
|
|
28
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
29
|
+
log.setLevel(level);
|
|
30
|
+
(0, _livekitClient.setLogLevel)((_options$liveKitClien = options.liveKitClientLogLevel) !== null && _options$liveKitClien !== void 0 ? _options$liveKitClien : level);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["logger.ts"],"names":["log","loglevel","getLogger","setDefaultLevel","setLogLevel","level","options","setLevel","liveKitClientLogLevel"],"mappings":";;;;;;;;AAAA;;AACA;;;;AAEO,MAAMA,GAAG,GAAGC,kBAASC,SAAT,CAAmB,iBAAnB,CAAZ;;;AACPF,GAAG,CAACG,eAAJ,CAAoB,MAApB;;AAOA;AACA;AACA;AACA;AACA;AACO,SAASC,WAAT,CACLC,KADK,EAGC;AAAA;;AAAA,MADNC,OACM,uEADwB,EACxB;AACNN,EAAAA,GAAG,CAACO,QAAJ,CAAaF,KAAb;AACA,2DAAqBC,OAAO,CAACE,qBAA7B,yEAAsDH,KAAtD;AACD","sourcesContent":["import { setLogLevel as setClientSdkLogLevel } from 'livekit-client';\nimport loglevel from 'loglevel';\n\nexport const log = loglevel.getLogger('lk-react-native');\nlog.setDefaultLevel('WARN');\n\nexport type LogLevel = Parameters<typeof setClientSdkLogLevel>[0];\nexport type SetLogLevelOptions = {\n liveKitClientLogLevel?: LogLevel;\n};\n\n/**\n * Set the log level for both the `@livekit/react-native` package and the `@livekit-client` package.\n * To set the `@livekit-client` log independently, use the `liveKitClientLogLevel` prop on the `options` object.\n * @public\n */\nexport function setLogLevel(\n level: LogLevel,\n options: SetLogLevelOptions = {}\n): void {\n log.setLevel(level);\n setClientSdkLogLevel(options.liveKitClientLogLevel ?? level);\n}\n"]}
|