Add setRemoteSDP method
This commit is contained in:
@@ -24,6 +24,10 @@
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>Needs microphone access for streaming your voice when you're joined in full audio mode</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Needs camera access for streaming your camera when you're sharing it</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
|
||||
@@ -12,7 +12,8 @@ open class BBBSampleHandler : RPBroadcastSampleHandler {
|
||||
// Logger (these messages are displayed in the console application)
|
||||
private var logger = os.Logger(subsystem: "BigBlueButtonMobileSDK", category: "BBBSampleHandler")
|
||||
private var appGroupName:String = "";
|
||||
private var observer:NSKeyValueObservation?;
|
||||
private var createOfferCallObserver:NSKeyValueObservation?;
|
||||
private var setRemoteSDPCallObserver:NSKeyValueObservation?;
|
||||
private var screenBroadcaster:ScreenBroadcaster?;
|
||||
|
||||
open func setAppGroupName(appGroupName:String) {
|
||||
@@ -35,8 +36,8 @@ open class BBBSampleHandler : RPBroadcastSampleHandler {
|
||||
self.screenBroadcaster = ScreenBroadcaster()
|
||||
|
||||
// Listen for createOffer requests from the UI APP
|
||||
logger.info("Configuring observer")
|
||||
self.observer = userDefaults.observe(\.createScreenShareOffer, options: [.new]) { (defaults, change) in
|
||||
logger.info("Configuring observer for createOffer")
|
||||
self.createOfferCallObserver = userDefaults.observe(\.createScreenShareOffer, options: [.new]) { (defaults, change) in
|
||||
self.logger.info("Observer detected a createScreenShareOffer request!")
|
||||
|
||||
Task.init {
|
||||
@@ -52,6 +53,26 @@ open class BBBSampleHandler : RPBroadcastSampleHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Configuring observer for setRemoteSDP")
|
||||
self.setRemoteSDPCallObserver = userDefaults.observe(\.setScreenShareRemoteSDP, options: [.new]) { (defaults, change) in
|
||||
let payload:String = (change.newValue!);
|
||||
self.logger.info("Observer detected a setScreenShareRemoteSDP request with payload \(payload)")
|
||||
let payloadData = payload.data(using: .utf8)!
|
||||
let decodedPayload = (try? JSONDecoder().decode([String: String].self, from: payloadData))!
|
||||
let sdp = decodedPayload["sdp"]
|
||||
|
||||
Task.init {
|
||||
let remoteSDPDefined = await self.screenBroadcaster!.setRemoteSDP(remoteSDP: sdp!)
|
||||
|
||||
if(remoteSDPDefined){
|
||||
self.logger.info("Remote SDP defined!")
|
||||
BBBSharedData
|
||||
.getUserDefaults(appGroupName: self.appGroupName)
|
||||
.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.setScreenShareRemoteSDPCompleted)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open override func broadcastPaused() {
|
||||
|
||||
@@ -29,4 +29,15 @@ open class ScreenBroadcaster {
|
||||
}
|
||||
}
|
||||
|
||||
public func setRemoteSDP(remoteSDP:String) async -> Bool {
|
||||
do {
|
||||
try await self.webRTCClient.setRemoteSDP(remoteSDP: remoteSDP)
|
||||
return true
|
||||
}
|
||||
catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ open class BBBSharedData {
|
||||
public static let broadcastFinished = "broadcastFinished" // Broadcaster -> UI APP
|
||||
public static let createScreenShareOffer = "createScreenShareOffer" // UI APP -> Broadcaster
|
||||
public static let screenShareOfferCreated = "screenShareOfferCreated" // Broadcaster -> UI APP
|
||||
public static let setScreenShareRemoteSDP = "setScreenShareRemoteSDP" // UI APP -> Broadcaster
|
||||
public static let setScreenShareRemoteSDPCompleted = "setScreenShareRemoteSDPCompleted" // Broadcaster -> UI APP
|
||||
}
|
||||
|
||||
// Get reference to userDefaults object (that's actually the object used to share information among UI APP and the BroadcastUploadExtension APP)
|
||||
|
||||
@@ -34,5 +34,15 @@ extension UserDefaults {
|
||||
@objc open dynamic var screenShareOfferCreated: String {
|
||||
return string(forKey: BBBSharedData.SharedData.createScreenShareOffer) ?? ""
|
||||
}
|
||||
|
||||
// UI APP -> Broadcaster
|
||||
@objc open dynamic var setScreenShareRemoteSDP: String {
|
||||
return string(forKey: BBBSharedData.SharedData.setScreenShareRemoteSDP) ?? ""
|
||||
}
|
||||
|
||||
// Broadcaster -> UI APP
|
||||
@objc open dynamic var setScreenShareRemoteSDPCompleted: String {
|
||||
return string(forKey: BBBSharedData.SharedData.setScreenShareRemoteSDPCompleted) ?? ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
import WebRTC
|
||||
import os
|
||||
|
||||
protocol WebRTCClientDelegate: AnyObject {
|
||||
func webRTCClient(_ client: WebRTCClient, didDiscoverLocalCandidate candidate: RTCIceCandidate)
|
||||
@@ -14,6 +15,7 @@ protocol WebRTCClientDelegate: AnyObject {
|
||||
}
|
||||
|
||||
open class WebRTCClient: NSObject {
|
||||
private var logger = os.Logger(subsystem: "BigBlueButtonMobileSDK", category: "WebRTCClient")
|
||||
|
||||
// The `RTCPeerConnectionFactory` is in charge of creating new RTCPeerConnection instances.
|
||||
// A new RTCPeerConnection should be created every new call, but the factory is shared.
|
||||
@@ -76,10 +78,16 @@ open class WebRTCClient: NSObject {
|
||||
return sdp
|
||||
}
|
||||
|
||||
func set(remoteSdp: RTCSessionDescription, completion: @escaping (Error?) -> ()) {
|
||||
self.peerConnection.setRemoteDescription(remoteSdp, completionHandler: completion)
|
||||
public func setRemoteSDP(remoteSDP: String) async {
|
||||
do {
|
||||
let rtcSessionDescription = RTCSessionDescription(type: RTCSdpType.answer, sdp: remoteSDP)
|
||||
try await self.peerConnection.setRemoteDescription(rtcSessionDescription)
|
||||
} catch {
|
||||
self.logger.error("Error setting remote SDP")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func set(remoteCandidate: RTCIceCandidate, completion: @escaping (Error?) -> ()) {
|
||||
self.peerConnection.add(remoteCandidate, completionHandler: completion)
|
||||
}
|
||||
@@ -138,41 +146,41 @@ open class WebRTCClient: NSObject {
|
||||
extension WebRTCClient: RTCPeerConnectionDelegate {
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didChange stateChanged: RTCSignalingState) {
|
||||
debugPrint("peerConnection new signaling state: \(stateChanged)")
|
||||
self.logger.info("peerConnection new signaling state: \(stateChanged.rawValue)")
|
||||
}
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didAdd stream: RTCMediaStream) {
|
||||
debugPrint("peerConnection did add stream \(stream)")
|
||||
self.logger.info("peerConnection did add stream \(stream.streamId)")
|
||||
}
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didRemove stream: RTCMediaStream) {
|
||||
debugPrint("peerConnection did remove stream \(stream)")
|
||||
self.logger.info("peerConnection did remove stream \(stream.streamId)")
|
||||
}
|
||||
|
||||
public func peerConnectionShouldNegotiate(_ peerConnection: RTCPeerConnection) {
|
||||
debugPrint("peerConnection should negotiate")
|
||||
self.logger.info("peerConnection should negotiate")
|
||||
}
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceConnectionState) {
|
||||
debugPrint("peerConnection new connection state: \(newState)")
|
||||
self.logger.info("peerConnection new connection state: \(newState.rawValue)")
|
||||
self.delegate?.webRTCClient(self, didChangeConnectionState: newState)
|
||||
}
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceGatheringState) {
|
||||
debugPrint("peerConnection new gathering state: \(newState)")
|
||||
self.logger.info("peerConnection new gathering state: \(newState.rawValue)")
|
||||
}
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didGenerate candidate: RTCIceCandidate) {
|
||||
debugPrint("peerConnection discovered new candidate")
|
||||
self.logger.info("peerConnection discovered new candidate")
|
||||
self.delegate?.webRTCClient(self, didDiscoverLocalCandidate: candidate)
|
||||
}
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didRemove candidates: [RTCIceCandidate]) {
|
||||
debugPrint("peerConnection did remove candidate(s)")
|
||||
self.logger.info("peerConnection did remove candidate(s)")
|
||||
}
|
||||
|
||||
public func peerConnection(_ peerConnection: RTCPeerConnection, didOpen dataChannel: RTCDataChannel) {
|
||||
debugPrint("peerConnection did open data channel")
|
||||
self.logger.info("peerConnection did open data channel")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ open class BigBlueButtonSDK: NSObject {
|
||||
private static var userDefaults:UserDefaults?
|
||||
private static var observer1: NSKeyValueObservation?
|
||||
private static var observer2: NSKeyValueObservation?
|
||||
private static var observer3: NSKeyValueObservation?
|
||||
|
||||
public static func initialize(broadcastExtensionBundleId:String, appGroupName:String) {
|
||||
self.broadcastExtensionBundleId = broadcastExtensionBundleId
|
||||
@@ -44,6 +45,11 @@ open class BigBlueButtonSDK: NSObject {
|
||||
ReactNativeEventEmitter.emitter.sendEvent(withName: ReactNativeEventEmitter.EVENT.onScreenShareOfferCreated.rawValue, body: sdp)
|
||||
}
|
||||
|
||||
//setScreenShareRemoteSDPCompleted
|
||||
observer3 = userDefaults?.observe(\.setScreenShareRemoteSDPCompleted, options: [.new]) { (defaults, change) in
|
||||
logger.info("Detected a change in userDefaults for key setScreenShareRemoteSDPCompleted")
|
||||
ReactNativeEventEmitter.emitter.sendEvent(withName: ReactNativeEventEmitter.EVENT.onSetScreenShareRemoteSDPCompleted.rawValue, body: nil)
|
||||
}
|
||||
}
|
||||
|
||||
public static func getBroadcastExtensionBundleId() -> String {
|
||||
|
||||
@@ -19,6 +19,7 @@ open class ReactNativeEventEmitter: RCTEventEmitter {
|
||||
case onBroadcastResumed = "onBroadcastResumed"
|
||||
case onBroadcastFinished = "onBroadcastFinished"
|
||||
case onScreenShareOfferCreated = "onScreenShareOfferCreated"
|
||||
case onSetScreenShareRemoteSDPCompleted = "onSetScreenShareRemoteSDPCompleted"
|
||||
}
|
||||
|
||||
override init() {
|
||||
|
||||
@@ -11,4 +11,5 @@
|
||||
|
||||
RCT_EXTERN_METHOD(initializeScreenShare)
|
||||
RCT_EXTERN_METHOD(createScreenShareOffer)
|
||||
RCT_EXTERN_METHOD(setScreenShareRemoteSDP: (NSString *)remoteSDP)
|
||||
@end
|
||||
|
||||
@@ -39,4 +39,17 @@ class ScreenShareServiceManager: NSObject {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@objc func setScreenShareRemoteSDP(_ remoteSDP:String) -> Void {
|
||||
logger.info("setScreenShareRemoteSDP call arrived on swift: \(remoteSDP)")
|
||||
// Send request of "set remote SDP" to broadcast upload extension
|
||||
// TIP - the handling of this method response is done in observer3 of BigBlueButtonSDK class
|
||||
logger.info("setScreenShareRemoteSDP - persisting information on UserDefaults")
|
||||
BBBSharedData
|
||||
.getUserDefaults(appGroupName: BigBlueButtonSDK.getAppGroupName())
|
||||
.set(BBBSharedData.generatePayload(properties: [
|
||||
"sdp": remoteSDP
|
||||
]), forKey: BBBSharedData.SharedData.setScreenShareRemoteSDP)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
32
src/methods/setScreenShareRemoteSDP.tsx
Normal file
32
src/methods/setScreenShareRemoteSDP.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { setScreenShareRemoteSDP as nativeSetScreenShareRemoteSDP } from '../native-components/BBBN_ScreenShareService';
|
||||
import nativeEmitter from '../native-messaging/emitter';
|
||||
|
||||
// Reference to the resolver of last call
|
||||
let resolve = (value: unknown) => {
|
||||
console.log(
|
||||
`default resolve function called, this should never happen: ${value}`
|
||||
);
|
||||
};
|
||||
|
||||
// Resolve promise when SDP offer is available
|
||||
nativeEmitter.addListener('onSetScreenShareRemoteSDPCompleted', () => {
|
||||
resolve(undefined);
|
||||
});
|
||||
|
||||
// Entry point of this method
|
||||
function setScreenShareRemoteSDP(remoteSdp: string) {
|
||||
return new Promise((res, rej) => {
|
||||
// store the resolver for later call (when event is received)
|
||||
resolve = res;
|
||||
|
||||
try {
|
||||
console.log(`>nativeSetScreenShareRemoteSDP ${remoteSdp}`);
|
||||
// call native swift method that triggers the broadcast popup
|
||||
nativeSetScreenShareRemoteSDP(remoteSdp);
|
||||
} catch (e) {
|
||||
rej(`Call to nativeSetScreenShareRemoteSDP failed`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default setScreenShareRemoteSDP;
|
||||
@@ -9,3 +9,7 @@ export function initializeScreenShare() {
|
||||
export function createScreenShareOffer() {
|
||||
ScreenShareService.createScreenShareOffer();
|
||||
}
|
||||
|
||||
export function setScreenShareRemoteSDP(remoteSDP: string) {
|
||||
ScreenShareService.setScreenShareRemoteSDP(remoteSDP);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { MutableRefObject } from 'react';
|
||||
import type { WebView, WebViewMessageEvent } from 'react-native-webview';
|
||||
import initializeScreenShare from '../methods/initializeScreenShare';
|
||||
import createScreenShareOffer from '../methods/createScreenShareOffer';
|
||||
import setScreenShareRemoteSDP from '../methods/setScreenShareRemoteSDP';
|
||||
|
||||
function observePromiseResult(
|
||||
webViewRef: MutableRefObject<WebView>,
|
||||
@@ -43,6 +44,9 @@ export function handleWebviewMessage(
|
||||
case 'createOffer':
|
||||
promise = createScreenShareOffer();
|
||||
break;
|
||||
case 'setRemoteDescription':
|
||||
promise = setScreenShareRemoteSDP(data?.arguments[0].sdp);
|
||||
break;
|
||||
default:
|
||||
throw `Unknown method ${data?.method}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user