@cloudflare/realtimekit-react-native 0.3.1-staging.2 → 0.3.2-staging.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/lib/commonjs/AGENTS.md +58 -0
- package/lib/commonjs/AudioSampleHandler.js +4 -2
- package/lib/commonjs/AudioSampleHandler.js.map +1 -1
- package/lib/commonjs/BackgroundHandler.js +3 -3
- package/lib/commonjs/BackgroundHandler.js.map +1 -1
- package/lib/commonjs/LocalMediaHandler.js +75 -30
- package/lib/commonjs/LocalMediaHandler.js.map +1 -1
- package/lib/commonjs/LocalMediaUtils.js +3 -2
- package/lib/commonjs/LocalMediaUtils.js.map +1 -1
- package/lib/commonjs/ReactHooks.js +26 -0
- package/lib/commonjs/ReactHooks.js.map +1 -1
- package/lib/commonjs/utils/version.js +1 -1
- package/lib/commonjs/utils/version.js.map +1 -1
- package/lib/module/AGENTS.md +58 -0
- package/lib/module/AudioSampleHandler.js +3 -1
- package/lib/module/AudioSampleHandler.js.map +1 -1
- package/lib/module/BackgroundHandler.js +2 -2
- package/lib/module/BackgroundHandler.js.map +1 -1
- package/lib/module/LocalMediaHandler.js +74 -29
- package/lib/module/LocalMediaHandler.js.map +1 -1
- package/lib/module/LocalMediaUtils.js +2 -1
- package/lib/module/LocalMediaUtils.js.map +1 -1
- package/lib/module/ReactHooks.js +26 -0
- package/lib/module/ReactHooks.js.map +1 -1
- package/lib/module/utils/version.js +1 -1
- package/lib/module/utils/version.js.map +1 -1
- package/lib/typescript/AudioSampleHandler.d.ts +2 -0
- package/lib/typescript/BackgroundHandler.d.ts +2 -0
- package/lib/typescript/LocalMediaHandler.d.ts +2 -0
- package/lib/typescript/LocalMediaUtils.d.ts +2 -0
- package/lib/typescript/ReactHooks.d.ts +1 -1
- package/lib/typescript/utils/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SDK_VERSION","exports"],"sources":["version.ts"],"sourcesContent":["export const SDK_VERSION = '0.3.
|
|
1
|
+
{"version":3,"names":["SDK_VERSION","exports"],"sources":["version.ts"],"sourcesContent":["export const SDK_VERSION = '0.3.2';\n"],"mappings":";;;;;;AAAO,MAAMA,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAG,OAAO","ignoreList":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# src/ — Library Source
|
|
2
|
+
|
|
3
|
+
Core TypeScript source for `@cloudflare/realtimekit-react-native`. Thin React Native bridge over `@cloudflare/realtimekit`.
|
|
4
|
+
|
|
5
|
+
## FILE MAP
|
|
6
|
+
|
|
7
|
+
| File | Lines | Role |
|
|
8
|
+
|------|-------|------|
|
|
9
|
+
| `index.tsx` | 87 | **Entry point**. Side-effect imports: registers WebRTC globals, patches `navigator`, polyfills crypto/URL/encoding. Exports hooks + provider. |
|
|
10
|
+
| `ReactHooks.tsx` | 99 | `useRealtimeKitClient`, `useRealtimeKitSelector`, `useRTKSelector` (deprecated), `useRealtimeKitMeeting`. Re-exports from ReactContext. |
|
|
11
|
+
| `ReactContext.tsx` | 140 | `RealtimeKitProvider` component + `RealtimeKitUpdates` listener manager. Has `@ts-nocheck` — legacy, do not propagate. |
|
|
12
|
+
| `LocalMediaHandler.ts` | 1084 | **Largest file.** Audio/video/screenshare track lifecycle, device switching, permission gating, iOS broadcast + Android foreground service integration. |
|
|
13
|
+
| `LocalMediaUtils.ts` | 481 | Static helpers: `getUserMedia` with timeout, device enumeration (audio from native, video from WebRTC), `chooseAudioRoute`, video constraints. |
|
|
14
|
+
| `LocalMediaInterfaces.ts` | 101 | Type definitions: `MediaDeviceInfo`, `MediaPermission`, constraint types, quality enums. |
|
|
15
|
+
| `LocalMediaError.ts` | 9 | Simple `Error` subclass with `code` field. |
|
|
16
|
+
| `NativeAudioManager.ts` | 105 | JS wrapper for `InCallManager` native module. Audio routing, speaker control, device queries. Has `@ts-nocheck`. |
|
|
17
|
+
| `PermissionHandler.ts` | 227 | Platform-specific permission flow. Custom `PERMISSIONS`/`RESULTS` constants (mirrors react-native-permissions API without the dependency). Recursive retry with 20s timeout. |
|
|
18
|
+
| `BackgroundHandler.ts` | 134 | Native timer bridge (`RTKRNBackgroundTimer`). setTimeout/setInterval that survive background. Exported as singleton instance. |
|
|
19
|
+
| `AudioSampleHandler.ts` | 65 | Listens to `audioSamples` events from WebRTCModule. Provides `getFloatTimeDomainData` for audio visualization. |
|
|
20
|
+
| `DeviceInfo.ts` | 34 | Reads platform info + SDK version. Exported as singleton. |
|
|
21
|
+
| `utils/crypto.ts` | 155 | `crypto.getRandomValues` polyfill. Cascading fallbacks: ExpoCrypto → NativeModules.Core → ExpoRandom (SDK 41-44) → ExpoModules (SDK 45+). Insecure Math.random fallback in debug only. |
|
|
22
|
+
| `utils/version.ts` | 2 | `SDK_VERSION` constant, auto-generated by `scripts/generate-version.js`. |
|
|
23
|
+
| `__tests__/index.test.tsx` | — | Placeholder: `it.todo('write a test')`. |
|
|
24
|
+
|
|
25
|
+
## KEY PATTERNS
|
|
26
|
+
|
|
27
|
+
### Navigator Property Injection
|
|
28
|
+
The core `@cloudflare/realtimekit` SDK reads implementations from `navigator` at runtime. This package injects them via `Object.defineProperty` in `index.tsx`:
|
|
29
|
+
- `navigator.RNLocalMediaHandlerImpl` → `LocalMediaHandler`
|
|
30
|
+
- `navigator.RNAudioSampleHandlerImpl` → `AudioSampleHandler`
|
|
31
|
+
- `navigator.RNBackgroundTimerImpl` → `BackgroundTimer`
|
|
32
|
+
- `navigator.RNDeviceInfoImpl` → `DeviceInfo`
|
|
33
|
+
|
|
34
|
+
### Audio Device Flow
|
|
35
|
+
```
|
|
36
|
+
Native event (onAudioDeviceChanged)
|
|
37
|
+
→ LocalMediaUtils.onDeviceChange()
|
|
38
|
+
→ LocalMediaHandler.onDeviceChange()
|
|
39
|
+
→ setupSpeaker() / setupAudioStream()
|
|
40
|
+
→ NativeAudioManager.chooseAudioRoute()
|
|
41
|
+
```
|
|
42
|
+
Audio devices (earpiece, speaker, bluetooth, wired) are enumerated from native layer, NOT from WebRTC `enumerateDevices`. Video devices use WebRTC enumeration.
|
|
43
|
+
|
|
44
|
+
### Selector Hook Pattern
|
|
45
|
+
`useRealtimeKitSelector(fn)` uses `useRef` + `useReducer` for forced re-renders. Two subscription paths:
|
|
46
|
+
1. If selected value has `addListener` → subscribes directly to that object
|
|
47
|
+
2. Otherwise → subscribes to `RealtimeKitUpdates` global event bus
|
|
48
|
+
|
|
49
|
+
### Permission Flow
|
|
50
|
+
`setupPermissions(audio, video)` → maps to platform constants → `requestMultiplePermissions` → recursive retry with `setInterval` + 20s rejection timeout. Returns `{camera, microphone, bluetooth, location}` states.
|
|
51
|
+
|
|
52
|
+
## ANTI-PATTERNS TO AVOID
|
|
53
|
+
|
|
54
|
+
- Do NOT add more `@ts-nocheck` files (ReactContext.tsx and NativeAudioManager.ts are legacy exceptions)
|
|
55
|
+
- Do NOT add `eslint-disable` without a tracked issue
|
|
56
|
+
- Do NOT export new singletons (BackgroundHandler/DeviceInfo pattern is tech debt)
|
|
57
|
+
- Do NOT use `as any` for type suppression — define proper types in LocalMediaInterfaces.ts
|
|
58
|
+
- Empty catch at `ReactHooks.tsx:122` (cleanUpEvents function) — should at minimum log
|
|
@@ -6,6 +6,7 @@ import { EventEmitter } from 'events';
|
|
|
6
6
|
const {
|
|
7
7
|
WebRTCModule
|
|
8
8
|
} = NativeModules;
|
|
9
|
+
export const webRTCModuleEmitter = new NativeEventEmitter(WebRTCModule);
|
|
9
10
|
export default class AudioSampleHandler extends EventEmitter {
|
|
10
11
|
constructor() {
|
|
11
12
|
super();
|
|
@@ -13,7 +14,7 @@ export default class AudioSampleHandler extends EventEmitter {
|
|
|
13
14
|
_defineProperty(this, "_audioSamplesListener", void 0);
|
|
14
15
|
_defineProperty(this, "_isListening", false);
|
|
15
16
|
_defineProperty(this, "_currentSamples", void 0);
|
|
16
|
-
this.webRTCModuleEmitter =
|
|
17
|
+
this.webRTCModuleEmitter = webRTCModuleEmitter;
|
|
17
18
|
this._audioSampleHandler = this._audioSampleHandler.bind(this);
|
|
18
19
|
this._currentSamples = new Float32Array(1024);
|
|
19
20
|
this.initialiseSampler();
|
|
@@ -41,6 +42,7 @@ export default class AudioSampleHandler extends EventEmitter {
|
|
|
41
42
|
}
|
|
42
43
|
stopListening() {
|
|
43
44
|
if (this._audioSamplesListener) {
|
|
45
|
+
this._audioSamplesListener.remove();
|
|
44
46
|
this._audioSamplesListener = undefined;
|
|
45
47
|
this._isListening = false;
|
|
46
48
|
this._currentSamples.fill(0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeEventEmitter","NativeModules","Platform","EventEmitter","WebRTCModule","AudioSampleHandler","constructor","_defineProperty","
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","NativeModules","Platform","EventEmitter","WebRTCModule","webRTCModuleEmitter","AudioSampleHandler","constructor","_defineProperty","_audioSampleHandler","bind","_currentSamples","Float32Array","initialiseSampler","init","audioData","fill","OS","set","samples","_audioSamplesListener","addListener","_isListening","getFloatTimeDomainData","stopListening","remove","undefined","destructor"],"sources":["AudioSampleHandler.ts"],"sourcesContent":["import {\n NativeEventEmitter,\n NativeEventSubscription,\n NativeModules,\n Platform,\n} from 'react-native';\nimport { EventEmitter } from 'events';\n\nconst { WebRTCModule } = NativeModules;\n\nexport const webRTCModuleEmitter = new NativeEventEmitter(WebRTCModule);\n\nexport default class AudioSampleHandler extends EventEmitter {\n private webRTCModuleEmitter: NativeEventEmitter;\n private _audioSamplesListener?: NativeEventSubscription;\n private _isListening = false;\n private _currentSamples: Float32Array;\n\n constructor() {\n super();\n this.webRTCModuleEmitter = webRTCModuleEmitter;\n this._audioSampleHandler = this._audioSampleHandler.bind(this);\n this._currentSamples = new Float32Array(1024);\n this.initialiseSampler();\n }\n\n public static async init() {\n return new AudioSampleHandler();\n }\n\n private _audioSampleHandler(audioData: any) {\n this._currentSamples.fill(0);\n if (Platform.OS === 'android') {\n this._currentSamples.set(audioData);\n } else {\n this._currentSamples.set(audioData.samples);\n }\n }\n\n private initialiseSampler() {\n this._audioSamplesListener = this.webRTCModuleEmitter.addListener(\n 'audioSamples',\n this._audioSampleHandler\n );\n this._isListening = true;\n }\n\n public getFloatTimeDomainData(samples: Float32Array) {\n if (!this._isListening) {\n this.initialiseSampler();\n }\n samples.set(this._currentSamples);\n }\n\n public stopListening() {\n if (this._audioSamplesListener) {\n this._audioSamplesListener.remove();\n this._audioSamplesListener = undefined;\n this._isListening = false;\n this._currentSamples.fill(0);\n }\n }\n\n public destructor() {\n this.stopListening();\n }\n}\n"],"mappings":";;;AAAA,SACEA,kBAAkB,EAElBC,aAAa,EACbC,QAAQ,QACH,cAAc;AACrB,SAASC,YAAY,QAAQ,QAAQ;AAErC,MAAM;EAAEC;AAAa,CAAC,GAAGH,aAAa;AAEtC,OAAO,MAAMI,mBAAmB,GAAG,IAAIL,kBAAkB,CAACI,YAAY,CAAC;AAEvE,eAAe,MAAME,kBAAkB,SAASH,YAAY,CAAC;EAM3DI,WAAWA,CAAA,EAAG;IACZ,KAAK,CAAC,CAAC;IAACC,eAAA;IAAAA,eAAA;IAAAA,eAAA,uBAJa,KAAK;IAAAA,eAAA;IAK1B,IAAI,CAACH,mBAAmB,GAAGA,mBAAmB;IAC9C,IAAI,CAACI,mBAAmB,GAAG,IAAI,CAACA,mBAAmB,CAACC,IAAI,CAAC,IAAI,CAAC;IAC9D,IAAI,CAACC,eAAe,GAAG,IAAIC,YAAY,CAAC,IAAI,CAAC;IAC7C,IAAI,CAACC,iBAAiB,CAAC,CAAC;EAC1B;EAEA,aAAoBC,IAAIA,CAAA,EAAG;IACzB,OAAO,IAAIR,kBAAkB,CAAC,CAAC;EACjC;EAEQG,mBAAmBA,CAACM,SAAc,EAAE;IAC1C,IAAI,CAACJ,eAAe,CAACK,IAAI,CAAC,CAAC,CAAC;IAC5B,IAAId,QAAQ,CAACe,EAAE,KAAK,SAAS,EAAE;MAC7B,IAAI,CAACN,eAAe,CAACO,GAAG,CAACH,SAAS,CAAC;IACrC,CAAC,MAAM;MACL,IAAI,CAACJ,eAAe,CAACO,GAAG,CAACH,SAAS,CAACI,OAAO,CAAC;IAC7C;EACF;EAEQN,iBAAiBA,CAAA,EAAG;IAC1B,IAAI,CAACO,qBAAqB,GAAG,IAAI,CAACf,mBAAmB,CAACgB,WAAW,CAC/D,cAAc,EACd,IAAI,CAACZ,mBACP,CAAC;IACD,IAAI,CAACa,YAAY,GAAG,IAAI;EAC1B;EAEOC,sBAAsBA,CAACJ,OAAqB,EAAE;IACnD,IAAI,CAAC,IAAI,CAACG,YAAY,EAAE;MACtB,IAAI,CAACT,iBAAiB,CAAC,CAAC;IAC1B;IACAM,OAAO,CAACD,GAAG,CAAC,IAAI,CAACP,eAAe,CAAC;EACnC;EAEOa,aAAaA,CAAA,EAAG;IACrB,IAAI,IAAI,CAACJ,qBAAqB,EAAE;MAC9B,IAAI,CAACA,qBAAqB,CAACK,MAAM,CAAC,CAAC;MACnC,IAAI,CAACL,qBAAqB,GAAGM,SAAS;MACtC,IAAI,CAACJ,YAAY,GAAG,KAAK;MACzB,IAAI,CAACX,eAAe,CAACK,IAAI,CAAC,CAAC,CAAC;IAC9B;EACF;EAEOW,UAAUA,CAAA,EAAG;IAClB,IAAI,CAACH,aAAa,CAAC,CAAC;EACtB;AACF","ignoreList":[]}
|
|
@@ -5,7 +5,7 @@ import { DeviceEventEmitter, NativeAppEventEmitter, NativeEventEmitter, NativeMo
|
|
|
5
5
|
const {
|
|
6
6
|
RTKRNBackgroundTimer
|
|
7
7
|
} = NativeModules;
|
|
8
|
-
const
|
|
8
|
+
export const backgroundEmitter = new NativeEventEmitter(RTKRNBackgroundTimer);
|
|
9
9
|
class BackgroundTimer {
|
|
10
10
|
constructor() {
|
|
11
11
|
_defineProperty(this, "uniqueId", void 0);
|
|
@@ -14,7 +14,7 @@ class BackgroundTimer {
|
|
|
14
14
|
_defineProperty(this, "backgroundListener", void 0);
|
|
15
15
|
this.uniqueId = 0;
|
|
16
16
|
this.callbacks = {};
|
|
17
|
-
|
|
17
|
+
backgroundEmitter.addListener('backgroundTimer.timeout', id => {
|
|
18
18
|
if (this.callbacks[id]) {
|
|
19
19
|
const callbackById = this.callbacks[id];
|
|
20
20
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["DeviceEventEmitter","NativeAppEventEmitter","NativeEventEmitter","NativeModules","Platform","RTKRNBackgroundTimer","
|
|
1
|
+
{"version":3,"names":["DeviceEventEmitter","NativeAppEventEmitter","NativeEventEmitter","NativeModules","Platform","RTKRNBackgroundTimer","backgroundEmitter","BackgroundTimer","constructor","_defineProperty","uniqueId","callbacks","addListener","id","callbackById","callback","interval","OS","backgroundTimerSetTimeout","timeout","setTimeout","init","start","delay","backgroundTimerStart","stop","backgroundTimerStop","runBackgroundTimer","EventEmitter","select","ios","android","backgroundListener","remove","backgroundClockMethod","backgroundTimer","stopBackgroundTimer","clearTimeout","timeoutId","setInterval","intervalId","clearInterval"],"sources":["BackgroundHandler.ts"],"sourcesContent":["import {\n DeviceEventEmitter,\n NativeAppEventEmitter,\n NativeEventEmitter,\n NativeModules,\n Platform,\n} from 'react-native';\n\nconst { RTKRNBackgroundTimer } = NativeModules;\nexport const backgroundEmitter = new NativeEventEmitter(RTKRNBackgroundTimer);\n\nclass BackgroundTimer {\n uniqueId: number;\n\n callbacks: { [key: string]: any };\n\n backgroundTimer: number | NodeJS.Timeout | null;\n\n backgroundListener: any;\n\n constructor() {\n this.uniqueId = 0;\n this.callbacks = {};\n\n backgroundEmitter.addListener('backgroundTimer.timeout', (id) => {\n if (this.callbacks[id]) {\n const callbackById = this.callbacks[id];\n const { callback } = callbackById;\n if (!this.callbacks[id].interval) {\n delete this.callbacks[id];\n } else {\n Platform.OS === 'android'\n ? RTKRNBackgroundTimer.backgroundTimerSetTimeout(\n id,\n this.callbacks[id].timeout\n )\n : RTKRNBackgroundTimer.setTimeout(id, this.callbacks[id].timeout);\n }\n callback();\n }\n });\n }\n\n init() {\n return new BackgroundTimer();\n }\n\n // Original API\n start(delay = 0) {\n return Platform.OS === 'android'\n ? RTKRNBackgroundTimer.backgroundTimerStart(delay)\n : RTKRNBackgroundTimer.start(delay);\n }\n\n stop() {\n return Platform.OS === 'android'\n ? RTKRNBackgroundTimer.backgroundTimerStop()\n : RTKRNBackgroundTimer.stop();\n }\n\n runBackgroundTimer(callback, delay) {\n const EventEmitter = Platform.select({\n ios: () => NativeAppEventEmitter,\n android: () => DeviceEventEmitter,\n })();\n this.start(0);\n this.backgroundListener = EventEmitter.addListener(\n 'backgroundTimer',\n () => {\n this.backgroundListener.remove();\n this.backgroundClockMethod(callback, delay);\n }\n );\n }\n\n backgroundClockMethod(callback, delay) {\n this.backgroundTimer = this.setTimeout(() => {\n callback();\n this.backgroundClockMethod(callback, delay);\n }, delay);\n }\n\n stopBackgroundTimer() {\n this.stop();\n this.clearTimeout(this.backgroundTimer);\n }\n\n // New API, allowing for multiple timers\n setTimeout(callback, timeout) {\n this.uniqueId += 1;\n const timeoutId = this.uniqueId;\n this.callbacks[timeoutId] = {\n callback,\n interval: false,\n timeout,\n };\n Platform.OS === 'android'\n ? RTKRNBackgroundTimer.backgroundTimerSetTimeout(timeoutId, timeout)\n : RTKRNBackgroundTimer.setTimeout(timeoutId, timeout);\n return timeoutId;\n }\n\n clearTimeout(timeoutId) {\n if (this.callbacks[timeoutId]) {\n delete this.callbacks[timeoutId];\n // RTKRNBackgroundTimer.clearTimeout(timeoutId);\n }\n }\n\n setInterval(callback, timeout) {\n this.uniqueId += 1;\n const intervalId = this.uniqueId;\n this.callbacks[intervalId] = {\n callback,\n interval: true,\n timeout,\n };\n Platform.OS === 'android'\n ? RTKRNBackgroundTimer.backgroundTimerSetTimeout(intervalId, timeout)\n : RTKRNBackgroundTimer.setTimeout(intervalId, timeout);\n return intervalId;\n }\n\n clearInterval(intervalId) {\n if (this.callbacks[intervalId]) {\n delete this.callbacks[intervalId];\n // RTKRNBackgroundTimer.clearTimeout(intervalId);\n }\n }\n}\n\n// TODO: Remove singleton pattern\nexport default new BackgroundTimer();\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -17,7 +17,7 @@ const {
|
|
|
17
17
|
RTKHelper,
|
|
18
18
|
BroadcastEventEmitter
|
|
19
19
|
} = NativeModules;
|
|
20
|
-
const broadcastEmitter = new NativeEventEmitter(BroadcastEventEmitter);
|
|
20
|
+
export const broadcastEmitter = new NativeEventEmitter(BroadcastEventEmitter);
|
|
21
21
|
|
|
22
22
|
// eslint-disable-next-line no-shadow
|
|
23
23
|
export let MediaEvents = /*#__PURE__*/function (MediaEvents) {
|
|
@@ -39,7 +39,11 @@ var _localMediaUtils = /*#__PURE__*/new WeakMap();
|
|
|
39
39
|
var _appState = /*#__PURE__*/new WeakMap();
|
|
40
40
|
var _appStateSubscription = /*#__PURE__*/new WeakMap();
|
|
41
41
|
var _interval = /*#__PURE__*/new WeakMap();
|
|
42
|
+
var _screenShareState = /*#__PURE__*/new WeakMap();
|
|
42
43
|
var _deviceRemovalTimeout = /*#__PURE__*/new WeakMap();
|
|
44
|
+
var _broadcastEmitter = /*#__PURE__*/new WeakMap();
|
|
45
|
+
var _broadcastStartedSubscription = /*#__PURE__*/new WeakMap();
|
|
46
|
+
var _broadcastStoppedSubscription = /*#__PURE__*/new WeakMap();
|
|
43
47
|
export default class LocalMediaHandler extends EventEmitter {
|
|
44
48
|
async configureForeground() {
|
|
45
49
|
if (Platform.OS !== 'android') return;
|
|
@@ -67,6 +71,7 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
67
71
|
_classPrivateFieldInitSpec(this, _appState, void 0);
|
|
68
72
|
_classPrivateFieldInitSpec(this, _appStateSubscription, void 0);
|
|
69
73
|
_classPrivateFieldInitSpec(this, _interval, void 0);
|
|
74
|
+
_classPrivateFieldInitSpec(this, _screenShareState, void 0);
|
|
70
75
|
_defineProperty(this, "audioTrack", void 0);
|
|
71
76
|
_defineProperty(this, "rawAudioTrack", void 0);
|
|
72
77
|
_defineProperty(this, "videoTrack", void 0);
|
|
@@ -79,6 +84,9 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
79
84
|
_defineProperty(this, "currentDevices", void 0);
|
|
80
85
|
_defineProperty(this, "permissions", void 0);
|
|
81
86
|
_classPrivateFieldInitSpec(this, _deviceRemovalTimeout, null);
|
|
87
|
+
_classPrivateFieldInitSpec(this, _broadcastEmitter, void 0);
|
|
88
|
+
_classPrivateFieldInitSpec(this, _broadcastStartedSubscription, void 0);
|
|
89
|
+
_classPrivateFieldInitSpec(this, _broadcastStoppedSubscription, void 0);
|
|
82
90
|
_defineProperty(this, "_handleAppStateChange", nextAppState => {
|
|
83
91
|
if (_classPrivateFieldGet(_appState, this).match(/inactive|background/) && nextAppState === 'active') {
|
|
84
92
|
BackgroundTimer.clearInterval(_classPrivateFieldGet(_interval, this));
|
|
@@ -102,6 +110,7 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
102
110
|
}
|
|
103
111
|
});
|
|
104
112
|
_classPrivateFieldSet(_localMediaUtils, this, localMediaUtils);
|
|
113
|
+
_classPrivateFieldSet(_broadcastEmitter, this, broadcastEmitter);
|
|
105
114
|
_classPrivateFieldSet(_appState, this, '');
|
|
106
115
|
this.audioEnabled = true;
|
|
107
116
|
this.videoEnabled = true;
|
|
@@ -124,12 +133,12 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
124
133
|
await this.onDeviceChange(changedDevices, false);
|
|
125
134
|
});
|
|
126
135
|
if (Platform.OS === 'ios') {
|
|
127
|
-
|
|
136
|
+
_classPrivateFieldSet(_broadcastStartedSubscription, this, _classPrivateFieldGet(_broadcastEmitter, this).addListener('iOS_BroadcastStarted', () => {
|
|
128
137
|
this.oniOSBroadcastStart();
|
|
129
|
-
});
|
|
130
|
-
|
|
138
|
+
}));
|
|
139
|
+
_classPrivateFieldSet(_broadcastStoppedSubscription, this, _classPrivateFieldGet(_broadcastEmitter, this).addListener('iOS_BroadcastStopped', () => {
|
|
131
140
|
this.oniOSBroadcastStop();
|
|
132
|
-
});
|
|
141
|
+
}));
|
|
133
142
|
}
|
|
134
143
|
NativeAudioManager.start({
|
|
135
144
|
media: 'video'
|
|
@@ -292,7 +301,7 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
292
301
|
}
|
|
293
302
|
}
|
|
294
303
|
this.setVideoTrack(this.rawVideoTrack);
|
|
295
|
-
this.addMediaStreamTrackListeners(this.
|
|
304
|
+
this.addMediaStreamTrackListeners(this.videoTrack);
|
|
296
305
|
this.emit('VIDEO_TRACK_CHANGE');
|
|
297
306
|
}
|
|
298
307
|
if (forceStopTrack) {
|
|
@@ -509,7 +518,10 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
509
518
|
return;
|
|
510
519
|
}
|
|
511
520
|
if (audioTrack === undefined) {
|
|
512
|
-
|
|
521
|
+
var _this$rawAudioTrack2, _this$rawAudioTrack3;
|
|
522
|
+
(_this$rawAudioTrack2 = this.rawAudioTrack) === null || _this$rawAudioTrack2 === void 0 || _this$rawAudioTrack2.stop();
|
|
523
|
+
(_this$rawAudioTrack3 = this.rawAudioTrack) === null || _this$rawAudioTrack3 === void 0 || _this$rawAudioTrack3.release();
|
|
524
|
+
this.rawAudioTrack = undefined;
|
|
513
525
|
}
|
|
514
526
|
this.audioTrack = audioTrack;
|
|
515
527
|
}
|
|
@@ -518,7 +530,10 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
518
530
|
return;
|
|
519
531
|
}
|
|
520
532
|
if (videoTrack === undefined) {
|
|
521
|
-
|
|
533
|
+
var _this$rawVideoTrack2, _this$rawVideoTrack3;
|
|
534
|
+
(_this$rawVideoTrack2 = this.rawVideoTrack) === null || _this$rawVideoTrack2 === void 0 || _this$rawVideoTrack2.stop();
|
|
535
|
+
(_this$rawVideoTrack3 = this.rawVideoTrack) === null || _this$rawVideoTrack3 === void 0 || _this$rawVideoTrack3.release();
|
|
536
|
+
this.rawVideoTrack = undefined;
|
|
522
537
|
}
|
|
523
538
|
this.videoTrack = videoTrack;
|
|
524
539
|
}
|
|
@@ -620,7 +635,10 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
620
635
|
return;
|
|
621
636
|
}
|
|
622
637
|
if (this.videoEnabled) {
|
|
623
|
-
|
|
638
|
+
var _this$rawVideoTrack4, _this$rawVideoTrack5;
|
|
639
|
+
(_this$rawVideoTrack4 = this.rawVideoTrack) === null || _this$rawVideoTrack4 === void 0 || _this$rawVideoTrack4.stop();
|
|
640
|
+
(_this$rawVideoTrack5 = this.rawVideoTrack) === null || _this$rawVideoTrack5 === void 0 || _this$rawVideoTrack5.release();
|
|
641
|
+
this.rawVideoTrack = undefined;
|
|
624
642
|
this.videoEnabled = false;
|
|
625
643
|
return;
|
|
626
644
|
}
|
|
@@ -636,7 +654,10 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
636
654
|
}
|
|
637
655
|
async setVideoDevice(device) {
|
|
638
656
|
if (this.videoEnabled) {
|
|
639
|
-
|
|
657
|
+
var _this$rawVideoTrack6, _this$rawVideoTrack7;
|
|
658
|
+
(_this$rawVideoTrack6 = this.rawVideoTrack) === null || _this$rawVideoTrack6 === void 0 || _this$rawVideoTrack6.stop();
|
|
659
|
+
(_this$rawVideoTrack7 = this.rawVideoTrack) === null || _this$rawVideoTrack7 === void 0 || _this$rawVideoTrack7.release();
|
|
660
|
+
this.rawVideoTrack = undefined;
|
|
640
661
|
}
|
|
641
662
|
await this.setupVideoStream(device.deviceId);
|
|
642
663
|
}
|
|
@@ -649,12 +670,12 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
649
670
|
async oniOSBroadcastStart() {
|
|
650
671
|
this.setScreenShareTracks(await LocalMediaUtils.getScreenShareTracks());
|
|
651
672
|
this.screenShareEnabled = true;
|
|
652
|
-
this
|
|
673
|
+
_classPrivateFieldSet(_screenShareState, this, 'STARTED');
|
|
653
674
|
}
|
|
654
675
|
async oniOSBroadcastStop() {
|
|
676
|
+
_classPrivateFieldSet(_screenShareState, this, 'STOPPED');
|
|
655
677
|
if (this.screenShareEnabled) {
|
|
656
678
|
this.removeScreenShareTracks();
|
|
657
|
-
this.emit('SCREENSHARE_TRACK_CHANGE');
|
|
658
679
|
return;
|
|
659
680
|
}
|
|
660
681
|
}
|
|
@@ -673,6 +694,22 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
673
694
|
}
|
|
674
695
|
if (Platform.OS === 'ios' && this.screenShareEnabled) {
|
|
675
696
|
NativeModules.RTKScreensharePickerView.showScreenSharePickerView();
|
|
697
|
+
_classPrivateFieldSet(_screenShareState, this, 'PENDING');
|
|
698
|
+
await new Promise((resolve, reject) => {
|
|
699
|
+
let timeoutId;
|
|
700
|
+
let time = 0;
|
|
701
|
+
timeoutId = setInterval(() => {
|
|
702
|
+
if (_classPrivateFieldGet(_screenShareState, this) === 'STOPPED') {
|
|
703
|
+
clearInterval(timeoutId);
|
|
704
|
+
resolve();
|
|
705
|
+
}
|
|
706
|
+
time = time + 100;
|
|
707
|
+
if (time > 20000) {
|
|
708
|
+
clearInterval(timeoutId);
|
|
709
|
+
reject('Timeout exceeded for disableScreenShare()');
|
|
710
|
+
}
|
|
711
|
+
}, 100);
|
|
712
|
+
});
|
|
676
713
|
return;
|
|
677
714
|
}
|
|
678
715
|
if (Platform.OS === 'android') {
|
|
@@ -694,7 +731,23 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
694
731
|
}
|
|
695
732
|
}
|
|
696
733
|
if (Platform.OS === 'ios') {
|
|
734
|
+
_classPrivateFieldSet(_screenShareState, this, 'PENDING');
|
|
697
735
|
NativeModules.RTKScreensharePickerView.showScreenSharePickerView();
|
|
736
|
+
await new Promise((resolve, reject) => {
|
|
737
|
+
let timeoutId;
|
|
738
|
+
let time = 0;
|
|
739
|
+
timeoutId = setInterval(() => {
|
|
740
|
+
if (_classPrivateFieldGet(_screenShareState, this) === 'STARTED') {
|
|
741
|
+
clearInterval(timeoutId);
|
|
742
|
+
resolve();
|
|
743
|
+
}
|
|
744
|
+
time = time + 100;
|
|
745
|
+
if (time > 20000) {
|
|
746
|
+
clearInterval(timeoutId);
|
|
747
|
+
reject('Timeout exceeded for enableScreenShare()');
|
|
748
|
+
}
|
|
749
|
+
}, 100);
|
|
750
|
+
});
|
|
698
751
|
}
|
|
699
752
|
}
|
|
700
753
|
async enableScreenShare() {
|
|
@@ -839,34 +892,26 @@ export default class LocalMediaHandler extends EventEmitter {
|
|
|
839
892
|
return super.on(event, listener);
|
|
840
893
|
}
|
|
841
894
|
destruct() {
|
|
842
|
-
|
|
895
|
+
this.stopAudioTrack();
|
|
896
|
+
this.stopVideoTrack();
|
|
897
|
+
this.stopScreenShareTracks();
|
|
843
898
|
if (Platform.OS === 'android') _classPrivateFieldGet(_appStateSubscription, this).remove();
|
|
844
|
-
BackgroundTimer.stop();
|
|
845
|
-
try {
|
|
846
|
-
if (Platform.OS === 'android') {
|
|
847
|
-
RTKHelper.isForegroundServiceRunning().then(val => {
|
|
848
|
-
if (val) {
|
|
849
|
-
RTKHelper.stopService();
|
|
850
|
-
}
|
|
851
|
-
});
|
|
852
|
-
}
|
|
853
|
-
} catch (_err) {}
|
|
854
899
|
}
|
|
855
900
|
stopAudioTrack() {
|
|
856
|
-
var _this$
|
|
857
|
-
(_this$
|
|
901
|
+
var _this$rawAudioTrack4, _this$audioTrack3, _this$rawAudioTrack5, _this$audioTrack4;
|
|
902
|
+
(_this$rawAudioTrack4 = this.rawAudioTrack) === null || _this$rawAudioTrack4 === void 0 || _this$rawAudioTrack4.stop();
|
|
858
903
|
(_this$audioTrack3 = this.audioTrack) === null || _this$audioTrack3 === void 0 || _this$audioTrack3.stop();
|
|
859
|
-
(_this$
|
|
904
|
+
(_this$rawAudioTrack5 = this.rawAudioTrack) === null || _this$rawAudioTrack5 === void 0 || _this$rawAudioTrack5.release();
|
|
860
905
|
(_this$audioTrack4 = this.audioTrack) === null || _this$audioTrack4 === void 0 || _this$audioTrack4.release();
|
|
861
906
|
this.audioEnabled = false;
|
|
862
907
|
this.audioTrack = undefined;
|
|
863
908
|
this.rawAudioTrack = undefined;
|
|
864
909
|
}
|
|
865
910
|
stopVideoTrack() {
|
|
866
|
-
var _this$
|
|
867
|
-
(_this$
|
|
911
|
+
var _this$rawVideoTrack8, _this$videoTrack3, _this$rawVideoTrack9, _this$videoTrack4;
|
|
912
|
+
(_this$rawVideoTrack8 = this.rawVideoTrack) === null || _this$rawVideoTrack8 === void 0 || _this$rawVideoTrack8.stop();
|
|
868
913
|
(_this$videoTrack3 = this.videoTrack) === null || _this$videoTrack3 === void 0 || _this$videoTrack3.stop();
|
|
869
|
-
(_this$
|
|
914
|
+
(_this$rawVideoTrack9 = this.rawVideoTrack) === null || _this$rawVideoTrack9 === void 0 || _this$rawVideoTrack9.release();
|
|
870
915
|
(_this$videoTrack4 = this.videoTrack) === null || _this$videoTrack4 === void 0 || _this$videoTrack4.release();
|
|
871
916
|
this.videoTrack = undefined;
|
|
872
917
|
this.rawVideoTrack = undefined;
|