@stream-io/video-react-native-sdk 1.37.0 → 1.37.1-beta.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.
Files changed (43) hide show
  1. package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +81 -0
  2. package/android/src/main/java/com/streamvideo/reactnative/recorder/AudioPipeline.kt +436 -0
  3. package/android/src/main/java/com/streamvideo/reactnative/recorder/EncoderConstants.kt +17 -0
  4. package/android/src/main/java/com/streamvideo/reactnative/recorder/PipelineHost.kt +36 -0
  5. package/android/src/main/java/com/streamvideo/reactnative/recorder/RecorderPlaybackSamplesSink.kt +60 -0
  6. package/android/src/main/java/com/streamvideo/reactnative/recorder/RecorderVideoSink.kt +31 -0
  7. package/android/src/main/java/com/streamvideo/reactnative/recorder/TracksRecorderManager.kt +329 -0
  8. package/android/src/main/java/com/streamvideo/reactnative/recorder/VideoPipeline.kt +472 -0
  9. package/dist/commonjs/hooks/index.js +11 -0
  10. package/dist/commonjs/hooks/index.js.map +1 -1
  11. package/dist/commonjs/hooks/useLoopbackRecording.js +243 -0
  12. package/dist/commonjs/hooks/useLoopbackRecording.js.map +1 -0
  13. package/dist/commonjs/utils/internal/callingx/callingx.js +2 -2
  14. package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -1
  15. package/dist/commonjs/version.js +1 -1
  16. package/dist/commonjs/version.js.map +1 -1
  17. package/dist/module/hooks/index.js +1 -0
  18. package/dist/module/hooks/index.js.map +1 -1
  19. package/dist/module/hooks/useLoopbackRecording.js +238 -0
  20. package/dist/module/hooks/useLoopbackRecording.js.map +1 -0
  21. package/dist/module/utils/internal/callingx/callingx.js +2 -2
  22. package/dist/module/utils/internal/callingx/callingx.js.map +1 -1
  23. package/dist/module/version.js +1 -1
  24. package/dist/module/version.js.map +1 -1
  25. package/dist/typescript/hooks/index.d.ts +1 -0
  26. package/dist/typescript/hooks/index.d.ts.map +1 -1
  27. package/dist/typescript/hooks/useLoopbackRecording.d.ts +85 -0
  28. package/dist/typescript/hooks/useLoopbackRecording.d.ts.map +1 -0
  29. package/dist/typescript/version.d.ts +1 -1
  30. package/dist/typescript/version.d.ts.map +1 -1
  31. package/ios/StreamVideoReactNative-Bridging-Header.h +2 -0
  32. package/ios/StreamVideoReactNative.m +81 -0
  33. package/ios/TracksRecorder/AudioPipeline.swift +270 -0
  34. package/ios/TracksRecorder/PipelineHost.swift +56 -0
  35. package/ios/TracksRecorder/RecorderAudioRenderTap.swift +154 -0
  36. package/ios/TracksRecorder/RecorderVideoSink.swift +137 -0
  37. package/ios/TracksRecorder/TracksRecorderManager.swift +327 -0
  38. package/ios/TracksRecorder/VideoPipeline.swift +297 -0
  39. package/package.json +8 -8
  40. package/src/hooks/index.ts +1 -0
  41. package/src/hooks/useLoopbackRecording.ts +438 -0
  42. package/src/utils/internal/callingx/callingx.ts +2 -2
  43. package/src/version.ts +1 -1
