@fishjam-cloud/react-native-client 0.24.0 → 0.25.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -15
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/overrides/RTCPeerConnection.d.ts +8 -0
- package/dist/overrides/RTCPeerConnection.d.ts.map +1 -0
- package/dist/overrides/RTCPeerConnection.js +16 -0
- package/dist/overrides/RTCView.d.ts +11 -0
- package/dist/overrides/RTCView.d.ts.map +1 -0
- package/dist/overrides/RTCView.js +21 -0
- package/dist/polyfills/local-storage.d.ts +10 -0
- package/dist/polyfills/local-storage.d.ts.map +1 -0
- package/dist/polyfills/local-storage.js +24 -0
- package/{build/hooks → dist}/useForegroundService.d.ts +10 -10
- package/dist/useForegroundService.d.ts.map +1 -0
- package/dist/useForegroundService.js +10 -0
- package/dist/webrtc-polyfill.d.ts +2 -0
- package/dist/webrtc-polyfill.d.ts.map +1 -0
- package/dist/webrtc-polyfill.js +14 -0
- package/package.json +44 -92
- package/plugin/broadcastExtensionFiles/Atomic.swift +37 -0
- package/plugin/broadcastExtensionFiles/DarwinNotificationCenter.swift +29 -0
- package/plugin/broadcastExtensionFiles/Info.plist +1 -1
- package/plugin/broadcastExtensionFiles/SampleHandler.swift +104 -0
- package/plugin/broadcastExtensionFiles/SampleUploader.swift +146 -0
- package/plugin/broadcastExtensionFiles/SocketConnection.swift +198 -0
- package/plugin/build/types.d.ts +5 -4
- package/plugin/build/withFishjam.d.ts +31 -2
- package/plugin/build/withFishjam.js +31 -5
- package/plugin/build/withFishjamAndroid.d.ts +2 -2
- package/plugin/build/withFishjamAndroid.js +48 -40
- package/plugin/build/withFishjamIos.d.ts +3 -8
- package/plugin/build/withFishjamIos.js +52 -72
- package/plugin/src/types.ts +19 -0
- package/plugin/src/withFishjam.ts +42 -0
- package/plugin/src/withFishjamAndroid.ts +112 -0
- package/plugin/src/withFishjamIos.ts +336 -0
- package/plugin/tsconfig.json +9 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/LICENSE.txt +0 -201
- package/android/build.gradle +0 -95
- package/android/src/main/AndroidManifest.xml +0 -2
- package/android/src/main/java/io/fishjam/reactnative/AudioDeviceKind.kt +0 -34
- package/android/src/main/java/io/fishjam/reactnative/AudioSwitchManager.kt +0 -61
- package/android/src/main/java/io/fishjam/reactnative/EmitableEvents.kt +0 -126
- package/android/src/main/java/io/fishjam/reactnative/Errors.kt +0 -31
- package/android/src/main/java/io/fishjam/reactnative/PipContainerView.kt +0 -282
- package/android/src/main/java/io/fishjam/reactnative/PipContainerViewModule.kt +0 -41
- package/android/src/main/java/io/fishjam/reactnative/PipTrackSelector.kt +0 -98
- package/android/src/main/java/io/fishjam/reactnative/PipViewFactory.kt +0 -186
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +0 -1001
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +0 -358
- package/android/src/main/java/io/fishjam/reactnative/Utils.kt +0 -11
- package/android/src/main/java/io/fishjam/reactnative/VideoPreviewView.kt +0 -40
- package/android/src/main/java/io/fishjam/reactnative/VideoPreviewViewModule.kt +0 -22
- package/android/src/main/java/io/fishjam/reactnative/VideoRendererView.kt +0 -76
- package/android/src/main/java/io/fishjam/reactnative/VideoRendererViewModule.kt +0 -33
- package/android/src/main/java/io/fishjam/reactnative/VideoView.kt +0 -257
- package/android/src/main/java/io/fishjam/reactnative/extensions/CaptureDevice.kt +0 -17
- package/android/src/main/java/io/fishjam/reactnative/foregroundService/FishjamForegroundService.kt +0 -101
- package/android/src/main/java/io/fishjam/reactnative/foregroundService/ForegroundServiceManager.kt +0 -118
- package/android/src/main/java/io/fishjam/reactnative/foregroundService/ForegroundServiceState.kt +0 -46
- package/android/src/main/java/io/fishjam/reactnative/helpers/PictureInPictureHelperFragment.kt +0 -20
- package/android/src/main/java/io/fishjam/reactnative/managers/ListenerManager.kt +0 -24
- package/android/src/main/java/io/fishjam/reactnative/managers/LocalCameraTracksChangedListenersManager.kt +0 -8
- package/android/src/main/java/io/fishjam/reactnative/managers/LocalTracksSwitchListenersManager.kt +0 -17
- package/android/src/main/java/io/fishjam/reactnative/managers/TracksUpdateListenersManager.kt +0 -7
- package/android/src/main/java/io/fishjam/reactnative/utils/PermissionUtils.kt +0 -45
- package/build/RNFishjamClientModule.d.ts +0 -106
- package/build/RNFishjamClientModule.d.ts.map +0 -1
- package/build/RNFishjamClientModule.js +0 -21
- package/build/RNFishjamClientModule.js.map +0 -1
- package/build/common/metadata.d.ts +0 -9
- package/build/common/metadata.d.ts.map +0 -1
- package/build/common/metadata.js +0 -11
- package/build/common/metadata.js.map +0 -1
- package/build/components/FishjamRoom/GridTrackItem.d.ts +0 -12
- package/build/components/FishjamRoom/GridTrackItem.d.ts.map +0 -1
- package/build/components/FishjamRoom/GridTrackItem.js +0 -56
- package/build/components/FishjamRoom/GridTrackItem.js.map +0 -1
- package/build/components/FishjamRoom/VideosGrid.d.ts +0 -3
- package/build/components/FishjamRoom/VideosGrid.d.ts.map +0 -1
- package/build/components/FishjamRoom/VideosGrid.js +0 -20
- package/build/components/FishjamRoom/VideosGrid.js.map +0 -1
- package/build/components/FishjamRoom/index.d.ts +0 -33
- package/build/components/FishjamRoom/index.d.ts.map +0 -1
- package/build/components/FishjamRoom/index.js +0 -52
- package/build/components/FishjamRoom/index.js.map +0 -1
- package/build/components/FishjamRoom/parsePeersToTracks.d.ts +0 -4
- package/build/components/FishjamRoom/parsePeersToTracks.d.ts.map +0 -1
- package/build/components/FishjamRoom/parsePeersToTracks.js +0 -37
- package/build/components/FishjamRoom/parsePeersToTracks.js.map +0 -1
- package/build/components/PipContainerView.d.ts +0 -48
- package/build/components/PipContainerView.d.ts.map +0 -1
- package/build/components/PipContainerView.js +0 -34
- package/build/components/PipContainerView.js.map +0 -1
- package/build/components/VideoPreviewView.d.ts +0 -28
- package/build/components/VideoPreviewView.d.ts.map +0 -1
- package/build/components/VideoPreviewView.js +0 -17
- package/build/components/VideoPreviewView.js.map +0 -1
- package/build/components/VideoRendererView.d.ts +0 -39
- package/build/components/VideoRendererView.d.ts.map +0 -1
- package/build/components/VideoRendererView.js +0 -25
- package/build/components/VideoRendererView.js.map +0 -1
- package/build/consts/index.d.ts +0 -5
- package/build/consts/index.d.ts.map +0 -1
- package/build/consts/index.js +0 -8
- package/build/consts/index.js.map +0 -1
- package/build/debug/common/webRTC.d.ts +0 -9
- package/build/debug/common/webRTC.d.ts.map +0 -1
- package/build/debug/common/webRTC.js +0 -11
- package/build/debug/common/webRTC.js.map +0 -1
- package/build/debug/index.d.ts +0 -4
- package/build/debug/index.d.ts.map +0 -1
- package/build/debug/index.js +0 -3
- package/build/debug/index.js.map +0 -1
- package/build/debug/stats/types.d.ts +0 -55
- package/build/debug/stats/types.d.ts.map +0 -1
- package/build/debug/stats/types.js +0 -2
- package/build/debug/stats/types.js.map +0 -1
- package/build/debug/stats/useRTCStatistics.d.ts +0 -9
- package/build/debug/stats/useRTCStatistics.d.ts.map +0 -1
- package/build/debug/stats/useRTCStatistics.js +0 -79
- package/build/debug/stats/useRTCStatistics.js.map +0 -1
- package/build/hooks/internal/useFishjamEvent.d.ts +0 -4
- package/build/hooks/internal/useFishjamEvent.d.ts.map +0 -1
- package/build/hooks/internal/useFishjamEvent.js +0 -38
- package/build/hooks/internal/useFishjamEvent.js.map +0 -1
- package/build/hooks/internal/useFishjamEventState.d.ts +0 -3
- package/build/hooks/internal/useFishjamEventState.d.ts.map +0 -1
- package/build/hooks/internal/useFishjamEventState.js +0 -18
- package/build/hooks/internal/useFishjamEventState.js.map +0 -1
- package/build/hooks/useAppScreenShare.d.ts +0 -18
- package/build/hooks/useAppScreenShare.d.ts.map +0 -1
- package/build/hooks/useAppScreenShare.js +0 -46
- package/build/hooks/useAppScreenShare.js.map +0 -1
- package/build/hooks/useAudioSettings.d.ts +0 -49
- package/build/hooks/useAudioSettings.d.ts.map +0 -1
- package/build/hooks/useAudioSettings.js +0 -70
- package/build/hooks/useAudioSettings.js.map +0 -1
- package/build/hooks/useBandwidthEstimation.d.ts +0 -14
- package/build/hooks/useBandwidthEstimation.d.ts.map +0 -1
- package/build/hooks/useBandwidthEstimation.js +0 -19
- package/build/hooks/useBandwidthEstimation.js.map +0 -1
- package/build/hooks/useCallKit.d.ts +0 -121
- package/build/hooks/useCallKit.d.ts.map +0 -1
- package/build/hooks/useCallKit.js +0 -142
- package/build/hooks/useCallKit.js.map +0 -1
- package/build/hooks/useCamera.d.ts +0 -113
- package/build/hooks/useCamera.d.ts.map +0 -1
- package/build/hooks/useCamera.js +0 -93
- package/build/hooks/useCamera.js.map +0 -1
- package/build/hooks/useConnection.d.ts +0 -73
- package/build/hooks/useConnection.d.ts.map +0 -1
- package/build/hooks/useConnection.js +0 -46
- package/build/hooks/useConnection.js.map +0 -1
- package/build/hooks/useForegroundService.d.ts.map +0 -1
- package/build/hooks/useForegroundService.js +0 -66
- package/build/hooks/useForegroundService.js.map +0 -1
- package/build/hooks/useMicrophone.d.ts +0 -16
- package/build/hooks/useMicrophone.d.ts.map +0 -1
- package/build/hooks/useMicrophone.js +0 -31
- package/build/hooks/useMicrophone.js.map +0 -1
- package/build/hooks/usePeerStatus.d.ts +0 -10
- package/build/hooks/usePeerStatus.d.ts.map +0 -1
- package/build/hooks/usePeerStatus.js +0 -13
- package/build/hooks/usePeerStatus.js.map +0 -1
- package/build/hooks/usePeers.d.ts +0 -98
- package/build/hooks/usePeers.d.ts.map +0 -1
- package/build/hooks/usePeers.js +0 -81
- package/build/hooks/usePeers.js.map +0 -1
- package/build/hooks/usePermissions.d.ts +0 -24
- package/build/hooks/usePermissions.d.ts.map +0 -1
- package/build/hooks/usePermissions.js +0 -61
- package/build/hooks/usePermissions.js.map +0 -1
- package/build/hooks/useReconnection.d.ts +0 -11
- package/build/hooks/useReconnection.d.ts.map +0 -1
- package/build/hooks/useReconnection.js +0 -14
- package/build/hooks/useReconnection.js.map +0 -1
- package/build/hooks/useSandbox.d.ts +0 -20
- package/build/hooks/useSandbox.d.ts.map +0 -1
- package/build/hooks/useSandbox.js +0 -54
- package/build/hooks/useSandbox.js.map +0 -1
- package/build/hooks/useScreenShare.d.ts +0 -36
- package/build/hooks/useScreenShare.d.ts.map +0 -1
- package/build/hooks/useScreenShare.js +0 -45
- package/build/hooks/useScreenShare.js.map +0 -1
- package/build/hooks/useUpdatePeerMetadata.d.ts +0 -15
- package/build/hooks/useUpdatePeerMetadata.d.ts.map +0 -1
- package/build/hooks/useUpdatePeerMetadata.js +0 -21
- package/build/hooks/useUpdatePeerMetadata.js.map +0 -1
- package/build/index.d.ts +0 -36
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -30
- package/build/index.js.map +0 -1
- package/build/livestream/components/LivestreamStreamer.d.ts +0 -24
- package/build/livestream/components/LivestreamStreamer.d.ts.map +0 -1
- package/build/livestream/components/LivestreamStreamer.js +0 -12
- package/build/livestream/components/LivestreamStreamer.js.map +0 -1
- package/build/livestream/components/LivestreamViewer.d.ts +0 -46
- package/build/livestream/components/LivestreamViewer.d.ts.map +0 -1
- package/build/livestream/components/LivestreamViewer.js +0 -10
- package/build/livestream/components/LivestreamViewer.js.map +0 -1
- package/build/livestream/hooks/useLivestreamScreenSharingStreamer.d.ts +0 -49
- package/build/livestream/hooks/useLivestreamScreenSharingStreamer.d.ts.map +0 -1
- package/build/livestream/hooks/useLivestreamScreenSharingStreamer.js +0 -58
- package/build/livestream/hooks/useLivestreamScreenSharingStreamer.js.map +0 -1
- package/build/livestream/hooks/useLivestreamStreamer.d.ts +0 -65
- package/build/livestream/hooks/useLivestreamStreamer.d.ts.map +0 -1
- package/build/livestream/hooks/useLivestreamStreamer.js +0 -71
- package/build/livestream/hooks/useLivestreamStreamer.js.map +0 -1
- package/build/livestream/hooks/useLivestreamViewer.d.ts +0 -36
- package/build/livestream/hooks/useLivestreamViewer.d.ts.map +0 -1
- package/build/livestream/hooks/useLivestreamViewer.js +0 -73
- package/build/livestream/hooks/useLivestreamViewer.js.map +0 -1
- package/build/livestream/index.d.ts +0 -12
- package/build/livestream/index.d.ts.map +0 -1
- package/build/livestream/index.js +0 -7
- package/build/livestream/index.js.map +0 -1
- package/build/protos/fishjam/peer_notifications.d.ts +0 -63
- package/build/protos/fishjam/peer_notifications.d.ts.map +0 -1
- package/build/protos/fishjam/peer_notifications.js +0 -235
- package/build/protos/fishjam/peer_notifications.js.map +0 -1
- package/build/types.d.ts +0 -34
- package/build/types.d.ts.map +0 -1
- package/build/types.js +0 -2
- package/build/types.js.map +0 -1
- package/build/utils/config.d.ts +0 -6
- package/build/utils/config.d.ts.map +0 -1
- package/build/utils/config.js +0 -10
- package/build/utils/config.js.map +0 -1
- package/build/utils/errorListener.d.ts +0 -2
- package/build/utils/errorListener.d.ts.map +0 -1
- package/build/utils/errorListener.js +0 -15
- package/build/utils/errorListener.js.map +0 -1
- package/build/utils/eventPayloadValidator.d.ts +0 -3
- package/build/utils/eventPayloadValidator.d.ts.map +0 -1
- package/build/utils/eventPayloadValidator.js +0 -86
- package/build/utils/eventPayloadValidator.js.map +0 -1
- package/build/utils/getFishjamUrl.d.ts +0 -2
- package/build/utils/getFishjamUrl.d.ts.map +0 -1
- package/build/utils/getFishjamUrl.js +0 -10
- package/build/utils/getFishjamUrl.js.map +0 -1
- package/debug/package.json +0 -4
- package/expo-module.config.json +0 -19
- package/ios/CameraPermissionsRequester.swift +0 -117
- package/ios/Events.swift +0 -152
- package/ios/PictureInPictureManager.swift +0 -215
- package/ios/PipContainerView.swift +0 -56
- package/ios/PipContainerViewModule.swift +0 -48
- package/ios/RNFishjamClient.podspec +0 -30
- package/ios/RNFishjamClient.swift +0 -995
- package/ios/RNFishjamClientModule.swift +0 -289
- package/ios/RNFishjamProxy.swift +0 -12
- package/ios/Utils/PermissionUtils.swift +0 -16
- package/ios/Utils.swift +0 -23
- package/ios/VideoPreviewView.swift +0 -54
- package/ios/VideoPreviewViewModule.swift +0 -21
- package/ios/VideoRendererView.swift +0 -98
- package/ios/VideoRendererViewModule.swift +0 -23
- package/ios/extensions/AVCaptureDevice.swift +0 -20
- package/ios/managers/LocalCameraTracksChangedListenersManager.swift +0 -23
- package/ios/managers/TracksUpdateListenersManager.swift +0 -21
- package/livestream/package.json +0 -4
- package/plugin/broadcastExtensionFiles/FishjamBroadcastSampleHandler.swift +0 -50
- /package/plugin/broadcastExtensionFiles/{FishjamScreenBroadcastExtension.entitlements → ScreenBroadcastExtension.entitlements} +0 -0
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
package io.fishjam.reactnative
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.os.Handler
|
|
5
|
-
import android.os.Looper
|
|
6
|
-
import com.twilio.audioswitch.AudioDevice
|
|
7
|
-
import com.twilio.audioswitch.AudioDeviceChangeListener
|
|
8
|
-
import com.twilio.audioswitch.AudioSwitch
|
|
9
|
-
|
|
10
|
-
class AudioSwitchManager(
|
|
11
|
-
private val context: Context
|
|
12
|
-
) {
|
|
13
|
-
private var preferredDeviceList =
|
|
14
|
-
listOf(
|
|
15
|
-
AudioDevice.BluetoothHeadset::class.java,
|
|
16
|
-
AudioDevice.WiredHeadset::class.java,
|
|
17
|
-
AudioDevice.Speakerphone::class.java,
|
|
18
|
-
AudioDevice.Earpiece::class.java
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
// AudioSwitch is not threadsafe, so all calls should be done on the main thread.
|
|
22
|
-
private val handler: Handler = Handler(Looper.getMainLooper())
|
|
23
|
-
|
|
24
|
-
private var audioSwitch: AudioSwitch =
|
|
25
|
-
AudioSwitch(context, loggingEnabled = true, preferredDeviceList = preferredDeviceList)
|
|
26
|
-
|
|
27
|
-
fun start(listener: AudioDeviceChangeListener) {
|
|
28
|
-
handler.removeCallbacksAndMessages(null)
|
|
29
|
-
handler.postAtFrontOfQueue {
|
|
30
|
-
audioSwitch.start(listener)
|
|
31
|
-
audioSwitch.activate()
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
fun stop() {
|
|
36
|
-
handler.removeCallbacksAndMessages(null)
|
|
37
|
-
handler.postAtFrontOfQueue {
|
|
38
|
-
audioSwitch.stop()
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
fun selectedAudioDevice(): AudioDevice? = audioSwitch.selectedAudioDevice
|
|
43
|
-
|
|
44
|
-
fun availableAudioDevices(): List<AudioDevice> = audioSwitch.availableAudioDevices
|
|
45
|
-
|
|
46
|
-
fun selectAudioOutput(audioDeviceClass: Class<out AudioDevice?>) {
|
|
47
|
-
handler.post {
|
|
48
|
-
availableAudioDevices()
|
|
49
|
-
.find { it.javaClass == audioDeviceClass }
|
|
50
|
-
?.let {
|
|
51
|
-
audioSwitch.selectDevice(it)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
fun selectAudioOutput(kind: AudioDeviceKind?) {
|
|
57
|
-
if (kind != null) {
|
|
58
|
-
selectAudioOutput(kind.audioDeviceClass)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
package io.fishjam.reactnative
|
|
2
|
-
|
|
3
|
-
import com.fishjamcloud.client.ReconnectionStatus
|
|
4
|
-
import com.fishjamcloud.client.models.SimulcastConfig
|
|
5
|
-
import com.twilio.audioswitch.AudioDevice
|
|
6
|
-
import io.fishjam.reactnative.extensions.LocalCamera
|
|
7
|
-
|
|
8
|
-
enum class PeerStatus(
|
|
9
|
-
val status: String
|
|
10
|
-
) {
|
|
11
|
-
Connecting("connecting"),
|
|
12
|
-
Connected("connected"),
|
|
13
|
-
Idle("idle"),
|
|
14
|
-
Error("error")
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class EmitableEvent private constructor(
|
|
18
|
-
private val event: EventName,
|
|
19
|
-
private val eventContent: Any? = null
|
|
20
|
-
) {
|
|
21
|
-
enum class EventName {
|
|
22
|
-
IsMicrophoneOn,
|
|
23
|
-
IsScreenShareOn,
|
|
24
|
-
SimulcastConfigUpdate,
|
|
25
|
-
PeersUpdate,
|
|
26
|
-
AudioDeviceUpdate,
|
|
27
|
-
BandwidthEstimation,
|
|
28
|
-
Warning,
|
|
29
|
-
PeerStatusChanged,
|
|
30
|
-
ReconnectionStatusChanged,
|
|
31
|
-
CurrentCameraChanged,
|
|
32
|
-
TrackAspectRatioUpdated
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
val name: String
|
|
36
|
-
get() = event.name
|
|
37
|
-
|
|
38
|
-
val data: Map<String, Any?>
|
|
39
|
-
get() = mapOf(event.name to eventContent)
|
|
40
|
-
|
|
41
|
-
companion object {
|
|
42
|
-
fun isMicrophoneOn(enabled: Boolean) = EmitableEvent(EventName.IsMicrophoneOn, enabled)
|
|
43
|
-
|
|
44
|
-
fun isScreenShareOn(enabled: Boolean) = EmitableEvent(EventName.IsScreenShareOn, enabled)
|
|
45
|
-
|
|
46
|
-
fun bandwidthEstimation(estimation: Long) = EmitableEvent(EventName.BandwidthEstimation, estimation.toFloat())
|
|
47
|
-
|
|
48
|
-
fun warning(message: String) = EmitableEvent(EventName.Warning, message)
|
|
49
|
-
|
|
50
|
-
fun peerStatusChanged(peerStatus: PeerStatus) = EmitableEvent(EventName.PeerStatusChanged, peerStatus.status)
|
|
51
|
-
|
|
52
|
-
fun reconnectionStatusChanged(reconnectionStatus: ReconnectionStatus) =
|
|
53
|
-
EmitableEvent(EventName.ReconnectionStatusChanged, reconnectionStatus.status)
|
|
54
|
-
|
|
55
|
-
fun currentCameraChanged(
|
|
56
|
-
localCamera: LocalCamera?,
|
|
57
|
-
isCameraOn: Boolean,
|
|
58
|
-
isCameraInitialized: Boolean
|
|
59
|
-
) = EmitableEvent(
|
|
60
|
-
EventName.CurrentCameraChanged,
|
|
61
|
-
mapOf(
|
|
62
|
-
"currentCamera" to localCamera,
|
|
63
|
-
"isCameraOn" to isCameraOn,
|
|
64
|
-
"isCameraInitialized" to isCameraInitialized
|
|
65
|
-
)
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
fun simulcastConfigUpdate(simulcastConfig: SimulcastConfig) =
|
|
69
|
-
EmitableEvent(
|
|
70
|
-
EventName.SimulcastConfigUpdate,
|
|
71
|
-
mapOf(
|
|
72
|
-
"enabled" to simulcastConfig.enabled,
|
|
73
|
-
"activeEncodings" to simulcastConfig.activeEncodings.map { it.rid }
|
|
74
|
-
)
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
fun peersUpdate(peersData: List<Map<String, Any?>>) = EmitableEvent(EventName.PeersUpdate, peersData)
|
|
78
|
-
|
|
79
|
-
fun audioDeviceUpdate(
|
|
80
|
-
audioDevices: List<AudioDevice>,
|
|
81
|
-
selectedDevice: AudioDevice?
|
|
82
|
-
): EmitableEvent {
|
|
83
|
-
val audioDeviceAsMap = { audioDevice: AudioDevice ->
|
|
84
|
-
mapOf(
|
|
85
|
-
"name" to audioDevice.name,
|
|
86
|
-
"type" to AudioDeviceKind.fromAudioDevice(audioDevice)?.typeName
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return EmitableEvent(
|
|
91
|
-
EventName.AudioDeviceUpdate,
|
|
92
|
-
mapOf(
|
|
93
|
-
"selectedDevice" to (
|
|
94
|
-
if (selectedDevice != null) {
|
|
95
|
-
audioDeviceAsMap(
|
|
96
|
-
selectedDevice
|
|
97
|
-
)
|
|
98
|
-
} else {
|
|
99
|
-
null
|
|
100
|
-
}
|
|
101
|
-
),
|
|
102
|
-
"availableDevices" to
|
|
103
|
-
audioDevices.map { audioDevice ->
|
|
104
|
-
audioDeviceAsMap(
|
|
105
|
-
audioDevice
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
)
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
fun trackAspectRatioUpdated(
|
|
113
|
-
trackId: String,
|
|
114
|
-
aspectRatio: Double?
|
|
115
|
-
) = EmitableEvent(
|
|
116
|
-
EventName.TrackAspectRatioUpdated,
|
|
117
|
-
mapOf(
|
|
118
|
-
"trackId" to trackId,
|
|
119
|
-
"aspectRatio" to aspectRatio
|
|
120
|
-
)
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
val allEvents: Array<String>
|
|
124
|
-
get() = EventName.entries.map { it.name }.toTypedArray()
|
|
125
|
-
}
|
|
126
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
package io.fishjam.reactnative
|
|
2
|
-
|
|
3
|
-
import com.fishjamcloud.client.models.AuthError
|
|
4
|
-
import expo.modules.kotlin.exception.CodedException
|
|
5
|
-
|
|
6
|
-
class JoinError(
|
|
7
|
-
metadata: Any
|
|
8
|
-
) : CodedException(message = "Join error: $metadata")
|
|
9
|
-
|
|
10
|
-
class ConnectionError(
|
|
11
|
-
reason: AuthError
|
|
12
|
-
) : CodedException(message = "Connection error: ${reason.error}")
|
|
13
|
-
|
|
14
|
-
class MissingScreenSharePermission : CodedException(message = "No permission to start screen share.")
|
|
15
|
-
|
|
16
|
-
class ClientNotConnectedError : CodedException(message = "Client not connected to server yet. Make sure to call connect() first!")
|
|
17
|
-
|
|
18
|
-
class NoLocalVideoTrackError : CodedException(message = "No local video track. Make sure to call connect() first!")
|
|
19
|
-
|
|
20
|
-
class NoLocalAudioTrackError : CodedException(message = "No local audio track. Make sure to call connect() first!")
|
|
21
|
-
|
|
22
|
-
class NoScreenShareTrackError : CodedException(message = "No local screen share track. Make sure to toggle screen share on first!")
|
|
23
|
-
|
|
24
|
-
class SocketClosedError(
|
|
25
|
-
code: Int,
|
|
26
|
-
reason: String
|
|
27
|
-
) : CodedException(message = "Socket was closed with code = $code and reason = $reason")
|
|
28
|
-
|
|
29
|
-
class SocketError(
|
|
30
|
-
message: String
|
|
31
|
-
) : CodedException(message = "Socket error: $message")
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
package io.fishjam.reactnative
|
|
2
|
-
|
|
3
|
-
import android.app.PictureInPictureParams
|
|
4
|
-
import android.content.Context
|
|
5
|
-
import android.os.Build
|
|
6
|
-
import android.util.Log
|
|
7
|
-
import android.view.View
|
|
8
|
-
import android.view.ViewGroup
|
|
9
|
-
import androidx.annotation.RequiresApi
|
|
10
|
-
import androidx.fragment.app.FragmentActivity
|
|
11
|
-
import expo.modules.kotlin.AppContext
|
|
12
|
-
import expo.modules.kotlin.views.ExpoView
|
|
13
|
-
import io.fishjam.reactnative.helpers.PictureInPictureHelperFragment
|
|
14
|
-
import io.fishjam.reactnative.managers.TrackUpdateListener
|
|
15
|
-
import java.lang.ref.WeakReference
|
|
16
|
-
|
|
17
|
-
data class RemoteTrackInfo(
|
|
18
|
-
val videoTrack: com.fishjamcloud.client.media.VideoTrack?,
|
|
19
|
-
val displayName: String?,
|
|
20
|
-
val videoTrackActive: Boolean
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
class PipContainerView(
|
|
24
|
-
context: Context,
|
|
25
|
-
appContext: AppContext
|
|
26
|
-
) : ExpoView(context, appContext), TrackUpdateListener {
|
|
27
|
-
|
|
28
|
-
companion object {
|
|
29
|
-
private const val TAG = "PipContainerView"
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
private val activityRef: WeakReference<FragmentActivity?> = WeakReference(
|
|
33
|
-
appContext.currentActivity as? FragmentActivity
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
private val decorView = activityRef.get()?.window?.decorView
|
|
37
|
-
private val rootView = decorView?.findViewById<ViewGroup>(android.R.id.content)
|
|
38
|
-
private val rootViewChildrenOriginalVisibility: ArrayList<Int> = arrayListOf()
|
|
39
|
-
|
|
40
|
-
private var pictureInPictureHelperTag: String? = null
|
|
41
|
-
private var pipViews: PipViewContainer? = null
|
|
42
|
-
private var isPipActive = false
|
|
43
|
-
|
|
44
|
-
private val trackSelector = PipTrackSelector()
|
|
45
|
-
private val viewFactory by lazy { PipViewFactory(context, appContext) }
|
|
46
|
-
|
|
47
|
-
@RequiresApi(Build.VERSION_CODES.O)
|
|
48
|
-
private val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
|
|
49
|
-
|
|
50
|
-
var startAutomatically: Boolean = true
|
|
51
|
-
set(value) {
|
|
52
|
-
field = value
|
|
53
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
54
|
-
updateAutoEnterEnabled()
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
var stopAutomatically: Boolean = true
|
|
59
|
-
|
|
60
|
-
var primaryPlaceholderText: String = "No camera"
|
|
61
|
-
set(value) {
|
|
62
|
-
field = value
|
|
63
|
-
pipViews?.primaryPlaceholder?.text = value
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
var secondaryPlaceholderText: String = "No active speaker"
|
|
67
|
-
set(value) {
|
|
68
|
-
field = value
|
|
69
|
-
pipViews?.secondaryPlaceholder?.text = value
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private var remoteTrackInfo: RemoteTrackInfo? = null
|
|
73
|
-
|
|
74
|
-
@RequiresApi(Build.VERSION_CODES.O)
|
|
75
|
-
private fun updatePictureInPictureParams() {
|
|
76
|
-
val activity = activityRef.get()
|
|
77
|
-
if (activity == null) {
|
|
78
|
-
Log.w(TAG, "Cannot update PiP params: activity reference is null")
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
activity.setPictureInPictureParams(pictureInPictureParamsBuilder.build())
|
|
84
|
-
} catch (e: IllegalStateException) {
|
|
85
|
-
Log.e(TAG, "Failed to update PiP params", e)
|
|
86
|
-
emitPipNotSupportedWarning()
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
private fun emitPipNotSupportedWarning() {
|
|
91
|
-
RNFishjamClient.sendEvent(
|
|
92
|
-
EmitableEvent.warning(
|
|
93
|
-
"Picture-in-Picture is not supported. Enable it in app.json."
|
|
94
|
-
)
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
@RequiresApi(Build.VERSION_CODES.S)
|
|
99
|
-
private fun updateAutoEnterEnabled() {
|
|
100
|
-
pictureInPictureParamsBuilder.setAutoEnterEnabled(startAutomatically)
|
|
101
|
-
updatePictureInPictureParams()
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private fun updatePipViews() {
|
|
105
|
-
val views = pipViews ?: run {
|
|
106
|
-
Log.w(TAG, "Cannot update PiP views: pipViews is null")
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
val localCameraTrack = trackSelector.findLocalCameraTrack()
|
|
111
|
-
updatePrimaryView(views, localCameraTrack)
|
|
112
|
-
|
|
113
|
-
remoteTrackInfo = trackSelector.findSecondaryRemoteTrack(remoteTrackInfo)
|
|
114
|
-
updateSecondaryView(views, remoteTrackInfo)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private fun updatePrimaryView(
|
|
118
|
-
views: PipViewContainer,
|
|
119
|
-
localCameraTrack: com.fishjamcloud.client.media.VideoTrack?
|
|
120
|
-
) {
|
|
121
|
-
if (localCameraTrack != null && localCameraTrack.isEnabled()) {
|
|
122
|
-
views.primaryVideoView.init(localCameraTrack.id())
|
|
123
|
-
views.primaryVideoView.visibility = View.VISIBLE
|
|
124
|
-
views.primaryPlaceholder.visibility = View.GONE
|
|
125
|
-
} else {
|
|
126
|
-
views.primaryVideoView.visibility = View.GONE
|
|
127
|
-
views.primaryPlaceholder.visibility = View.VISIBLE
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private fun updateSecondaryView(
|
|
132
|
-
views: PipViewContainer,
|
|
133
|
-
trackInfo: RemoteTrackInfo?
|
|
134
|
-
) {
|
|
135
|
-
trackInfo?.let { info ->
|
|
136
|
-
if (info.videoTrackActive && info.videoTrack != null) {
|
|
137
|
-
views.secondaryVideoView.init(info.videoTrack.id())
|
|
138
|
-
views.secondaryVideoView.visibility = View.VISIBLE
|
|
139
|
-
views.secondaryPlaceholder.visibility = View.GONE
|
|
140
|
-
|
|
141
|
-
info.displayName?.let { displayName ->
|
|
142
|
-
views.secondaryNameOverlay.text = displayName
|
|
143
|
-
views.secondaryNameOverlay.visibility = View.VISIBLE
|
|
144
|
-
} ?: run {
|
|
145
|
-
views.secondaryNameOverlay.visibility = View.GONE
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
views.secondaryVideoView.visibility = View.GONE
|
|
149
|
-
views.secondaryPlaceholder.text = info.displayName
|
|
150
|
-
views.secondaryPlaceholder.visibility = View.VISIBLE
|
|
151
|
-
views.secondaryNameOverlay.visibility = View.GONE
|
|
152
|
-
}
|
|
153
|
-
} ?: run {
|
|
154
|
-
views.secondaryVideoView.visibility = View.GONE
|
|
155
|
-
views.secondaryPlaceholder.text = secondaryPlaceholderText
|
|
156
|
-
views.secondaryPlaceholder.visibility = View.VISIBLE
|
|
157
|
-
views.secondaryNameOverlay.visibility = View.GONE
|
|
158
|
-
}
|
|
159
|
-
views.secondaryContainer.visibility = View.VISIBLE
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
@RequiresApi(Build.VERSION_CODES.O)
|
|
163
|
-
fun startPictureInPicture() {
|
|
164
|
-
val activity = activityRef.get()
|
|
165
|
-
if (activity == null) {
|
|
166
|
-
Log.w(TAG, "Cannot start PiP: activity reference is null")
|
|
167
|
-
return
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
try {
|
|
171
|
-
activity.enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
|
|
172
|
-
} catch (e: IllegalStateException) {
|
|
173
|
-
Log.e(TAG, "Failed to enter PiP mode", e)
|
|
174
|
-
emitPipNotSupportedWarning()
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
fun stopPictureInPicture() {
|
|
179
|
-
Log.d(TAG, "stopPictureInPicture called, but no-op on Android")
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
override fun onAttachedToWindow() {
|
|
183
|
-
super.onAttachedToWindow()
|
|
184
|
-
|
|
185
|
-
activityRef.get()?.let { activity ->
|
|
186
|
-
val fragment = PictureInPictureHelperFragment(this)
|
|
187
|
-
pictureInPictureHelperTag = fragment.id
|
|
188
|
-
activity.supportFragmentManager.beginTransaction()
|
|
189
|
-
.add(fragment, fragment.id)
|
|
190
|
-
.commitAllowingStateLoss()
|
|
191
|
-
} ?: Log.w(TAG, "Cannot attach PiP helper: activity reference is null")
|
|
192
|
-
|
|
193
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
194
|
-
updateAutoEnterEnabled()
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
RNFishjamClient.trackUpdateListenersManager.add(this)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
override fun onDetachedFromWindow() {
|
|
201
|
-
super.onDetachedFromWindow()
|
|
202
|
-
|
|
203
|
-
activityRef.get()?.let { activity ->
|
|
204
|
-
pictureInPictureHelperTag?.let { tag ->
|
|
205
|
-
activity.supportFragmentManager.findFragmentByTag(tag)?.let { fragment ->
|
|
206
|
-
activity.supportFragmentManager.beginTransaction()
|
|
207
|
-
.remove(fragment)
|
|
208
|
-
.commitAllowingStateLoss()
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
startAutomatically = false
|
|
214
|
-
RNFishjamClient.trackUpdateListenersManager.remove(this)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
override fun onTracksUpdate() {
|
|
218
|
-
if (isPipActive) {
|
|
219
|
-
updatePipViews()
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
fun layoutForPiPEnter() {
|
|
224
|
-
val root = rootView
|
|
225
|
-
if (root == null) {
|
|
226
|
-
Log.w(TAG, "Cannot enter PiP layout: rootView is null")
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
isPipActive = true
|
|
231
|
-
|
|
232
|
-
hideAllRootViewChildren(root)
|
|
233
|
-
pipViews = viewFactory.createPipViews(primaryPlaceholderText, secondaryPlaceholderText)
|
|
234
|
-
pipViews?.let { views ->
|
|
235
|
-
root.addView(views.splitScreenContainer)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
updatePipViews()
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
fun layoutForPiPExit() {
|
|
242
|
-
val root = rootView
|
|
243
|
-
if (root == null) {
|
|
244
|
-
Log.w(TAG, "Cannot exit PiP layout: rootView is null")
|
|
245
|
-
return
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
isPipActive = false
|
|
249
|
-
|
|
250
|
-
pipViews?.let { views ->
|
|
251
|
-
root.removeView(views.splitScreenContainer)
|
|
252
|
-
cleanUpViews(views)
|
|
253
|
-
}
|
|
254
|
-
pipViews = null
|
|
255
|
-
|
|
256
|
-
restoreRootViewChildren(root)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
private fun cleanUpViews(views: PipViewContainer) {
|
|
260
|
-
views.primaryVideoView.dispose()
|
|
261
|
-
views.secondaryVideoView.dispose()
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
private fun hideAllRootViewChildren(rootView: ViewGroup) {
|
|
265
|
-
rootViewChildrenOriginalVisibility.clear()
|
|
266
|
-
(0 until rootView.childCount).forEach { i ->
|
|
267
|
-
val child = rootView.getChildAt(i)
|
|
268
|
-
rootViewChildrenOriginalVisibility.add(child.visibility)
|
|
269
|
-
child.visibility = View.GONE
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
private fun restoreRootViewChildren(rootView: ViewGroup) {
|
|
274
|
-
rootViewChildrenOriginalVisibility.forEachIndexed { index, originalVisibility ->
|
|
275
|
-
if (index < rootView.childCount) {
|
|
276
|
-
rootView.getChildAt(index).visibility = originalVisibility
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
rootViewChildrenOriginalVisibility.clear()
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
package io.fishjam.reactnative
|
|
2
|
-
|
|
3
|
-
import expo.modules.kotlin.modules.Module
|
|
4
|
-
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
-
|
|
6
|
-
class PipContainerViewModule : Module() {
|
|
7
|
-
override fun definition() =
|
|
8
|
-
ModuleDefinition {
|
|
9
|
-
Name("PipContainerViewModule")
|
|
10
|
-
|
|
11
|
-
View(PipContainerView::class) {
|
|
12
|
-
Prop("startAutomatically") { view: PipContainerView, value: Boolean ->
|
|
13
|
-
view.startAutomatically = value
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
Prop("stopAutomatically") { view: PipContainerView, value: Boolean ->
|
|
17
|
-
view.stopAutomatically = value
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// iOS-only property, no-op on Android
|
|
21
|
-
Prop("allowsCameraInBackground") { _: PipContainerView, _: Boolean -> }
|
|
22
|
-
|
|
23
|
-
Prop("primaryPlaceholderText") { view: PipContainerView, value: String ->
|
|
24
|
-
view.primaryPlaceholderText = value
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
Prop("secondaryPlaceholderText") { view: PipContainerView, value: String ->
|
|
28
|
-
view.secondaryPlaceholderText = value
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
AsyncFunction("startPictureInPicture") { view: PipContainerView ->
|
|
32
|
-
view.startPictureInPicture()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
AsyncFunction("stopPictureInPicture") { view: PipContainerView ->
|
|
36
|
-
view.stopPictureInPicture()
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
package io.fishjam.reactnative
|
|
2
|
-
|
|
3
|
-
import com.fishjamcloud.client.media.RemoteAudioTrack
|
|
4
|
-
import com.fishjamcloud.client.media.Track
|
|
5
|
-
import com.fishjamcloud.client.media.VideoTrack
|
|
6
|
-
import com.fishjamcloud.client.models.Peer
|
|
7
|
-
import fishjam.media_events.server.Server
|
|
8
|
-
|
|
9
|
-
class PipTrackSelector {
|
|
10
|
-
companion object {
|
|
11
|
-
private const val METADATA_TYPE = "type"
|
|
12
|
-
private const val METADATA_CAMERA = "camera"
|
|
13
|
-
private const val METADATA_DISPLAY_NAME = "displayName"
|
|
14
|
-
private const val METADATA_NAME = "name"
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
fun findLocalCameraTrack(): VideoTrack? {
|
|
18
|
-
val peers = RNFishjamClient.getAllPeers()
|
|
19
|
-
val localEndpointId = RNFishjamClient.fishjamClient.getLocalEndpoint().id
|
|
20
|
-
val localPeer = peers.find { it.id == localEndpointId } ?: return null
|
|
21
|
-
|
|
22
|
-
return localPeer.tracks.values
|
|
23
|
-
.filterIsInstance<VideoTrack>()
|
|
24
|
-
.firstOrNull { track ->
|
|
25
|
-
(track.metadata as? Map<*, *>)?.get(METADATA_TYPE) == METADATA_CAMERA
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
fun findSecondaryRemoteTrack(currentTrackInfo: RemoteTrackInfo?): RemoteTrackInfo? {
|
|
30
|
-
val peers = RNFishjamClient.getAllPeers()
|
|
31
|
-
val localEndpointId = RNFishjamClient.fishjamClient.getLocalEndpoint().id
|
|
32
|
-
val remotePeers = peers.filter { it.id != localEndpointId }
|
|
33
|
-
|
|
34
|
-
if (remotePeers.isEmpty()) {
|
|
35
|
-
return null
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
remotePeers.firstOrNull { it.hasActiveVoiceActivity() }?.let { activeSpeaker ->
|
|
39
|
-
return activeSpeaker.toRemoteTrackInfo()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
currentTrackInfo?.let { currentInfo ->
|
|
43
|
-
val existingPeer = remotePeers.firstOrNull() { peer -> peer.hasTrack(currentInfo.videoTrack) }
|
|
44
|
-
if (existingPeer != null) {
|
|
45
|
-
return existingPeer.toRemoteTrackInfo()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
remotePeers.firstOrNull { it.hasVideoTrack() }?.let { peerWithVideo ->
|
|
50
|
-
return peerWithVideo.toRemoteTrackInfo()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return null
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private fun Peer.hasActiveVoiceActivity(): Boolean {
|
|
58
|
-
return tracks.values
|
|
59
|
-
.filterIsInstance<RemoteAudioTrack>()
|
|
60
|
-
.any { it.vadStatus == Server.MediaEvent.VadNotification.Status.STATUS_SPEECH }
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private fun Peer.hasTrack(videoTrack: VideoTrack?): Boolean {
|
|
64
|
-
return videoTrack != null && tracks.values.contains(videoTrack)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private fun Peer.hasVideoTrack(): Boolean {
|
|
68
|
-
return tracks.values.any { it is VideoTrack }
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private fun Peer.getDisplayName(): String {
|
|
72
|
-
val serverMetadata = metadata?.get("peer") as? Map<*, *>
|
|
73
|
-
val displayName = serverMetadata?.get("displayName") as? String
|
|
74
|
-
return displayName ?: id
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
private fun Track.getTrackActive(): Boolean {
|
|
78
|
-
|
|
79
|
-
if (metadata["active"] as? Boolean == false) {
|
|
80
|
-
return false
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (metadata["paused"] as? Boolean == true) {
|
|
84
|
-
return false
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return true
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
private fun Peer.toRemoteTrackInfo(): RemoteTrackInfo {
|
|
91
|
-
val videoTrack = tracks.values.filterIsInstance<VideoTrack>().firstOrNull()
|
|
92
|
-
return RemoteTrackInfo(
|
|
93
|
-
videoTrack = videoTrack,
|
|
94
|
-
displayName = getDisplayName(),
|
|
95
|
-
videoTrackActive = videoTrack?.getTrackActive() ?: false
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|