From 109e588459392f0918ac0112f5739ddbd31545a8 Mon Sep 17 00:00:00 2001 From: Angelika Serwa Date: Wed, 19 Jun 2024 17:59:24 +0200 Subject: [PATCH 1/3] Remove websockets --- .../reactnative/MembraneWebRTC.kt | 166 +++++++------ .../reactnative/MembraneWebRTCModule.kt | 23 +- example/App.tsx | 5 +- example/hooks/useJoinRoom.ts | 7 +- .../FishjamExample.xcodeproj/project.pbxproj | 172 +++++++------- example/ios/Podfile | 5 +- example/ios/Podfile.lock | 28 ++- .../screens/ConnectWithRoomManagerScreen.tsx | 3 +- example/screens/ConnectWithTokenScreen.tsx | 3 +- example/screens/RoomScreen.tsx | 6 +- ios/MembraneWebRTC.swift | 222 +++++++++++------- ios/MembraneWebRTCModule.swift | 19 +- ios/RNFishjamClient.podspec | 2 +- src/FishjamClientContext.tsx | 165 ------------- src/MembraneWebRTC.types.ts | 10 +- src/__tests__/FishjamContext.test.tsx | 154 ------------ src/common/client.ts | 18 ++ src/index.tsx | 2 +- 18 files changed, 386 insertions(+), 624 deletions(-) delete mode 100644 src/FishjamClientContext.tsx delete mode 100644 src/__tests__/FishjamContext.test.tsx create mode 100644 src/common/client.ts diff --git a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTC.kt b/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTC.kt index 074c197d..89dd6bda 100644 --- a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTC.kt +++ b/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTC.kt @@ -3,20 +3,22 @@ package org.membraneframework.reactnative import android.app.Activity import android.content.ActivityNotFoundException import android.content.Intent -import org.membraneframework.rtc.media.AudioTrack import android.media.projection.MediaProjectionManager import androidx.appcompat.app.AppCompatActivity +import com.fishjamdev.client.Config +import com.fishjamdev.client.FishjamClient +import com.fishjamdev.client.FishjamClientListener +import com.fishjamdev.client.Peer +import com.fishjamdev.client.TrackContext import com.twilio.audioswitch.AudioDevice -import expo.modules.kotlin.Promise import expo.modules.kotlin.AppContext +import expo.modules.kotlin.Promise import expo.modules.kotlin.exception.CodedException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.membraneframework.rtc.MembraneRTC -import org.membraneframework.rtc.MembraneRTCListener import org.membraneframework.rtc.SimulcastConfig -import org.membraneframework.rtc.media.VideoTrack +import org.membraneframework.rtc.media.AudioTrack import org.membraneframework.rtc.media.LocalAudioTrack import org.membraneframework.rtc.media.LocalScreencastTrack import org.membraneframework.rtc.media.LocalVideoTrack @@ -24,20 +26,18 @@ import org.membraneframework.rtc.media.RemoteAudioTrack import org.membraneframework.rtc.media.RemoteVideoTrack import org.membraneframework.rtc.media.TrackBandwidthLimit import org.membraneframework.rtc.media.VideoParameters -import org.membraneframework.rtc.models.Endpoint +import org.membraneframework.rtc.media.VideoTrack import org.membraneframework.rtc.models.RTCInboundStats import org.membraneframework.rtc.models.RTCOutboundStats -import org.membraneframework.rtc.models.TrackContext import org.membraneframework.rtc.models.TrackData import org.membraneframework.rtc.utils.Metadata -import org.membraneframework.rtc.utils.SerializedMediaEvent import org.webrtc.Logging import java.util.UUID class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> Unit) : - MembraneRTCListener { + FishjamClientListener { private val SCREENCAST_REQUEST = 1 - private var membraneRTC: MembraneRTC? = null + private var fishjamClient: FishjamClient? = null var localAudioTrack: LocalAudioTrack? = null var localVideoTrack: LocalVideoTrack? = null @@ -53,6 +53,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U private val globalToLocalTrackId = HashMap() private var connectPromise: Promise? = null + private var joinPromise: Promise? = null private var screencastPromise: Promise? = null var videoSimulcastConfig: SimulcastConfig = SimulcastConfig() @@ -143,7 +144,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U fun create() { audioSwitchManager = AudioSwitchManager(appContext?.reactContext!!) - membraneRTC = MembraneRTC.create( + fishjamClient = FishjamClient( appContext = appContext?.reactContext!!, listener = this ) ensureCreated() @@ -175,13 +176,13 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U } private fun ensureCreated() { - if (membraneRTC == null) { + if (fishjamClient == null) { throw CodedException("Client not created yet. Make sure to call create() first!") } } private fun ensureConnected() { - if (membraneRTC == null) { + if (fishjamClient == null) { throw CodedException("Client not connected to server yet. Make sure to call connect() first!") } } @@ -210,30 +211,53 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U } } + override fun onAuthError() { + CoroutineScope(Dispatchers.Main).launch { + connectPromise?.reject(CodedException("Connection error")) + connectPromise = null + } + } - fun receiveMediaEvent(data: String) { - ensureConnected() - membraneRTC?.receiveMediaEvent(data) + override fun onAuthSuccess() { + CoroutineScope(Dispatchers.Main).launch { + connectPromise?.resolve() + connectPromise = null + } } - fun connect(endpointMetadata: Metadata = mapOf(), promise: Promise) { + fun connect(url: String, peerToken: String, promise: Promise) { ensureCreated() - ensureEndpoints() connectPromise = promise - localUserMetadata = endpointMetadata + fishjamClient?.connect(Config(url, peerToken)) + } + + fun joinRoom(peerMetadata: Metadata = mapOf(), promise: Promise) { + ensureCreated() + ensureEndpoints() + joinPromise = promise + localUserMetadata = peerMetadata val id = localEndpointId ?: return val endpoint = endpoints[id] ?: return endpoints[id] = endpoint.copy(metadata = localUserMetadata) - membraneRTC?.connect(localUserMetadata) + fishjamClient?.join(localUserMetadata) } - fun disconnect() { + fun leaveRoom() { ensureCreated() if (isScreencastOn) { stopScreencast() } - membraneRTC?.disconnect() - membraneRTC = null + fishjamClient?.leave() + endpoints.clear() + } + + fun cleanUp() { + ensureCreated() + if (isScreencastOn) { + stopScreencast() + } + fishjamClient?.cleanUp() + fishjamClient = null endpoints.clear() } @@ -250,7 +274,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U ensureConnected() val videoParameters = getVideoParametersFromOptions(config) videoSimulcastConfig = getSimulcastConfigFromOptions(config.simulcastConfig) - return membraneRTC?.createVideoTrack( + return fishjamClient?.createVideoTrack( videoParameters, config.videoTrackMetadata, config.captureDeviceId ) } @@ -307,7 +331,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U val localEndpoint = endpoints[localEndpointId] localEndpoint?.let { it.removeTrack(track) - membraneRTC?.removeTrack(track.id()) + fishjamClient?.removeTrack(track.id()) emitEndpoints() } } @@ -317,14 +341,14 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U val localEndpoint = endpoints[localEndpointId] localEndpoint?.let { it.removeTrack(track) - membraneRTC?.removeTrack(track.id()) + fishjamClient?.removeTrack(track.id()) emitEndpoints() } } fun startMicrophone(config: MicrophoneConfig) { ensureConnected() - val microphoneTrack = membraneRTC?.createAudioTrack(config.audioTrackMetadata) + val microphoneTrack = fishjamClient?.createAudioTrack(config.audioTrackMetadata) ?: throw CodedException("Failed to Create Track") localAudioTrack = microphoneTrack addTrackToLocalEndpoint(microphoneTrack, config.audioTrackMetadata) @@ -383,12 +407,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U "encodingReason" to trackContexts[video.id()]?.encodingReason?.value ) - val simulcastConfig: SimulcastConfig? = - if (video.id() == localAudioTrack?.id() || video.id() == localVideoTrack?.id() || video.id() == localScreencastTrack?.id()) { - endpoint.tracksData[video.id()]?.simulcastConfig - } else { - trackContexts[video.id()]?.simulcastConfig - } + val simulcastConfig: SimulcastConfig? = endpoint.tracksData[video.id()]?.simulcastConfig simulcastConfig?.let { config -> videoMap["simulcastConfig"] = mutableMapOf( @@ -422,11 +441,11 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U fun updateEndpointMetadata(metadata: Metadata) { ensureConnected() - membraneRTC?.updateEndpointMetadata(metadata) + fishjamClient?.updatePeerMetadata(metadata) } private fun updateTrackMetadata(trackId: String, metadata: Metadata) { - membraneRTC?.updateTrackMetadata(trackId, metadata) + fishjamClient?.updateTrackMetadata(trackId, metadata) localEndpointId?.let { val endpoint = endpoints[it] ?: throw CodedException("Endpoint with id $it not Found") val trackMetadata = endpoint.tracksData[trackId] @@ -486,9 +505,9 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U val isTrackEncodingActive = simulcastConfig.activeEncodings.contains(trackEncoding) if (isTrackEncodingActive) { - membraneRTC?.disableTrackEncoding(trackId, trackEncoding) + fishjamClient?.disableTrackEncoding(trackId, trackEncoding) } else { - membraneRTC?.enableTrackEncoding(trackId, trackEncoding) + fishjamClient?.enableTrackEncoding(trackId, trackEncoding) } val updatedActiveEncodings = if (isTrackEncodingActive) { @@ -515,7 +534,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U ensureScreencastTrack() localScreencastTrack?.let { val trackId = it.id() - membraneRTC?.setTrackBandwidth(trackId, TrackBandwidthLimit.BandwidthLimit(bandwidth)) + fishjamClient?.setTrackBandwidth(trackId, TrackBandwidthLimit.BandwidthLimit(bandwidth)) } } @@ -523,7 +542,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U ensureScreencastTrack() localScreencastTrack?.let { val trackId = it.id() - membraneRTC?.setEncodingBandwidth( + fishjamClient?.setEncodingBandwidth( trackId, encoding, TrackBandwidthLimit.BandwidthLimit(bandwidth) ) } @@ -534,7 +553,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U val globalTrackId = getGlobalTrackId(trackId) ?: throw CodedException("Remote track with id=$trackId not found") - membraneRTC?.setTargetTrackEncoding(globalTrackId, encoding.toTrackEncoding()) + fishjamClient?.setTargetTrackEncoding(globalTrackId, encoding.toTrackEncoding()) } fun toggleVideoTrackEncoding(encoding: String): Map { @@ -550,7 +569,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U ensureVideoTrack() localVideoTrack?.let { val trackId = it.id() - membraneRTC?.setEncodingBandwidth( + fishjamClient?.setEncodingBandwidth( trackId, encoding, TrackBandwidthLimit.BandwidthLimit(bandwidth) ) } @@ -560,17 +579,17 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U ensureVideoTrack() localVideoTrack?.let { val trackId = it.id() - membraneRTC?.setTrackBandwidth(trackId, TrackBandwidthLimit.BandwidthLimit(bandwidth)) + fishjamClient?.setTrackBandwidth(trackId, TrackBandwidthLimit.BandwidthLimit(bandwidth)) } } fun changeWebRTCLoggingSeverity(severity: String) { when (severity) { - "verbose" -> membraneRTC?.changeWebRTCLoggingSeverity(Logging.Severity.LS_VERBOSE) - "info" -> membraneRTC?.changeWebRTCLoggingSeverity(Logging.Severity.LS_INFO) - "error" -> membraneRTC?.changeWebRTCLoggingSeverity(Logging.Severity.LS_ERROR) - "warning" -> membraneRTC?.changeWebRTCLoggingSeverity(Logging.Severity.LS_WARNING) - "none" -> membraneRTC?.changeWebRTCLoggingSeverity(Logging.Severity.LS_NONE) + "verbose" -> fishjamClient?.changeWebRTCLoggingSeverity(Logging.Severity.LS_VERBOSE) + "info" -> fishjamClient?.changeWebRTCLoggingSeverity(Logging.Severity.LS_INFO) + "error" -> fishjamClient?.changeWebRTCLoggingSeverity(Logging.Severity.LS_ERROR) + "warning" -> fishjamClient?.changeWebRTCLoggingSeverity(Logging.Severity.LS_WARNING) + "none" -> fishjamClient?.changeWebRTCLoggingSeverity(Logging.Severity.LS_NONE) else -> { throw CodedException("Severity with name=$severity not found") } @@ -618,7 +637,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U fun getStatistics(): MutableMap> { ensureCreated() val newMap = mutableMapOf>() - membraneRTC?.getStats()?.forEach { entry -> + fishjamClient?.getStats()?.forEach { entry -> newMap[entry.key] = if (entry.value is RTCInboundStats) rtcInboundStatsToRNMap( entry.value as RTCInboundStats ) else rtcOutboundStatsToRNMap(entry.value as RTCOutboundStats) @@ -629,7 +648,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U private fun startScreencast(mediaProjectionPermission: Intent) { localScreencastId = UUID.randomUUID().toString() val videoParameters = getScreencastVideoParameters() - val screencastTrack = membraneRTC?.createScreencastTrack( + val screencastTrack = fishjamClient?.createScreencastTrack( mediaProjectionPermission, videoParameters, screencastMetadata ) ?: throw CodedException("Failed to Create ScreenCast Track") localScreencastTrack = screencastTrack @@ -720,29 +739,29 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U }) } - override fun onConnected(endpointID: String, otherEndpoints: List) { + override fun onJoined(peerID: String, peersInRoom: List) { CoroutineScope(Dispatchers.Main).launch { - endpoints.remove(endpointID) - otherEndpoints.forEach { + endpoints.remove(peerID) + peersInRoom.forEach { endpoints[it.id] = RNEndpoint(it.id, it.metadata ?: mapOf(), it.type, tracksData = HashMap(it.tracks)) } - connectPromise?.resolve(null) - connectPromise = null + joinPromise?.resolve(null) + joinPromise = null emitEndpoints() } } - override fun onConnectError(metadata: Any) { + override fun onJoinError(metadata: Any) { CoroutineScope(Dispatchers.Main).launch { - connectPromise?.reject(CodedException("Connection error: $metadata")) - connectPromise = null + joinPromise?.reject(CodedException("Join error: $metadata")) + joinPromise = null } } private fun addOrUpdateTrack(ctx: TrackContext) { - val endpoint = endpoints[ctx.endpoint.id] - ?: throw IllegalArgumentException("endpoint with id ${ctx.endpoint.id} not found") + val endpoint = endpoints[ctx.peer.id] + ?: throw IllegalArgumentException("endpoint with id ${ctx.peer.id} not found") when (ctx.track) { is RemoteVideoTrack -> { @@ -786,8 +805,8 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U override fun onTrackRemoved(ctx: TrackContext) { CoroutineScope(Dispatchers.Main).launch { - val endpoint = endpoints[ctx.endpoint.id] - ?: throw IllegalArgumentException("endpoint with id ${ctx.endpoint.id} not found") + val endpoint = endpoints[ctx.peer.id] + ?: throw IllegalArgumentException("endpoint with id ${ctx.peer.id} not found") when (ctx.track) { is RemoteVideoTrack -> endpoint.removeTrack(ctx.track as RemoteVideoTrack) @@ -796,8 +815,6 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U } globalToLocalTrackId.remove(ctx.trackId) - ctx.setOnEncodingChangedListener(null) - ctx.setOnVoiceActivityChangedListener(null) trackContexts.remove(ctx.trackId) emitEndpoints() onTracksUpdateListeners.forEach { it.onTracksUpdate() } @@ -810,32 +827,27 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U } } - override fun onEndpointAdded(endpoint: Endpoint) { + override fun onPeerJoined(peer: Peer) { CoroutineScope(Dispatchers.Main).launch { - endpoints[endpoint.id] = + endpoints[peer.id] = RNEndpoint( - id = endpoint.id, - metadata = endpoint.metadata, - type = endpoint.type, - tracksData = HashMap(endpoint.tracks) + id = peer.id, + metadata = peer.metadata, + type = peer.type, + tracksData = HashMap(peer.tracks) ) emitEndpoints() } } - override fun onEndpointRemoved(endpoint: Endpoint) { + override fun onPeerLeft(peer: Peer) { CoroutineScope(Dispatchers.Main).launch { - endpoints.remove(endpoint.id) + endpoints.remove(peer.id) emitEndpoints() } } - override fun onEndpointUpdated(endpoint: Endpoint) {} - - override fun onSendMediaEvent(event: SerializedMediaEvent) { - val eventName = EmitableEvents.SendMediaEvent - emitEvent(eventName, mapOf("event" to event)) - } + override fun onPeerUpdated(peer: Peer) {} override fun onBandwidthEstimationChanged(estimation: Long) { val eventName = EmitableEvents.BandwidthEstimation diff --git a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTCModule.kt b/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTCModule.kt index ba86fd23..2410ae19 100644 --- a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTCModule.kt +++ b/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTCModule.kt @@ -99,34 +99,35 @@ class MembraneWebRTCModule : Module() { } OnActivityDestroys { - membraneWebRTC.disconnect() + membraneWebRTC.cleanUp() } OnActivityResult { _, result -> membraneWebRTC.onActivityResult(result.requestCode, result.resultCode, result.data) } - AsyncFunction("create") Coroutine ({ -> - withContext(Dispatchers.Main) { + AsyncFunction("connect") { url: String, peerToken: String, promise: Promise -> + CoroutineScope(Dispatchers.Main).launch { membraneWebRTC.create() + membraneWebRTC.connect(url, peerToken, promise) } - }) + } - AsyncFunction("receiveMediaEvent") Coroutine { data: String -> - withContext(Dispatchers.Main) { - membraneWebRTC.receiveMediaEvent(data) + AsyncFunction("joinRoom") { peerMetadata: Map, promise: Promise -> + CoroutineScope(Dispatchers.Main).launch { + membraneWebRTC.joinRoom(peerMetadata, promise) } } - AsyncFunction("connect") { endpointMetadata: Map, promise: Promise -> + AsyncFunction("leaveRoom") { -> CoroutineScope(Dispatchers.Main).launch { - membraneWebRTC.connect(endpointMetadata, promise) + membraneWebRTC.leaveRoom() } } - AsyncFunction("disconnect") Coroutine { -> + AsyncFunction("cleanUp") Coroutine { -> withContext(Dispatchers.Main) { - membraneWebRTC.disconnect() + membraneWebRTC.cleanUp() } } diff --git a/example/App.tsx b/example/App.tsx index 1386ddac..354ab592 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -1,4 +1,3 @@ -import { FishjamContextProvider } from '@fishjam-dev/react-native-client'; import React from 'react'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import Toast from 'react-native-toast-message'; @@ -9,9 +8,7 @@ function App(): React.JSX.Element { return ( <> - - - + diff --git a/example/hooks/useJoinRoom.ts b/example/hooks/useJoinRoom.ts index d17e691e..b271eb41 100644 --- a/example/hooks/useJoinRoom.ts +++ b/example/hooks/useJoinRoom.ts @@ -1,6 +1,6 @@ import { useCamera, - useFishjamClient, + joinRoom as jsJoinRoom, useMicrophone, VideoQuality, } from '@fishjam-dev/react-native-client'; @@ -47,7 +47,6 @@ export function useJoinRoom({ isCameraAvailable, isMicrophoneAvailable, }: Props) { - const { join } = useFishjamClient(); const { startCamera, getCaptureDevices } = useCamera(); const { startMicrophone } = useMicrophone(); @@ -68,7 +67,7 @@ export function useJoinRoom({ cameraEnabled: isCameraAvailable, }); - await join({ + await jsJoinRoom({ name: 'RN mobile', }); @@ -79,7 +78,7 @@ export function useJoinRoom({ }, [ isCameraAvailable, isMicrophoneAvailable, - join, + jsJoinRoom, startCamera, startMicrophone, ]); diff --git a/example/ios/FishjamExample.xcodeproj/project.pbxproj b/example/ios/FishjamExample.xcodeproj/project.pbxproj index f8781768..922b9a22 100644 --- a/example/ios/FishjamExample.xcodeproj/project.pbxproj +++ b/example/ios/FishjamExample.xcodeproj/project.pbxproj @@ -11,15 +11,15 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 494772249E59F520382695A2 /* libPods-FishjamExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D1154418646A82F7B861371 /* libPods-FishjamExample.a */; }; - 53CAE1ADCD46FFCF9845E18E /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C08BB2FC59A69B8F776546 /* libPods-FishjamExample-FishjamExampleTests.a */; }; + 52D75531E85EB473D2428C5F /* libPods-FishjamExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 346A0E12933FC858CE94205E /* libPods-FishjamExample.a */; }; + 8030B691EDEA2170614263F6 /* libPods-ScreenBroadcast.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8721169503B33E647FF504AF /* libPods-ScreenBroadcast.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; A4AE54082454256BB1348002 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6486D552DE55BE12979D457F /* ExpoModulesProvider.swift */; }; C36C387544222DE51F95C8C8 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96822F1E4B772E6913DCDDDB /* ExpoModulesProvider.swift */; }; D2D7AC482B0BA9380029C1D6 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D249AAD22B06724C0053962E /* ReplayKit.framework */; }; D2D7AC4B2B0BA9390029C1D6 /* ScreenBroadcast.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D7AC4A2B0BA9390029C1D6 /* ScreenBroadcast.swift */; }; D2D7AC4F2B0BA9390029C1D6 /* ScreenBroadcast.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D2D7AC472B0BA9380029C1D6 /* ScreenBroadcast.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - D778E1D3FF567142578C29C8 /* libPods-ScreenBroadcast.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8FE83EC6BFA828FC4458A003 /* libPods-ScreenBroadcast.a */; }; + E97D9B616B89C39F04DF3929 /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B7998A241CE6D040FFE45634 /* libPods-FishjamExample-FishjamExampleTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -57,30 +57,30 @@ 00E356EE1AD99517003FC87E /* FishjamExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FishjamExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* FishjamExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FishjamExampleTests.m; sourceTree = ""; }; + 022BEA2C30E36AAA56B468E7 /* Pods-ScreenBroadcast.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.release.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.release.xcconfig"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* FishjamExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FishjamExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = FishjamExample/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = FishjamExample/AppDelegate.mm; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = FishjamExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = FishjamExample/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = FishjamExample/main.m; sourceTree = ""; }; - 19561A64C6E4BFD8040EF166 /* Pods-FishjamExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.release.xcconfig"; sourceTree = ""; }; - 3513E681619570F54AA7CF70 /* Pods-ScreenBroadcast.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.debug.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.debug.xcconfig"; sourceTree = ""; }; - 3D1154418646A82F7B861371 /* libPods-FishjamExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 42542A7FF19E518798AA2333 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; sourceTree = ""; }; + 346A0E12933FC858CE94205E /* libPods-FishjamExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 52441C999465B5CE22B7FCDE /* Pods-FishjamExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.debug.xcconfig"; sourceTree = ""; }; 6486D552DE55BE12979D457F /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-FishjamExample/ExpoModulesProvider.swift"; sourceTree = ""; }; - 773268FAE61862FD7D3FC892 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; sourceTree = ""; }; + 68EE46E3072DB8A787CD8035 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = FishjamExample/LaunchScreen.storyboard; sourceTree = ""; }; - 85FA140C08D09906C5C4EF05 /* Pods-ScreenBroadcast.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.release.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.release.xcconfig"; sourceTree = ""; }; - 8FE83EC6BFA828FC4458A003 /* libPods-ScreenBroadcast.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScreenBroadcast.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8721169503B33E647FF504AF /* libPods-ScreenBroadcast.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScreenBroadcast.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 96822F1E4B772E6913DCDDDB /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-FishjamExample-FishjamExampleTests/ExpoModulesProvider.swift"; sourceTree = ""; }; - BA8AD1101C6FCDF20058746C /* Pods-FishjamExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.debug.xcconfig"; sourceTree = ""; }; + 9E1769BCCB84DDDEC053EB27 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; sourceTree = ""; }; + A1C5753310FDDC6F2A62B0CA /* Pods-FishjamExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.release.xcconfig"; sourceTree = ""; }; + B7998A241CE6D040FFE45634 /* libPods-FishjamExample-FishjamExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample-FishjamExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CF7DBBB233EC29A31E7B4847 /* Pods-ScreenBroadcast.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.debug.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.debug.xcconfig"; sourceTree = ""; }; D249AAD22B06724C0053962E /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; }; D249AADF2B0672950053962E /* FishjamExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = FishjamExample.entitlements; path = FishjamExample/FishjamExample.entitlements; sourceTree = ""; }; D2D7AC472B0BA9380029C1D6 /* ScreenBroadcast.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ScreenBroadcast.appex; sourceTree = BUILT_PRODUCTS_DIR; }; D2D7AC4A2B0BA9390029C1D6 /* ScreenBroadcast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBroadcast.swift; sourceTree = ""; }; D2D7AC4C2B0BA9390029C1D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D2D7AC532B0BA98B0029C1D6 /* ScreenBroadcast.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ScreenBroadcast.entitlements; sourceTree = ""; }; - E7C08BB2FC59A69B8F776546 /* libPods-FishjamExample-FishjamExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample-FishjamExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -89,7 +89,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 53CAE1ADCD46FFCF9845E18E /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */, + E97D9B616B89C39F04DF3929 /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -97,7 +97,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 494772249E59F520382695A2 /* libPods-FishjamExample.a in Frameworks */, + 52D75531E85EB473D2428C5F /* libPods-FishjamExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -106,7 +106,7 @@ buildActionMask = 2147483647; files = ( D2D7AC482B0BA9380029C1D6 /* ReplayKit.framework in Frameworks */, - D778E1D3FF567142578C29C8 /* libPods-ScreenBroadcast.a in Frameworks */, + 8030B691EDEA2170614263F6 /* libPods-ScreenBroadcast.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -149,9 +149,9 @@ children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, D249AAD22B06724C0053962E /* ReplayKit.framework */, - 3D1154418646A82F7B861371 /* libPods-FishjamExample.a */, - E7C08BB2FC59A69B8F776546 /* libPods-FishjamExample-FishjamExampleTests.a */, - 8FE83EC6BFA828FC4458A003 /* libPods-ScreenBroadcast.a */, + 346A0E12933FC858CE94205E /* libPods-FishjamExample.a */, + B7998A241CE6D040FFE45634 /* libPods-FishjamExample-FishjamExampleTests.a */, + 8721169503B33E647FF504AF /* libPods-ScreenBroadcast.a */, ); name = Frameworks; sourceTree = ""; @@ -210,12 +210,12 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - BA8AD1101C6FCDF20058746C /* Pods-FishjamExample.debug.xcconfig */, - 19561A64C6E4BFD8040EF166 /* Pods-FishjamExample.release.xcconfig */, - 773268FAE61862FD7D3FC892 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */, - 42542A7FF19E518798AA2333 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */, - 3513E681619570F54AA7CF70 /* Pods-ScreenBroadcast.debug.xcconfig */, - 85FA140C08D09906C5C4EF05 /* Pods-ScreenBroadcast.release.xcconfig */, + 52441C999465B5CE22B7FCDE /* Pods-FishjamExample.debug.xcconfig */, + A1C5753310FDDC6F2A62B0CA /* Pods-FishjamExample.release.xcconfig */, + 9E1769BCCB84DDDEC053EB27 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */, + 68EE46E3072DB8A787CD8035 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */, + CF7DBBB233EC29A31E7B4847 /* Pods-ScreenBroadcast.debug.xcconfig */, + 022BEA2C30E36AAA56B468E7 /* Pods-ScreenBroadcast.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -245,13 +245,13 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "FishjamExampleTests" */; buildPhases = ( - 8068874C39157CAF6BA4DCCE /* [CP] Check Pods Manifest.lock */, + 530F8EAF2628D2940B7AEE36 /* [CP] Check Pods Manifest.lock */, EC302C2D573892907E91A28D /* [Expo] Configure project */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - DA1EF6A3774946049CF6E045 /* [CP] Embed Pods Frameworks */, - C10F5983D98DB5865540E201 /* [CP] Copy Pods Resources */, + 9559F1A9AAEF870E60A6D055 /* [CP] Embed Pods Frameworks */, + 6C2C22BEF743DBDD9D633ED8 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -267,7 +267,7 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "FishjamExample" */; buildPhases = ( - B0822E316EAD6E2AA6D734D8 /* [CP] Check Pods Manifest.lock */, + 0D3E62BC0B095146C437D6BA /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 2C2C21F5B052BD7681B67CFD /* [Expo] Configure project */, 13B07F871A680F5B00A75B9A /* Sources */, @@ -275,8 +275,8 @@ 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, D249AADB2B06724D0053962E /* Embed Foundation Extensions */, - BFCE6A1EAB0D59A561FA977C /* [CP] Embed Pods Frameworks */, - B2F1B3E0C7E5A3EACF61042D /* [CP] Copy Pods Resources */, + 96637B25966F8B9A3BAE5CD8 /* [CP] Embed Pods Frameworks */, + 0436BB40ABFCEE65CFA7D833 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -292,11 +292,11 @@ isa = PBXNativeTarget; buildConfigurationList = D2D7AC502B0BA9390029C1D6 /* Build configuration list for PBXNativeTarget "ScreenBroadcast" */; buildPhases = ( - 1EF466BF7B9C57D0FD8B7A9A /* [CP] Check Pods Manifest.lock */, + 22021E26669B6ABB77577E1F /* [CP] Check Pods Manifest.lock */, D2D7AC432B0BA9380029C1D6 /* Sources */, D2D7AC442B0BA9380029C1D6 /* Frameworks */, D2D7AC452B0BA9380029C1D6 /* Resources */, - 2F638C07E517226D4E372B33 /* [CP] Copy Pods Resources */, + BA28A958809C756716EFF9B5 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -391,87 +391,87 @@ shellPath = /bin/sh; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; - 1EF466BF7B9C57D0FD8B7A9A /* [CP] Check Pods Manifest.lock */ = { + 0436BB40ABFCEE65CFA7D833 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ScreenBroadcast-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 2C2C21F5B052BD7681B67CFD /* [Expo] Configure project */ = { + 0D3E62BC0B095146C437D6BA /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "[Expo] Configure project"; + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-FishjamExample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-FishjamExample/expo-configure-project.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 2F638C07E517226D4E372B33 /* [CP] Copy Pods Resources */ = { + 22021E26669B6ABB77577E1F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ScreenBroadcast-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 8068874C39157CAF6BA4DCCE /* [CP] Check Pods Manifest.lock */ = { + 2C2C21F5B052BD7681B67CFD /* [Expo] Configure project */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Check Pods Manifest.lock"; + name = "[Expo] Configure project"; outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-FishjamExample-FishjamExampleTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-FishjamExample/expo-configure-project.sh\"\n"; }; - B0822E316EAD6E2AA6D734D8 /* [CP] Check Pods Manifest.lock */ = { + 530F8EAF2628D2940B7AEE36 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -486,79 +486,79 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-FishjamExample-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-FishjamExample-FishjamExampleTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - B2F1B3E0C7E5A3EACF61042D /* [CP] Copy Pods Resources */ = { + 6C2C22BEF743DBDD9D633ED8 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - BFCE6A1EAB0D59A561FA977C /* [CP] Embed Pods Frameworks */ = { + 9559F1A9AAEF870E60A6D055 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - C10F5983D98DB5865540E201 /* [CP] Copy Pods Resources */ = { + 96637B25966F8B9A3BAE5CD8 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - DA1EF6A3774946049CF6E045 /* [CP] Embed Pods Frameworks */ = { + BA28A958809C756716EFF9B5 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources.sh\"\n"; showEnvVarsInLog = 0; }; EC302C2D573892907E91A28D /* [Expo] Configure project */ = { @@ -647,7 +647,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 773268FAE61862FD7D3FC892 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */; + baseConfigurationReference = 9E1769BCCB84DDDEC053EB27 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -675,7 +675,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 42542A7FF19E518798AA2333 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */; + baseConfigurationReference = 68EE46E3072DB8A787CD8035 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -700,7 +700,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BA8AD1101C6FCDF20058746C /* Pods-FishjamExample.debug.xcconfig */; + baseConfigurationReference = 52441C999465B5CE22B7FCDE /* Pods-FishjamExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -736,7 +736,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 19561A64C6E4BFD8040EF166 /* Pods-FishjamExample.release.xcconfig */; + baseConfigurationReference = A1C5753310FDDC6F2A62B0CA /* Pods-FishjamExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -818,7 +818,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", @@ -890,7 +890,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", @@ -918,7 +918,7 @@ }; D2D7AC512B0BA9390029C1D6 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3513E681619570F54AA7CF70 /* Pods-ScreenBroadcast.debug.xcconfig */; + baseConfigurationReference = CF7DBBB233EC29A31E7B4847 /* Pods-ScreenBroadcast.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; @@ -962,7 +962,7 @@ }; D2D7AC522B0BA9390029C1D6 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 85FA140C08D09906C5C4EF05 /* Pods-ScreenBroadcast.release.xcconfig */; + baseConfigurationReference = 022BEA2C30E36AAA56B468E7 /* Pods-ScreenBroadcast.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; diff --git a/example/ios/Podfile b/example/ios/Podfile index cbb2e25f..e82f0c06 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -57,8 +57,11 @@ target 'FishjamExample' do :mac_catalyst_enabled => false ) end + pod 'FishjamClient', :git => 'https://github.com/fishjam-dev/ios-client-sdk.git', :commit => '9d22ecaf75cc563a24212c13e15cd83a3f76ac0f' end + + target 'ScreenBroadcast' do - pod 'FishjamClient/Broadcast' + pod 'FishjamClient/Broadcast', :git => 'https://github.com/fishjam-dev/ios-client-sdk.git', :commit => '9d22ecaf75cc563a24212c13e15cd83a3f76ac0f' end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index f68a0f24..a0da1882 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -32,15 +32,15 @@ PODS: - React-Core (= 0.73.4) - React-jsi (= 0.73.4) - ReactCommon/turbomodule/core (= 0.73.4) - - FishjamClient (0.3.0): - - FishjamClient/Broadcast (= 0.3.0) + - FishjamClient (0.3.1): + - FishjamClient/Broadcast (= 0.3.1) - PromisesSwift - Starscream (~> 4.0.0) - SwiftLogJellyfish (= 1.5.2) - SwiftPhoenixClient (~> 5.0.0) - SwiftProtobuf (~> 1.18.0) - WebRTC-SDK (= 114.5735.08) - - FishjamClient/Broadcast (0.3.0): + - FishjamClient/Broadcast (0.3.1): - PromisesSwift - Starscream (~> 4.0.0) - SwiftLogJellyfish (= 1.5.2) @@ -1098,7 +1098,7 @@ PODS: - React-perflogger (= 0.73.4) - RNFishjamClient (0.3.0): - ExpoModulesCore - - FishjamClient (= 0.3.0) + - FishjamClient (= 0.3.1) - RNGestureHandler (2.16.2): - glog - RCT-Folly (= 2022.05.16.00) @@ -1144,7 +1144,8 @@ DEPENDENCIES: - ExpoModulesCore (from `../node_modules/expo-modules-core`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - - FishjamClient/Broadcast + - FishjamClient (from `https://github.com/fishjam-dev/ios-client-sdk.git`, commit `9d22ecaf75cc563a24212c13e15cd83a3f76ac0f`) + - FishjamClient/Broadcast (from `https://github.com/fishjam-dev/ios-client-sdk.git`, commit `9d22ecaf75cc563a24212c13e15cd83a3f76ac0f`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - libevent (~> 2.1.12) @@ -1201,7 +1202,6 @@ DEPENDENCIES: SPEC REPOS: trunk: - - FishjamClient - fmt - libevent - PromisesObjC @@ -1239,6 +1239,9 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/FBLazyVector" FBReactNativeSpec: :path: "../node_modules/react-native/React/FBReactNativeSpec" + FishjamClient: + :commit: 9d22ecaf75cc563a24212c13e15cd83a3f76ac0f + :git: https://github.com/fishjam-dev/ios-client-sdk.git glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: @@ -1341,6 +1344,11 @@ EXTERNAL SOURCES: Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" +CHECKOUT OPTIONS: + FishjamClient: + :commit: 9d22ecaf75cc563a24212c13e15cd83a3f76ac0f + :git: https://github.com/fishjam-dev/ios-client-sdk.git + SPEC CHECKSUMS: boost: d3f49c53809116a5d38da093a8aa78bf551aed09 DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953 @@ -1354,7 +1362,7 @@ SPEC CHECKSUMS: ExpoModulesCore: 4a8928a228569301ac4fc4a1e846713e05754d05 FBLazyVector: 84f6edbe225f38aebd9deaf1540a4160b1f087d7 FBReactNativeSpec: d0086a479be91c44ce4687a962956a352d2dc697 - FishjamClient: b811a3384a56839bed9553ad0fee1cd4b3422d3d + FishjamClient: c1cf10484a705500c9fac352b75a4c1b8cec3cf2 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 hermes-engine: b2669ce35fc4ac14f523b307aff8896799829fe2 @@ -1403,7 +1411,7 @@ SPEC CHECKSUMS: React-runtimescheduler: ed48e5faac6751e66ee1261c4bd01643b436f112 React-utils: 6e5ad394416482ae21831050928ae27348f83487 ReactCommon: 840a955d37b7f3358554d819446bffcf624b2522 - RNFishjamClient: 6a090b2a484c9f09ed8a42ccc434f1c3cd0bf201 + RNFishjamClient: 6e7021e6d170aabdde759ebade44151960244a05 RNGestureHandler: 48c9d38f57c7761b4153def57b718f491f4bbb4b RNNotifee: 8e2d3df3f0e9ce8f5d1fe4c967431138190b6175 RNReanimated: 071599dab9e3769c03b84c984c87dc79087fef2f @@ -1417,6 +1425,6 @@ SPEC CHECKSUMS: Yoga: 64cd2a583ead952b0315d5135bf39e053ae9be70 ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: 8daa796ed34dbeeeb2b648d198968b27b4c2ae8d +PODFILE CHECKSUM: 0376e85da25bcfda7c0095d7c9d174ee924ff49d -COCOAPODS: 1.13.0 +COCOAPODS: 1.14.3 diff --git a/example/screens/ConnectWithRoomManagerScreen.tsx b/example/screens/ConnectWithRoomManagerScreen.tsx index 9a7635bd..3868f915 100644 --- a/example/screens/ConnectWithRoomManagerScreen.tsx +++ b/example/screens/ConnectWithRoomManagerScreen.tsx @@ -1,4 +1,4 @@ -import { useFishjamClient } from '@fishjam-dev/react-native-client'; +import { connect } from '@fishjam-dev/react-native-client'; import type { BottomTabScreenProps } from '@react-navigation/bottom-tabs'; import { CompositeScreenProps } from '@react-navigation/native'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; @@ -50,7 +50,6 @@ async function getFishjamServer( } const ConnectScreen = ({ navigation }: Props) => { - const { connect } = useFishjamClient(); const [connectionError, setConnectionError] = useState(null); const [loading, setLoading] = useState(false); diff --git a/example/screens/ConnectWithTokenScreen.tsx b/example/screens/ConnectWithTokenScreen.tsx index 63a72c69..06f9685e 100644 --- a/example/screens/ConnectWithTokenScreen.tsx +++ b/example/screens/ConnectWithTokenScreen.tsx @@ -1,4 +1,4 @@ -import { useFishjamClient } from '@fishjam-dev/react-native-client'; +import { connect } from '@fishjam-dev/react-native-client'; import type { BottomTabScreenProps } from '@react-navigation/bottom-tabs'; import { CompositeScreenProps } from '@react-navigation/native'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; @@ -32,7 +32,6 @@ type Props = CompositeScreenProps< const { URL_INPUT, TOKEN_INPUT, CONNECT_BUTTON } = connectScreenLabels; const ConnectScreen = ({ navigation }: Props) => { - const { connect } = useFishjamClient(); const [connectionError, setConnectionError] = useState(null); const [peerToken, onChangePeerToken] = useState(''); diff --git a/example/screens/RoomScreen.tsx b/example/screens/RoomScreen.tsx index 0ee88efb..ee4a474a 100644 --- a/example/screens/RoomScreen.tsx +++ b/example/screens/RoomScreen.tsx @@ -1,5 +1,5 @@ import { - useFishjamClient, + cleanUp, usePeers, useScreencast, ScreencastQuality, @@ -40,7 +40,6 @@ const RoomScreen = ({ navigation, route }: Props) => { userName, } = route?.params; usePreventBackButton(); - const { cleanUp } = useFishjamClient(); const audioSettings = useAudioSettings(); const { joinRoom } = useJoinRoom({ @@ -57,6 +56,7 @@ const RoomScreen = ({ navigation, route }: Props) => { }, [joinRoom]); const peers = usePeers(); + const tracks = useMemo( () => peers.flatMap((peer) => @@ -72,7 +72,7 @@ const RoomScreen = ({ navigation, route }: Props) => { const onDisconnectPress = useCallback(() => { cleanUp(); navigation.navigate('Home'); - }, [navigation, cleanUp]); + }, [navigation]); const onToggleScreenCast = useCallback(() => { toggleScreencast({ diff --git a/ios/MembraneWebRTC.swift b/ios/MembraneWebRTC.swift index a78a93da..70b3bdb1 100644 --- a/ios/MembraneWebRTC.swift +++ b/ios/MembraneWebRTC.swift @@ -63,8 +63,8 @@ extension String { } } -class MembraneWebRTC: MembraneRTCDelegate { - var membraneRTC: MembraneRTC? = nil +class MembraneWebRTC: FishjamClientListener { + var fishjamClient: FishjamClient? = nil var localAudioTrack: LocalAudioTrack? var localVideoTrack: LocalVideoTrack? @@ -78,6 +78,7 @@ class MembraneWebRTC: MembraneRTCDelegate { var globalToLocalTrackId: [String: String] = [:] var connectPromise: Promise? = nil + var joinPromise: Promise? = nil var videoSimulcastConfig: SimulcastConfig = SimulcastConfig() var localUserMetadata: Metadata = .init() @@ -152,7 +153,7 @@ class MembraneWebRTC: MembraneRTCDelegate { } func create() throws { - self.membraneRTC = MembraneRTC.create(delegate: self) + self.fishjamClient = FishjamClient(listener: self) try ensureCreated() initLocalEndpoint() } @@ -198,14 +199,14 @@ class MembraneWebRTC: MembraneRTCDelegate { return videoParameters } private func ensureCreated() throws { - if membraneRTC == nil { + if fishjamClient == nil { throw Exception( name: "E_NO_MEMBRANERTC", description: "Client not created yet. Make sure to call create() first!") } } private func ensureConnected() throws { - if membraneRTC == nil { + if fishjamClient == nil { throw Exception( name: "E_NOT_CONNECTED", description: "Client not connected to server yet. Make sure to call connect() first!") @@ -213,7 +214,7 @@ class MembraneWebRTC: MembraneRTCDelegate { } private func ensureVideoTrack() throws { - if membraneRTC == nil { + if fishjamClient == nil { throw Exception( name: "E_NO_LOCAL_VIDEO_TRACK", description: "No local video track. Make sure to call connect() first!") @@ -221,7 +222,7 @@ class MembraneWebRTC: MembraneRTCDelegate { } private func ensureAudioTrack() throws { - if membraneRTC == nil { + if fishjamClient == nil { throw Exception( name: "E_NO_LOCAL_AUDIO_TRACK", description: "No local audio track. Make sure to call connect() first!") @@ -229,7 +230,7 @@ class MembraneWebRTC: MembraneRTCDelegate { } private func ensureScreencastTrack() throws { - if membraneRTC == nil { + if fishjamClient == nil { throw Exception( name: "E_NO_LOCAL_SCREENCAST_TRACK", description: "No local screencast track. Make sure to toggle screencast on first!") @@ -243,39 +244,107 @@ class MembraneWebRTC: MembraneRTCDelegate { "No endpoints available. Ensure the connection is established or endpoints are present.") } } - - func receiveMediaEvent(data: String) throws { - try ensureConnected() - membraneRTC?.receiveMediaEvent(mediaEvent: data as SerializedMediaEvent) + + func onSocketClose(code: UInt16, reason: String) { + if let connectPromise = connectPromise { + connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket close") } - - func connect(metadata: [String: Any], promise: Promise) { - connectPromise = promise - localUserMetadata = metadata.toMetadata() - - guard let localEndpointId = localEndpointId, - var endpoint = MembraneRoom.sharedInstance.endpoints[localEndpointId] - else { - return - } - - endpoint.metadata = metadata.toMetadata() - membraneRTC?.connect(metadata: metadata.toMetadata()) + connectPromise = nil + } + + func onSocketError() { + if let connectPromise = connectPromise { + connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error") } - - func disconnect() { - if isScreensharingEnabled { - let screencastExtensionBundleId = - Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] as? String - DispatchQueue.main.async { - RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) - } - } - membraneRTC?.remove(delegate: self) - membraneRTC?.disconnect() - membraneRTC = nil - MembraneRoom.sharedInstance.endpoints = [:] + connectPromise = nil + } + + func onSocketOpen() { + + } + + func onAuthSuccess() { + if let connectPromise = connectPromise { + connectPromise.resolve(nil) + } + connectPromise = nil + } + + func onAuthError() { + if let connectPromise = connectPromise { + connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error") + } + connectPromise = nil + } + + func onDisconnected() { + + } + + func onJoined(peerID: String, peersInRoom: [Endpoint]) { + peersInRoom.forEach { endpoint in + MembraneRoom.sharedInstance.endpoints[endpoint.id] = RNEndpoint( + id: endpoint.id, metadata: endpoint.metadata, type: endpoint.type, tracks: endpoint.tracks ?? [:] + ) + } + + emitEndpoints() + if let joinPromise = joinPromise { + joinPromise.resolve(nil) + } + joinPromise = nil + } + + func onJoinError(metadata: Any) { + if let joinPromise = joinPromise { + joinPromise.reject("E_MEMBRANE_CONNECT", "Failed to join room") } + joinPromise = nil + } + + func connect(url: String, peerToken: String, promise: Promise) { + connectPromise = promise + fishjamClient?.connect(config: Config(websocketUrl: url, token: peerToken)) + } + + func joinRoom(peerMetadata: [String: Any], promise: Promise) { + joinPromise = promise + localUserMetadata = peerMetadata.toMetadata() + + guard let localEndpointId = localEndpointId, + var endpoint = MembraneRoom.sharedInstance.endpoints[localEndpointId] + else { + return + } + + endpoint.metadata = peerMetadata.toMetadata() + fishjamClient?.join(peerMetadata: peerMetadata.toMetadata()) + } + + func leaveRoom() { + if isScreensharingEnabled { + let screencastExtensionBundleId = + Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] as? String + DispatchQueue.main.async { + RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) + } + } + fishjamClient?.leave() + MembraneRoom.sharedInstance.endpoints = [:] + } + + func cleanUp() { + if isScreensharingEnabled { + let screencastExtensionBundleId = + Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] as? String + DispatchQueue.main.async { + RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) + } + } + fishjamClient?.cleanUp() + fishjamClient = nil + MembraneRoom.sharedInstance.endpoints = [:] + } func startCamera(config: CameraConfig) throws { try ensureConnected() @@ -294,11 +363,10 @@ class MembraneWebRTC: MembraneRTCDelegate { simulcastConfig: config.simulcastConfig) else { return nil } self.videoSimulcastConfig = simulcastConfig - return membraneRTC?.createVideoTrack( + return fishjamClient?.createVideoTrack( videoParameters: videoParameters, metadata: config.videoTrackMetadata.toMetadata(), - captureDeviceId: config.captureDeviceId, - simulcastConfig: simulcastConfig + captureDeviceName: config.captureDeviceId ) } private func setCameraTrackState(cameraTrack: LocalVideoTrack, isEnabled: Bool) throws { @@ -363,7 +431,7 @@ class MembraneWebRTC: MembraneRTCDelegate { func startMicrophone(config: MicrophoneConfig) throws { try ensureConnected() guard - let microphoneTrack = membraneRTC?.createAudioTrack( + let microphoneTrack = fishjamClient?.createAudioTrack( metadata: config.audioTrackMetadata.toMetadata()) else { return } localAudioTrack = microphoneTrack @@ -450,7 +518,7 @@ class MembraneWebRTC: MembraneRTCDelegate { maxBandwidth: screencastOptions.maxBandwidth) let screencastMetadata = screencastOptions.screencastMetadata.toMetadata() let videoParameters = getScreencastVideoParameters(screencastOptions: screencastOptions) - localScreencastTrack = membraneRTC?.createScreencastTrack( + localScreencastTrack = fishjamClient?.createScreencastTrack( appGroup: appGroupName, videoParameters: videoParameters, metadata: screencastMetadata, @@ -570,11 +638,11 @@ class MembraneWebRTC: MembraneRTCDelegate { func updateEndpointMetadata(metadata: [String: Any]) throws { try ensureConnected() - membraneRTC?.updateEndpointMetadata(metadata: metadata.toMetadata()) + fishjamClient?.updatePeerMetadata(peerMetadata: metadata.toMetadata()) } func updateTrackMetadata(trackId: String, metadata: [String: Any]) { - guard let room = membraneRTC, let endpointId = localEndpointId else { + guard let room = fishjamClient, let endpointId = localEndpointId else { return } @@ -616,7 +684,7 @@ class MembraneWebRTC: MembraneRTCDelegate { private func toggleTrackEncoding( encoding: TrackEncoding, trackId: String, simulcastConfig: SimulcastConfig ) -> SimulcastConfig? { - guard let room = membraneRTC else { + guard let room = fishjamClient else { return nil } if simulcastConfig.activeEncodings.contains(encoding) { @@ -651,26 +719,26 @@ class MembraneWebRTC: MembraneRTCDelegate { } func setScreencastTrackBandwidth(bandwidth: Int) throws { try ensureScreencastTrack() - guard let room = membraneRTC, let trackId = localScreencastTrack?.trackId() else { + guard let room = fishjamClient, let trackId = localScreencastTrack?.trackId() else { return } - room.setTrackBandwidth(trackId: trackId, bandwidth: BandwidthLimit(bandwidth)) + room.setTrackBandwidth(trackId: trackId, bandwidthLimit: BandwidthLimit(bandwidth)) } func setScreencastTrackEncodingBandwidth(encoding: String, bandwidth: Int) throws { try ensureScreencastTrack() let trackEncoding = try validateEncoding(encoding: encoding as String) - guard let room = membraneRTC, let trackId = localScreencastTrack?.trackId() else { + guard let room = fishjamClient, let trackId = localScreencastTrack?.trackId() else { return } room.setEncodingBandwidth( - trackId: trackId, encoding: trackEncoding.description, bandwidth: BandwidthLimit(bandwidth)) + trackId: trackId, encoding: trackEncoding.description, bandwidthLimit: BandwidthLimit(bandwidth)) } func setTargetTrackEncoding(trackId: String, encoding: String) throws { try ensureConnected() guard - let room = membraneRTC, + let room = fishjamClient, let videoTrack = MembraneRoom.sharedInstance.getVideoTrackById(trackId: trackId as String), let trackId = (videoTrack as? RemoteVideoTrack)?.track.trackId ?? (videoTrack as? LocalVideoTrack)?.trackId(), @@ -706,33 +774,33 @@ class MembraneWebRTC: MembraneRTCDelegate { func setVideoTrackEncodingBandwidth(encoding: String, bandwidth: Int) throws { try ensureVideoTrack() - guard let room = membraneRTC, let trackId = localVideoTrack?.trackId() else { + guard let room = fishjamClient, let trackId = localVideoTrack?.trackId() else { return } room.setEncodingBandwidth( - trackId: trackId, encoding: encoding as String, bandwidth: BandwidthLimit(bandwidth)) + trackId: trackId, encoding: encoding as String, bandwidthLimit: BandwidthLimit(bandwidth)) } func setVideoTrackBandwidth(bandwidth: Int) throws { try ensureVideoTrack() - guard let room = membraneRTC, let trackId = localVideoTrack?.trackId() else { + guard let room = fishjamClient, let trackId = localVideoTrack?.trackId() else { return } - room.setTrackBandwidth(trackId: trackId, bandwidth: BandwidthLimit(bandwidth)) + room.setTrackBandwidth(trackId: trackId, bandwidthLimit: BandwidthLimit(bandwidth)) } func changeWebRTCLoggingSeverity(severity: String) throws { switch severity { case "verbose": - membraneRTC?.changeWebRTCLoggingSeverity(severity: .verbose) + fishjamClient?.changeWebRTCLoggingSeverity(severity: .verbose) case "info": - membraneRTC?.changeWebRTCLoggingSeverity(severity: .info) + fishjamClient?.changeWebRTCLoggingSeverity(severity: .info) case "warning": - membraneRTC?.changeWebRTCLoggingSeverity(severity: .warning) + fishjamClient?.changeWebRTCLoggingSeverity(severity: .warning) case "error": - membraneRTC?.changeWebRTCLoggingSeverity(severity: .error) + fishjamClient?.changeWebRTCLoggingSeverity(severity: .error) case "none": - membraneRTC?.changeWebRTCLoggingSeverity(severity: .none) + fishjamClient?.changeWebRTCLoggingSeverity(severity: .none) default: throw Exception( name: "E_INVALID_SEVERITY_LEVEL", description: "Severity with name=\(severity) not found") @@ -791,7 +859,7 @@ class MembraneWebRTC: MembraneRTCDelegate { } func getStatistics() -> [String: Any] { - return statsToRNMap(stats: membraneRTC?.getStats()) + return statsToRNMap(stats: fishjamClient?.getStats()) } func setAudioSessionMode() { @@ -885,32 +953,6 @@ class MembraneWebRTC: MembraneRTCDelegate { ] as [String: [String: Any]]) } - func onSendMediaEvent(event: SerializedMediaEvent) { - let eventName = EmitableEvents.SendMediaEvent - emitEvent(name: eventName, data: ["event": event]) - } - - func onConnected(endpointId: String, otherEndpoints: [Endpoint]) { - otherEndpoints.forEach { endpoint in - MembraneRoom.sharedInstance.endpoints[endpoint.id] = RNEndpoint( - id: endpoint.id, metadata: endpoint.metadata, type: endpoint.type, tracks: endpoint.tracks ?? [:] - ) - } - - emitEndpoints() - if let connectPromise = connectPromise { - connectPromise.resolve(nil) - } - connectPromise = nil - } - - func onConnectionError(metadata: Any) { - if let connectPromise = connectPromise { - connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: \(metadata)") - } - connectPromise = nil - } - func updateOrAddTrack(ctx: TrackContext) { guard var endpoint = MembraneRoom.sharedInstance.endpoints[ctx.endpoint.id] else { return @@ -981,18 +1023,18 @@ class MembraneWebRTC: MembraneRTCDelegate { updateOrAddTrack(ctx: ctx) } - func onEndpointAdded(endpoint: Endpoint) { + func onPeerJoined(endpoint: Endpoint) { MembraneRoom.sharedInstance.endpoints[endpoint.id] = RNEndpoint( id: endpoint.id, metadata: endpoint.metadata, type: endpoint.type) emitEndpoints() } - func onEndpointRemoved(endpoint: Endpoint) { + func onPeerLeft(endpoint: Endpoint) { MembraneRoom.sharedInstance.endpoints.removeValue(forKey: endpoint.id) emitEndpoints() } - func onEndpointUpdated(endpoint: Endpoint) { + func onPeerUpdated(endpoint: Endpoint) { } diff --git a/ios/MembraneWebRTCModule.swift b/ios/MembraneWebRTCModule.swift index 4aea4f42..29d6c332 100644 --- a/ios/MembraneWebRTCModule.swift +++ b/ios/MembraneWebRTCModule.swift @@ -74,19 +74,24 @@ public class MembraneWebRTCModule: Module { } AsyncFunction("create") { - try membraneWebRTC.create() + } - AsyncFunction("connect") { (endpointMetadata: [String: Any], promise: Promise) in - membraneWebRTC.connect(metadata: endpointMetadata, promise: promise) + AsyncFunction("connect") { (url: String, peerToken: String, promise: Promise ) in + try membraneWebRTC.create() + membraneWebRTC.connect(url: url, peerToken: peerToken, promise: promise) } - AsyncFunction("disconnect") { - membraneWebRTC.disconnect() + AsyncFunction("joinRoom") { (peerMetadata: [String: Any], promise: Promise ) in + membraneWebRTC.joinRoom(peerMetadata: peerMetadata, promise: promise) } - AsyncFunction("receiveMediaEvent") { (data: String) in - try membraneWebRTC.receiveMediaEvent(data: data) + AsyncFunction("leaveRoom") { + membraneWebRTC.leaveRoom() + } + + AsyncFunction("cleanUp") { + membraneWebRTC.cleanUp() } AsyncFunction("startCamera") { (config: CameraConfig) in diff --git a/ios/RNFishjamClient.podspec b/ios/RNFishjamClient.podspec index 5f6c0a34..8d31a2c6 100644 --- a/ios/RNFishjamClient.podspec +++ b/ios/RNFishjamClient.podspec @@ -25,6 +25,6 @@ Pod::Spec.new do |s| s.source_files = "**/*.{h,m,swift}" - s.dependency "FishjamClient", '0.3.0' + s.dependency "FishjamClient", '0.3.1' end diff --git a/src/FishjamClientContext.tsx b/src/FishjamClientContext.tsx deleted file mode 100644 index d33559fd..00000000 --- a/src/FishjamClientContext.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { requireNativeModule, NativeModulesProxy } from 'expo-modules-core'; -import React, { useCallback, useEffect, useRef } from 'react'; -import { NativeEventEmitter } from 'react-native'; - -import { Metadata } from './MembraneWebRTC.types'; -import { PeerMessage } from './protos/fishjam/peer_notifications'; - -const membraneModule = requireNativeModule('MembraneWebRTC'); - -const eventEmitter = new NativeEventEmitter( - membraneModule ?? NativeModulesProxy.MembraneWebRTC, -); - -const generateMessage = (event: WebSocketCloseEvent) => { - return ( - 'WebSocket was closed: ' + - [event.message, event.code, event.reason].filter((i) => !!i).join(' ') - ); -}; - -export const FishjamContext = React.createContext< - | { - /** - * Connects to the server using the websocket connection. - * If fishjam server is in local network, on iOS devices make sure to grant local network permission before - * calling this function. Otherwise, the function will fail unless the user grants that permission. - * @param url - websocket url - * @param peerToken - token used to authenticate when joining the room - */ - connect: (url: string, peerToken: string) => Promise; - - /** - * Tries to join the room. If user is accepted then onJoinSuccess will be called. - * In other case onJoinError is invoked. - * @param peerMetadata - Any information that other peers will receive in onPeerJoined - * after accepting this peer. - */ - - join: (peerMetadata: Metadata) => Promise; - /** - * Disconnect from the room, and close the websocket connection. Tries to leave the room gracefully, but if it fails, - * it will close the websocket anyway. - */ - cleanUp: () => void; - - /** - * Leaves the room. This function should be called when user leaves the room in a clean way e.g. by clicking a - * dedicated, custom button `disconnect`. As a result there will be generated one more media event that should be sent - * to the RTC Engine. Thanks to it each other peer will be notified that peer left in MessageEvents.onPeerLeft. - */ - leave: () => void; - } - | undefined ->(undefined); - -const FishjamContextProvider = (props: any) => { - const websocket = useRef(null); - - const sendMediaEvent = ({ event }: { event: string }) => { - if (websocket.current?.readyState !== WebSocket.OPEN) { - return; - } - - const message = PeerMessage.encode({ - mediaEvent: { data: event }, - }).finish(); - - websocket.current?.send(message); - }; - - useEffect(() => { - const eventListener = eventEmitter.addListener( - 'SendMediaEvent', - sendMediaEvent, - ); - return () => eventListener.remove(); - }, []); - - const connect = useCallback(async (url: string, peerToken: string) => { - websocket.current?.close(); - websocket.current = new WebSocket(url); - - const processIncomingMessages = new Promise((resolve, reject) => { - websocket.current?.addEventListener('close', (event) => { - if (event.code !== 1000 || event.isTrusted === false) { - // todo: improve error handling - reject(new Error(generateMessage(event))); - } - }); - - websocket.current?.addEventListener('open', () => { - const message = PeerMessage.encode({ - authRequest: { - token: peerToken, - }, - }).finish(); - websocket.current?.send(message); - }); - - websocket.current?.addEventListener('message', (event) => { - const uint8Array = new Uint8Array(event.data); - try { - const data = PeerMessage.decode(uint8Array); - - if (data.authenticated !== undefined) { - resolve(); - } else if (data.authRequest !== undefined) { - reject( - new Error('Received unexpected control message: authRequest'), - ); - } else if (data.mediaEvent !== undefined) { - membraneModule.receiveMediaEvent(data.mediaEvent.data); - } - } catch (e) { - reject(e); - } - }); - }); - await membraneModule.create(); - await processIncomingMessages; - }, []); - - const join = useCallback(async (peerMetadata: Metadata = {}) => { - await membraneModule.connect(peerMetadata); - }, []); - - const cleanUp = useCallback(() => { - membraneModule?.disconnect(); - websocket.current?.close(); - websocket.current = null; - }, []); - - useEffect(() => { - return cleanUp; - }, [cleanUp]); - - const leave = useCallback(() => { - membraneModule.disconnect(); - }, []); - - const value = { - connect, - join, - cleanUp, - leave, - }; - - return ( - - {props.children} - - ); -}; - -function useFishjamClient() { - const context = React.useContext(FishjamContext); - if (context === undefined) { - throw new Error( - 'useFishjamClient must be used within a FishjamContextProvider', - ); - } - return context; -} - -export { FishjamContextProvider, useFishjamClient }; diff --git a/src/MembraneWebRTC.types.ts b/src/MembraneWebRTC.types.ts index ad1e9032..096455e0 100644 --- a/src/MembraneWebRTC.types.ts +++ b/src/MembraneWebRTC.types.ts @@ -376,12 +376,10 @@ export type VideoRendererProps = { export type MembraneWebRTC = { appContext?: any; - create: () => Promise; - receiveMediaEvent: (data: string) => Promise; - connect: ( - endpointMetadata: MetadataType, - ) => Promise; - disconnect: () => Promise; + connect: (url: string, peerToken: string) => Promise; + joinRoom: (peerMetadata: Metadata) => Promise; + leaveRoom: () => Promise; + cleanUp: () => Promise; startCamera: ( config: Partial>, ) => Promise; diff --git a/src/__tests__/FishjamContext.test.tsx b/src/__tests__/FishjamContext.test.tsx deleted file mode 100644 index 72f39870..00000000 --- a/src/__tests__/FishjamContext.test.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { renderHook, act } from '@testing-library/react'; -import { requireNativeModule } from 'expo-modules-core'; -import WS from 'jest-websocket-mock'; - -import { - FishjamContextProvider, - useFishjamClient, -} from '../FishjamClientContext'; -import { PeerMessage } from '../protos/fishjam/peer_notifications'; - -let sendEvent: null | (({ event }: { event: string }) => void) = null; - -jest.mock('expo-modules-core', () => ({ - EventEmitter: jest.fn().mockImplementation(() => ({ - addListener: jest.fn((_, _sendEvent) => { - sendEvent = _sendEvent; - return { remove: jest.fn() }; - }), - })), - requireNativeModule: jest.fn().mockReturnValue({ - receiveMediaEvent: jest.fn(), - create: jest.fn(), - disconnect: jest.fn(), - }), - NativeModulesProxy: jest.fn().mockImplementation(() => { - return jest.fn(); - }), -})); - -jest.mock('react-native', () => ({ - NativeEventEmitter: jest.fn().mockImplementation(() => ({ - addListener: jest.fn((_, _sendEvent) => { - sendEvent = _sendEvent; - return { remove: jest.fn() }; - }), - })), -})); - -const socketUrl = 'ws://localhost:1234'; -const peerToken = 'token'; - -function encodePeerMessage(peerMessage: object) { - const encodedAsNodeBuffer = PeerMessage.encode(peerMessage).finish(); - - const newBuffer = new ArrayBuffer(encodedAsNodeBuffer.byteLength); - const newBufferView = new Uint8Array(newBuffer); - newBufferView.set(encodedAsNodeBuffer, 0); - - return newBuffer; -} - -describe('FishjamClient', () => { - afterEach(() => { - WS.clean(); - }); - - const setUpAndConnect = async () => { - const server = new WS(socketUrl); - - const { result } = renderHook(() => useFishjamClient(), { - wrapper: FishjamContextProvider, - }); - - const connectPromise = result.current.connect(socketUrl, peerToken); - - await server.connected; - - const msg = await server.nextMessage; - - expect(msg).toEqual( - PeerMessage.encode({ - authRequest: { token: peerToken }, - }).finish(), - ); - - server.send( - encodePeerMessage({ - authenticated: true, - }), - ); - - await connectPromise; - - return { server, result }; - }; - - it('connects and resolves', async () => { - await setUpAndConnect(); - }); - - it('rejects if socket error', async () => { - const server = new WS(socketUrl); - - const { - result: { - current: { connect }, - }, - } = renderHook(() => useFishjamClient(), { - wrapper: FishjamContextProvider, - }); - - const connectPromise = connect(socketUrl, peerToken); - - act(() => { - server.error({ code: 1234, reason: 'An error', wasClean: false }); - }); - - await expect(connectPromise).rejects.toThrow( - new Error('WebSocket was closed: 1234 An error'), - ); - }); - - it('returns error if it happens after a connection is established', async () => { - const { server /*, result*/ } = await setUpAndConnect(); - act(() => { - server.error({ code: 3000, reason: 'An error', wasClean: false }); - }); - // TODO: improve error handling - // expect(result.current.error).toEqual('WebSocket was closed: 3000 An error'); - }); - - it('sends media event', async () => { - const { server } = await setUpAndConnect(); - - sendEvent?.({ event: 'join' }); - - const msg = await server.nextMessage; - - expect(msg).toEqual( - PeerMessage.encode({ - mediaEvent: { data: 'join' }, - }).finish(), - ); - }); - - it('receives media event', async () => { - const { server } = await setUpAndConnect(); - - server.send( - encodePeerMessage({ - mediaEvent: { - data: 'sdpOffer', - }, - }), - ); - - expect( - requireNativeModule('MembraneWebRTC').receiveMediaEvent, - ).toBeCalledTimes(1); - expect( - requireNativeModule('MembraneWebRTC').receiveMediaEvent, - ).toHaveBeenCalledWith('sdpOffer'); - }); -}); diff --git a/src/common/client.ts b/src/common/client.ts new file mode 100644 index 00000000..950a2f1d --- /dev/null +++ b/src/common/client.ts @@ -0,0 +1,18 @@ +import { Metadata } from '../MembraneWebRTC.types'; +import MembraneWebRTCModule from '../MembraneWebRTCModule'; + +export const connect = (url: string, peerToken: string) => { + return MembraneWebRTCModule.connect(url, peerToken); +}; + +export const joinRoom = (peerMetadata: Metadata) => { + return MembraneWebRTCModule.joinRoom(peerMetadata); +}; + +export const leaveRoom = () => { + return MembraneWebRTCModule.leaveRoom(); +}; + +export const cleanUp = () => { + return MembraneWebRTCModule.cleanUp(); +}; diff --git a/src/index.tsx b/src/index.tsx index 55f13e13..9ddeab19 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -19,11 +19,11 @@ export { changeWebRTCLoggingSeverity, setTargetTrackEncoding, } from './common/webRTC'; +export * from './common/client'; export { default as VideoPreviewView } from './VideoPreviewView'; export { default as VideoRendererView } from './VideoRendererView'; export * from './MembraneWebRTC.types'; -export * from './FishjamClientContext'; // below are aliases used by 'old' rn-client-sdk. They should be removed export type Peer< From 27d2b2febceae19c028119e8ee590be581cde534 Mon Sep 17 00:00:00 2001 From: Angelika Serwa Date: Thu, 20 Jun 2024 00:24:16 +0200 Subject: [PATCH 2/3] Rename membrane webrtc -> fishjam client --- .../{MembraneWebRTC.kt => RNFishjamClient.kt} | 6 +- ...bRTCModule.kt => RNFishjamClientModule.kt} | 82 ++++----- .../reactnative/VideoRendererView.kt | 10 +- .../FishjamExample.xcodeproj/project.pbxproj | 160 +++++++++--------- expo-module.config.json | 4 +- ...raneWebRTC.swift => RNFishjamClient.swift} | 2 +- ...dule.swift => RNFishjamClientModule.swift} | 76 ++++----- ...bRTC.types.ts => RNFishjamClient.types.ts} | 2 +- ...bRTCModule.ts => RNFishjamClientModule.ts} | 6 +- src/VideoPreviewView.tsx | 2 +- src/VideoRendererView.tsx | 2 +- src/common/client.ts | 12 +- src/common/eventEmitter.ts | 4 +- src/common/metadata.ts | 10 +- src/common/webRTC.ts | 8 +- src/hooks/useAudioSettings.ts | 14 +- src/hooks/useBandwidthEstimation.ts | 2 +- src/hooks/useCamera.ts | 26 +-- src/hooks/useEndpoints.ts | 6 +- src/hooks/useMicrophone.ts | 12 +- src/hooks/useRTCStatistics.ts | 6 +- src/hooks/useScreencast.ts | 18 +- src/index.tsx | 4 +- 23 files changed, 235 insertions(+), 239 deletions(-) rename android/src/main/java/org/membraneframework/reactnative/{MembraneWebRTC.kt => RNFishjamClient.kt} (99%) rename android/src/main/java/org/membraneframework/reactnative/{MembraneWebRTCModule.kt => RNFishjamClientModule.kt} (72%) rename ios/{MembraneWebRTC.swift => RNFishjamClient.swift} (99%) rename ios/{MembraneWebRTCModule.swift => RNFishjamClientModule.swift} (62%) rename src/{MembraneWebRTC.types.ts => RNFishjamClient.types.ts} (99%) rename src/{MembraneWebRTCModule.ts => RNFishjamClientModule.ts} (60%) diff --git a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTC.kt b/android/src/main/java/org/membraneframework/reactnative/RNFishjamClient.kt similarity index 99% rename from android/src/main/java/org/membraneframework/reactnative/MembraneWebRTC.kt rename to android/src/main/java/org/membraneframework/reactnative/RNFishjamClient.kt index 89dd6bda..89fe9700 100644 --- a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTC.kt +++ b/android/src/main/java/org/membraneframework/reactnative/RNFishjamClient.kt @@ -34,7 +34,7 @@ import org.membraneframework.rtc.utils.Metadata import org.webrtc.Logging import java.util.UUID -class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> Unit) : +class RNFishjamClient(val sendEvent: (name: String, data: Map) -> Unit) : FishjamClientListener { private val SCREENCAST_REQUEST = 1 private var fishjamClient: FishjamClient? = null @@ -80,7 +80,7 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U var onTracksUpdateListeners: MutableList = mutableListOf() } - fun onModuleCreate(appContext: AppContext){ + fun onModuleCreate(appContext: AppContext) { this.appContext = appContext this.audioSwitchManager = AudioSwitchManager(appContext.reactContext!!) } @@ -855,6 +855,4 @@ class MembraneWebRTC(val sendEvent: (name: String, data: Map) -> U } override fun onDisconnected() {} - - } diff --git a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTCModule.kt b/android/src/main/java/org/membraneframework/reactnative/RNFishjamClientModule.kt similarity index 72% rename from android/src/main/java/org/membraneframework/reactnative/MembraneWebRTCModule.kt rename to android/src/main/java/org/membraneframework/reactnative/RNFishjamClientModule.kt index 2410ae19..51652467 100644 --- a/android/src/main/java/org/membraneframework/reactnative/MembraneWebRTCModule.kt +++ b/android/src/main/java/org/membraneframework/reactnative/RNFishjamClientModule.kt @@ -71,9 +71,9 @@ class ScreencastOptions : Record { val maxBandwidthInt: Int = 0 } -class MembraneWebRTCModule : Module() { +class RNFishjamClientModule : Module() { override fun definition() = ModuleDefinition { - Name("MembraneWebRTC") + Name("RNFishjamClient") Events( "IsCameraOn", @@ -86,204 +86,204 @@ class MembraneWebRTCModule : Module() { "BandwidthEstimation" ) - val membraneWebRTC = MembraneWebRTC { name: String, data: Map -> + val rnFishjamClient = RNFishjamClient { name: String, data: Map -> sendEvent(name, data) } OnCreate { - membraneWebRTC.onModuleCreate(appContext) + rnFishjamClient.onModuleCreate(appContext) } OnDestroy { - membraneWebRTC.onModuleDestroy() + rnFishjamClient.onModuleDestroy() } OnActivityDestroys { - membraneWebRTC.cleanUp() + rnFishjamClient.cleanUp() } OnActivityResult { _, result -> - membraneWebRTC.onActivityResult(result.requestCode, result.resultCode, result.data) + rnFishjamClient.onActivityResult(result.requestCode, result.resultCode, result.data) } AsyncFunction("connect") { url: String, peerToken: String, promise: Promise -> CoroutineScope(Dispatchers.Main).launch { - membraneWebRTC.create() - membraneWebRTC.connect(url, peerToken, promise) + rnFishjamClient.create() + rnFishjamClient.connect(url, peerToken, promise) } } AsyncFunction("joinRoom") { peerMetadata: Map, promise: Promise -> CoroutineScope(Dispatchers.Main).launch { - membraneWebRTC.joinRoom(peerMetadata, promise) + rnFishjamClient.joinRoom(peerMetadata, promise) } } - AsyncFunction("leaveRoom") { -> + AsyncFunction("leaveRoom") { -> CoroutineScope(Dispatchers.Main).launch { - membraneWebRTC.leaveRoom() + rnFishjamClient.leaveRoom() } } AsyncFunction("cleanUp") Coroutine { -> withContext(Dispatchers.Main) { - membraneWebRTC.cleanUp() + rnFishjamClient.cleanUp() } } AsyncFunction("startCamera") Coroutine { config: CameraConfig -> withContext(Dispatchers.Main) { - membraneWebRTC.startCamera(config) + rnFishjamClient.startCamera(config) } } AsyncFunction("startMicrophone") Coroutine { config: MicrophoneConfig -> withContext(Dispatchers.Main) { - membraneWebRTC.startMicrophone(config) + rnFishjamClient.startMicrophone(config) } } Property("isMicrophoneOn") { - return@Property membraneWebRTC.isMicrophoneOn + return@Property rnFishjamClient.isMicrophoneOn } AsyncFunction("toggleMicrophone") Coroutine { -> withContext(Dispatchers.Main) { - membraneWebRTC.toggleMicrophone() + rnFishjamClient.toggleMicrophone() } } Property("isCameraOn") { - return@Property membraneWebRTC.isCameraOn + return@Property rnFishjamClient.isCameraOn } AsyncFunction("toggleCamera") Coroutine { -> withContext(Dispatchers.Main) { - membraneWebRTC.toggleCamera() + rnFishjamClient.toggleCamera() } } AsyncFunction("flipCamera") Coroutine { -> withContext(Dispatchers.Main) { - membraneWebRTC.flipCamera() + rnFishjamClient.flipCamera() } } AsyncFunction("switchCamera") Coroutine { captureDeviceId: String -> withContext(Dispatchers.Main) { - membraneWebRTC.switchCamera(captureDeviceId) + rnFishjamClient.switchCamera(captureDeviceId) } } AsyncFunction("getCaptureDevices") Coroutine { -> withContext(Dispatchers.Main) { - membraneWebRTC.getCaptureDevices() + rnFishjamClient.getCaptureDevices() } } AsyncFunction("toggleScreencast") { screencastOptions: ScreencastOptions, promise: Promise -> CoroutineScope(Dispatchers.Main).launch { - membraneWebRTC.toggleScreencast(screencastOptions, promise) + rnFishjamClient.toggleScreencast(screencastOptions, promise) } } Property("isScreencastOn") { - return@Property membraneWebRTC.isScreencastOn + return@Property rnFishjamClient.isScreencastOn } AsyncFunction("getEndpoints") Coroutine { -> withContext(Dispatchers.Main) { - membraneWebRTC.getEndpoints() + rnFishjamClient.getEndpoints() } } AsyncFunction("updateEndpointMetadata") Coroutine { metadata: Map -> withContext(Dispatchers.Main) { - membraneWebRTC.updateEndpointMetadata(metadata) + rnFishjamClient.updateEndpointMetadata(metadata) } } AsyncFunction("updateVideoTrackMetadata") Coroutine { metadata: Map -> withContext(Dispatchers.Main) { - membraneWebRTC.updateLocalVideoTrackMetadata(metadata) + rnFishjamClient.updateLocalVideoTrackMetadata(metadata) } } AsyncFunction("updateAudioTrackMetadata") Coroutine { metadata: Map -> withContext(Dispatchers.Main) { - membraneWebRTC.updateLocalAudioTrackMetadata(metadata) + rnFishjamClient.updateLocalAudioTrackMetadata(metadata) } } AsyncFunction("updateScreencastTrackMetadata") Coroutine { metadata: Map -> withContext(Dispatchers.Main) { - membraneWebRTC.updateLocalScreencastTrackMetadata(metadata) + rnFishjamClient.updateLocalScreencastTrackMetadata(metadata) } } AsyncFunction("setOutputAudioDevice") { audioDevice: String -> - membraneWebRTC.setOutputAudioDevice(audioDevice) + rnFishjamClient.setOutputAudioDevice(audioDevice) } AsyncFunction("startAudioSwitcher") { - membraneWebRTC.startAudioSwitcher() + rnFishjamClient.startAudioSwitcher() } AsyncFunction("stopAudioSwitcher") { - membraneWebRTC.stopAudioSwitcher() + rnFishjamClient.stopAudioSwitcher() } AsyncFunction("toggleScreencastTrackEncoding") Coroutine { encoding: String -> withContext(Dispatchers.Main) { - membraneWebRTC.toggleScreencastTrackEncoding(encoding) + rnFishjamClient.toggleScreencastTrackEncoding(encoding) } } AsyncFunction("setScreencastTrackBandwidth") Coroutine { bandwidth: Int -> withContext(Dispatchers.Main) { - membraneWebRTC.setScreencastTrackBandwidth(bandwidth) + rnFishjamClient.setScreencastTrackBandwidth(bandwidth) } } AsyncFunction("setScreencastTrackEncodingBandwidth") Coroutine { encoding: String, bandwidth: Int -> withContext(Dispatchers.Main) { - membraneWebRTC.setScreencastTrackEncodingBandwidth(encoding, bandwidth) + rnFishjamClient.setScreencastTrackEncodingBandwidth(encoding, bandwidth) } } AsyncFunction("setTargetTrackEncoding") Coroutine { trackId: String, encoding: String -> withContext(Dispatchers.Main) { - membraneWebRTC.setTargetTrackEncoding(trackId, encoding) + rnFishjamClient.setTargetTrackEncoding(trackId, encoding) } } AsyncFunction("toggleVideoTrackEncoding") Coroutine { encoding: String -> withContext(Dispatchers.Main) { - membraneWebRTC.toggleVideoTrackEncoding(encoding) + rnFishjamClient.toggleVideoTrackEncoding(encoding) } } AsyncFunction("setVideoTrackEncodingBandwidth") Coroutine { encoding: String, bandwidth: Int -> withContext(Dispatchers.Main) { - membraneWebRTC.setVideoTrackEncodingBandwidth(encoding, bandwidth) + rnFishjamClient.setVideoTrackEncodingBandwidth(encoding, bandwidth) } } AsyncFunction("setVideoTrackBandwidth") Coroutine { bandwidth: Int -> withContext(Dispatchers.Main) { - membraneWebRTC.setVideoTrackBandwidth(bandwidth) + rnFishjamClient.setVideoTrackBandwidth(bandwidth) } } AsyncFunction("changeWebRTCLoggingSeverity") Coroutine { severity: String -> CoroutineScope(Dispatchers.Main).launch { - membraneWebRTC.changeWebRTCLoggingSeverity(severity) + rnFishjamClient.changeWebRTCLoggingSeverity(severity) } } AsyncFunction("getStatistics") { -> - membraneWebRTC.getStatistics() + rnFishjamClient.getStatistics() } } } diff --git a/android/src/main/java/org/membraneframework/reactnative/VideoRendererView.kt b/android/src/main/java/org/membraneframework/reactnative/VideoRendererView.kt index c653f4a8..0406145b 100644 --- a/android/src/main/java/org/membraneframework/reactnative/VideoRendererView.kt +++ b/android/src/main/java/org/membraneframework/reactnative/VideoRendererView.kt @@ -11,14 +11,14 @@ import org.membraneframework.rtc.ui.VideoTextureViewRenderer import org.webrtc.RendererCommon class VideoRendererView(context: Context, appContext: AppContext) : ExpoView(context, appContext), - MembraneWebRTC.OnTrackUpdateListener { + RNFishjamClient.OnTrackUpdateListener { var isInitialized = false var activeVideoTrack: VideoTrack? = null var trackId: String? = null private val videoView = VideoTextureViewRenderer(context).also { addView(it) - MembraneWebRTC.onTracksUpdateListeners.add(this) + RNFishjamClient.onTracksUpdateListeners.add(this) } private fun setupTrack(videoTrack: VideoTrack) { @@ -31,7 +31,7 @@ class VideoRendererView(context: Context, appContext: AppContext) : ExpoView(con private fun update() { CoroutineScope(Dispatchers.Main).launch { - val endpoint = MembraneWebRTC.endpoints.values.firstOrNull { it.videoTracks[trackId] != null } + val endpoint = RNFishjamClient.endpoints.values.firstOrNull { it.videoTracks[trackId] != null } val videoTrack = endpoint?.videoTracks?.get(trackId) ?: return@launch if(!isInitialized) { isInitialized = true @@ -49,7 +49,7 @@ class VideoRendererView(context: Context, appContext: AppContext) : ExpoView(con fun dispose() { activeVideoTrack?.removeRenderer(videoView) videoView.release() - MembraneWebRTC.onTracksUpdateListeners.remove(this) + RNFishjamClient.onTracksUpdateListeners.remove(this) } override fun onTracksUpdate() { @@ -70,4 +70,4 @@ class VideoRendererView(context: Context, appContext: AppContext) : ExpoView(con videoView.setMirror(mirrorVideo) } -} \ No newline at end of file +} diff --git a/example/ios/FishjamExample.xcodeproj/project.pbxproj b/example/ios/FishjamExample.xcodeproj/project.pbxproj index 922b9a22..f86e2306 100644 --- a/example/ios/FishjamExample.xcodeproj/project.pbxproj +++ b/example/ios/FishjamExample.xcodeproj/project.pbxproj @@ -11,15 +11,15 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 52D75531E85EB473D2428C5F /* libPods-FishjamExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 346A0E12933FC858CE94205E /* libPods-FishjamExample.a */; }; - 8030B691EDEA2170614263F6 /* libPods-ScreenBroadcast.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8721169503B33E647FF504AF /* libPods-ScreenBroadcast.a */; }; + 4260C286C2219F7CAB85F71A /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 166D5E981A645A2FC9DB0D48 /* libPods-FishjamExample-FishjamExampleTests.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + 8A346C17648758BE51A3CE79 /* libPods-ScreenBroadcast.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A31B95120FA559AFAE2CC6C8 /* libPods-ScreenBroadcast.a */; }; A4AE54082454256BB1348002 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6486D552DE55BE12979D457F /* ExpoModulesProvider.swift */; }; C36C387544222DE51F95C8C8 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96822F1E4B772E6913DCDDDB /* ExpoModulesProvider.swift */; }; D2D7AC482B0BA9380029C1D6 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D249AAD22B06724C0053962E /* ReplayKit.framework */; }; D2D7AC4B2B0BA9390029C1D6 /* ScreenBroadcast.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D7AC4A2B0BA9390029C1D6 /* ScreenBroadcast.swift */; }; D2D7AC4F2B0BA9390029C1D6 /* ScreenBroadcast.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D2D7AC472B0BA9380029C1D6 /* ScreenBroadcast.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - E97D9B616B89C39F04DF3929 /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B7998A241CE6D040FFE45634 /* libPods-FishjamExample-FishjamExampleTests.a */; }; + DE4A099F11649A8C173A4969 /* libPods-FishjamExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F817DCE5EE483A5BB654E22A /* libPods-FishjamExample.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -57,24 +57,23 @@ 00E356EE1AD99517003FC87E /* FishjamExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FishjamExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* FishjamExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FishjamExampleTests.m; sourceTree = ""; }; - 022BEA2C30E36AAA56B468E7 /* Pods-ScreenBroadcast.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.release.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.release.xcconfig"; sourceTree = ""; }; + 042756EB89E770B917E5A8FE /* Pods-FishjamExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.debug.xcconfig"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* FishjamExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FishjamExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = FishjamExample/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = FishjamExample/AppDelegate.mm; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = FishjamExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = FishjamExample/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = FishjamExample/main.m; sourceTree = ""; }; - 346A0E12933FC858CE94205E /* libPods-FishjamExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 52441C999465B5CE22B7FCDE /* Pods-FishjamExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.debug.xcconfig"; sourceTree = ""; }; + 166D5E981A645A2FC9DB0D48 /* libPods-FishjamExample-FishjamExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample-FishjamExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 3D78678BC8D65B9B4260B18C /* Pods-ScreenBroadcast.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.release.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.release.xcconfig"; sourceTree = ""; }; + 42875828FE3022D0A15ABD3A /* Pods-ScreenBroadcast.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.debug.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.debug.xcconfig"; sourceTree = ""; }; 6486D552DE55BE12979D457F /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-FishjamExample/ExpoModulesProvider.swift"; sourceTree = ""; }; - 68EE46E3072DB8A787CD8035 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = FishjamExample/LaunchScreen.storyboard; sourceTree = ""; }; - 8721169503B33E647FF504AF /* libPods-ScreenBroadcast.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScreenBroadcast.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 96822F1E4B772E6913DCDDDB /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-FishjamExample-FishjamExampleTests/ExpoModulesProvider.swift"; sourceTree = ""; }; - 9E1769BCCB84DDDEC053EB27 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; sourceTree = ""; }; - A1C5753310FDDC6F2A62B0CA /* Pods-FishjamExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.release.xcconfig"; sourceTree = ""; }; - B7998A241CE6D040FFE45634 /* libPods-FishjamExample-FishjamExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample-FishjamExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - CF7DBBB233EC29A31E7B4847 /* Pods-ScreenBroadcast.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreenBroadcast.debug.xcconfig"; path = "Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast.debug.xcconfig"; sourceTree = ""; }; + A31B95120FA559AFAE2CC6C8 /* libPods-ScreenBroadcast.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScreenBroadcast.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + BD1B88771F61C05C20E8AD42 /* Pods-FishjamExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample/Pods-FishjamExample.release.xcconfig"; sourceTree = ""; }; + C38E472A6FF76019ACADAE3F /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.debug.xcconfig"; sourceTree = ""; }; + C73BA7D7393EA2E70440D1CF /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; path = "Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests.release.xcconfig"; sourceTree = ""; }; D249AAD22B06724C0053962E /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; }; D249AADF2B0672950053962E /* FishjamExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = FishjamExample.entitlements; path = FishjamExample/FishjamExample.entitlements; sourceTree = ""; }; D2D7AC472B0BA9380029C1D6 /* ScreenBroadcast.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ScreenBroadcast.appex; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -82,6 +81,7 @@ D2D7AC4C2B0BA9390029C1D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D2D7AC532B0BA98B0029C1D6 /* ScreenBroadcast.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ScreenBroadcast.entitlements; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + F817DCE5EE483A5BB654E22A /* libPods-FishjamExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FishjamExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -89,7 +89,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E97D9B616B89C39F04DF3929 /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */, + 4260C286C2219F7CAB85F71A /* libPods-FishjamExample-FishjamExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -97,7 +97,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 52D75531E85EB473D2428C5F /* libPods-FishjamExample.a in Frameworks */, + DE4A099F11649A8C173A4969 /* libPods-FishjamExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -106,7 +106,7 @@ buildActionMask = 2147483647; files = ( D2D7AC482B0BA9380029C1D6 /* ReplayKit.framework in Frameworks */, - 8030B691EDEA2170614263F6 /* libPods-ScreenBroadcast.a in Frameworks */, + 8A346C17648758BE51A3CE79 /* libPods-ScreenBroadcast.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -149,9 +149,9 @@ children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, D249AAD22B06724C0053962E /* ReplayKit.framework */, - 346A0E12933FC858CE94205E /* libPods-FishjamExample.a */, - B7998A241CE6D040FFE45634 /* libPods-FishjamExample-FishjamExampleTests.a */, - 8721169503B33E647FF504AF /* libPods-ScreenBroadcast.a */, + F817DCE5EE483A5BB654E22A /* libPods-FishjamExample.a */, + 166D5E981A645A2FC9DB0D48 /* libPods-FishjamExample-FishjamExampleTests.a */, + A31B95120FA559AFAE2CC6C8 /* libPods-ScreenBroadcast.a */, ); name = Frameworks; sourceTree = ""; @@ -210,12 +210,12 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - 52441C999465B5CE22B7FCDE /* Pods-FishjamExample.debug.xcconfig */, - A1C5753310FDDC6F2A62B0CA /* Pods-FishjamExample.release.xcconfig */, - 9E1769BCCB84DDDEC053EB27 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */, - 68EE46E3072DB8A787CD8035 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */, - CF7DBBB233EC29A31E7B4847 /* Pods-ScreenBroadcast.debug.xcconfig */, - 022BEA2C30E36AAA56B468E7 /* Pods-ScreenBroadcast.release.xcconfig */, + 042756EB89E770B917E5A8FE /* Pods-FishjamExample.debug.xcconfig */, + BD1B88771F61C05C20E8AD42 /* Pods-FishjamExample.release.xcconfig */, + C38E472A6FF76019ACADAE3F /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */, + C73BA7D7393EA2E70440D1CF /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */, + 42875828FE3022D0A15ABD3A /* Pods-ScreenBroadcast.debug.xcconfig */, + 3D78678BC8D65B9B4260B18C /* Pods-ScreenBroadcast.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -245,13 +245,13 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "FishjamExampleTests" */; buildPhases = ( - 530F8EAF2628D2940B7AEE36 /* [CP] Check Pods Manifest.lock */, + 8B3850633EB4340F052A15C7 /* [CP] Check Pods Manifest.lock */, EC302C2D573892907E91A28D /* [Expo] Configure project */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - 9559F1A9AAEF870E60A6D055 /* [CP] Embed Pods Frameworks */, - 6C2C22BEF743DBDD9D633ED8 /* [CP] Copy Pods Resources */, + 0351D24E9D87522099DE113A /* [CP] Embed Pods Frameworks */, + E55918CECB9F9E288584B84F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -267,7 +267,7 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "FishjamExample" */; buildPhases = ( - 0D3E62BC0B095146C437D6BA /* [CP] Check Pods Manifest.lock */, + B334397D39CA46826D3B6851 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 2C2C21F5B052BD7681B67CFD /* [Expo] Configure project */, 13B07F871A680F5B00A75B9A /* Sources */, @@ -275,8 +275,8 @@ 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, D249AADB2B06724D0053962E /* Embed Foundation Extensions */, - 96637B25966F8B9A3BAE5CD8 /* [CP] Embed Pods Frameworks */, - 0436BB40ABFCEE65CFA7D833 /* [CP] Copy Pods Resources */, + A2BC8692534C8F3B4A61DABF /* [CP] Embed Pods Frameworks */, + C107685779D80C5C65302600 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -292,11 +292,11 @@ isa = PBXNativeTarget; buildConfigurationList = D2D7AC502B0BA9390029C1D6 /* Build configuration list for PBXNativeTarget "ScreenBroadcast" */; buildPhases = ( - 22021E26669B6ABB77577E1F /* [CP] Check Pods Manifest.lock */, + AAACE72C22B963E0998B18BF /* [CP] Check Pods Manifest.lock */, D2D7AC432B0BA9380029C1D6 /* Sources */, D2D7AC442B0BA9380029C1D6 /* Frameworks */, D2D7AC452B0BA9380029C1D6 /* Resources */, - BA28A958809C756716EFF9B5 /* [CP] Copy Pods Resources */, + AFD92517E0A08AD7FE83B1FE /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -391,46 +391,43 @@ shellPath = /bin/sh; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; - 0436BB40ABFCEE65CFA7D833 /* [CP] Copy Pods Resources */ = { + 0351D24E9D87522099DE113A /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 0D3E62BC0B095146C437D6BA /* [CP] Check Pods Manifest.lock */ = { + 2C2C21F5B052BD7681B67CFD /* [Expo] Configure project */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Check Pods Manifest.lock"; + name = "[Expo] Configure project"; outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-FishjamExample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-FishjamExample/expo-configure-project.sh\"\n"; }; - 22021E26669B6ABB77577E1F /* [CP] Check Pods Manifest.lock */ = { + 8B3850633EB4340F052A15C7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -445,33 +442,31 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ScreenBroadcast-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-FishjamExample-FishjamExampleTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 2C2C21F5B052BD7681B67CFD /* [Expo] Configure project */ = { + A2BC8692534C8F3B4A61DABF /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); - name = "[Expo] Configure project"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-FishjamExample/expo-configure-project.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; - 530F8EAF2628D2940B7AEE36 /* [CP] Check Pods Manifest.lock */ = { + AAACE72C22B963E0998B18BF /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -486,79 +481,84 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-FishjamExample-FishjamExampleTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-ScreenBroadcast-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 6C2C22BEF743DBDD9D633ED8 /* [CP] Copy Pods Resources */ = { + AFD92517E0A08AD7FE83B1FE /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 9559F1A9AAEF870E60A6D055 /* [CP] Embed Pods Frameworks */ = { + B334397D39CA46826D3B6851 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-FishjamExample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 96637B25966F8B9A3BAE5CD8 /* [CP] Embed Pods Frameworks */ = { + C107685779D80C5C65302600 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample/Pods-FishjamExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - BA28A958809C756716EFF9B5 /* [CP] Copy Pods Resources */ = { + E55918CECB9F9E288584B84F /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ScreenBroadcast/Pods-ScreenBroadcast-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FishjamExample-FishjamExampleTests/Pods-FishjamExample-FishjamExampleTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; EC302C2D573892907E91A28D /* [Expo] Configure project */ = { @@ -647,7 +647,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9E1769BCCB84DDDEC053EB27 /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */; + baseConfigurationReference = C38E472A6FF76019ACADAE3F /* Pods-FishjamExample-FishjamExampleTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -675,7 +675,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 68EE46E3072DB8A787CD8035 /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */; + baseConfigurationReference = C73BA7D7393EA2E70440D1CF /* Pods-FishjamExample-FishjamExampleTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -700,7 +700,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 52441C999465B5CE22B7FCDE /* Pods-FishjamExample.debug.xcconfig */; + baseConfigurationReference = 042756EB89E770B917E5A8FE /* Pods-FishjamExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -736,7 +736,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A1C5753310FDDC6F2A62B0CA /* Pods-FishjamExample.release.xcconfig */; + baseConfigurationReference = BD1B88771F61C05C20E8AD42 /* Pods-FishjamExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -918,7 +918,7 @@ }; D2D7AC512B0BA9390029C1D6 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CF7DBBB233EC29A31E7B4847 /* Pods-ScreenBroadcast.debug.xcconfig */; + baseConfigurationReference = 42875828FE3022D0A15ABD3A /* Pods-ScreenBroadcast.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; @@ -962,7 +962,7 @@ }; D2D7AC522B0BA9390029C1D6 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 022BEA2C30E36AAA56B468E7 /* Pods-ScreenBroadcast.release.xcconfig */; + baseConfigurationReference = 3D78678BC8D65B9B4260B18C /* Pods-ScreenBroadcast.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; diff --git a/expo-module.config.json b/expo-module.config.json index c3763dec..3db746c4 100644 --- a/expo-module.config.json +++ b/expo-module.config.json @@ -2,14 +2,14 @@ "platforms": ["ios", "android", "web"], "ios": { "modules": [ - "MembraneWebRTCModule", + "RNFishjamClientModule", "VideoPreviewViewModule", "VideoRendererViewModule" ] }, "android": { "modules": [ - "org.membraneframework.reactnative.MembraneWebRTCModule", + "org.membraneframework.reactnative.RNFishjamClientModule", "org.membraneframework.reactnative.VideoPreviewViewModule", "org.membraneframework.reactnative.VideoRendererViewModule" ] diff --git a/ios/MembraneWebRTC.swift b/ios/RNFishjamClient.swift similarity index 99% rename from ios/MembraneWebRTC.swift rename to ios/RNFishjamClient.swift index 70b3bdb1..6675b453 100644 --- a/ios/MembraneWebRTC.swift +++ b/ios/RNFishjamClient.swift @@ -63,7 +63,7 @@ extension String { } } -class MembraneWebRTC: FishjamClientListener { +class RNFishjamClient: FishjamClientListener { var fishjamClient: FishjamClient? = nil var localAudioTrack: LocalAudioTrack? diff --git a/ios/MembraneWebRTCModule.swift b/ios/RNFishjamClientModule.swift similarity index 62% rename from ios/MembraneWebRTCModule.swift rename to ios/RNFishjamClientModule.swift index 29d6c332..42f04a2a 100644 --- a/ios/MembraneWebRTCModule.swift +++ b/ios/RNFishjamClientModule.swift @@ -55,9 +55,9 @@ struct ScreencastOptions: Record { typealias RNTrackBandwidthLimit = Either -public class MembraneWebRTCModule: Module { +public class RNFishjamClientModule: Module { public func definition() -> ModuleDefinition { - Name("MembraneWebRTC") + Name("RNFishjamClient") Events( "IsCameraOn", @@ -69,141 +69,137 @@ public class MembraneWebRTCModule: Module { "SendMediaEvent", "BandwidthEstimation") - let membraneWebRTC: MembraneWebRTC = MembraneWebRTC { (eventName: String, data: [String: Any]) in + let rnFishjamClient: RNFishjamClient = RNFishjamClient { (eventName: String, data: [String: Any]) in self.sendEvent(eventName, data) } - AsyncFunction("create") { - - } - AsyncFunction("connect") { (url: String, peerToken: String, promise: Promise ) in - try membraneWebRTC.create() - membraneWebRTC.connect(url: url, peerToken: peerToken, promise: promise) + try rnFishjamClient.create() + rnFishjamClient.connect(url: url, peerToken: peerToken, promise: promise) } AsyncFunction("joinRoom") { (peerMetadata: [String: Any], promise: Promise ) in - membraneWebRTC.joinRoom(peerMetadata: peerMetadata, promise: promise) + rnFishjamClient.joinRoom(peerMetadata: peerMetadata, promise: promise) } AsyncFunction("leaveRoom") { - membraneWebRTC.leaveRoom() + rnFishjamClient.leaveRoom() } AsyncFunction("cleanUp") { - membraneWebRTC.cleanUp() + rnFishjamClient.cleanUp() } AsyncFunction("startCamera") { (config: CameraConfig) in - try membraneWebRTC.startCamera(config: config) + try rnFishjamClient.startCamera(config: config) } AsyncFunction("startMicrophone") { (config: MicrophoneConfig) in - try membraneWebRTC.startMicrophone(config: config) + try rnFishjamClient.startMicrophone(config: config) } Property("isMicrophoneOn") { - return membraneWebRTC.isMicEnabled + return rnFishjamClient.isMicEnabled } AsyncFunction("toggleMicrophone") { - try membraneWebRTC.toggleMicrophone() + try rnFishjamClient.toggleMicrophone() } Property("isCameraOn") { - return membraneWebRTC.isCameraEnabled + return rnFishjamClient.isCameraEnabled } AsyncFunction("toggleCamera") { - try membraneWebRTC.toggleCamera() + try rnFishjamClient.toggleCamera() } AsyncFunction("flipCamera") { - try membraneWebRTC.flipCamera() + try rnFishjamClient.flipCamera() } AsyncFunction("switchCamera") { (captureDeviceId: String) in - try membraneWebRTC.switchCamera(captureDeviceId: captureDeviceId) + try rnFishjamClient.switchCamera(captureDeviceId: captureDeviceId) } AsyncFunction("getCaptureDevices") { - membraneWebRTC.getCaptureDevices() + rnFishjamClient.getCaptureDevices() } AsyncFunction("toggleScreencast") { (screencastOptions: ScreencastOptions) in - try membraneWebRTC.toggleScreencast(screencastOptions: screencastOptions) + try rnFishjamClient.toggleScreencast(screencastOptions: screencastOptions) } Property("isScreencastOn") { - return membraneWebRTC.isScreensharingEnabled + return rnFishjamClient.isScreensharingEnabled } AsyncFunction("getEndpoints") { - membraneWebRTC.getEndpoints() + rnFishjamClient.getEndpoints() } AsyncFunction("updateEndpointMetadata") { (metadata: [String: Any]) in - try membraneWebRTC.updateEndpointMetadata(metadata: metadata) + try rnFishjamClient.updateEndpointMetadata(metadata: metadata) } AsyncFunction("updateVideoTrackMetadata") { (metadata: [String: Any]) in - try membraneWebRTC.updateVideoTrackMetadata(metadata: metadata) + try rnFishjamClient.updateVideoTrackMetadata(metadata: metadata) } AsyncFunction("updateAudioTrackMetadata") { (metadata: [String: Any]) in - try membraneWebRTC.updateAudioTrackMetadata(metadata: metadata) + try rnFishjamClient.updateAudioTrackMetadata(metadata: metadata) } AsyncFunction("updateScreencastTrackMetadata") { (metadata: [String: Any]) in - try membraneWebRTC.updateScreencastTrackMetadata(metadata: metadata) + try rnFishjamClient.updateScreencastTrackMetadata(metadata: metadata) } AsyncFunction("toggleScreencastTrackEncoding") { (encoding: String) in - try membraneWebRTC.toggleScreencastTrackEncoding(encoding: encoding) + try rnFishjamClient.toggleScreencastTrackEncoding(encoding: encoding) } AsyncFunction("setScreencastTrackBandwidth") { (bandwidth: Int) in - try membraneWebRTC.setScreencastTrackBandwidth(bandwidth: bandwidth) + try rnFishjamClient.setScreencastTrackBandwidth(bandwidth: bandwidth) } AsyncFunction("setScreencastTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in - try membraneWebRTC.setScreencastTrackEncodingBandwidth(encoding: encoding, bandwidth: bandwidth) + try rnFishjamClient.setScreencastTrackEncodingBandwidth(encoding: encoding, bandwidth: bandwidth) } AsyncFunction("setTargetTrackEncoding") { (trackId: String, encoding: String) in - try membraneWebRTC.setTargetTrackEncoding(trackId: trackId, encoding: encoding) + try rnFishjamClient.setTargetTrackEncoding(trackId: trackId, encoding: encoding) } AsyncFunction("toggleVideoTrackEncoding") { (encoding: String) in - try membraneWebRTC.toggleVideoTrackEncoding(encoding: encoding) + try rnFishjamClient.toggleVideoTrackEncoding(encoding: encoding) } AsyncFunction("setVideoTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in - try membraneWebRTC.setVideoTrackEncodingBandwidth(encoding: encoding, bandwidth: bandwidth) + try rnFishjamClient.setVideoTrackEncodingBandwidth(encoding: encoding, bandwidth: bandwidth) } AsyncFunction("setVideoTrackBandwidth") { (bandwidth: Int) in - try membraneWebRTC.setVideoTrackBandwidth(bandwidth: bandwidth) + try rnFishjamClient.setVideoTrackBandwidth(bandwidth: bandwidth) } AsyncFunction("changeWebRTCLoggingSeverity") { (severity: String) in - try membraneWebRTC.changeWebRTCLoggingSeverity(severity: severity) + try rnFishjamClient.changeWebRTCLoggingSeverity(severity: severity) } AsyncFunction("getStatistics") { - membraneWebRTC.getStatistics() + rnFishjamClient.getStatistics() } AsyncFunction("selectAudioSessionMode") { (sessionMode: String) in - try membraneWebRTC.selectAudioSessionMode(sessionMode: sessionMode) + try rnFishjamClient.selectAudioSessionMode(sessionMode: sessionMode) } AsyncFunction("showAudioRoutePicker") { () in - membraneWebRTC.showAudioRoutePicker() + rnFishjamClient.showAudioRoutePicker() } AsyncFunction("startAudioSwitcher") { - membraneWebRTC.startAudioSwitcher() + rnFishjamClient.startAudioSwitcher() } } } diff --git a/src/MembraneWebRTC.types.ts b/src/RNFishjamClient.types.ts similarity index 99% rename from src/MembraneWebRTC.types.ts rename to src/RNFishjamClient.types.ts index 096455e0..d8d056a5 100644 --- a/src/MembraneWebRTC.types.ts +++ b/src/RNFishjamClient.types.ts @@ -374,7 +374,7 @@ export type VideoRendererProps = { style?: ViewStyle; }; -export type MembraneWebRTC = { +export type RNFishjamClient = { appContext?: any; connect: (url: string, peerToken: string) => Promise; joinRoom: (peerMetadata: Metadata) => Promise; diff --git a/src/MembraneWebRTCModule.ts b/src/RNFishjamClientModule.ts similarity index 60% rename from src/MembraneWebRTCModule.ts rename to src/RNFishjamClientModule.ts index cfad295f..f873684f 100644 --- a/src/MembraneWebRTCModule.ts +++ b/src/RNFishjamClientModule.ts @@ -1,12 +1,12 @@ import { requireNativeModule } from 'expo-modules-core'; import { NativeModule } from 'react-native'; -import { MembraneWebRTC } from './MembraneWebRTC.types'; +import { RNFishjamClient } from './RNFishjamClient.types'; import { NativeMembraneMock } from './__mocks__/native'; import { isJest } from './utils'; const nativeModule = isJest() ? NativeMembraneMock - : requireNativeModule('MembraneWebRTC'); + : requireNativeModule('RNFishjamClient'); -export default nativeModule as MembraneWebRTC & NativeModule; +export default nativeModule as RNFishjamClient & NativeModule; diff --git a/src/VideoPreviewView.tsx b/src/VideoPreviewView.tsx index d2d54c73..c94261a8 100644 --- a/src/VideoPreviewView.tsx +++ b/src/VideoPreviewView.tsx @@ -2,7 +2,7 @@ import { requireNativeViewManager } from 'expo-modules-core'; import * as React from 'react'; import { View } from 'react-native'; -import { VideoPreviewViewProps } from './MembraneWebRTC.types'; +import { VideoPreviewViewProps } from './RNFishjamClient.types'; import { isJest } from './utils'; const NativeView: React.ComponentType = isJest() diff --git a/src/VideoRendererView.tsx b/src/VideoRendererView.tsx index b383f7ec..d1980373 100644 --- a/src/VideoRendererView.tsx +++ b/src/VideoRendererView.tsx @@ -2,7 +2,7 @@ import { requireNativeViewManager } from 'expo-modules-core'; import * as React from 'react'; import { View } from 'react-native'; -import { VideoRendererProps } from './MembraneWebRTC.types'; +import { VideoRendererProps } from './RNFishjamClient.types'; import { isJest } from './utils'; const NativeView: React.ComponentType = isJest() diff --git a/src/common/client.ts b/src/common/client.ts index 950a2f1d..d466b199 100644 --- a/src/common/client.ts +++ b/src/common/client.ts @@ -1,18 +1,18 @@ -import { Metadata } from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +import { Metadata } from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; export const connect = (url: string, peerToken: string) => { - return MembraneWebRTCModule.connect(url, peerToken); + return RNFishjamClientModule.connect(url, peerToken); }; export const joinRoom = (peerMetadata: Metadata) => { - return MembraneWebRTCModule.joinRoom(peerMetadata); + return RNFishjamClientModule.joinRoom(peerMetadata); }; export const leaveRoom = () => { - return MembraneWebRTCModule.leaveRoom(); + return RNFishjamClientModule.leaveRoom(); }; export const cleanUp = () => { - return MembraneWebRTCModule.cleanUp(); + return RNFishjamClientModule.cleanUp(); }; diff --git a/src/common/eventEmitter.ts b/src/common/eventEmitter.ts index 41419af2..dc4fd04e 100644 --- a/src/common/eventEmitter.ts +++ b/src/common/eventEmitter.ts @@ -1,6 +1,6 @@ import { NativeModulesProxy, EventEmitter } from 'expo-modules-core'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +import RNFishjamClientModule from '../RNFishjamClientModule'; export const ReceivableEvents = { IsCameraOn: 'IsCameraOn', @@ -14,5 +14,5 @@ export const ReceivableEvents = { } as const; export const eventEmitter = new EventEmitter( - MembraneWebRTCModule ?? NativeModulesProxy.MembraneWebRTC, + RNFishjamClientModule ?? NativeModulesProxy.RNFishjamClient, ); diff --git a/src/common/metadata.ts b/src/common/metadata.ts index c4043759..9512fd1e 100644 --- a/src/common/metadata.ts +++ b/src/common/metadata.ts @@ -1,5 +1,5 @@ -import { Metadata } from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +import { Metadata } from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; /** /** @@ -9,7 +9,7 @@ import MembraneWebRTCModule from '../MembraneWebRTCModule'; export async function updateEndpointMetadata< EndpointMetadataType extends Metadata, >(metadata: EndpointMetadataType) { - await MembraneWebRTCModule.updateEndpointMetadata(metadata); + await RNFishjamClientModule.updateEndpointMetadata(metadata); } /** @@ -19,7 +19,7 @@ export async function updateEndpointMetadata< export async function updateVideoTrackMetadata< VideoTrackMetadataType extends Metadata, >(metadata: VideoTrackMetadataType) { - await MembraneWebRTCModule.updateVideoTrackMetadata(metadata); + await RNFishjamClientModule.updateVideoTrackMetadata(metadata); } /** * a function that updates audio metadata on the server @@ -28,5 +28,5 @@ export async function updateVideoTrackMetadata< export async function updateAudioTrackMetadata< AudioTrackMetadataType extends Metadata, >(metadata: AudioTrackMetadataType) { - await MembraneWebRTCModule.updateAudioTrackMetadata(metadata); + await RNFishjamClientModule.updateAudioTrackMetadata(metadata); } diff --git a/src/common/webRTC.ts b/src/common/webRTC.ts index 93602e87..9b501484 100644 --- a/src/common/webRTC.ts +++ b/src/common/webRTC.ts @@ -1,5 +1,5 @@ -import { LoggingSeverity, TrackEncoding } from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +import { LoggingSeverity, TrackEncoding } from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; /** * sets track encoding that server should send to the client library. @@ -14,7 +14,7 @@ export async function setTargetTrackEncoding( trackId: string, encoding: TrackEncoding, ) { - await MembraneWebRTCModule.setTargetTrackEncoding(trackId, encoding); + await RNFishjamClientModule.setTargetTrackEncoding(trackId, encoding); } /** @@ -25,5 +25,5 @@ export async function setTargetTrackEncoding( export function changeWebRTCLoggingSeverity( severity: LoggingSeverity, ): Promise { - return MembraneWebRTCModule.changeWebRTCLoggingSeverity(severity); + return RNFishjamClientModule.changeWebRTCLoggingSeverity(severity); } diff --git a/src/hooks/useAudioSettings.ts b/src/hooks/useAudioSettings.ts index a4b1e637..d8f3135f 100644 --- a/src/hooks/useAudioSettings.ts +++ b/src/hooks/useAudioSettings.ts @@ -5,8 +5,8 @@ import { AudioOutputDevice, AudioOutputDeviceType, AudioSessionMode, -} from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +} from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; import { ReceivableEvents, eventEmitter } from '../common/eventEmitter'; /** @@ -36,11 +36,11 @@ export function useAudioSettings() { ReceivableEvents.AudioDeviceUpdate, onAudioDevice, ); - MembraneWebRTCModule.startAudioSwitcher(); + RNFishjamClientModule.startAudioSwitcher(); return () => { eventListener.remove(); if (Platform.OS === 'android') { - MembraneWebRTCModule.stopAudioSwitcher(); + RNFishjamClientModule.stopAudioSwitcher(); } }; }, []); @@ -57,7 +57,7 @@ export function useAudioSettings() { 'To select an output audio device on iOS use selectAudioSessionMode or showAudioRoutePicker functions', ); } - await MembraneWebRTCModule.setOutputAudioDevice(device); + await RNFishjamClientModule.setOutputAudioDevice(device); }, [], ); @@ -72,7 +72,7 @@ export function useAudioSettings() { if (Platform.OS === 'android') { throw Error('selectAudioSessionMode function is supported only on iOS'); } - await MembraneWebRTCModule.selectAudioSessionMode(audioSessionMode); + await RNFishjamClientModule.selectAudioSessionMode(audioSessionMode); }, [], ); @@ -88,7 +88,7 @@ export function useAudioSettings() { 'To select an output audio device on Android use selectOutputAudioDevice function', ); } - await MembraneWebRTCModule.showAudioRoutePicker(); + await RNFishjamClientModule.showAudioRoutePicker(); }, []); return { diff --git a/src/hooks/useBandwidthEstimation.ts b/src/hooks/useBandwidthEstimation.ts index 5548fb47..7b1d79c6 100644 --- a/src/hooks/useBandwidthEstimation.ts +++ b/src/hooks/useBandwidthEstimation.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; -import { BandwidthEstimationEvent } from '../MembraneWebRTC.types'; +import { BandwidthEstimationEvent } from '../RNFishjamClient.types'; import { ReceivableEvents, eventEmitter } from '../common/eventEmitter'; /** diff --git a/src/hooks/useCamera.ts b/src/hooks/useCamera.ts index 80a07597..8097a0fd 100644 --- a/src/hooks/useCamera.ts +++ b/src/hooks/useCamera.ts @@ -10,8 +10,8 @@ import { SimulcastConfig, SimulcastConfigUpdateEvent, TrackEncoding, -} from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +} from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; import { ReceivableEvents, eventEmitter } from '../common/eventEmitter'; const defaultSimulcastConfig = () => ({ @@ -26,7 +26,7 @@ let videoSimulcastConfig: SimulcastConfig = defaultSimulcastConfig(); */ export function useCamera() { const [isCameraOn, setIsCameraOn] = useState( - MembraneWebRTCModule.isCameraOn, + RNFishjamClientModule.isCameraOn, ); const [simulcastConfig, setSimulcastConfig] = @@ -45,7 +45,7 @@ export function useCamera() { ReceivableEvents.IsCameraOn, (event) => setIsCameraOn(event.IsCameraOn), ); - setIsCameraOn(MembraneWebRTCModule.isCameraOn); + setIsCameraOn(RNFishjamClientModule.isCameraOn); return () => eventListener.remove(); }, []); @@ -56,7 +56,7 @@ export function useCamera() { const toggleVideoTrackEncoding = useCallback( async (encoding: TrackEncoding) => { videoSimulcastConfig = - await MembraneWebRTCModule.toggleVideoTrackEncoding(encoding); + await RNFishjamClientModule.toggleVideoTrackEncoding(encoding); setSimulcastConfig(videoSimulcastConfig); }, [], @@ -69,7 +69,7 @@ export function useCamera() { */ const setVideoTrackEncodingBandwidth = useCallback( async (encoding: TrackEncoding, bandwidth: BandwidthLimit) => { - await MembraneWebRTCModule.setVideoTrackEncodingBandwidth( + await RNFishjamClientModule.setVideoTrackEncodingBandwidth( encoding, bandwidth, ); @@ -81,7 +81,7 @@ export function useCamera() { * Function to toggle camera on/off */ const toggleCamera = useCallback(async () => { - const state = await MembraneWebRTCModule.toggleCamera(); + const state = await RNFishjamClientModule.toggleCamera(); setIsCameraOn(state); }, []); @@ -106,7 +106,7 @@ export function useCamera() { } delete config.maxBandwidth; } - await MembraneWebRTCModule.startCamera(config); + await RNFishjamClientModule.startCamera(config); }, [], ); @@ -116,7 +116,7 @@ export function useCamera() { * @returns A promise that resolves when camera is toggled. */ const flipCamera = useCallback(async () => { - return MembraneWebRTCModule.flipCamera(); + return RNFishjamClientModule.flipCamera(); }, []); /** @@ -124,14 +124,16 @@ export function useCamera() { * @returns A promise that resolves when camera is switched. */ const switchCamera = useCallback(async (captureDeviceId: string) => { - return MembraneWebRTCModule.switchCamera(captureDeviceId); + return RNFishjamClientModule.switchCamera(captureDeviceId); }, []); /** Function that queries available cameras. * @returns A promise that resolves to the list of available cameras. */ const getCaptureDevices = useCallback(async () => { - return MembraneWebRTCModule.getCaptureDevices() as Promise; + return RNFishjamClientModule.getCaptureDevices() as Promise< + CaptureDevice[] + >; }, []); /** @@ -142,7 +144,7 @@ export function useCamera() { * @param BandwidthLimit to set */ const setVideoTrackBandwidth = async (bandwidth: BandwidthLimit) => { - await MembraneWebRTCModule.setVideoTrackBandwidth(bandwidth); + await RNFishjamClientModule.setVideoTrackBandwidth(bandwidth); }; return { diff --git a/src/hooks/useEndpoints.ts b/src/hooks/useEndpoints.ts index 0fb7877b..cca4c2f3 100644 --- a/src/hooks/useEndpoints.ts +++ b/src/hooks/useEndpoints.ts @@ -4,8 +4,8 @@ import { Endpoint, EndpointsUpdateEvent, Metadata, -} from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +} from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; import { ReceivableEvents, eventEmitter } from '../common/eventEmitter'; /** @@ -35,7 +35,7 @@ export function useEndpoints< >(ReceivableEvents.EndpointsUpdate, (event) => { setEndpoints(event.EndpointsUpdate); }); - MembraneWebRTCModule.getEndpoints< + RNFishjamClientModule.getEndpoints< EndpointMetadataType, VideoTrackMetadataType, AudioTrackMetadataType diff --git a/src/hooks/useMicrophone.ts b/src/hooks/useMicrophone.ts index a2e8ef75..ea09db04 100644 --- a/src/hooks/useMicrophone.ts +++ b/src/hooks/useMicrophone.ts @@ -4,8 +4,8 @@ import { IsMicrophoneOnEvent, Metadata, MicrophoneConfig, -} from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +} from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; import { ReceivableEvents, eventEmitter } from '../common/eventEmitter'; /** @@ -13,7 +13,7 @@ import { ReceivableEvents, eventEmitter } from '../common/eventEmitter'; */ export function useMicrophone() { const [isMicrophoneOn, setIsMicrophoneOn] = useState( - MembraneWebRTCModule.isMicrophoneOn, + RNFishjamClientModule.isMicrophoneOn, ); useEffect(() => { @@ -21,7 +21,7 @@ export function useMicrophone() { ReceivableEvents.IsMicrophoneOn, (event) => setIsMicrophoneOn(event.IsMicrophoneOn), ); - setIsMicrophoneOn(MembraneWebRTCModule.isMicrophoneOn); + setIsMicrophoneOn(RNFishjamClientModule.isMicrophoneOn); return () => eventListener.remove(); }, []); @@ -29,7 +29,7 @@ export function useMicrophone() { * Function to toggle microphone on/off */ const toggleMicrophone = useCallback(async () => { - const state = await MembraneWebRTCModule.toggleMicrophone(); + const state = await RNFishjamClientModule.toggleMicrophone(); setIsMicrophoneOn(state); }, []); @@ -42,7 +42,7 @@ export function useMicrophone() { async ( config: Partial> = {}, ) => { - await MembraneWebRTCModule.startMicrophone(config); + await RNFishjamClientModule.startMicrophone(config); }, [], ); diff --git a/src/hooks/useRTCStatistics.ts b/src/hooks/useRTCStatistics.ts index 4c250d6b..f17f6846 100644 --- a/src/hooks/useRTCStatistics.ts +++ b/src/hooks/useRTCStatistics.ts @@ -5,8 +5,8 @@ import { RTCInboundStats, RTCOutboundStats, RTCStats, -} from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +} from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; /** * This hook provides access to current rtc statistics data. @@ -25,7 +25,7 @@ export function useRTCStatistics(refreshInterval: number) { // Gets stats from the native libraries. const getStatistics = useCallback(async () => { - const stats = await MembraneWebRTCModule.getStatistics(); + const stats = await RNFishjamClientModule.getStatistics(); setStatistics((prev) => { const newStats = [...prev, processIncomingStats(prev, stats)]; takeRight(newStats, MAX_SIZE); diff --git a/src/hooks/useScreencast.ts b/src/hooks/useScreencast.ts index 5c8aa526..5edac7d1 100644 --- a/src/hooks/useScreencast.ts +++ b/src/hooks/useScreencast.ts @@ -7,8 +7,8 @@ import { ScreencastOptions, SimulcastConfig, TrackEncoding, -} from '../MembraneWebRTC.types'; -import MembraneWebRTCModule from '../MembraneWebRTCModule'; +} from '../RNFishjamClient.types'; +import RNFishjamClientModule from '../RNFishjamClientModule'; import { ReceivableEvents, eventEmitter } from '../common/eventEmitter'; const defaultSimulcastConfig = () => ({ @@ -24,7 +24,7 @@ let screencastSimulcastConfig: SimulcastConfig = defaultSimulcastConfig(); */ export function useScreencast() { const [isScreencastOn, setIsScreencastOn] = useState( - MembraneWebRTCModule.isScreencastOn, + RNFishjamClientModule.isScreencastOn, ); const [simulcastConfig, setSimulcastConfig] = useState( screencastSimulcastConfig, @@ -34,7 +34,7 @@ export function useScreencast() { ReceivableEvents.IsScreencastOn, (event) => setIsScreencastOn(event.IsScreencastOn), ); - setIsScreencastOn(MembraneWebRTCModule.isScreencastOn); + setIsScreencastOn(RNFishjamClientModule.isScreencastOn); return () => eventListener.remove(); }, []); @@ -47,7 +47,7 @@ export function useScreencast() { ScreencastOptions > = {}, ) => { - await MembraneWebRTCModule.toggleScreencast(screencastOptions); + await RNFishjamClientModule.toggleScreencast(screencastOptions); screencastSimulcastConfig = screencastOptions.simulcastConfig || defaultSimulcastConfig(); setSimulcastConfig(screencastSimulcastConfig); @@ -63,7 +63,7 @@ export function useScreencast() { async ( metadata: ScreencastMetadataType, ) => { - await MembraneWebRTCModule.updateScreencastTrackMetadata(metadata); + await RNFishjamClientModule.updateScreencastTrackMetadata(metadata); }, [], ); @@ -75,7 +75,7 @@ export function useScreencast() { const toggleScreencastTrackEncoding = useCallback( async (encoding: TrackEncoding) => { screencastSimulcastConfig = - await MembraneWebRTCModule.toggleScreencastTrackEncoding(encoding); + await RNFishjamClientModule.toggleScreencastTrackEncoding(encoding); setSimulcastConfig(screencastSimulcastConfig); }, [], @@ -88,7 +88,7 @@ export function useScreencast() { */ const setScreencastTrackEncodingBandwidth = useCallback( async (encoding: TrackEncoding, bandwidth: BandwidthLimit) => { - await MembraneWebRTCModule.setScreencastTrackEncodingBandwidth( + await RNFishjamClientModule.setScreencastTrackEncodingBandwidth( encoding, bandwidth, ); @@ -105,7 +105,7 @@ export function useScreencast() { */ const setScreencastTrackBandwidth = useCallback( async (bandwidth: BandwidthLimit) => { - await MembraneWebRTCModule.setScreencastTrackBandwidth(bandwidth); + await RNFishjamClientModule.setScreencastTrackBandwidth(bandwidth); }, [], ); diff --git a/src/index.tsx b/src/index.tsx index 9ddeab19..302fbaeb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,4 @@ -import { Endpoint, Metadata } from './MembraneWebRTC.types'; +import { Endpoint, Metadata } from './RNFishjamClient.types'; import { updateEndpointMetadata } from './common/metadata'; import { useEndpoints } from './hooks/useEndpoints'; @@ -23,7 +23,7 @@ export * from './common/client'; export { default as VideoPreviewView } from './VideoPreviewView'; export { default as VideoRendererView } from './VideoRendererView'; -export * from './MembraneWebRTC.types'; +export * from './RNFishjamClient.types'; // below are aliases used by 'old' rn-client-sdk. They should be removed export type Peer< From 846f8aa3b47ceac00776b2e3e303be32ea7e4e76 Mon Sep 17 00:00:00 2001 From: Angelika Serwa Date: Fri, 21 Jun 2024 14:24:03 +0200 Subject: [PATCH 3/3] Review changes --- example/hooks/useJoinRoom.ts | 6 +- ios/RNFishjamClient.swift | 311 ++++++++++++++++++-------------- ios/RNFishjamClientModule.swift | 19 +- 3 files changed, 187 insertions(+), 149 deletions(-) diff --git a/example/hooks/useJoinRoom.ts b/example/hooks/useJoinRoom.ts index b271eb41..a58cfeda 100644 --- a/example/hooks/useJoinRoom.ts +++ b/example/hooks/useJoinRoom.ts @@ -1,6 +1,6 @@ import { useCamera, - joinRoom as jsJoinRoom, + joinRoom as fjJoinRoom, useMicrophone, VideoQuality, } from '@fishjam-dev/react-native-client'; @@ -67,7 +67,7 @@ export function useJoinRoom({ cameraEnabled: isCameraAvailable, }); - await jsJoinRoom({ + await fjJoinRoom({ name: 'RN mobile', }); @@ -78,7 +78,7 @@ export function useJoinRoom({ }, [ isCameraAvailable, isMicrophoneAvailable, - jsJoinRoom, + fjJoinRoom, startCamera, startMicrophone, ]); diff --git a/ios/RNFishjamClient.swift b/ios/RNFishjamClient.swift index 6675b453..8afaf0f7 100644 --- a/ios/RNFishjamClient.swift +++ b/ios/RNFishjamClient.swift @@ -64,7 +64,7 @@ extension String { } class RNFishjamClient: FishjamClientListener { - var fishjamClient: FishjamClient? = nil + var fishjamClient: FishjamClient? = nil var localAudioTrack: LocalAudioTrack? var localVideoTrack: LocalVideoTrack? @@ -123,7 +123,8 @@ class RNFishjamClient: FishjamClientListener { { if let maxBandwidth: Int = maxBandwidth.get() { return .BandwidthLimit(maxBandwidth) - } else if let maxBandwidth: [String: Int] = maxBandwidth.get() { + } + else if let maxBandwidth: [String: Int] = maxBandwidth.get() { return .SimulcastBandwidthLimit(maxBandwidth) } return .BandwidthLimit(0) @@ -136,7 +137,8 @@ class RNFishjamClient: FishjamClientListener { let trackEncoding = encoding.toTrackEncoding() guard let trackEncoding = trackEncoding else { throw Exception( - name: "E_INVALID_ENCODING", description: "Invalid track encoding specified: \(encoding)") + name: "E_INVALID_ENCODING", + description: "Invalid track encoding specified: \(encoding)") } return trackEncoding } @@ -163,7 +165,9 @@ class RNFishjamClient: FishjamClientListener { let flipVideo = connectionOptions.flipVideo let videoBandwidthLimit = getMaxBandwidthFromOptions( maxBandwidth: connectionOptions.maxBandwidth) - let simulcastConfig = try getSimulcastConfigFromOptions(simulcastConfig: connectionOptions.simulcastConfig) ?? SimulcastConfig() + let simulcastConfig = + try getSimulcastConfigFromOptions(simulcastConfig: connectionOptions.simulcastConfig) + ?? SimulcastConfig() let preset: VideoParameters = { switch videoQuality { @@ -209,7 +213,8 @@ class RNFishjamClient: FishjamClientListener { if fishjamClient == nil { throw Exception( name: "E_NOT_CONNECTED", - description: "Client not connected to server yet. Make sure to call connect() first!") + description: + "Client not connected to server yet. Make sure to call connect() first!") } } @@ -241,120 +246,124 @@ class RNFishjamClient: FishjamClientListener { throw Exception( name: "E_NO_ENDPOINTS", description: - "No endpoints available. Ensure the connection is established or endpoints are present.") - } - } - - func onSocketClose(code: UInt16, reason: String) { - if let connectPromise = connectPromise { - connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket close") - } - connectPromise = nil - } - - func onSocketError() { - if let connectPromise = connectPromise { - connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error") - } - connectPromise = nil - } - - func onSocketOpen() { - - } - - func onAuthSuccess() { - if let connectPromise = connectPromise { - connectPromise.resolve(nil) - } - connectPromise = nil - } - - func onAuthError() { - if let connectPromise = connectPromise { - connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error") - } - connectPromise = nil - } - - func onDisconnected() { - - } - - func onJoined(peerID: String, peersInRoom: [Endpoint]) { - peersInRoom.forEach { endpoint in - MembraneRoom.sharedInstance.endpoints[endpoint.id] = RNEndpoint( - id: endpoint.id, metadata: endpoint.metadata, type: endpoint.type, tracks: endpoint.tracks ?? [:] - ) - } - - emitEndpoints() - if let joinPromise = joinPromise { - joinPromise.resolve(nil) - } - joinPromise = nil - } - - func onJoinError(metadata: Any) { - if let joinPromise = joinPromise { - joinPromise.reject("E_MEMBRANE_CONNECT", "Failed to join room") - } - joinPromise = nil - } - - func connect(url: String, peerToken: String, promise: Promise) { - connectPromise = promise - fishjamClient?.connect(config: Config(websocketUrl: url, token: peerToken)) - } - - func joinRoom(peerMetadata: [String: Any], promise: Promise) { - joinPromise = promise - localUserMetadata = peerMetadata.toMetadata() - - guard let localEndpointId = localEndpointId, - var endpoint = MembraneRoom.sharedInstance.endpoints[localEndpointId] - else { - return + "No endpoints available. Ensure the connection is established or endpoints are present." + ) + } + } + + func onSocketClose(code: UInt16, reason: String) { + if let connectPromise = connectPromise { + connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket close") + } + connectPromise = nil + } + + func onSocketError() { + if let connectPromise = connectPromise { + connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error") + } + connectPromise = nil + } + + func onSocketOpen() { + + } + + func onAuthSuccess() { + if let connectPromise = connectPromise { + connectPromise.resolve(nil) + } + connectPromise = nil + } + + func onAuthError() { + if let connectPromise = connectPromise { + connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error") + } + connectPromise = nil + } + + func onDisconnected() { + + } + + func onJoined(peerID: String, peersInRoom: [Endpoint]) { + peersInRoom.forEach { endpoint in + MembraneRoom.sharedInstance.endpoints[endpoint.id] = RNEndpoint( + id: endpoint.id, metadata: endpoint.metadata, type: endpoint.type, + tracks: endpoint.tracks ?? [:] + ) + } + + emitEndpoints() + if let joinPromise = joinPromise { + joinPromise.resolve(nil) + } + joinPromise = nil + } + + func onJoinError(metadata: Any) { + if let joinPromise = joinPromise { + joinPromise.reject("E_MEMBRANE_CONNECT", "Failed to join room") + } + joinPromise = nil + } + + func connect(url: String, peerToken: String, promise: Promise) { + connectPromise = promise + fishjamClient?.connect(config: Config(websocketUrl: url, token: peerToken)) + } + + func joinRoom(peerMetadata: [String: Any], promise: Promise) { + joinPromise = promise + localUserMetadata = peerMetadata.toMetadata() + + guard let localEndpointId = localEndpointId, + var endpoint = MembraneRoom.sharedInstance.endpoints[localEndpointId] + else { + return + } + + endpoint.metadata = peerMetadata.toMetadata() + fishjamClient?.join(peerMetadata: peerMetadata.toMetadata()) + } + + func leaveRoom() { + if isScreensharingEnabled { + let screencastExtensionBundleId = + Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] as? String + DispatchQueue.main.async { + RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) + } + } + fishjamClient?.leave() + MembraneRoom.sharedInstance.endpoints = [:] + } + + func cleanUp() { + if isScreensharingEnabled { + let screencastExtensionBundleId = + Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] as? String + DispatchQueue.main.async { + RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) } - - endpoint.metadata = peerMetadata.toMetadata() - fishjamClient?.join(peerMetadata: peerMetadata.toMetadata()) - } - - func leaveRoom() { - if isScreensharingEnabled { - let screencastExtensionBundleId = - Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] as? String - DispatchQueue.main.async { - RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) - } - } - fishjamClient?.leave() - MembraneRoom.sharedInstance.endpoints = [:] - } - - func cleanUp() { - if isScreensharingEnabled { - let screencastExtensionBundleId = - Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] as? String - DispatchQueue.main.async { - RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) - } - } - fishjamClient?.cleanUp() - fishjamClient = nil - MembraneRoom.sharedInstance.endpoints = [:] - } + } + fishjamClient?.cleanUp() + fishjamClient = nil + MembraneRoom.sharedInstance.endpoints = [:] + } func startCamera(config: CameraConfig) throws { try ensureConnected() guard let cameraTrack = try createCameraTrack(config: config) else { return } localVideoTrack = cameraTrack - let simulcastConfig = try? getSimulcastConfigFromOptions(simulcastConfig: config.simulcastConfig) - try addTrackToLocalEndpoint(cameraTrack, config.videoTrackMetadata.toMetadata(), simulcastConfig) + let simulcastConfig = try? getSimulcastConfigFromOptions( + simulcastConfig: config.simulcastConfig) + try addTrackToLocalEndpoint( + cameraTrack, config.videoTrackMetadata.toMetadata(), simulcastConfig) try setCameraTrackState(cameraTrack: cameraTrack, isEnabled: config.cameraEnabled) } - + private func createCameraTrack(config: CameraConfig) throws -> LocalVideoTrack? { try ensureConnected() let videoParameters = try getVideoParametersFromOptions(connectionOptions: config) @@ -377,12 +386,15 @@ class RNFishjamClient: FishjamClientListener { let isCameraEnabledMap = [eventName: isEnabled] emitEvent(name: eventName, data: isCameraEnabledMap) } - private func addTrackToLocalEndpoint(_ track: LocalVideoTrack, _ metadata: Metadata, _ simulcastConfig: SimulcastConfig?) throws { + private func addTrackToLocalEndpoint( + _ track: LocalVideoTrack, _ metadata: Metadata, _ simulcastConfig: SimulcastConfig? + ) throws { try ensureEndpoints() if let localEndpointId = localEndpointId { let trackId = track.trackId() MembraneRoom.sharedInstance.endpoints[localEndpointId]?.videoTracks[trackId] = track - MembraneRoom.sharedInstance.endpoints[localEndpointId]?.tracksData[trackId] = TrackData(metadata: metadata, simulcastConfig: simulcastConfig) + MembraneRoom.sharedInstance.endpoints[localEndpointId]?.tracksData[trackId] = TrackData( + metadata: metadata, simulcastConfig: simulcastConfig) emitEndpoints() } @@ -412,8 +424,10 @@ class RNFishjamClient: FishjamClientListener { private func addTrackToLocalEndpoint(_ track: LocalAudioTrack, _ metadata: Metadata) throws { try ensureEndpoints() if let localEndpointId = localEndpointId { - MembraneRoom.sharedInstance.endpoints[localEndpointId]?.audioTracks[track.trackId()] = track - MembraneRoom.sharedInstance.endpoints[localEndpointId]?.tracksData[track.trackId()] = TrackData(metadata: metadata) + MembraneRoom.sharedInstance.endpoints[localEndpointId]?.audioTracks[track.trackId()] = + track + MembraneRoom.sharedInstance.endpoints[localEndpointId]?.tracksData[track.trackId()] = + TrackData(metadata: metadata) emitEndpoints() } } @@ -439,7 +453,9 @@ class RNFishjamClient: FishjamClientListener { try addTrackToLocalEndpoint(microphoneTrack, config.audioTrackMetadata.toMetadata()) try setMicrophoneTrackState(microphoneTrack, config.microphoneEnabled) } - private func setMicrophoneTrackState(_ microphoneTrack: LocalAudioTrack, _ isEnabled: Bool) throws { + private func setMicrophoneTrackState(_ microphoneTrack: LocalAudioTrack, _ isEnabled: Bool) + throws + { try ensureConnected() microphoneTrack.setEnabled(isEnabled) isMicEnabled = isEnabled @@ -454,7 +470,9 @@ class RNFishjamClient: FishjamClientListener { } return isMicEnabled } - private func getScreencastVideoParameters(screencastOptions: ScreencastOptions) -> VideoParameters { + private func getScreencastVideoParameters(screencastOptions: ScreencastOptions) + -> VideoParameters + { let preset: VideoParameters switch screencastOptions.quality { case "VGA": @@ -486,7 +504,8 @@ class RNFishjamClient: FishjamClientListener { func toggleScreencast(screencastOptions: ScreencastOptions) throws { try ensureConnected() guard - let screencastExtensionBundleId = Bundle.main.infoDictionary?["ScreencastExtensionBundleId"] + let screencastExtensionBundleId = Bundle.main.infoDictionary?[ + "ScreencastExtensionBundleId"] as? String else { throw Exception( @@ -531,9 +550,11 @@ class RNFishjamClient: FishjamClientListener { } do { guard let screencastTrack = localScreencastTrack else { return } - try addTrackToLocalEndpoint(screencastTrack, screencastMetadata, simulcastConfig) + try addTrackToLocalEndpoint( + screencastTrack, screencastMetadata, simulcastConfig) try setScreencastTrackState(isEnabled: true) - } catch { + } + catch { os_log( "Error starting screencast: %{public}s", log: log, type: .error, String(describing: error)) @@ -549,7 +570,8 @@ class RNFishjamClient: FishjamClientListener { try removeTrackFromLocalEndpoint(screencastTrack) localScreencastTrack = nil try setScreencastTrackState(isEnabled: false) - } catch { + } + catch { os_log( "Error stopping screencast: %{public}s", log: log, type: .error, String(describing: error)) @@ -559,8 +581,9 @@ class RNFishjamClient: FishjamClientListener { RPSystemBroadcastPickerView.show(for: screencastExtensionBundleId) } } - private func isTrackLocal(_ trackId : String) -> Bool{ - return trackId == localAudioTrack?.trackId() || trackId == localVideoTrack?.trackId() || trackId == localScreencastTrack?.trackId() + private func isTrackLocal(_ trackId: String) -> Bool { + return trackId == localAudioTrack?.trackId() || trackId == localVideoTrack?.trackId() + || trackId == localScreencastTrack?.trackId() } func getEndpoints() -> [[String: Any]] { MembraneRoom.sharedInstance.endpoints.values.sorted(by: { $0.order < $1.order }).map { @@ -574,11 +597,12 @@ class RNFishjamClient: FishjamClientListener { "encodingReason": tracksContexts[trackId]?.encodingReason?.rawValue as Any, ] - var simulcastConfig : SimulcastConfig? = nil + var simulcastConfig: SimulcastConfig? = nil if isTrackLocal(trackId) { simulcastConfig = p.tracksData[trackId]?.simulcastConfig - }else{ + } + else { simulcastConfig = tracksContexts[trackId]?.simulcastConfig } @@ -587,7 +611,7 @@ class RNFishjamClient: FishjamClientListener { "enabled": simulcastConfig.enabled, "activeEncodings": simulcastConfig.activeEncodings.map({ encoding in encoding.description - }) + }), ] data["simulcastConfig"] = simulcastConfigMap @@ -693,7 +717,8 @@ class RNFishjamClient: FishjamClientListener { enabled: true, activeEncodings: simulcastConfig.activeEncodings.filter { e in e != encoding } ) - } else { + } + else { room.enableTrackEncoding(trackId: trackId, encoding: encoding) return SimulcastConfig( enabled: true, @@ -708,11 +733,13 @@ class RNFishjamClient: FishjamClientListener { guard let trackId = localScreencastTrack?.trackId(), let simulcastConfig = toggleTrackEncoding( - encoding: trackEncoding, trackId: trackId, simulcastConfig: screencastSimulcastConfig) + encoding: trackEncoding, trackId: trackId, + simulcastConfig: screencastSimulcastConfig) else { throw Exception( name: "E_NOT_CONNECTED", - description: "Client not connected to server yet. Make sure to call connect() first!") + description: + "Client not connected to server yet. Make sure to call connect() first!") } self.screencastSimulcastConfig = simulcastConfig return getSimulcastConfigAsRNMap(simulcastConfig: simulcastConfig) @@ -732,20 +759,23 @@ class RNFishjamClient: FishjamClientListener { return } room.setEncodingBandwidth( - trackId: trackId, encoding: trackEncoding.description, bandwidthLimit: BandwidthLimit(bandwidth)) + trackId: trackId, encoding: trackEncoding.description, + bandwidthLimit: BandwidthLimit(bandwidth)) } func setTargetTrackEncoding(trackId: String, encoding: String) throws { try ensureConnected() guard let room = fishjamClient, - let videoTrack = MembraneRoom.sharedInstance.getVideoTrackById(trackId: trackId as String), + let videoTrack = MembraneRoom.sharedInstance.getVideoTrackById( + trackId: trackId as String), let trackId = (videoTrack as? RemoteVideoTrack)?.track.trackId ?? (videoTrack as? LocalVideoTrack)?.trackId(), let globalTrackId = getGlobalTrackId(localTrackId: trackId as String) else { throw Exception( - name: "E_INVALID_TRACK_ID", description: "Remote track with id=\(trackId) not found") + name: "E_INVALID_TRACK_ID", description: "Remote track with id=\(trackId) not found" + ) } let trackEncoding = try validateEncoding(encoding: encoding as String) room.setTargetTrackEncoding(trackId: globalTrackId, encoding: trackEncoding) @@ -761,7 +791,8 @@ class RNFishjamClient: FishjamClientListener { else { throw Exception( name: "E_NOT_CONNECTED", - description: "Client not connected to server yet. Make sure to call connect() first!") + description: + "Client not connected to server yet. Make sure to call connect() first!") } self.videoSimulcastConfig = simulcastConfig let eventName = EmitableEvents.SimulcastConfigUpdate @@ -778,7 +809,8 @@ class RNFishjamClient: FishjamClientListener { return } room.setEncodingBandwidth( - trackId: trackId, encoding: encoding as String, bandwidthLimit: BandwidthLimit(bandwidth)) + trackId: trackId, encoding: encoding as String, + bandwidthLimit: BandwidthLimit(bandwidth)) } func setVideoTrackBandwidth(bandwidth: Int) throws { @@ -803,7 +835,8 @@ class RNFishjamClient: FishjamClientListener { fishjamClient?.changeWebRTCLoggingSeverity(severity: .none) default: throw Exception( - name: "E_INVALID_SEVERITY_LEVEL", description: "Severity with name=\(severity) not found") + name: "E_INVALID_SEVERITY_LEVEL", + description: "Severity with name=\(severity) not found") } } @@ -851,7 +884,8 @@ class RNFishjamClient: FishjamClientListener { stats?.forEach { pair in if let val = pair.value as? RTCOutboundStats { res[pair.key] = getMapFromStatsObject(obj: val) - } else { + } + else { res[pair.key] = getMapFromStatsObject(obj: pair.value as! RTCInboundStats) } } @@ -892,7 +926,8 @@ class RNFishjamClient: FishjamClientListener { throw Exception( name: "E_MEMBRANE_AUDIO_SESSION", description: - "Invalid audio session mode: \(sessionMode). Supported modes: videoChat, voiceChat") + "Invalid audio session mode: \(sessionMode). Supported modes: videoChat, voiceChat" + ) } setAudioSessionMode() } @@ -980,7 +1015,7 @@ class RNFishjamClient: FishjamClientListener { endpoint.videoTracks[videoTrack.track.trackId] = videoTrack let trackData = endpoint.tracksData[videoTrack.track.trackId] - endpoint.tracksData[videoTrack.track.trackId] = + endpoint.tracksData[videoTrack.track.trackId] = TrackData(metadata: ctx.metadata, simulcastConfig: trackData?.simulcastConfig) if let localTrackId = localTrackId, diff --git a/ios/RNFishjamClientModule.swift b/ios/RNFishjamClientModule.swift index 42f04a2a..afe247f7 100644 --- a/ios/RNFishjamClientModule.swift +++ b/ios/RNFishjamClientModule.swift @@ -69,20 +69,21 @@ public class RNFishjamClientModule: Module { "SendMediaEvent", "BandwidthEstimation") - let rnFishjamClient: RNFishjamClient = RNFishjamClient { (eventName: String, data: [String: Any]) in + let rnFishjamClient: RNFishjamClient = RNFishjamClient { + (eventName: String, data: [String: Any]) in self.sendEvent(eventName, data) } - AsyncFunction("connect") { (url: String, peerToken: String, promise: Promise ) in - try rnFishjamClient.create() - rnFishjamClient.connect(url: url, peerToken: peerToken, promise: promise) + AsyncFunction("connect") { (url: String, peerToken: String, promise: Promise) in + try rnFishjamClient.create() + rnFishjamClient.connect(url: url, peerToken: peerToken, promise: promise) } - AsyncFunction("joinRoom") { (peerMetadata: [String: Any], promise: Promise ) in + AsyncFunction("joinRoom") { (peerMetadata: [String: Any], promise: Promise) in rnFishjamClient.joinRoom(peerMetadata: peerMetadata, promise: promise) } - AsyncFunction("leaveRoom") { + AsyncFunction("leaveRoom") { rnFishjamClient.leaveRoom() } @@ -163,7 +164,8 @@ public class RNFishjamClientModule: Module { } AsyncFunction("setScreencastTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in - try rnFishjamClient.setScreencastTrackEncodingBandwidth(encoding: encoding, bandwidth: bandwidth) + try rnFishjamClient.setScreencastTrackEncodingBandwidth( + encoding: encoding, bandwidth: bandwidth) } AsyncFunction("setTargetTrackEncoding") { (trackId: String, encoding: String) in @@ -175,7 +177,8 @@ public class RNFishjamClientModule: Module { } AsyncFunction("setVideoTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in - try rnFishjamClient.setVideoTrackEncodingBandwidth(encoding: encoding, bandwidth: bandwidth) + try rnFishjamClient.setVideoTrackEncodingBandwidth( + encoding: encoding, bandwidth: bandwidth) } AsyncFunction("setVideoTrackBandwidth") { (bandwidth: Int) in