@@ -0,0 +1,472 @@
1
+ package com.streamvideo.reactnative.recorder
2
+
3
+ import android.media.MediaCodec
4
+ import android.media.MediaCodecInfo
5
+ import android.media.MediaFormat
6
+ import android.media.MediaMuxer
7
+ import android.util.Log
8
+ import org.webrtc.VideoFrame
9
+ import org.webrtc.VideoTrack
10
+
11
+ /**
12
+ * Video pipeline encapsulates everything specific to the H.264 video path:
13
+ * - the [RecorderVideoSink] attached to the source [VideoTrack],
14
+ * - the [MediaCodec] H.264 encoder + its configuration,
15
+ * - per-frame I420→NV12 normalisation (via [YuvHelper.I420ToNV12]),
16
+ * - encoder output drain (format-locked addTrack, sample append, EOS),
17
+ * - per-recording counters surfaced for the end-of-recording log line.
18
+ *
19
+ * Reports format-locked / sample-appended events to the host so the host
20
+ * can gate the muxer-start and track file duration. All state mutation
21
+ * runs on the host's handler thread.
22
+ */
23
+ internal class VideoPipeline(
24
+ private val host: PipelineHost,
25
+ private val videoTrack: VideoTrack,
26
+ private val targetWidth: Int = 0,
27
+ private val targetHeight: Int = 0,
28
+ ) {
29
+ private companion object {
30
+ const val TAG = "TracksRecorder.Video"
31
+ const val MIME = "video/avc"
32
+ const val BIT_RATE = 1_000_000
33
+ const val FRAME_RATE = 30
34
+ const val I_FRAME_INTERVAL_SECS = 1
35
+ }
36
+
37
+ private val handler = host.handler
38
+
39
+ private var encoder: MediaCodec? = null
40
+ private var sink: RecorderVideoSink? = null
41
+
42
+ private var trackIndex: Int = -1
43
+ private var formatLocked = false
44
+
45
+ /**
46
+ * Dimensions the encoder was configured with (locked to the first
47
+ * delivered frame). MediaCodec's input buffer slot size is fixed at
48
+ * `configure()` time, so frames at a different resolution are
49
+ * rescaled before encoding.
50
+ */
51
+ private var encoderWidth: Int = 0
52
+ private var encoderHeight: Int = 0
53
+ private var rotationApplied = false
54
+
55
+ //diagnostic counters
56
+ private var framesEncoded = 0
57
+ private var samplesAppended = 0
58
+ private var framesDropped = 0
59
+ private var framesScaled = 0
60
+ private var firstSamplePtsUs: Long = -1
61
+ private var lastSamplePtsUs: Long = -1
62
+
63
+ /** Attach the sink to the video track. Future frames post to the handler. */
64
+ fun start() {
65
+ val s = RecorderVideoSink { frame -> onFrameDelivered(frame) }
66
+ sink = s
67
+ videoTrack.addSink(s)
68
+ }
69
+
70
+ /**
71
+ * Detach the sink synchronously from any thread. `VideoTrack.removeSink`
72
+ * is thread-safe and idempotent. Called off the recorder handler so
73
+ * no new frames arrive while the backlog drains — going through the
74
+ * handler would queue the detach behind the encoder backlog.
75
+ */
76
+ fun detachSink() {
77
+ try {
78
+ sink?.let { videoTrack.removeSink(it) }
79
+ } catch (t: Throwable) {
80
+ Log.w(TAG, "removeSink threw", t)
81
+ }
82
+ sink = null
83
+ }
84
+
85
+ /** On-handler. Submit EOS to the encoder. Returns `true` if queued. */
86
+ fun signalEndOfStream(muxerInstance: MediaMuxer): Boolean {
87
+ val enc = encoder ?: return false
88
+ return signalEoS(enc, muxerInstance)
89
+ }
90
+
91
+ /** On-handler. Drain until BUFFER_FLAG_END_OF_STREAM or budget expires. */
92
+ fun drainAfterEoS(muxerInstance: MediaMuxer) {
93
+ val enc = encoder ?: return
94
+ drain(enc, muxerInstance, endOfStream = true)
95
+ }
96
+
97
+ /** On-handler. Stop + release the encoder. */
98
+ fun stopAndRelease() {
99
+ try {
100
+ encoder?.stop()
101
+ } catch (t: Throwable) {
102
+ Log.w(TAG, "encoder.stop() threw", t)
103
+ }
104
+ try {
105
+ encoder?.release()
106
+ } catch (t: Throwable) {
107
+ Log.w(TAG, "encoder.release() threw", t)
108
+ }
109
+ encoder = null
110
+ }
111
+
112
+ fun logSummary() {
113
+ val durationMs = if (firstSamplePtsUs >= 0 && lastSamplePtsUs >= firstSamplePtsUs) {
114
+ (lastSamplePtsUs - firstSamplePtsUs) / 1000
115
+ } else {
116
+ -1
117
+ }
118
+ Log.i(
119
+ TAG,
120
+ "summary encoded=$framesEncoded appended=$samplesAppended scaled=$framesScaled dropped=$framesDropped firstPtsUs=$firstSamplePtsUs lastPtsUs=$lastSamplePtsUs durationMs=$durationMs",
121
+ )
122
+ }
123
+
124
+ private fun onFrameDelivered(frame: VideoFrame) {
125
+ // Sink already retained the frame on the WebRTC delivery thread;
126
+ // release once on the recorder handler after encoding.
127
+ handler.post {
128
+ try {
129
+ handleVideoFrameOnHandler(frame)
130
+ } finally {
131
+ frame.release()
132
+ }
133
+ }
134
+ }
135
+
136
+ private fun handleVideoFrameOnHandler(frame: VideoFrame) {
137
+ val muxerInstance = host.muxer ?: return
138
+ val width = frame.buffer.width
139
+ val height = frame.buffer.height
140
+ if (width <= 0 || height <= 0) return
141
+
142
+ // Lazy-create the encoder on the first frame. Prefer the
143
+ // publisher's max video dimensions so the encoder is sized for the
144
+ // highest layer the SFU might ever forward; fall back to the
145
+ // first frame's actual dimensions when no target is supplied.
146
+ val (encW, encH) = resolveEncoderDimensions(
147
+ targetW = targetWidth,
148
+ targetH = targetHeight,
149
+ frameW = width,
150
+ frameH = height,
151
+ )
152
+ val enc = encoder ?: createEncoder(encW, encH) ?: return
153
+
154
+ // WebRTC's adaptive layers can change resolution mid-recording.
155
+ // The encoder's input slots are sized to its configured
156
+ // dimensions, so frames are rescaled instead of dropped.
157
+ // Aspect-ratio mismatches stretch (no crop) — in practice the
158
+ // adaptive layers preserve ratio.
159
+ val needsScale = (width != encoderWidth || height != encoderHeight)
160
+ val originNs = host.seedOriginNs(frame.timestampNs)
161
+ val ptsUs = ((frame.timestampNs - originNs) / 1000L).coerceAtLeast(0L)
162
+
163
+ if (!rotationApplied) {
164
+ rotationApplied = true
165
+ try {
166
+ muxerInstance.setOrientationHint(((frame.rotation % 360) + 360) % 360)
167
+ } catch (t: Throwable) {
168
+ Log.w(TAG, "setOrientationHint failed", t)
169
+ }
170
+ }
171
+
172
+ // Both branches end with a buffer the caller owns and must
173
+ // release: `cropAndScale` produces a new ref-counted buffer,
174
+ // and the no-scale branch retains the original. Every exit
175
+ // path below calls `sourceBuffer.release()`.
176
+ val sourceBuffer: VideoFrame.Buffer = if (needsScale) {
177
+ framesScaled++
178
+ try {
179
+ frame.buffer.cropAndScale(0, 0, width, height, encoderWidth, encoderHeight)
180
+ } catch (t: Throwable) {
181
+ Log.e(TAG, "cropAndScale failed", t)
182
+ framesDropped++
183
+ return
184
+ }
185
+ } else {
186
+ frame.buffer.also { it.retain() }
187
+ }
188
+
189
+ val i420 = sourceBuffer.toI420()
190
+ if (i420 == null) {
191
+ sourceBuffer.release()
192
+ framesDropped++
193
+ return
194
+ }
195
+
196
+ val inputIndex = try {
197
+ enc.dequeueInputBuffer(EncoderConstants.DEQUEUE_TIMEOUT_US)
198
+ } catch (t: Throwable) {
199
+ Log.e(TAG, "dequeueInputBuffer threw", t)
200
+ i420.release()
201
+ sourceBuffer.release()
202
+ framesDropped++
203
+ return
204
+ }
205
+ if (inputIndex < 0) {
206
+ i420.release()
207
+ sourceBuffer.release()
208
+ framesDropped++
209
+ return
210
+ }
211
+
212
+ // The codec's Image exposes each plane's actual `rowStride` /
213
+ // `pixelStride`, so libyuv can write into the slot honouring
214
+ // whatever alignment the hardware needs. A tightly-packed
215
+ // ByteBuffer would produce green chroma + grey Y banding
216
+ // whenever the encoder pads rows or slice height.
217
+ val image = enc.getInputImage(inputIndex)
218
+ val bytesQueued = if (image != null) {
219
+ try {
220
+ writeI420ToCodecImage(i420, image, encoderWidth, encoderHeight)
221
+ } catch (t: Throwable) {
222
+ Log.e(TAG, "writeI420ToCodecImage failed", t)
223
+ -1
224
+ }
225
+ } else {
226
+ -1
227
+ }
228
+ i420.release()
229
+ sourceBuffer.release()
230
+
231
+ if (bytesQueued <= 0) {
232
+ // Release the codec slot without queueing real data.
233
+ enc.queueInputBuffer(inputIndex, 0, 0, ptsUs, 0)
234
+ framesDropped++
235
+ return
236
+ }
237
+
238
+ enc.queueInputBuffer(inputIndex, 0, bytesQueued, ptsUs, 0)
239
+ framesEncoded++
240
+
241
+ drain(enc, muxerInstance, endOfStream = false)
242
+ }
243
+
244
+ /**
245
+ * Converts an I420 frame to NV12 directly into the codec's `Image`
246
+ * plane buffers via libyuv. For NV12 semi-planar, `planes[1]` is
247
+ * the U-byte view of the UV plane and its underlying buffer is a
248
+ * contiguous U,V,U,V,… byte sequence — exactly what `I420ToNV12`
249
+ * writes, so it can be passed directly as `dstUV`. libyuv honours
250
+ * the supplied row strides, handling any encoder padding
251
+ * automatically.
252
+ *
253
+ * Returns the logical NV12 frame size (`width * height * 3 / 2`).
254
+ * NOT the strided sum: `queueInputBuffer`'s underlying input
255
+ * buffer is sized to the natural frame, and passing the strided
256
+ * value would crash with `IllegalArgumentException: buffer offset
257
+ * and size goes beyond the capacity`.
258
+ */
259
+ private fun writeI420ToCodecImage(
260
+ i420: VideoFrame.I420Buffer,
261
+ image: android.media.Image,
262
+ width: Int,
263
+ height: Int,
264
+ ): Int {
265
+ val planes = image.planes
266
+ if (planes.size < 3) return -1
267
+
268
+ val planeY = planes[0]
269
+ val planeUV = planes[1]
270
+ try {
271
+ org.webrtc.YuvHelper.I420ToNV12(
272
+ i420.dataY, i420.strideY,
273
+ i420.dataU, i420.strideU,
274
+ i420.dataV, i420.strideV,
275
+ planeY.buffer, planeY.rowStride,
276
+ planeUV.buffer, planeUV.rowStride,
277
+ width, height,
278
+ )
279
+ } catch (t: Throwable) {
280
+ Log.e(TAG, "YuvHelper.I420ToNV12 failed", t)
281
+ return -1
282
+ }
283
+ return width * height * 3 / 2
284
+ }
285
+
286
+ /**
287
+ * Picks the encoder dimensions, preferring the caller-supplied
288
+ * `targetW`/`targetH` (publisher's max video publish dimension) but
289
+ * oriented to match the actual frame buffer. Publish options are
290
+ * expressed in WebRTC's canonical landscape form; the buffer may
291
+ * be portrait. When they disagree, swap the target axes so the
292
+ * encoder slot is in the same orientation as the frames flowing
293
+ * through it. Falls back to the frame's own dimensions if no
294
+ * target was supplied (target ≤ 0).
295
+ */
296
+ private fun resolveEncoderDimensions(
297
+ targetW: Int,
298
+ targetH: Int,
299
+ frameW: Int,
300
+ frameH: Int,
301
+ ): Pair<Int, Int> {
302
+ if (targetW <= 0 || targetH <= 0) return frameW to frameH
303
+
304
+ val framePortrait = frameH > frameW
305
+ val targetPortrait = targetH > targetW
306
+ return if (framePortrait == targetPortrait) {
307
+ targetW to targetH
308
+ } else {
309
+ targetH to targetW
310
+ }
311
+ }
312
+
313
+ private fun createEncoder(width: Int, height: Int): MediaCodec? {
314
+ // Without KEY_MAX_INPUT_SIZE MediaCodec picks a small default
315
+ // (~64 KB) and `put(nv12)` overflows at any non-trivial size.
316
+ val nv12FrameSize = width * height * 3 / 2
317
+ val format = MediaFormat.createVideoFormat(MIME, width, height).apply {
318
+ setInteger(
319
+ MediaFormat.KEY_COLOR_FORMAT,
320
+ MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
321
+ )
322
+ setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE)
323
+ setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE)
324
+ setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL_SECS)
325
+ setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, nv12FrameSize)
326
+ // Baseline profile suppresses B-frames. With B-frames the
327
+ // output `presentationTimeUs` arrives in coded (DTS) order
328
+ // and MediaMuxer silently truncates the file's reported
329
+ // duration at the first non-monotonic transition. Level 3.1
330
+ // covers up to 720p30, well above the SFU loopback range.
331
+ setInteger(
332
+ MediaFormat.KEY_PROFILE,
333
+ MediaCodecInfo.CodecProfileLevel.AVCProfileBaseline,
334
+ )
335
+ setInteger(
336
+ MediaFormat.KEY_LEVEL,
337
+ MediaCodecInfo.CodecProfileLevel.AVCLevel31,
338
+ )
339
+ // API 30+: low-latency encode = no reorder. Harmless on
340
+ // older API levels (key ignored).
341
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
342
+ setInteger(MediaFormat.KEY_LATENCY, 1)
343
+ }
344
+ }
345
+ return try {
346
+ val enc = MediaCodec.createEncoderByType(MIME)
347
+ enc.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
348
+ enc.start()
349
+ encoder = enc
350
+ encoderWidth = width
351
+ encoderHeight = height
352
+ // INVARIANT: the host's "pending pipelines" counter must
353
+ // stay positive for this pipeline until INFO_OUTPUT_FORMAT_CHANGED
354
+ // has fired and `muxer.addTrack(video)` has been called.
355
+ // Reporting onTrackAdded() here would let the muxer start
356
+ // before the video track was added, and a later `addTrack`
357
+ // would crash with "Muxer is not initialized".
358
+ enc
359
+ } catch (t: Throwable) {
360
+ Log.e(TAG, "failed to create H.264 encoder", t)
361
+ host.onFatalError(t)
362
+ null
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Queues a zero-length input buffer with `BUFFER_FLAG_END_OF_STREAM`.
368
+ * Drains output between input attempts so the encoder's input
369
+ * slots can free up — a polling-only loop deadlocks when output
370
+ * queues are full. Returns `true` only if the marker was
371
+ * successfully queued; the caller skips the EOS drain otherwise so
372
+ * the handler doesn't hang waiting for a marker that won't arrive.
373
+ */
374
+ private fun signalEoS(enc: MediaCodec, muxerInstance: MediaMuxer): Boolean {
375
+ repeat(EncoderConstants.EOS_INPUT_RETRIES) {
376
+ val idx = try {
377
+ enc.dequeueInputBuffer(EncoderConstants.DEQUEUE_TIMEOUT_US)
378
+ } catch (t: Throwable) {
379
+ Log.w(TAG, "dequeueInputBuffer during EOS threw", t)
380
+ return false
381
+ }
382
+ if (idx >= 0) {
383
+ enc.queueInputBuffer(
384
+ idx, 0, 0, 0L,
385
+ MediaCodec.BUFFER_FLAG_END_OF_STREAM,
386
+ )
387
+ return true
388
+ }
389
+ // Keep output flowing so input slots can be released.
390
+ try {
391
+ drain(enc, muxerInstance, endOfStream = false)
392
+ } catch (t: Throwable) {
393
+ Log.w(TAG, "drainEncoder during EOS retry threw", t)
394
+ }
395
+ }
396
+ Log.w(TAG, "could not queue EOS — skipping EOS drain to avoid hang")
397
+ return false
398
+ }
399
+
400
+ private fun drain(
401
+ enc: MediaCodec,
402
+ muxerInstance: MediaMuxer,
403
+ endOfStream: Boolean,
404
+ ) {
405
+ val info = MediaCodec.BufferInfo()
406
+ val timeoutUs =
407
+ if (endOfStream) EncoderConstants.DEQUEUE_TIMEOUT_US_EOS else 0L
408
+ val deadlineMs = System.currentTimeMillis() +
409
+ if (endOfStream) EncoderConstants.EOS_DRAIN_BUDGET_MS else Long.MAX_VALUE
410
+
411
+ while (true) {
412
+ val outIndex = try {
413
+ enc.dequeueOutputBuffer(info, timeoutUs)
414
+ } catch (t: Throwable) {
415
+ Log.e(TAG, "dequeueOutputBuffer threw", t)
416
+ return
417
+ }
418
+
419
+ when {
420
+ outIndex == MediaCodec.INFO_TRY_AGAIN_LATER -> {
421
+ if (!endOfStream) return
422
+ if (System.currentTimeMillis() >= deadlineMs) {
423
+ Log.w(
424
+ TAG,
425
+ "EOS drain timed out without seeing BUFFER_FLAG_END_OF_STREAM — bailing out",
426
+ )
427
+ return
428
+ }
429
+ // During EOS keep polling until the marker arrives.
430
+ }
431
+
432
+ outIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED -> {
433
+ if (formatLocked) {
434
+ Log.w(TAG, "output format changed twice — ignoring")
435
+ continue
436
+ }
437
+ val newIndex = muxerInstance.addTrack(enc.outputFormat)
438
+ trackIndex = newIndex
439
+ formatLocked = true
440
+ host.onTrackAdded()
441
+ }
442
+
443
+ outIndex >= 0 -> {
444
+ val out = enc.getOutputBuffer(outIndex)
445
+ if (out != null && info.size > 0 && host.muxerStarted &&
446
+ trackIndex >= 0 &&
447
+ info.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG == 0
448
+ ) {
449
+ out.position(info.offset)
450
+ out.limit(info.offset + info.size)
451
+ try {
452
+ muxerInstance.writeSampleData(trackIndex, out, info)
453
+ samplesAppended++
454
+ if (firstSamplePtsUs < 0 || info.presentationTimeUs < firstSamplePtsUs) {
455
+ firstSamplePtsUs = info.presentationTimeUs
456
+ }
457
+ if (info.presentationTimeUs > lastSamplePtsUs) {
458
+ lastSamplePtsUs = info.presentationTimeUs
459
+ }
460
+ } catch (t: Throwable) {
461
+ Log.e(TAG, "writeSampleData failed", t)
462
+ }
463
+ }
464
+ enc.releaseOutputBuffer(outIndex, false)
465
+ if (info.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0) return
466
+ }
467
+ }
468
+
469
+ if (!endOfStream && outIndex < 0) return
470
+ }
471
+ }
472
+ }
@@ -102,6 +102,17 @@ Object.keys(_useScreenShareAudioMixing).forEach(function (key) {
102
102
  }
103
103
  });
