@stream-io/video-react-native-sdk 1.30.5 → 1.31.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/CHANGELOG.md +11 -0
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +85 -0
- package/android/src/main/java/com/streamvideo/reactnative/screenshare/ScreenAudioCapture.kt +111 -0
- package/dist/commonjs/components/Call/CallControls/ScreenShareToggleButton.js +3 -2
- package/dist/commonjs/components/Call/CallControls/ScreenShareToggleButton.js.map +1 -1
- package/dist/commonjs/hooks/index.js +11 -0
- package/dist/commonjs/hooks/index.js.map +1 -1
- package/dist/commonjs/hooks/useScreenShareAudioMixing.js +126 -0
- package/dist/commonjs/hooks/useScreenShareAudioMixing.js.map +1 -0
- package/dist/commonjs/hooks/useScreenShareButton.js +57 -3
- package/dist/commonjs/hooks/useScreenShareButton.js.map +1 -1
- package/dist/commonjs/modules/ScreenShareAudioManager.js +54 -0
- package/dist/commonjs/modules/ScreenShareAudioManager.js.map +1 -0
- package/dist/commonjs/providers/StreamCall/index.js +11 -1
- package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/components/Call/CallControls/ScreenShareToggleButton.js +3 -2
- package/dist/module/components/Call/CallControls/ScreenShareToggleButton.js.map +1 -1
- package/dist/module/hooks/index.js +1 -0
- package/dist/module/hooks/index.js.map +1 -1
- package/dist/module/hooks/useScreenShareAudioMixing.js +119 -0
- package/dist/module/hooks/useScreenShareAudioMixing.js.map +1 -0
- package/dist/module/hooks/useScreenShareButton.js +57 -3
- package/dist/module/hooks/useScreenShareButton.js.map +1 -1
- package/dist/module/modules/ScreenShareAudioManager.js +47 -0
- package/dist/module/modules/ScreenShareAudioManager.js.map +1 -0
- package/dist/module/providers/StreamCall/index.js +11 -1
- package/dist/module/providers/StreamCall/index.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/components/Call/CallControls/ScreenShareToggleButton.d.ts +6 -1
- package/dist/typescript/components/Call/CallControls/ScreenShareToggleButton.d.ts.map +1 -1
- package/dist/typescript/hooks/index.d.ts +1 -0
- package/dist/typescript/hooks/index.d.ts.map +1 -1
- package/dist/typescript/hooks/useScreenShareAudioMixing.d.ts +14 -0
- package/dist/typescript/hooks/useScreenShareAudioMixing.d.ts.map +1 -0
- package/dist/typescript/hooks/useScreenShareButton.d.ts +39 -2
- package/dist/typescript/hooks/useScreenShareButton.d.ts.map +1 -1
- package/dist/typescript/modules/ScreenShareAudioManager.d.ts +28 -0
- package/dist/typescript/modules/ScreenShareAudioManager.d.ts.map +1 -0
- package/dist/typescript/providers/StreamCall/index.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/ios/StreamVideoReactNative.m +93 -4
- package/package.json +5 -5
- package/src/components/Call/CallControls/ScreenShareToggleButton.tsx +11 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useScreenShareAudioMixing.ts +130 -0
- package/src/hooks/useScreenShareButton.ts +87 -2
- package/src/modules/ScreenShareAudioManager.ts +49 -0
- package/src/providers/StreamCall/index.tsx +11 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.31.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.30.5...@stream-io/video-react-native-sdk-1.31.0) (2026-03-31)
|
|
6
|
+
|
|
7
|
+
### Dependency Updates
|
|
8
|
+
|
|
9
|
+
- `@stream-io/noise-cancellation-react-native` updated to version `0.6.0`
|
|
10
|
+
- `@stream-io/video-filters-react-native` updated to version `0.11.0`
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- screen share audio ([#2157](https://github.com/GetStream/stream-video-js/issues/2157)) ([ba3b9d8](https://github.com/GetStream/stream-video-js/commit/ba3b9d8c2168d7c1cd66050524a5dc0a0f7e3e6e))
|
|
15
|
+
|
|
5
16
|
## [1.30.5](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.30.4...@stream-io/video-react-native-sdk-1.30.5) (2026-03-27)
|
|
6
17
|
|
|
7
18
|
### Dependency Updates
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.streamvideo.reactnative
|
|
2
2
|
|
|
3
|
+
import android.app.Activity
|
|
3
4
|
import android.content.BroadcastReceiver
|
|
4
5
|
import android.content.Context
|
|
5
6
|
import android.content.Intent
|
|
@@ -9,6 +10,7 @@ import android.graphics.Bitmap
|
|
|
9
10
|
import android.media.AudioAttributes
|
|
10
11
|
import android.media.AudioFormat
|
|
11
12
|
import android.media.AudioTrack
|
|
13
|
+
import android.media.projection.MediaProjectionManager
|
|
12
14
|
import android.net.Uri
|
|
13
15
|
import android.os.BatteryManager
|
|
14
16
|
import android.os.Build
|
|
@@ -23,6 +25,8 @@ import com.facebook.react.bridge.ReactMethod
|
|
|
23
25
|
import com.facebook.react.bridge.WritableMap
|
|
24
26
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
|
25
27
|
import com.oney.WebRTCModule.WebRTCModule
|
|
28
|
+
import com.oney.WebRTCModule.WebRTCModuleOptions
|
|
29
|
+
import com.streamvideo.reactnative.screenshare.ScreenAudioCapture
|
|
26
30
|
import com.streamvideo.reactnative.util.CallAlivePermissionsHelper
|
|
27
31
|
import com.streamvideo.reactnative.util.CallAliveServiceChecker
|
|
28
32
|
import com.streamvideo.reactnative.util.PiPHelper
|
|
@@ -52,6 +56,9 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
52
56
|
private var busyToneAudioTrack: AudioTrack? = null
|
|
53
57
|
private var busyToneJob: Job? = null
|
|
54
58
|
|
|
59
|
+
// Screen share audio mixing
|
|
60
|
+
private var screenAudioCapture: ScreenAudioCapture? = null
|
|
61
|
+
|
|
55
62
|
private var thermalStatusListener: PowerManager.OnThermalStatusChangedListener? = null
|
|
56
63
|
|
|
57
64
|
private var batteryChargingStateReceiver = object : BroadcastReceiver() {
|
|
@@ -148,6 +155,7 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
148
155
|
reactApplicationContext.unregisterReceiver(batteryChargingStateReceiver)
|
|
149
156
|
stopThermalStatusUpdates()
|
|
150
157
|
stopBusyToneInternal() // Clean up busy tone on invalidate
|
|
158
|
+
stopScreenShareAudioMixingInternal() // Clean up screen share audio on invalidate
|
|
151
159
|
super.invalidate()
|
|
152
160
|
}
|
|
153
161
|
|
|
@@ -484,6 +492,83 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
484
492
|
return ShortArray(totalSamples)
|
|
485
493
|
}
|
|
486
494
|
|
|
495
|
+
@ReactMethod
|
|
496
|
+
fun startScreenShareAudioMixing(promise: Promise) {
|
|
497
|
+
try {
|
|
498
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
|
499
|
+
promise.reject("API_LEVEL", "Screen audio capture requires Android 10 (API 29)+")
|
|
500
|
+
return
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (screenAudioCapture != null) {
|
|
504
|
+
Log.w(NAME, "Screen share audio mixing is already active")
|
|
505
|
+
promise.resolve(null)
|
|
506
|
+
return
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
val module = reactApplicationContext.getNativeModule(WebRTCModule::class.java)!!
|
|
510
|
+
|
|
511
|
+
// Get the MediaProjection permission result Intent from WebRTC
|
|
512
|
+
val permissionIntent = module.userMediaImpl?.mediaProjectionPermissionResultData
|
|
513
|
+
if (permissionIntent == null) {
|
|
514
|
+
promise.reject("NO_PROJECTION", "No MediaProjection permission available. Start screen sharing first.")
|
|
515
|
+
return
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Create a MediaProjection for audio capture
|
|
519
|
+
val mediaProjectionManager = reactApplicationContext.getSystemService(
|
|
520
|
+
Context.MEDIA_PROJECTION_SERVICE
|
|
521
|
+
) as MediaProjectionManager
|
|
522
|
+
val mediaProjection = mediaProjectionManager.getMediaProjection(
|
|
523
|
+
Activity.RESULT_OK, permissionIntent
|
|
524
|
+
)
|
|
525
|
+
if (mediaProjection == null) {
|
|
526
|
+
promise.reject("PROJECTION_ERROR", "Failed to create MediaProjection for audio capture")
|
|
527
|
+
return
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
screenAudioCapture = ScreenAudioCapture(mediaProjection).also { it.start() }
|
|
531
|
+
|
|
532
|
+
// Register the screen audio bytes provider so the AudioBufferCallback
|
|
533
|
+
// in WebRTCModule mixes screen audio into the mic buffer.
|
|
534
|
+
WebRTCModuleOptions.getInstance().screenAudioBytesProvider =
|
|
535
|
+
WebRTCModuleOptions.ScreenAudioBytesProvider { bytesRequested ->
|
|
536
|
+
screenAudioCapture?.getScreenAudioBytes(bytesRequested)
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
Log.d(NAME, "Screen share audio mixing started")
|
|
540
|
+
promise.resolve(null)
|
|
541
|
+
} catch (e: Exception) {
|
|
542
|
+
Log.e(NAME, "Error starting screen share audio mixing: ${e.message}")
|
|
543
|
+
promise.reject("ERROR", e.message, e)
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
@ReactMethod
|
|
548
|
+
fun stopScreenShareAudioMixing(promise: Promise) {
|
|
549
|
+
try {
|
|
550
|
+
stopScreenShareAudioMixingInternal()
|
|
551
|
+
promise.resolve(null)
|
|
552
|
+
} catch (e: Exception) {
|
|
553
|
+
Log.e(NAME, "Error stopping screen share audio mixing: ${e.message}")
|
|
554
|
+
promise.reject("ERROR", e.message, e)
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
private fun stopScreenShareAudioMixingInternal() {
|
|
559
|
+
try {
|
|
560
|
+
// Clear the provider so the AudioBufferCallback stops mixing
|
|
561
|
+
WebRTCModuleOptions.getInstance().screenAudioBytesProvider = null
|
|
562
|
+
|
|
563
|
+
screenAudioCapture?.stop()
|
|
564
|
+
screenAudioCapture = null
|
|
565
|
+
|
|
566
|
+
Log.d(NAME, "Screen share audio mixing stopped")
|
|
567
|
+
} catch (e: Exception) {
|
|
568
|
+
Log.e(NAME, "Error in stopScreenShareAudioMixingInternal: ${e.message}")
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
487
572
|
companion object {
|
|
488
573
|
private const val NAME = "StreamVideoReactNative"
|
|
489
574
|
private const val SAMPLE_RATE = 22050
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
package com.streamvideo.reactnative.screenshare
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.media.AudioAttributes
|
|
5
|
+
import android.media.AudioFormat
|
|
6
|
+
import android.media.AudioPlaybackCaptureConfiguration
|
|
7
|
+
import android.media.AudioRecord
|
|
8
|
+
import android.media.projection.MediaProjection
|
|
9
|
+
import android.os.Build
|
|
10
|
+
import android.util.Log
|
|
11
|
+
import androidx.annotation.RequiresApi
|
|
12
|
+
import java.nio.ByteBuffer
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Captures system media audio using [AudioPlaybackCaptureConfiguration].
|
|
16
|
+
*
|
|
17
|
+
* Uses the given [MediaProjection] to set up an [AudioRecord] that captures
|
|
18
|
+
* audio from media playback, games, and other apps (USAGE_MEDIA, USAGE_GAME,
|
|
19
|
+
* USAGE_UNKNOWN) but not notifications, alarms, or system sounds.
|
|
20
|
+
*
|
|
21
|
+
* Audio is captured in a pull-based manner via [getScreenAudioBytes], which
|
|
22
|
+
* reads exactly the requested number of bytes using [AudioRecord.READ_BLOCKING].
|
|
23
|
+
* This is designed to be called from the WebRTC audio processing thread.
|
|
24
|
+
*
|
|
25
|
+
* Format: 48kHz, mono, PCM 16-bit (matching WebRTC's audio pipeline).
|
|
26
|
+
*
|
|
27
|
+
* Requires Android 10 (API 29+).
|
|
28
|
+
*/
|
|
29
|
+
@RequiresApi(Build.VERSION_CODES.Q)
|
|
30
|
+
class ScreenAudioCapture(private val mediaProjection: MediaProjection) {
|
|
31
|
+
|
|
32
|
+
private var audioRecord: AudioRecord? = null
|
|
33
|
+
private var screenAudioBuffer: ByteBuffer? = null
|
|
34
|
+
|
|
35
|
+
companion object {
|
|
36
|
+
private const val TAG = "ScreenAudioCapture"
|
|
37
|
+
const val SAMPLE_RATE = 48000
|
|
38
|
+
private const val CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO
|
|
39
|
+
private const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@SuppressLint("MissingPermission")
|
|
43
|
+
fun start() {
|
|
44
|
+
val playbackConfig = AudioPlaybackCaptureConfiguration.Builder(mediaProjection)
|
|
45
|
+
.addMatchingUsage(AudioAttributes.USAGE_MEDIA)
|
|
46
|
+
.addMatchingUsage(AudioAttributes.USAGE_GAME)
|
|
47
|
+
.addMatchingUsage(AudioAttributes.USAGE_UNKNOWN)
|
|
48
|
+
.build()
|
|
49
|
+
|
|
50
|
+
val audioFormat = AudioFormat.Builder()
|
|
51
|
+
.setSampleRate(SAMPLE_RATE)
|
|
52
|
+
.setChannelMask(CHANNEL_CONFIG)
|
|
53
|
+
.setEncoding(AUDIO_FORMAT)
|
|
54
|
+
.build()
|
|
55
|
+
|
|
56
|
+
audioRecord = AudioRecord.Builder()
|
|
57
|
+
.setAudioFormat(audioFormat)
|
|
58
|
+
.setAudioPlaybackCaptureConfig(playbackConfig)
|
|
59
|
+
.build()
|
|
60
|
+
|
|
61
|
+
if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) {
|
|
62
|
+
Log.e(TAG, "AudioRecord failed to initialize")
|
|
63
|
+
audioRecord?.release()
|
|
64
|
+
audioRecord = null
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
audioRecord?.startRecording()
|
|
69
|
+
Log.d(TAG, "Screen audio capture started")
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Pull-based read: returns a [ByteBuffer] containing exactly [bytesRequested] bytes
|
|
74
|
+
* of captured screen audio.
|
|
75
|
+
*
|
|
76
|
+
* Called from the WebRTC audio processing thread. Uses [AudioRecord.READ_BLOCKING]
|
|
77
|
+
* so it will block until the requested bytes are available.
|
|
78
|
+
*
|
|
79
|
+
* @return A [ByteBuffer] with screen audio data, or `null` if capture is not active.
|
|
80
|
+
*/
|
|
81
|
+
fun getScreenAudioBytes(bytesRequested: Int): ByteBuffer? {
|
|
82
|
+
val record = audioRecord ?: return null
|
|
83
|
+
if (bytesRequested <= 0) return null
|
|
84
|
+
|
|
85
|
+
val buffer = screenAudioBuffer?.takeIf { it.capacity() >= bytesRequested }
|
|
86
|
+
?: ByteBuffer.allocateDirect(bytesRequested).also { screenAudioBuffer = it }
|
|
87
|
+
|
|
88
|
+
buffer.clear()
|
|
89
|
+
buffer.limit(bytesRequested)
|
|
90
|
+
|
|
91
|
+
val bytesRead = record.read(buffer, bytesRequested, AudioRecord.READ_BLOCKING)
|
|
92
|
+
if (bytesRead > 0) {
|
|
93
|
+
buffer.position(0)
|
|
94
|
+
buffer.limit(bytesRead)
|
|
95
|
+
return buffer
|
|
96
|
+
}
|
|
97
|
+
return null
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fun stop() {
|
|
101
|
+
try {
|
|
102
|
+
audioRecord?.stop()
|
|
103
|
+
} catch (e: Exception) {
|
|
104
|
+
Log.w(TAG, "Error stopping AudioRecord: ${e.message}")
|
|
105
|
+
}
|
|
106
|
+
audioRecord?.release()
|
|
107
|
+
audioRecord = null
|
|
108
|
+
screenAudioBuffer = null
|
|
109
|
+
Log.d(TAG, "Screen audio capture stopped")
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -24,7 +24,8 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
24
24
|
*/
|
|
25
25
|
const ScreenShareToggleButton = ({
|
|
26
26
|
onScreenShareStartedHandler,
|
|
27
|
-
onScreenShareStoppedHandler
|
|
27
|
+
onScreenShareStoppedHandler,
|
|
28
|
+
screenShareOptions
|
|
28
29
|
}) => {
|
|
29
30
|
const {
|
|
30
31
|
theme: {
|
|
@@ -37,7 +38,7 @@ const ScreenShareToggleButton = ({
|
|
|
37
38
|
const {
|
|
38
39
|
onPress,
|
|
39
40
|
hasPublishedScreenShare
|
|
40
|
-
} = (0, _useScreenShareButton.useScreenShareButton)(screenCapturePickerViewiOSRef, onScreenShareStartedHandler, onScreenShareStoppedHandler);
|
|
41
|
+
} = (0, _useScreenShareButton.useScreenShareButton)(screenCapturePickerViewiOSRef, onScreenShareStartedHandler, onScreenShareStoppedHandler, undefined, screenShareOptions);
|
|
41
42
|
if (!onPress) return null;
|
|
42
43
|
return /*#__PURE__*/_react.default.createElement(_CallControlsButton.CallControlsButton, {
|
|
43
44
|
onPress: onPress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeWebrtc","_ScreenShare","_StopScreenShare","_CallControlsButton","_ThemeContext","_useScreenShareButton","_icons","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","ScreenShareToggleButton","onScreenShareStartedHandler","onScreenShareStoppedHandler","theme","colors","screenShareToggleButton","variants","useTheme","screenCapturePickerViewiOSRef","useRef","onPress","hasPublishedScreenShare","useScreenShareButton","createElement","CallControlsButton","color","buttonWarning","buttonSecondary","style","container","svgContainer","IconWrapper","StopScreenShare","size","iconSizes","md","iconPrimary","ScreenShare","Platform","OS","ScreenCapturePickerView","ref","exports"],"sourceRoot":"../../../../../src","sources":["components/Call/CallControls/ScreenShareToggleButton.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,kBAAA,GAAAF,OAAA;AACA,IAAAG,YAAA,GAAAH,OAAA;AACA,IAAAI,gBAAA,GAAAJ,OAAA;AACA,IAAAK,mBAAA,GAAAL,OAAA;AACA,IAAAM,aAAA,GAAAN,OAAA;AACA,IAAAO,qBAAA,GAAAP,OAAA;
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeWebrtc","_ScreenShare","_StopScreenShare","_CallControlsButton","_ThemeContext","_useScreenShareButton","_icons","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","ScreenShareToggleButton","onScreenShareStartedHandler","onScreenShareStoppedHandler","screenShareOptions","theme","colors","screenShareToggleButton","variants","useTheme","screenCapturePickerViewiOSRef","useRef","onPress","hasPublishedScreenShare","useScreenShareButton","undefined","createElement","CallControlsButton","color","buttonWarning","buttonSecondary","style","container","svgContainer","IconWrapper","StopScreenShare","size","iconSizes","md","iconPrimary","ScreenShare","Platform","OS","ScreenCapturePickerView","ref","exports"],"sourceRoot":"../../../../../src","sources":["components/Call/CallControls/ScreenShareToggleButton.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -91,6 +91,17 @@ Object.keys(_useScreenShareButton).forEach(function (key) {
|
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
93
|
});
|
|
94
|
+
var _useScreenShareAudioMixing = require("./useScreenShareAudioMixing");
|
|
95
|
+
Object.keys(_useScreenShareAudioMixing).forEach(function (key) {
|
|
96
|
+
if (key === "default" || key === "__esModule") return;
|
|
97
|
+
if (key in exports && exports[key] === _useScreenShareAudioMixing[key]) return;
|
|
98
|
+
Object.defineProperty(exports, key, {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
get: function () {
|
|
101
|
+
return _useScreenShareAudioMixing[key];
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
94
105
|
var _useTrackDimensions = require("./useTrackDimensions");
|
|
95
106
|
Object.keys(_useTrackDimensions).forEach(function (key) {
|
|
96
107
|
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","_useTrackDimensions","_useScreenshot","_useSpeechDetection","_useModeration"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"names":["_usePermissionRequest","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_usePermissionNotification","_push","_useAndroidKeepCallAliveEffect","_useIsIosScreenshareBroadcastStarted","_useIsInPiPMode","_useAutoEnterPiPEffect","_useScreenShareButton","_useScreenShareAudioMixing","_useTrackDimensions","_useScreenshot","_useSpeechDetection","_useModeration"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useScreenShareAudioMixing = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _videoClient = require("@stream-io/video-client");
|
|
9
|
+
var _videoReactBindings = require("@stream-io/video-react-bindings");
|
|
10
|
+
var _ScreenShareAudioManager = require("../modules/ScreenShareAudioManager");
|
|
11
|
+
var _lib = require("../providers/NoiseCancellation/lib");
|
|
12
|
+
const logger = _videoClient.videoLoggerSystem.getLogger('useScreenShareAudioMixing');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Tries to disable noise cancellation so screen audio passes through
|
|
16
|
+
* unfiltered. Returns true if NC was disabled (and should be re-enabled later).
|
|
17
|
+
*/
|
|
18
|
+
async function disableNoiseCancellation() {
|
|
19
|
+
try {
|
|
20
|
+
const nc = _lib.NoiseCancellationWrapper.getInstance();
|
|
21
|
+
const wasEnabled = await nc.isEnabled();
|
|
22
|
+
if (wasEnabled) {
|
|
23
|
+
await nc.disable();
|
|
24
|
+
logger.info('Noise cancellation disabled for screen share audio');
|
|
25
|
+
}
|
|
26
|
+
return wasEnabled;
|
|
27
|
+
} catch {
|
|
28
|
+
// NC module not installed or not configured — nothing to do
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Re-enables noise cancellation if it was previously disabled.
|
|
35
|
+
*/
|
|
36
|
+
async function restoreNoiseCancellation() {
|
|
37
|
+
try {
|
|
38
|
+
const nc = _lib.NoiseCancellationWrapper.getInstance();
|
|
39
|
+
await nc.enable();
|
|
40
|
+
logger.info('Noise cancellation re-enabled after screen share audio');
|
|
41
|
+
} catch {
|
|
42
|
+
// NC module not installed — nothing to do
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Hook that manages the lifecycle of screen share audio mixing.
|
|
48
|
+
*
|
|
49
|
+
* When screen share is active and audio mixing is enabled
|
|
50
|
+
* (via `call.screenShare.enableScreenShareAudio()`), this hook
|
|
51
|
+
* calls the native module to mix captured screen/app audio
|
|
52
|
+
* into the microphone audio track.
|
|
53
|
+
*
|
|
54
|
+
* Noise cancellation is temporarily disabled while screen audio mixing
|
|
55
|
+
* is active so that all captured sounds (music, game audio, etc.)
|
|
56
|
+
* pass through without being filtered.
|
|
57
|
+
*/
|
|
58
|
+
const useScreenShareAudioMixing = () => {
|
|
59
|
+
const call = (0, _videoReactBindings.useCall)();
|
|
60
|
+
const {
|
|
61
|
+
useLocalParticipant
|
|
62
|
+
} = (0, _videoReactBindings.useCallStateHooks)();
|
|
63
|
+
const localParticipant = useLocalParticipant();
|
|
64
|
+
const isScreenSharing = localParticipant != null && (0, _videoClient.hasScreenShare)(localParticipant);
|
|
65
|
+
const [audioEnabled, setAudioEnabled] = (0, _react.useState)(() => call?.screenShare.state.audioEnabled ?? false);
|
|
66
|
+
const isMixingActiveRef = (0, _react.useRef)(false);
|
|
67
|
+
const ncWasEnabledRef = (0, _react.useRef)(false);
|
|
68
|
+
(0, _react.useEffect)(() => {
|
|
69
|
+
if (!call) return;
|
|
70
|
+
const sub = call.screenShare.state.audioEnabled$.subscribe(setAudioEnabled);
|
|
71
|
+
return () => sub.unsubscribe();
|
|
72
|
+
}, [call]);
|
|
73
|
+
const startMixing = (0, _react.useCallback)(async () => {
|
|
74
|
+
if (isMixingActiveRef.current) return;
|
|
75
|
+
try {
|
|
76
|
+
// Disable NC before starting mixing so screen audio is not filtered
|
|
77
|
+
ncWasEnabledRef.current = await disableNoiseCancellation();
|
|
78
|
+
logger.info('Starting screen share audio mixing');
|
|
79
|
+
await _ScreenShareAudioManager.screenShareAudioMixingManager.startScreenShareAudioMixing();
|
|
80
|
+
isMixingActiveRef.current = true;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
logger.warn('Failed to start screen share audio mixing', error);
|
|
83
|
+
if (ncWasEnabledRef.current) {
|
|
84
|
+
restoreNoiseCancellation().catch(() => {});
|
|
85
|
+
ncWasEnabledRef.current = false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}, []);
|
|
89
|
+
const stopMixing = (0, _react.useCallback)(async () => {
|
|
90
|
+
if (!isMixingActiveRef.current) return;
|
|
91
|
+
try {
|
|
92
|
+
logger.info('Stopping screen share audio mixing');
|
|
93
|
+
await _ScreenShareAudioManager.screenShareAudioMixingManager.stopScreenShareAudioMixing();
|
|
94
|
+
isMixingActiveRef.current = false;
|
|
95
|
+
if (ncWasEnabledRef.current) {
|
|
96
|
+
await restoreNoiseCancellation();
|
|
97
|
+
ncWasEnabledRef.current = false;
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
logger.warn('Failed to stop screen share audio mixing', error);
|
|
101
|
+
}
|
|
102
|
+
}, []);
|
|
103
|
+
|
|
104
|
+
// Start/stop audio mixing based on screen share status and audio preference
|
|
105
|
+
(0, _react.useEffect)(() => {
|
|
106
|
+
if (isScreenSharing && audioEnabled) {
|
|
107
|
+
startMixing();
|
|
108
|
+
} else {
|
|
109
|
+
stopMixing();
|
|
110
|
+
}
|
|
111
|
+
}, [isScreenSharing, audioEnabled, startMixing, stopMixing]);
|
|
112
|
+
(0, _react.useEffect)(() => {
|
|
113
|
+
return () => {
|
|
114
|
+
if (isMixingActiveRef.current) {
|
|
115
|
+
_ScreenShareAudioManager.screenShareAudioMixingManager.stopScreenShareAudioMixing().catch(() => {});
|
|
116
|
+
isMixingActiveRef.current = false;
|
|
117
|
+
if (ncWasEnabledRef.current) {
|
|
118
|
+
restoreNoiseCancellation().catch(() => {});
|
|
119
|
+
ncWasEnabledRef.current = false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}, []);
|
|
124
|
+
};
|
|
125
|
+
exports.useScreenShareAudioMixing = useScreenShareAudioMixing;
|
|
126
|
+
//# sourceMappingURL=useScreenShareAudioMixing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_videoClient","_videoReactBindings","_ScreenShareAudioManager","_lib","logger","videoLoggerSystem","getLogger","disableNoiseCancellation","nc","NoiseCancellationWrapper","getInstance","wasEnabled","isEnabled","disable","info","restoreNoiseCancellation","enable","useScreenShareAudioMixing","call","useCall","useLocalParticipant","useCallStateHooks","localParticipant","isScreenSharing","hasScreenShare","audioEnabled","setAudioEnabled","useState","screenShare","state","isMixingActiveRef","useRef","ncWasEnabledRef","useEffect","sub","audioEnabled$","subscribe","unsubscribe","startMixing","useCallback","current","screenShareAudioMixingManager","startScreenShareAudioMixing","error","warn","catch","stopMixing","stopScreenShareAudioMixing","exports"],"sourceRoot":"../../../src","sources":["hooks/useScreenShareAudioMixing.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -10,9 +10,25 @@ var _react = require("react");
|
|
|
10
10
|
var _reactNative = require("react-native");
|
|
11
11
|
var _hooks = require("../utils/hooks");
|
|
12
12
|
var _useIsIosScreenshareBroadcastStarted = require("./useIsIosScreenshareBroadcastStarted");
|
|
13
|
+
var _ScreenShareAudioManager = require("../modules/ScreenShareAudioManager");
|
|
14
|
+
/**
|
|
15
|
+
* The type of screen sharing to use on iOS.
|
|
16
|
+
*
|
|
17
|
+
* - `'broadcast'` — Uses a Broadcast Upload Extension (RPSystemBroadcastPickerView).
|
|
18
|
+
* Captures the entire device screen, works across all apps. Requires an extension target.
|
|
19
|
+
* - `'inApp'` — Uses RPScreenRecorder.startCapture to capture the current app's screen.
|
|
20
|
+
* Only captures the current app. Supports `.audioApp` sample buffers for audio mixing.
|
|
21
|
+
*
|
|
22
|
+
* On Android, this option is ignored — the system screen capture dialog is always used.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Options for screen share behavior.
|
|
27
|
+
*/
|
|
28
|
+
|
|
13
29
|
// ios >= 14.0 or android - platform restrictions
|
|
14
30
|
const CanDeviceScreenShare = _reactNative.Platform.OS === 'ios' && Number.parseInt(_reactNative.Platform.Version?.split('.')[0] ?? '0', 10) >= 14 || _reactNative.Platform.OS === 'android';
|
|
15
|
-
const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShareStartedHandler, onScreenShareStoppedHandler, onMissingScreenShareStreamPermission) => {
|
|
31
|
+
const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShareStartedHandler, onScreenShareStoppedHandler, onMissingScreenShareStreamPermission, screenShareOptions) => {
|
|
16
32
|
const call = (0, _videoReactBindings.useCall)();
|
|
17
33
|
const {
|
|
18
34
|
useLocalParticipant,
|
|
@@ -23,6 +39,8 @@ const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShareStarte
|
|
|
23
39
|
const ownCapabilities = useOwnCapabilities();
|
|
24
40
|
const hasScreenSharingPermissions = ownCapabilities?.includes(_videoClient.OwnCapability.SCREENSHARE);
|
|
25
41
|
const isScreenSharingEnabledInCall = callSettings?.screensharing.enabled;
|
|
42
|
+
const screenShareType = screenShareOptions?.type ?? 'broadcast';
|
|
43
|
+
const includeAudio = screenShareOptions?.includeAudio ?? false;
|
|
26
44
|
const onScreenShareStartedHandlerRef = (0, _react.useRef)(onScreenShareStartedHandler);
|
|
27
45
|
onScreenShareStartedHandlerRef.current = onScreenShareStartedHandler;
|
|
28
46
|
const onScreenShareStoppedHandlerRef = (0, _react.useRef)(onScreenShareStoppedHandler);
|
|
@@ -33,31 +51,63 @@ const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShareStarte
|
|
|
33
51
|
const hasPublishedScreenShare = localParticipant && (0, _videoClient.hasScreenShare)(localParticipant);
|
|
34
52
|
|
|
35
53
|
// listens to iOS screen share broadcast started event from the system
|
|
54
|
+
// (only relevant for broadcast mode)
|
|
36
55
|
(0, _react.useEffect)(() => {
|
|
37
56
|
if (_reactNative.Platform.OS !== 'ios') {
|
|
38
57
|
return;
|
|
39
58
|
}
|
|
59
|
+
if (screenShareType !== 'broadcast') {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
40
62
|
if (iosScreenShareStartedFromSystem && !prevIosScreenShareStartedFromSystem) {
|
|
41
63
|
onScreenShareStartedHandlerRef.current?.();
|
|
64
|
+
if (includeAudio) {
|
|
65
|
+
call?.screenShare.enableScreenShareAudio();
|
|
66
|
+
}
|
|
42
67
|
call?.screenShare.enable();
|
|
43
68
|
} else if (!iosScreenShareStartedFromSystem && prevIosScreenShareStartedFromSystem) {
|
|
44
69
|
onScreenShareStoppedHandlerRef.current?.();
|
|
45
70
|
call?.screenShare.disable(true);
|
|
46
71
|
}
|
|
47
|
-
}, [call, iosScreenShareStartedFromSystem, prevIosScreenShareStartedFromSystem]);
|
|
72
|
+
}, [call, includeAudio, screenShareType, iosScreenShareStartedFromSystem, prevIosScreenShareStartedFromSystem]);
|
|
48
73
|
const onPress = async () => {
|
|
49
74
|
if (!hasScreenSharingPermissions) {
|
|
50
75
|
const logger = _videoClient.videoLoggerSystem.getLogger('useScreenShareButton');
|
|
51
76
|
logger.info('User does not have permissions to stream the screen share media, calling onMissingScreenShareStreamPermission handler if present');
|
|
52
77
|
onMissingScreenShareStreamPermission?.();
|
|
78
|
+
return;
|
|
53
79
|
}
|
|
54
80
|
if (!hasPublishedScreenShare) {
|
|
55
|
-
|
|
81
|
+
// Set audio mixing preference before starting screen share
|
|
82
|
+
if (includeAudio) {
|
|
83
|
+
call?.screenShare.enableScreenShareAudio();
|
|
84
|
+
} else {
|
|
85
|
+
try {
|
|
86
|
+
await call?.screenShare.disableScreenShareAudio();
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const logger = _videoClient.videoLoggerSystem.getLogger('useScreenShareButton');
|
|
89
|
+
logger.warn('Failed to disable screen share audio', error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (_reactNative.Platform.OS === 'ios' && screenShareType === 'inApp') {
|
|
93
|
+
// In-app screen sharing on iOS — uses RPScreenRecorder directly
|
|
94
|
+
try {
|
|
95
|
+
await _ScreenShareAudioManager.screenShareAudioMixingManager.startInAppScreenCapture(includeAudio);
|
|
96
|
+
await call?.screenShare.enable();
|
|
97
|
+
onScreenShareStartedHandler?.();
|
|
98
|
+
} catch (error) {
|
|
99
|
+
await _ScreenShareAudioManager.screenShareAudioMixingManager.stopInAppScreenCapture();
|
|
100
|
+
const logger = _videoClient.videoLoggerSystem.getLogger('useScreenShareButton');
|
|
101
|
+
logger.warn('Failed to start in-app screen capture', error);
|
|
102
|
+
}
|
|
103
|
+
} else if (_reactNative.Platform.OS === 'ios') {
|
|
104
|
+
// Broadcast screen sharing on iOS — shows the system picker
|
|
56
105
|
const reactTag = (0, _reactNative.findNodeHandle)(screenCapturePickerViewiOSRef.current);
|
|
57
106
|
await _reactNative.NativeModules.ScreenCapturePickerViewManager.show(reactTag);
|
|
58
107
|
// After this the iOS screen share broadcast started/stopped event will be triggered
|
|
59
108
|
// and the useEffect listener will handle the rest
|
|
60
109
|
} else {
|
|
110
|
+
// Android screen sharing
|
|
61
111
|
try {
|
|
62
112
|
await call?.screenShare.enable();
|
|
63
113
|
onScreenShareStartedHandler?.();
|
|
@@ -69,6 +119,10 @@ const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShareStarte
|
|
|
69
119
|
}
|
|
70
120
|
} else if (hasPublishedScreenShare) {
|
|
71
121
|
onScreenShareStoppedHandler?.();
|
|
122
|
+
// Stop in-app screen capture if it was active (iOS only)
|
|
123
|
+
if (_reactNative.Platform.OS === 'ios' && screenShareType === 'inApp') {
|
|
124
|
+
await _ScreenShareAudioManager.screenShareAudioMixingManager.stopInAppScreenCapture();
|
|
125
|
+
}
|
|
72
126
|
await call?.screenShare.disable(true);
|
|
73
127
|
}
|
|
74
128
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_videoClient","require","_videoReactBindings","_react","_reactNative","_hooks","_useIsIosScreenshareBroadcastStarted","CanDeviceScreenShare","Platform","OS","Number","parseInt","Version","split","useScreenShareButton","screenCapturePickerViewiOSRef","onScreenShareStartedHandler","onScreenShareStoppedHandler","onMissingScreenShareStreamPermission","call","useCall","useLocalParticipant","useCallSettings","useOwnCapabilities","useCallStateHooks","callSettings","ownCapabilities","hasScreenSharingPermissions","includes","OwnCapability","SCREENSHARE","isScreenSharingEnabledInCall","screensharing","enabled","onScreenShareStartedHandlerRef","useRef","current","onScreenShareStoppedHandlerRef","iosScreenShareStartedFromSystem","useIsIosScreenshareBroadcastStarted","prevIosScreenShareStartedFromSystem","usePrevious","localParticipant","hasPublishedScreenShare","hasScreenShare","useEffect","screenShare","enable","disable","onPress","logger","videoLoggerSystem","getLogger","info","reactTag","findNodeHandle","NativeModules","ScreenCapturePickerViewManager","show","
|
|
1
|
+
{"version":3,"names":["_videoClient","require","_videoReactBindings","_react","_reactNative","_hooks","_useIsIosScreenshareBroadcastStarted","_ScreenShareAudioManager","CanDeviceScreenShare","Platform","OS","Number","parseInt","Version","split","useScreenShareButton","screenCapturePickerViewiOSRef","onScreenShareStartedHandler","onScreenShareStoppedHandler","onMissingScreenShareStreamPermission","screenShareOptions","call","useCall","useLocalParticipant","useCallSettings","useOwnCapabilities","useCallStateHooks","callSettings","ownCapabilities","hasScreenSharingPermissions","includes","OwnCapability","SCREENSHARE","isScreenSharingEnabledInCall","screensharing","enabled","screenShareType","type","includeAudio","onScreenShareStartedHandlerRef","useRef","current","onScreenShareStoppedHandlerRef","iosScreenShareStartedFromSystem","useIsIosScreenshareBroadcastStarted","prevIosScreenShareStartedFromSystem","usePrevious","localParticipant","hasPublishedScreenShare","hasScreenShare","useEffect","screenShare","enableScreenShareAudio","enable","disable","onPress","logger","videoLoggerSystem","getLogger","info","disableScreenShareAudio","error","warn","screenShareAudioMixingManager","startInAppScreenCapture","stopInAppScreenCapture","reactTag","findNodeHandle","NativeModules","ScreenCapturePickerViewManager","show","undefined","exports"],"sourceRoot":"../../../src","sources":["hooks/useScreenShareButton.ts"],"mappings":"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","ignoreList":[]}
|