@voltkit-rtc/react-native 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +121 -0
- package/LICENSE +21 -0
- package/README.md +1608 -2
- package/android/build.gradle +70 -0
- package/android/consumer-rules.pro +21 -0
- package/android/src/main/AndroidManifest.xml +25 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/AppVisibility.kt +67 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/AudioDevices.kt +67 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/AudioRouter.kt +487 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/CallServiceTypes.kt +120 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/NativeTimers.kt +106 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/NetworkWatch.kt +120 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/OutputChoice.kt +65 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/RtcConfig.kt +83 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/ScoLink.kt +61 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitCallService.kt +287 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcInitProvider.kt +215 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcModule.kt +313 -0
- package/android/src/main/java/com/voltkit/rtc/reactnative/VoltkitRtcPackage.kt +30 -0
- package/android/src/main/res/drawable/voltkit_rtc_default_call_icon.xml +15 -0
- package/android/src/main/res/raw/voltkit_rtc_keep.xml +7 -0
- package/app.plugin.js +17 -0
- package/lib/commonjs/audio.js +215 -0
- package/lib/commonjs/audio.js.map +1 -0
- package/lib/commonjs/components.js +207 -0
- package/lib/commonjs/components.js.map +1 -0
- package/lib/commonjs/create-client.js +47 -0
- package/lib/commonjs/create-client.js.map +1 -0
- package/lib/commonjs/errors.js +99 -0
- package/lib/commonjs/errors.js.map +1 -0
- package/lib/commonjs/globals.js +61 -0
- package/lib/commonjs/globals.js.map +1 -0
- package/lib/commonjs/index.js +234 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/local-media.js +392 -0
- package/lib/commonjs/local-media.js.map +1 -0
- package/lib/commonjs/native-session.js +365 -0
- package/lib/commonjs/native-session.js.map +1 -0
- package/lib/commonjs/native.js +99 -0
- package/lib/commonjs/native.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/permissions.js +166 -0
- package/lib/commonjs/permissions.js.map +1 -0
- package/lib/commonjs/platform/android.js +126 -0
- package/lib/commonjs/platform/android.js.map +1 -0
- package/lib/commonjs/platform/common.js +138 -0
- package/lib/commonjs/platform/common.js.map +1 -0
- package/lib/commonjs/platform/devices.js +151 -0
- package/lib/commonjs/platform/devices.js.map +1 -0
- package/lib/commonjs/platform/index.js +35 -0
- package/lib/commonjs/platform/index.js.map +1 -0
- package/lib/commonjs/platform/ios.js +54 -0
- package/lib/commonjs/platform/ios.js.map +1 -0
- package/lib/commonjs/platform/streams.js +273 -0
- package/lib/commonjs/platform/streams.js.map +1 -0
- package/lib/commonjs/platform/timers.js +71 -0
- package/lib/commonjs/platform/timers.js.map +1 -0
- package/lib/commonjs/platform/visibility.js +60 -0
- package/lib/commonjs/platform/visibility.js.map +1 -0
- package/lib/commonjs/preflight.js +77 -0
- package/lib/commonjs/preflight.js.map +1 -0
- package/lib/commonjs/provider.js +75 -0
- package/lib/commonjs/provider.js.map +1 -0
- package/lib/commonjs/specs/NativeVoltkitRtc.js +29 -0
- package/lib/commonjs/specs/NativeVoltkitRtc.js.map +1 -0
- package/lib/module/audio.js +207 -0
- package/lib/module/audio.js.map +1 -0
- package/lib/module/components.js +200 -0
- package/lib/module/components.js.map +1 -0
- package/lib/module/create-client.js +42 -0
- package/lib/module/create-client.js.map +1 -0
- package/lib/module/errors.js +87 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/globals.js +53 -0
- package/lib/module/globals.js.map +1 -0
- package/lib/module/index.js +33 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/local-media.js +387 -0
- package/lib/module/local-media.js.map +1 -0
- package/lib/module/native-session.js +360 -0
- package/lib/module/native-session.js.map +1 -0
- package/lib/module/native.js +87 -0
- package/lib/module/native.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/permissions.js +160 -0
- package/lib/module/permissions.js.map +1 -0
- package/lib/module/platform/android.js +122 -0
- package/lib/module/platform/android.js.map +1 -0
- package/lib/module/platform/common.js +128 -0
- package/lib/module/platform/common.js.map +1 -0
- package/lib/module/platform/devices.js +142 -0
- package/lib/module/platform/devices.js.map +1 -0
- package/lib/module/platform/index.js +24 -0
- package/lib/module/platform/index.js.map +1 -0
- package/lib/module/platform/ios.js +49 -0
- package/lib/module/platform/ios.js.map +1 -0
- package/lib/module/platform/streams.js +268 -0
- package/lib/module/platform/streams.js.map +1 -0
- package/lib/module/platform/timers.js +67 -0
- package/lib/module/platform/timers.js.map +1 -0
- package/lib/module/platform/visibility.js +54 -0
- package/lib/module/platform/visibility.js.map +1 -0
- package/lib/module/preflight.js +72 -0
- package/lib/module/preflight.js.map +1 -0
- package/lib/module/provider.js +70 -0
- package/lib/module/provider.js.map +1 -0
- package/lib/module/specs/NativeVoltkitRtc.js +37 -0
- package/lib/module/specs/NativeVoltkitRtc.js.map +1 -0
- package/lib/typescript/commonjs/audio.d.ts +58 -0
- package/lib/typescript/commonjs/audio.d.ts.map +1 -0
- package/lib/typescript/commonjs/components.d.ts +58 -0
- package/lib/typescript/commonjs/components.d.ts.map +1 -0
- package/lib/typescript/commonjs/create-client.d.ts +35 -0
- package/lib/typescript/commonjs/create-client.d.ts.map +1 -0
- package/lib/typescript/commonjs/errors.d.ts +34 -0
- package/lib/typescript/commonjs/errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/globals.d.ts +16 -0
- package/lib/typescript/commonjs/globals.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +24 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/local-media.d.ts +86 -0
- package/lib/typescript/commonjs/local-media.d.ts.map +1 -0
- package/lib/typescript/commonjs/native-session.d.ts +38 -0
- package/lib/typescript/commonjs/native-session.d.ts.map +1 -0
- package/lib/typescript/commonjs/native.d.ts +18 -0
- package/lib/typescript/commonjs/native.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/permissions.d.ts +30 -0
- package/lib/typescript/commonjs/permissions.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/android.d.ts +4 -0
- package/lib/typescript/commonjs/platform/android.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/common.d.ts +101 -0
- package/lib/typescript/commonjs/platform/common.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/devices.d.ts +42 -0
- package/lib/typescript/commonjs/platform/devices.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/index.d.ts +6 -0
- package/lib/typescript/commonjs/platform/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/ios.d.ts +4 -0
- package/lib/typescript/commonjs/platform/ios.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/streams.d.ts +82 -0
- package/lib/typescript/commonjs/platform/streams.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/timers.d.ts +19 -0
- package/lib/typescript/commonjs/platform/timers.d.ts.map +1 -0
- package/lib/typescript/commonjs/platform/visibility.d.ts +11 -0
- package/lib/typescript/commonjs/platform/visibility.d.ts.map +1 -0
- package/lib/typescript/commonjs/preflight.d.ts +19 -0
- package/lib/typescript/commonjs/preflight.d.ts.map +1 -0
- package/lib/typescript/commonjs/provider.d.ts +35 -0
- package/lib/typescript/commonjs/provider.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/NativeVoltkitRtc.d.ts +157 -0
- package/lib/typescript/commonjs/specs/NativeVoltkitRtc.d.ts.map +1 -0
- package/lib/typescript/module/audio.d.ts +58 -0
- package/lib/typescript/module/audio.d.ts.map +1 -0
- package/lib/typescript/module/components.d.ts +58 -0
- package/lib/typescript/module/components.d.ts.map +1 -0
- package/lib/typescript/module/create-client.d.ts +35 -0
- package/lib/typescript/module/create-client.d.ts.map +1 -0
- package/lib/typescript/module/errors.d.ts +34 -0
- package/lib/typescript/module/errors.d.ts.map +1 -0
- package/lib/typescript/module/globals.d.ts +16 -0
- package/lib/typescript/module/globals.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +24 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/local-media.d.ts +86 -0
- package/lib/typescript/module/local-media.d.ts.map +1 -0
- package/lib/typescript/module/native-session.d.ts +38 -0
- package/lib/typescript/module/native-session.d.ts.map +1 -0
- package/lib/typescript/module/native.d.ts +18 -0
- package/lib/typescript/module/native.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/permissions.d.ts +30 -0
- package/lib/typescript/module/permissions.d.ts.map +1 -0
- package/lib/typescript/module/platform/android.d.ts +4 -0
- package/lib/typescript/module/platform/android.d.ts.map +1 -0
- package/lib/typescript/module/platform/common.d.ts +101 -0
- package/lib/typescript/module/platform/common.d.ts.map +1 -0
- package/lib/typescript/module/platform/devices.d.ts +42 -0
- package/lib/typescript/module/platform/devices.d.ts.map +1 -0
- package/lib/typescript/module/platform/index.d.ts +6 -0
- package/lib/typescript/module/platform/index.d.ts.map +1 -0
- package/lib/typescript/module/platform/ios.d.ts +4 -0
- package/lib/typescript/module/platform/ios.d.ts.map +1 -0
- package/lib/typescript/module/platform/streams.d.ts +82 -0
- package/lib/typescript/module/platform/streams.d.ts.map +1 -0
- package/lib/typescript/module/platform/timers.d.ts +19 -0
- package/lib/typescript/module/platform/timers.d.ts.map +1 -0
- package/lib/typescript/module/platform/visibility.d.ts +11 -0
- package/lib/typescript/module/platform/visibility.d.ts.map +1 -0
- package/lib/typescript/module/preflight.d.ts +19 -0
- package/lib/typescript/module/preflight.d.ts.map +1 -0
- package/lib/typescript/module/provider.d.ts +35 -0
- package/lib/typescript/module/provider.d.ts.map +1 -0
- package/lib/typescript/module/specs/NativeVoltkitRtc.d.ts +157 -0
- package/lib/typescript/module/specs/NativeVoltkitRtc.d.ts.map +1 -0
- package/package.json +140 -4
- package/plugin/build/android.d.ts +36 -0
- package/plugin/build/android.js +265 -0
- package/plugin/build/index.d.ts +9 -0
- package/plugin/build/index.js +54 -0
- package/plugin/build/ios.d.ts +4 -0
- package/plugin/build/ios.js +43 -0
- package/plugin/build/options.d.ts +93 -0
- package/plugin/build/options.js +140 -0
- package/react-native.config.js +11 -0
- package/src/audio.ts +221 -0
- package/src/components.tsx +233 -0
- package/src/create-client.ts +53 -0
- package/src/errors.ts +81 -0
- package/src/globals.ts +54 -0
- package/src/index.ts +95 -0
- package/src/local-media.ts +420 -0
- package/src/native-session.tsx +384 -0
- package/src/native.ts +84 -0
- package/src/permissions.ts +173 -0
- package/src/platform/android.ts +128 -0
- package/src/platform/common.ts +157 -0
- package/src/platform/devices.ts +148 -0
- package/src/platform/index.ts +22 -0
- package/src/platform/ios.ts +48 -0
- package/src/platform/streams.ts +285 -0
- package/src/platform/timers.ts +72 -0
- package/src/platform/visibility.ts +59 -0
- package/src/preflight.ts +60 -0
- package/src/provider.tsx +88 -0
- package/src/specs/NativeVoltkitRtc.ts +180 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Call audio on Android: the speaker or the earpiece, headsets and Bluetooth, through this package's audio router (a
|
|
5
|
+
* port of the Android SDK's AudioRouter, AudioSwitch's rules). Process-wide, like Android's AudioManager: every
|
|
6
|
+
* connected client holds the call audio (the provider does it), and the last to let go puts the device's audio mode,
|
|
7
|
+
* speakerphone and microphone mute back as it found them. setSpeakerphoneOn and selectAudioOutput work before any
|
|
8
|
+
* client exists: the choice is kept for the call.
|
|
9
|
+
*
|
|
10
|
+
* In the audio mode `media` (the Expo plugin's android.audioMode, for apps whose users only listen) sound follows the
|
|
11
|
+
* system's media routing: there is no earpiece and nothing to choose. On iOS (preview) there is no routing at all.
|
|
12
|
+
*/
|
|
13
|
+
import { useMemo, useSyncExternalStore } from 'react';
|
|
14
|
+
import { Platform } from 'react-native';
|
|
15
|
+
import { RpcError } from '@voltkit-rtc/client';
|
|
16
|
+
import { listen, nativeConstants, nativeModule, requireNative, toMediaDevice } from "./native.js";
|
|
17
|
+
import { logError, nativeFailure } from "./errors.js";
|
|
18
|
+
|
|
19
|
+
/** Whether this app chose the speaker itself (setSpeakerphoneOn): the provider then leaves that choice alone. */
|
|
20
|
+
let speakerChosen = null;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Play call audio on the loudspeaker (true) or the earpiece (false) when no headset is connected; a wired or Bluetooth
|
|
24
|
+
* headset still wins. Kept until changed, and applied to calls joined later. Rejects with `media-unavailable` on iOS
|
|
25
|
+
* and where the native module is missing.
|
|
26
|
+
*/
|
|
27
|
+
export async function setSpeakerphoneOn(on) {
|
|
28
|
+
const module = requireNative('Choosing the speaker or the earpiece');
|
|
29
|
+
module.setSpeakerphoneOn(Boolean(on));
|
|
30
|
+
speakerChosen = Boolean(on);
|
|
31
|
+
outputs.preferenceChanged();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Play call audio on this output (a deviceId from useAudioOutput().outputs) while it stays connected. Rejects with
|
|
36
|
+
* `bad-params` for an output that is not there and in the audio mode `media`, and with `media-unavailable` on iOS and
|
|
37
|
+
* where the native module is missing.
|
|
38
|
+
*/
|
|
39
|
+
export async function selectAudioOutput(deviceId) {
|
|
40
|
+
const module = requireNative('Choosing the audio output');
|
|
41
|
+
let routed;
|
|
42
|
+
try {
|
|
43
|
+
routed = await module.selectAudioOutput(deviceId);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
throw nativeFailure(err);
|
|
46
|
+
}
|
|
47
|
+
if (!routed) {
|
|
48
|
+
throw new RpcError('bad-params', nativeConstants()?.audioMode === 'media' ? 'in the audio mode media, sound follows the system\'s media routing: there is no output to choose' : `there is no audio output with the id ${deviceId}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The speaker preference a newly joined call holds the audio with: the provider's (default the loudspeaker), unless
|
|
54
|
+
* the app chose with setSpeakerphoneOn, which the router keeps (null).
|
|
55
|
+
*/
|
|
56
|
+
export function speakerPreference(provider) {
|
|
57
|
+
return speakerChosen !== null ? null : provider ?? true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ------------------------------------------------------------------------------------------- holding the call audio
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* One client's hold on the call audio: acquired once it is connected, released when it closes or the provider lets go
|
|
64
|
+
* of it. Released a moment late, so React's StrictMode (an effect unmounted and mounted again at once) neither
|
|
65
|
+
* releases nor acquires twice.
|
|
66
|
+
*/
|
|
67
|
+
class AudioHold {
|
|
68
|
+
holder = null;
|
|
69
|
+
users = 0;
|
|
70
|
+
pendingRelease = false;
|
|
71
|
+
constructor(onError) {
|
|
72
|
+
this.onError = onError;
|
|
73
|
+
}
|
|
74
|
+
retain() {
|
|
75
|
+
this.users += 1;
|
|
76
|
+
this.pendingRelease = false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** One user less; the hold goes when none is left. */
|
|
80
|
+
unretain() {
|
|
81
|
+
this.users = Math.max(0, this.users - 1);
|
|
82
|
+
if (this.users > 0) return;
|
|
83
|
+
this.pendingRelease = true;
|
|
84
|
+
queueMicrotask(() => {
|
|
85
|
+
if (this.pendingRelease && this.users === 0) this.release();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
acquire(speakerphone) {
|
|
89
|
+
if (this.holder) return;
|
|
90
|
+
const module = nativeModule();
|
|
91
|
+
if (!module) return;
|
|
92
|
+
this.holder = module.audioAcquire(speakerphone).then(id => id, err => {
|
|
93
|
+
this.onError(nativeFailure(err));
|
|
94
|
+
return null;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
release() {
|
|
98
|
+
this.pendingRelease = false;
|
|
99
|
+
const holder = this.holder;
|
|
100
|
+
if (!holder) return;
|
|
101
|
+
this.holder = null;
|
|
102
|
+
void holder.then(id => {
|
|
103
|
+
if (id !== null) nativeModule()?.audioRelease(id);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const holds = new WeakMap();
|
|
108
|
+
|
|
109
|
+
/** The call audio hold of `client`. */
|
|
110
|
+
export function audioHoldOf(client, onError) {
|
|
111
|
+
let hold = holds.get(client);
|
|
112
|
+
if (!hold) {
|
|
113
|
+
hold = new AudioHold(onError);
|
|
114
|
+
holds.set(client, hold);
|
|
115
|
+
}
|
|
116
|
+
return hold;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ------------------------------------------------------------------------------------------- useAudioOutput
|
|
120
|
+
|
|
121
|
+
const NONE = Object.freeze({
|
|
122
|
+
supported: false,
|
|
123
|
+
outputs: Object.freeze([]),
|
|
124
|
+
current: null,
|
|
125
|
+
speakerphone: false
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
/** The audio outputs, kept current from the router's events while something listens. */
|
|
129
|
+
class OutputStore {
|
|
130
|
+
state = NONE;
|
|
131
|
+
listeners = new Set();
|
|
132
|
+
stop = null;
|
|
133
|
+
subscribe = listener => {
|
|
134
|
+
this.listeners.add(listener);
|
|
135
|
+
if (this.listeners.size === 1) this.start();
|
|
136
|
+
return () => {
|
|
137
|
+
this.listeners.delete(listener);
|
|
138
|
+
if (this.listeners.size === 0) {
|
|
139
|
+
this.stop?.();
|
|
140
|
+
this.stop = null;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
snapshot = () => this.state;
|
|
145
|
+
|
|
146
|
+
/** The app changed the speaker preference: what is shown before a call holds the audio follows it. */
|
|
147
|
+
preferenceChanged() {
|
|
148
|
+
if (this.listeners.size > 0) this.set({
|
|
149
|
+
...this.state,
|
|
150
|
+
speakerphone: this.state.current ? this.state.current.type === 'speaker' : speakerChosen ?? true
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
start() {
|
|
154
|
+
const module = nativeModule();
|
|
155
|
+
const supported = Platform.OS === 'android' && module !== null && nativeConstants()?.audioMode !== 'media';
|
|
156
|
+
if (!module) {
|
|
157
|
+
this.set(NONE);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.set({
|
|
161
|
+
...this.state,
|
|
162
|
+
supported,
|
|
163
|
+
speakerphone: this.state.current ? this.state.current.type === 'speaker' : speakerChosen ?? true
|
|
164
|
+
});
|
|
165
|
+
const stops = [listen(module.onAudioDevicesChanged, 'onAudioDevicesChanged', e => this.setOutputs(e.devices.map(toMediaDevice))), listen(module.onAudioOutputChanged, 'onAudioOutputChanged', e => this.setCurrent(e.device ? toMediaDevice(e.device) : null))];
|
|
166
|
+
this.stop = () => {
|
|
167
|
+
for (const stop of stops) stop();
|
|
168
|
+
};
|
|
169
|
+
module.listAudioDevices().then(list => this.setOutputs(list.map(toMediaDevice)), err => logError('could not list the audio devices', err));
|
|
170
|
+
module.currentAudioOutput().then(device => this.setCurrent(device ? toMediaDevice(device) : null), err => logError('could not read the audio output', err));
|
|
171
|
+
}
|
|
172
|
+
setOutputs(devices) {
|
|
173
|
+
const outputs = this.state.supported ? devices.filter(d => d.kind === 'audiooutput') : [];
|
|
174
|
+
const same = outputs.length === this.state.outputs.length && outputs.every((d, i) => d.deviceId === this.state.outputs[i].deviceId && d.label === this.state.outputs[i].label);
|
|
175
|
+
if (!same) this.set({
|
|
176
|
+
...this.state,
|
|
177
|
+
outputs
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
setCurrent(device) {
|
|
181
|
+
if (device?.deviceId === this.state.current?.deviceId) return;
|
|
182
|
+
this.set({
|
|
183
|
+
...this.state,
|
|
184
|
+
current: device,
|
|
185
|
+
speakerphone: device ? device.type === 'speaker' : speakerChosen ?? true
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
set(next) {
|
|
189
|
+
this.state = next;
|
|
190
|
+
for (const listener of [...this.listeners]) listener();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const outputs = new OutputStore();
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Where call audio plays, and the choice of output (an Android "speaker / phone / headset" picker). Works before any
|
|
197
|
+
* call: a choice made then is kept. On iOS and without the native module `supported` is false and the calls reject.
|
|
198
|
+
*/
|
|
199
|
+
export function useAudioOutput() {
|
|
200
|
+
const state = useSyncExternalStore(outputs.subscribe, outputs.snapshot, outputs.snapshot);
|
|
201
|
+
return useMemo(() => ({
|
|
202
|
+
...state,
|
|
203
|
+
select: selectAudioOutput,
|
|
204
|
+
setSpeakerphoneOn
|
|
205
|
+
}), [state]);
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=audio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useMemo","useSyncExternalStore","Platform","RpcError","listen","nativeConstants","nativeModule","requireNative","toMediaDevice","logError","nativeFailure","speakerChosen","setSpeakerphoneOn","on","module","Boolean","outputs","preferenceChanged","selectAudioOutput","deviceId","routed","err","audioMode","speakerPreference","provider","AudioHold","holder","users","pendingRelease","constructor","onError","retain","unretain","Math","max","queueMicrotask","release","acquire","speakerphone","audioAcquire","then","id","audioRelease","holds","WeakMap","audioHoldOf","client","hold","get","set","NONE","Object","freeze","supported","current","OutputStore","state","listeners","Set","stop","subscribe","listener","add","size","start","delete","snapshot","type","OS","stops","onAudioDevicesChanged","e","setOutputs","devices","map","onAudioOutputChanged","setCurrent","device","listAudioDevices","list","currentAudioOutput","filter","d","kind","same","length","every","i","label","next","useAudioOutput","select"],"sourceRoot":"../../src","sources":["audio.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* VideoTrack and AudioTrack, React Native's versions of @voltkit-rtc/react's.
|
|
5
|
+
*
|
|
6
|
+
* VideoTrack shows a track in react-native-webrtc's RTCView, which plays a stream by URL. Its stream is a wrapper made
|
|
7
|
+
* through platform/streams.ts, one per track and shared by every view of it, released (never the track) when the last
|
|
8
|
+
* view goes -- or earlier, while the connection still exists, when the client is about to close what receives the
|
|
9
|
+
* track or stops it: releasing a wrapper after its track died kills the app (Phase 0 finding 1). The URL is set one
|
|
10
|
+
* frame after mounting, and the native view is mounted again once if no frame size arrives within 3 s
|
|
11
|
+
* (react-native-webrtc #1611, black video).
|
|
12
|
+
*
|
|
13
|
+
* AudioTrack renders nothing: React Native plays every remote audio track by itself. It sets one track's volume
|
|
14
|
+
* (react-native-webrtc's `_setVolume`, unity at 1) or mutes it here only.
|
|
15
|
+
*/
|
|
16
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
17
|
+
import { StyleSheet, View } from 'react-native';
|
|
18
|
+
import { useVoltkitClient } from '@voltkit-rtc/react';
|
|
19
|
+
import { loadWebRTC } from "./globals.js";
|
|
20
|
+
import { logError } from "./errors.js";
|
|
21
|
+
import { streamBook } from "./platform/streams.js";
|
|
22
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
23
|
+
/** How long a view waits for its first frame before its native view is mounted again (react-native-webrtc #1611). */
|
|
24
|
+
export const FIRST_FRAME_TIMEOUT_MS = 3000;
|
|
25
|
+
/** A video track in an RTCView, sized by `style`. */
|
|
26
|
+
export function VideoTrack({
|
|
27
|
+
track,
|
|
28
|
+
producerId,
|
|
29
|
+
mirror = false,
|
|
30
|
+
objectFit = 'cover',
|
|
31
|
+
zOrder,
|
|
32
|
+
visible = true,
|
|
33
|
+
onDimensionsChange,
|
|
34
|
+
style,
|
|
35
|
+
testID
|
|
36
|
+
}) {
|
|
37
|
+
const client = useVoltkitClient();
|
|
38
|
+
const [url, setUrl] = useState(null);
|
|
39
|
+
// The RTCView's key: changed once to mount it again when no frame came.
|
|
40
|
+
const [mount, setMount] = useState(0);
|
|
41
|
+
const sawFrame = useRef(false);
|
|
42
|
+
const dimensions = useRef(onDimensionsChange);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
dimensions.current = onDimensionsChange;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// The wrapper stream, held while this view shows the track; its URL one frame after mounting.
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
setUrl(null);
|
|
50
|
+
if (!track) return;
|
|
51
|
+
const view = streamBook().view(track);
|
|
52
|
+
if (!view) return;
|
|
53
|
+
let frame = requestAnimationFrame(() => {
|
|
54
|
+
frame = null;
|
|
55
|
+
setUrl(view.url);
|
|
56
|
+
});
|
|
57
|
+
const stopEnd = view.onEnd(() => {
|
|
58
|
+
if (frame !== null) cancelAnimationFrame(frame);
|
|
59
|
+
frame = null;
|
|
60
|
+
setUrl(null);
|
|
61
|
+
});
|
|
62
|
+
return () => {
|
|
63
|
+
if (frame !== null) cancelAnimationFrame(frame);
|
|
64
|
+
stopEnd();
|
|
65
|
+
view.release();
|
|
66
|
+
};
|
|
67
|
+
}, [track]);
|
|
68
|
+
|
|
69
|
+
// react-native-webrtc #1611: a view that never shows a frame is mounted again, once per stream.
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
sawFrame.current = false;
|
|
72
|
+
if (!url) return;
|
|
73
|
+
const timer = setTimeout(() => {
|
|
74
|
+
if (!sawFrame.current) setMount(n => n + 1);
|
|
75
|
+
}, FIRST_FRAME_TIMEOUT_MS);
|
|
76
|
+
return () => clearTimeout(timer);
|
|
77
|
+
}, [url]);
|
|
78
|
+
|
|
79
|
+
// Adaptive stream: the view reports its size (onLayout) and visibility (`visible`) through a ViewSource.
|
|
80
|
+
const box = useRef(null);
|
|
81
|
+
const shown = useRef(visible);
|
|
82
|
+
const reports = useRef(new Set());
|
|
83
|
+
const tell = (nextBox, nextVisible) => {
|
|
84
|
+
for (const report of [...reports.current]) {
|
|
85
|
+
try {
|
|
86
|
+
report(nextBox, nextVisible);
|
|
87
|
+
} catch (err) {
|
|
88
|
+
logError('listener for videoView threw', err);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (shown.current === visible) return;
|
|
94
|
+
shown.current = visible;
|
|
95
|
+
tell(null, visible);
|
|
96
|
+
}, [visible]);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!box.current || box.current.fit === objectFit) return;
|
|
99
|
+
box.current = {
|
|
100
|
+
...box.current,
|
|
101
|
+
fit: objectFit
|
|
102
|
+
};
|
|
103
|
+
tell(box.current, null);
|
|
104
|
+
}, [objectFit]);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
const attach = client?.attachVideo;
|
|
107
|
+
if (!client || !producerId || typeof attach !== 'function') return;
|
|
108
|
+
const source = {
|
|
109
|
+
subscribe(onChange) {
|
|
110
|
+
reports.current.add(onChange);
|
|
111
|
+
if (box.current || !shown.current) onChange(box.current, shown.current);
|
|
112
|
+
return () => {
|
|
113
|
+
reports.current.delete(onChange);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
return attach.call(client, producerId, source);
|
|
118
|
+
}, [client, producerId]);
|
|
119
|
+
const onLayout = useCallback(event => {
|
|
120
|
+
const {
|
|
121
|
+
width,
|
|
122
|
+
height
|
|
123
|
+
} = event.nativeEvent.layout;
|
|
124
|
+
const previous = box.current;
|
|
125
|
+
if (previous && previous.width === width && previous.height === height && previous.fit === objectFit) return;
|
|
126
|
+
box.current = {
|
|
127
|
+
width,
|
|
128
|
+
height,
|
|
129
|
+
fit: objectFit
|
|
130
|
+
};
|
|
131
|
+
tell(box.current, null);
|
|
132
|
+
}, [objectFit]);
|
|
133
|
+
const onFrameSize = useCallback(event => {
|
|
134
|
+
sawFrame.current = true;
|
|
135
|
+
const {
|
|
136
|
+
width,
|
|
137
|
+
height
|
|
138
|
+
} = event.nativeEvent;
|
|
139
|
+
try {
|
|
140
|
+
dimensions.current?.({
|
|
141
|
+
width,
|
|
142
|
+
height
|
|
143
|
+
});
|
|
144
|
+
} catch (err) {
|
|
145
|
+
logError('listener for onDimensionsChange threw', err);
|
|
146
|
+
}
|
|
147
|
+
}, []);
|
|
148
|
+
const RTCView = loadWebRTC()?.RTCView;
|
|
149
|
+
return /*#__PURE__*/_jsx(View, {
|
|
150
|
+
style: style,
|
|
151
|
+
onLayout: onLayout,
|
|
152
|
+
testID: testID,
|
|
153
|
+
collapsable: false,
|
|
154
|
+
children: RTCView && url ? /*#__PURE__*/_jsx(RTCView, {
|
|
155
|
+
streamURL: url,
|
|
156
|
+
mirror: mirror,
|
|
157
|
+
objectFit: objectFit,
|
|
158
|
+
zOrder: zOrder,
|
|
159
|
+
onDimensionsChange: onFrameSize,
|
|
160
|
+
style: StyleSheet.absoluteFill
|
|
161
|
+
}, mount) : null
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/** One remote audio track's volume, or muted, while mounted. Renders nothing: React Native plays remote audio itself. */
|
|
165
|
+
export function AudioTrack({
|
|
166
|
+
track,
|
|
167
|
+
volume,
|
|
168
|
+
muted = false
|
|
169
|
+
}) {
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
const audio = track;
|
|
172
|
+
if (!audio || audio.kind !== 'audio' || typeof audio._setVolume !== 'function') return;
|
|
173
|
+
if (typeof volume !== 'number' || Number.isNaN(volume)) return;
|
|
174
|
+
const gain = Math.min(1, Math.max(0, volume));
|
|
175
|
+
try {
|
|
176
|
+
audio._setVolume(gain);
|
|
177
|
+
} catch (err) {
|
|
178
|
+
logError('could not set a track\'s volume', err);
|
|
179
|
+
}
|
|
180
|
+
return () => {
|
|
181
|
+
if (audio.readyState === 'ended') return;
|
|
182
|
+
try {
|
|
183
|
+
audio._setVolume?.(1);
|
|
184
|
+
} catch (err) {
|
|
185
|
+
logError('could not set a track\'s volume', err);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}, [track, volume]);
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
const audio = track;
|
|
191
|
+
if (!audio || !muted) return;
|
|
192
|
+
const was = audio.enabled;
|
|
193
|
+
audio.enabled = false;
|
|
194
|
+
return () => {
|
|
195
|
+
if (audio.readyState !== 'ended') audio.enabled = was;
|
|
196
|
+
};
|
|
197
|
+
}, [track, muted]);
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","StyleSheet","View","useVoltkitClient","loadWebRTC","logError","streamBook","jsx","_jsx","FIRST_FRAME_TIMEOUT_MS","VideoTrack","track","producerId","mirror","objectFit","zOrder","visible","onDimensionsChange","style","testID","client","url","setUrl","mount","setMount","sawFrame","dimensions","current","view","frame","requestAnimationFrame","stopEnd","onEnd","cancelAnimationFrame","release","timer","setTimeout","n","clearTimeout","box","shown","reports","Set","tell","nextBox","nextVisible","report","err","fit","attach","attachVideo","source","subscribe","onChange","add","delete","call","onLayout","event","width","height","nativeEvent","layout","previous","onFrameSize","RTCView","collapsable","children","streamURL","absoluteFill","AudioTrack","volume","muted","audio","kind","_setVolume","Number","isNaN","gain","Math","min","max","readyState","was","enabled"],"sourceRoot":"../../src","sources":["components.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A StreamClient for React Native: react-native-webrtc's mediasoup handler (ReactNative106) and this package's
|
|
5
|
+
* platform, with the background pause on for the camera. The provider makes its clients this way; an app that makes and
|
|
6
|
+
* owns its client (the provider's `client` prop, a PK battle's second client) uses createClient.
|
|
7
|
+
*/
|
|
8
|
+
import { StreamClient } from '@voltkit-rtc/client';
|
|
9
|
+
import { registerVoltkitGlobals } from "./globals.js";
|
|
10
|
+
import { webrtcMissing } from "./errors.js";
|
|
11
|
+
import { reactNativePlatform } from "./platform/index.js";
|
|
12
|
+
|
|
13
|
+
/** What happens to the camera and microphone while the app is in the background. */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The ClientOptions a React Native client is made with: `{ handlerName: 'ReactNative106', platform,
|
|
17
|
+
* pauseCameraInBackground, pauseMicInBackground, ...clientOptions }`.
|
|
18
|
+
*/
|
|
19
|
+
export function reactNativeClientOptions(options = {}) {
|
|
20
|
+
const {
|
|
21
|
+
background,
|
|
22
|
+
clientOptions
|
|
23
|
+
} = options;
|
|
24
|
+
return {
|
|
25
|
+
handlerName: 'ReactNative106',
|
|
26
|
+
platform: reactNativePlatform(),
|
|
27
|
+
pauseCameraInBackground: background?.pauseCamera ?? true,
|
|
28
|
+
pauseMicInBackground: background?.pauseMic ?? false,
|
|
29
|
+
...clientOptions
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A StreamClient for React Native, not yet connected: call `connect()`. Throws `media-unavailable` with
|
|
35
|
+
* `{ reason: 'webrtc-missing' }` where react-native-webrtc's native module is missing (Expo Go: it needs a development
|
|
36
|
+
* build).
|
|
37
|
+
*/
|
|
38
|
+
export function createClient(wsUrl, token, options = {}) {
|
|
39
|
+
if (!registerVoltkitGlobals()) throw webrtcMissing();
|
|
40
|
+
return new StreamClient(wsUrl, token, reactNativeClientOptions(options));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=create-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["StreamClient","registerVoltkitGlobals","webrtcMissing","reactNativePlatform","reactNativeClientOptions","options","background","clientOptions","handlerName","platform","pauseCameraInBackground","pauseCamera","pauseMicInBackground","pauseMic","createClient","wsUrl","token"],"sourceRoot":"../../src","sources":["create-client.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA,SAASA,YAAY,QAA4B,qBAAqB;AACtE,SAASC,sBAAsB,QAAQ,cAAW;AAClD,SAASC,aAAa,QAAQ,aAAU;AACxC,SAASC,mBAAmB,QAAQ,qBAAY;;AAEhD;;AAmBA;AACA;AACA;AACA;AACA,OAAO,SAASC,wBAAwBA,CAACC,OAA4B,GAAG,CAAC,CAAC,EAAiB;EACzF,MAAM;IAAEC,UAAU;IAAEC;EAAc,CAAC,GAAGF,OAAO;EAC7C,OAAO;IACLG,WAAW,EAAE,gBAAgB;IAC7BC,QAAQ,EAAEN,mBAAmB,CAAC,CAAC;IAC/BO,uBAAuB,EAAEJ,UAAU,EAAEK,WAAW,IAAI,IAAI;IACxDC,oBAAoB,EAAEN,UAAU,EAAEO,QAAQ,IAAI,KAAK;IACnD,GAAGN;EACL,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASO,YAAYA,CAACC,KAAa,EAAEC,KAAa,EAAEX,OAA4B,GAAG,CAAC,CAAC,EAAgB;EAC1G,IAAI,CAACJ,sBAAsB,CAAC,CAAC,EAAE,MAAMC,aAAa,CAAC,CAAC;EACpD,OAAO,IAAIF,YAAY,CAACe,KAAK,EAAEC,KAAK,EAAEZ,wBAAwB,CAACC,OAAO,CAAC,CAAC;AAC1E","ignoreList":[]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The errors this package raises. Every one is an RpcError with a code from the VoltKit error registry
|
|
5
|
+
* (@voltkit-rtc/client ERROR_CODES, checked code for code against every SDK by scripts/test/sdk-contract-sdks.mjs), so
|
|
6
|
+
* an app switches on `error.code` exactly as it does in a browser or the Android SDK. What is missing goes in `data`:
|
|
7
|
+
*
|
|
8
|
+
* - `media-unavailable` `{ reason: 'webrtc-missing' }`: react-native-webrtc's native module is not in the app (Expo Go,
|
|
9
|
+
* or an app not rebuilt after installing it). The message says it needs a development build.
|
|
10
|
+
* - `media-unavailable` `{ reason: 'native-missing', feature }`: this package's own native module is not in the app.
|
|
11
|
+
* - `media-unavailable` `{ platform: 'ios', feature }`: not in the iOS preview (audio routing: setSpeakerphoneOn,
|
|
12
|
+
* selectAudioOutput, switchDevice('audiooutput')). The call service and screen sharing do not raise it there: the
|
|
13
|
+
* service is simply not declared (useCallService), and the client answers `screen-share-unsupported`.
|
|
14
|
+
* - `media-unavailable` `{ permission: 'camera' | 'microphone', status: 'denied' | 'blocked' }`: a refused permission,
|
|
15
|
+
* the field names of the Android SDK.
|
|
16
|
+
* - `media-unavailable` `{ feature: 'callService' }`: the call service could not start or keep running.
|
|
17
|
+
*/
|
|
18
|
+
import { RpcError } from '@voltkit-rtc/client';
|
|
19
|
+
/** react-native-webrtc's native module is missing: Expo Go, or the app was not rebuilt. */
|
|
20
|
+
export function webrtcMissing() {
|
|
21
|
+
return new RpcError('media-unavailable', "react-native-webrtc's native module is not in this app: @voltkit-rtc/react-native needs a development build (Expo Go cannot load it). Install react-native-webrtc and rebuild the app (npx expo run:android, or an EAS development build).", {
|
|
22
|
+
reason: 'webrtc-missing'
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** This package's own native module is missing: the app was not rebuilt after installing it. */
|
|
27
|
+
export function nativeMissing(feature) {
|
|
28
|
+
return new RpcError('media-unavailable', `${feature} needs @voltkit-rtc/react-native's native module, which is not in this app: it needs a development build. Rebuild the app after installing the package (Expo Go cannot load it).`, {
|
|
29
|
+
reason: 'native-missing',
|
|
30
|
+
feature
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Not in the iOS preview of 0.1.0. */
|
|
35
|
+
export function iosUnsupported(feature) {
|
|
36
|
+
return new RpcError('media-unavailable', `${feature} is not available in the iOS preview of @voltkit-rtc/react-native`, {
|
|
37
|
+
platform: 'ios',
|
|
38
|
+
feature
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A camera or microphone permission the user refused: `blocked` when Android will not ask again. */
|
|
43
|
+
export function permissionRefused(permission, status) {
|
|
44
|
+
const what = permission === 'camera' ? 'camera' : 'microphone';
|
|
45
|
+
const why = status === 'blocked' ? `the ${what} permission is blocked: the user has to allow it in the app's settings` : `the ${what} permission was not granted`;
|
|
46
|
+
return new RpcError('media-unavailable', why, {
|
|
47
|
+
permission,
|
|
48
|
+
status
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The call service could not start, or Android stopped it. */
|
|
53
|
+
export function callServiceFailed(message) {
|
|
54
|
+
return new RpcError('media-unavailable', `the call service: ${message}`, {
|
|
55
|
+
feature: 'callService'
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** A failure a native module or react-native-webrtc reported, as an RpcError with a registry code. */
|
|
60
|
+
export function nativeFailure(error, code = 'media-unavailable', data) {
|
|
61
|
+
if (error instanceof RpcError) return error;
|
|
62
|
+
return new RpcError(code, describeError(error), data);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** A readable message from anything thrown: an Error, react-native-webrtc's MediaStreamError (not an Error), a string. */
|
|
66
|
+
export function describeError(error) {
|
|
67
|
+
if (typeof error === 'string') return error;
|
|
68
|
+
if (error && typeof error === 'object') {
|
|
69
|
+
const {
|
|
70
|
+
name,
|
|
71
|
+
message
|
|
72
|
+
} = error;
|
|
73
|
+
const text = typeof message === 'string' && message.length > 0 ? message : '';
|
|
74
|
+
const label = typeof name === 'string' && name.length > 0 && name !== 'Error' ? name : '';
|
|
75
|
+
if (label && text && !text.includes(label)) return `${label}: ${text}`;
|
|
76
|
+
if (text) return text;
|
|
77
|
+
if (label) return label;
|
|
78
|
+
}
|
|
79
|
+
return String(error);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Report a failure from code no caller awaits: the error listener's own errors never escape into the app. */
|
|
83
|
+
export function logError(context, error) {
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
console.error(`[voltkit-rtc] ${context}`, error);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["RpcError","webrtcMissing","reason","nativeMissing","feature","iosUnsupported","platform","permissionRefused","permission","status","what","why","callServiceFailed","message","nativeFailure","error","code","data","describeError","name","text","length","label","includes","String","logError","context","console"],"sourceRoot":"../../src","sources":["errors.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,QAAQ,QAAQ,qBAAqB;AAI9C;AACA,OAAO,SAASC,aAAaA,CAAA,EAAa;EACxC,OAAO,IAAID,QAAQ,CACjB,mBAAmB,EACnB,4OAA4O,EAC5O;IAAEE,MAAM,EAAE;EAAiB,CAC7B,CAAC;AACH;;AAEA;AACA,OAAO,SAASC,aAAaA,CAACC,OAAe,EAAY;EACvD,OAAO,IAAIJ,QAAQ,CACjB,mBAAmB,EACnB,GAAGI,OAAO,kLAAkL,EAC5L;IAAEF,MAAM,EAAE,gBAAgB;IAAEE;EAAQ,CACtC,CAAC;AACH;;AAEA;AACA,OAAO,SAASC,cAAcA,CAACD,OAAe,EAAY;EACxD,OAAO,IAAIJ,QAAQ,CAAC,mBAAmB,EAAE,GAAGI,OAAO,mEAAmE,EAAE;IAAEE,QAAQ,EAAE,KAAK;IAAEF;EAAQ,CAAC,CAAC;AACvJ;;AAEA;AACA,OAAO,SAASG,iBAAiBA,CAACC,UAA+B,EAAEC,MAA4B,EAAY;EACzG,MAAMC,IAAI,GAAGF,UAAU,KAAK,QAAQ,GAAG,QAAQ,GAAG,YAAY;EAC9D,MAAMG,GAAG,GAAGF,MAAM,KAAK,SAAS,GAC5B,OAAOC,IAAI,wEAAwE,GACnF,OAAOA,IAAI,6BAA6B;EAC5C,OAAO,IAAIV,QAAQ,CAAC,mBAAmB,EAAEW,GAAG,EAAE;IAAEH,UAAU;IAAEC;EAAO,CAAC,CAAC;AACvE;;AAEA;AACA,OAAO,SAASG,iBAAiBA,CAACC,OAAe,EAAY;EAC3D,OAAO,IAAIb,QAAQ,CAAC,mBAAmB,EAAE,qBAAqBa,OAAO,EAAE,EAAE;IAAET,OAAO,EAAE;EAAc,CAAC,CAAC;AACtG;;AAEA;AACA,OAAO,SAASU,aAAaA,CAACC,KAAc,EAAEC,IAAmE,GAAG,mBAAmB,EAAEC,IAA8B,EAAY;EACjL,IAAIF,KAAK,YAAYf,QAAQ,EAAE,OAAOe,KAAK;EAC3C,OAAO,IAAIf,QAAQ,CAACgB,IAAI,EAAEE,aAAa,CAACH,KAAK,CAAC,EAAEE,IAAI,CAAC;AACvD;;AAEA;AACA,OAAO,SAASC,aAAaA,CAACH,KAAc,EAAU;EACpD,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE,OAAOA,KAAK;EAC3C,IAAIA,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;IACtC,MAAM;MAAEI,IAAI;MAAEN;IAAQ,CAAC,GAAGE,KAA8C;IACxE,MAAMK,IAAI,GAAG,OAAOP,OAAO,KAAK,QAAQ,IAAIA,OAAO,CAACQ,MAAM,GAAG,CAAC,GAAGR,OAAO,GAAG,EAAE;IAC7E,MAAMS,KAAK,GAAG,OAAOH,IAAI,KAAK,QAAQ,IAAIA,IAAI,CAACE,MAAM,GAAG,CAAC,IAAIF,IAAI,KAAK,OAAO,GAAGA,IAAI,GAAG,EAAE;IACzF,IAAIG,KAAK,IAAIF,IAAI,IAAI,CAACA,IAAI,CAACG,QAAQ,CAACD,KAAK,CAAC,EAAE,OAAO,GAAGA,KAAK,KAAKF,IAAI,EAAE;IACtE,IAAIA,IAAI,EAAE,OAAOA,IAAI;IACrB,IAAIE,KAAK,EAAE,OAAOA,KAAK;EACzB;EACA,OAAOE,MAAM,CAACT,KAAK,CAAC;AACtB;;AAEA;AACA,OAAO,SAASU,QAAQA,CAACC,OAAe,EAAEX,KAAc,EAAQ;EAC9D;EACAY,OAAO,CAACZ,KAAK,CAAC,iBAAiBW,OAAO,EAAE,EAAEX,KAAK,CAAC;AAClD","ignoreList":[]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* react-native-webrtc, loaded only once its native module is known to be in the app. Its entry module talks to
|
|
5
|
+
* WebRTCModule as soon as it runs, so in Expo Go (or an app not rebuilt after installing it) merely importing it can
|
|
6
|
+
* throw or leave the app in a broken state. This package never imports it at the top level: everything goes through
|
|
7
|
+
* `loadWebRTC()`, which answers null instead, and `registerVoltkitGlobals()` (run when the package is imported) is safe
|
|
8
|
+
* anywhere.
|
|
9
|
+
*/
|
|
10
|
+
import { NativeModules } from 'react-native';
|
|
11
|
+
let loaded = null;
|
|
12
|
+
let registered = false;
|
|
13
|
+
|
|
14
|
+
/** Whether react-native-webrtc's native module is in this app. */
|
|
15
|
+
export function webrtcAvailable() {
|
|
16
|
+
return NativeModules.WebRTCModule != null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** react-native-webrtc, or null when its native module is not in the app (Expo Go, an app not rebuilt). */
|
|
20
|
+
export function loadWebRTC() {
|
|
21
|
+
if (loaded) return loaded;
|
|
22
|
+
if (!webrtcAvailable()) return null;
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
24
|
+
loaded = require('react-native-webrtc');
|
|
25
|
+
return loaded;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Install react-native-webrtc's WebRTC classes as globals (RTCPeerConnection, MediaStream, ...), which mediasoup-client
|
|
30
|
+
* needs. Runs when the package is imported; calling it again does nothing. Returns false, without throwing, where
|
|
31
|
+
* react-native-webrtc's native module is missing: the provider then reports `media-unavailable` with
|
|
32
|
+
* `{ reason: 'webrtc-missing' }`.
|
|
33
|
+
*/
|
|
34
|
+
export function registerVoltkitGlobals() {
|
|
35
|
+
if (registered) return true;
|
|
36
|
+
const webrtc = loadWebRTC();
|
|
37
|
+
if (!webrtc) return false;
|
|
38
|
+
webrtc.registerGlobals();
|
|
39
|
+
registered = true;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The version of react-native-webrtc in the app, for getDiagnostics(); null when it cannot be read. */
|
|
44
|
+
export function webrtcVersion() {
|
|
45
|
+
try {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
47
|
+
const pkg = require('react-native-webrtc/package.json');
|
|
48
|
+
return typeof pkg.version === 'string' ? pkg.version : null;
|
|
49
|
+
} catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=globals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeModules","loaded","registered","webrtcAvailable","WebRTCModule","loadWebRTC","require","registerVoltkitGlobals","webrtc","registerGlobals","webrtcVersion","pkg","version"],"sourceRoot":"../../src","sources":["globals.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,aAAa,QAAQ,cAAc;AAK5C,IAAIC,MAA2B,GAAG,IAAI;AACtC,IAAIC,UAAU,GAAG,KAAK;;AAEtB;AACA,OAAO,SAASC,eAAeA,CAAA,EAAY;EACzC,OAAQH,aAAa,CAA6BI,YAAY,IAAI,IAAI;AACxE;;AAEA;AACA,OAAO,SAASC,UAAUA,CAAA,EAAwB;EAChD,IAAIJ,MAAM,EAAE,OAAOA,MAAM;EACzB,IAAI,CAACE,eAAe,CAAC,CAAC,EAAE,OAAO,IAAI;EACnC;EACAF,MAAM,GAAGK,OAAO,CAAC,qBAAqB,CAAiB;EACvD,OAAOL,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASM,sBAAsBA,CAAA,EAAY;EAChD,IAAIL,UAAU,EAAE,OAAO,IAAI;EAC3B,MAAMM,MAAM,GAAGH,UAAU,CAAC,CAAC;EAC3B,IAAI,CAACG,MAAM,EAAE,OAAO,KAAK;EACzBA,MAAM,CAACC,eAAe,CAAC,CAAC;EACxBP,UAAU,GAAG,IAAI;EACjB,OAAO,IAAI;AACb;;AAEA;AACA,OAAO,SAASQ,aAAaA,CAAA,EAAkB;EAC7C,IAAI;IACF;IACA,MAAMC,GAAG,GAAGL,OAAO,CAAC,kCAAkC,CAA0B;IAChF,OAAO,OAAOK,GAAG,CAACC,OAAO,KAAK,QAAQ,GAAGD,GAAG,CAACC,OAAO,GAAG,IAAI;EAC7D,CAAC,CAAC,MAAM;IACN,OAAO,IAAI;EACb;AACF","ignoreList":[]}
|