104
104
  });
105
+ var _useLoopbackRecording = require("./useLoopbackRecording");
106
+ Object.keys(_useLoopbackRecording).forEach(function (key) {
107
+ if (key === "default" || key === "__esModule") return;
108
+ if (key in exports && exports[key] === _useLoopbackRecording[key]) return;
109
+ Object.defineProperty(exports, key, {
110
+ enumerable: true,
111
+ get: function () {
112
+ return _useLoopbackRecording[key];
113
+ }
114
+ });
115
+ });
105
116
  var _useTrackDimensions = require("./useTrackDimensions");
106
117
  Object.keys(_useTrackDimensions).forEach(function (key) {
107
118
  if (key === "default" || key === "__esModule") return;
@@ -1 +1 @@
1
- {"version":3,"names":["_usePermissionRequest","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_usePermissionNotification","_push","_useAndroidKeepCallAliveEffect","_useIsIosScreenshareBroadcastStarted","_useIsInPiPMode","_useAutoEnterPiPEffect","_useScreenShareButton","_useScreenShareAudioMixing","_useTrackDimensions","_useScreenshot","_useModeration"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_usePermissionRequest","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_usePermissionNotification","_push","_useAndroidKeepCallAliveEffect","_useIsIosScreenshareBroadcastStarted","_useIsInPiPMode","_useAutoEnterPiPEffect","_useScreenShareButton","_useScreenShareAudioMixing","_useLoopbackRecording","_useTrackDimensions","_useScreenshot","_useModeration"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":"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","ignoreList":[]}