bigbluebutton-tablet-sdk/ios-broadcast-upload-extension/Classes/BBBSampleHandler.swift
2022-05-11 10:49:25 -03:00

156 lines
7.6 KiB
Swift

//
// BBBSampleHandler.swift
//
// Created by Tiago Daniel Jacobs on 11/03/22.
//
import ReplayKit
import os
import bigbluebutton_mobile_sdk_common
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 createScreenShareOfferObserver:NSKeyValueObservation?;
private var setScreenShareRemoteSDPOBserver:NSKeyValueObservation?;
private var addScreenShareRemoteIceCandidateObserver:NSKeyValueObservation?;
private var onApplicationTerminatedObserver:NSKeyValueObservation?;
private var screenBroadcaster:ScreenBroadcasterService?;
open func setAppGroupName(appGroupName:String) {
logger.info("Received appGroupName: \(appGroupName)")
self.appGroupName = appGroupName
}
// Called by IOS when the user authorized to start the broadcast
open override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
logger.info("ReplayKit2 event - broadcastStarted")
// Object used to share data
let userDefaults = BBBSharedData
.getUserDefaults(appGroupName: self.appGroupName)
// Notify the UI app that the broadcast has been started
logger.info("ReplayKit2 event - broadcastStarted - persisting information on UserDefaults")
userDefaults.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.broadcastStarted)
self.screenBroadcaster = ScreenBroadcasterService(appGroupName: appGroupName)
// Handle quit application to finish broadcast togheter
logger.info("Configuring observer for finishApplication")
self.onApplicationTerminatedObserver = userDefaults.observe(\.onApplicationTerminated, options: [.new]) { (defaults, change) in
self.logger.info("Observer detected a onQuitApplicationWithBroadcastActive request!")
finishBroadcastGracefully(self)
}
// Listen for createOffer requests from the UI APP
logger.info("Configuring observer for createOffer")
self.createScreenShareOfferObserver = userDefaults.observe(\.createScreenShareOffer, options: [.new]) { (defaults, change) in
self.logger.info("Observer detected a createScreenShareOffer request!")
Task.init {
let optionalSdp = await self.screenBroadcaster?.createOffer()
if(optionalSdp != nil){
let sdp = optionalSdp!
self.logger.info("Got SDP back from screenBroadcaster: \(sdp)")
BBBSharedData
.getUserDefaults(appGroupName: self.appGroupName)
.set(BBBSharedData.generatePayload(properties: [
"sdp": sdp
]), forKey: BBBSharedData.SharedData.screenShareOfferCreated)
}
}
}
logger.info("Configuring observer for setRemoteSDP")
self.setScreenShareRemoteSDPOBserver = userDefaults.observe(\.setScreenShareRemoteSDP, options: [.new]) { (defaults, change) in
let payload:String = (change.newValue!);
// self.logger.info("Observer detected a setScreenShareRemoteSDP request with payload \(payload)")
self.logger.info("Observer detected a setScreenShareRemoteSDP request")
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)
}
}
}
logger.info("Configuring observer for addScreenShareRemoteIceCandidate")
self.addScreenShareRemoteIceCandidateObserver = userDefaults.observe(\.addScreenShareRemoteIceCandidate, options: [.new]) { (defaults, change) in
let payload:String = (change.newValue!);
// self.logger.info("Observer detected a addScreenShareRemoteIceCandidate request with payload \(payload)")
self.logger.info("Observer detected a addScreenShareRemoteIceCandidate request")
let payloadData = payload.data(using: .utf8)!
let decodedPayload = (try? JSONDecoder().decode([String: String].self, from: payloadData))!
let candidateAsString = decodedPayload["candidate"]!
let candidateAsData = candidateAsString.data(using: .utf8)!
let candidate = (try? JSONDecoder().decode(IceCandidate.self, from: candidateAsData))
Task.init {
let remoteCandidateAdded = await self.screenBroadcaster!.addRemoteCandidate(remoteCandidate: candidate!)
if(remoteCandidateAdded){
self.logger.info("Remote candidate added!")
BBBSharedData
.getUserDefaults(appGroupName: self.appGroupName)
.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.addScreenShareRemoteIceCandidateCompleted)
}
}
}
}
open override func broadcastPaused() {
logger.info("ReplayKit2 event - broadcastPaused")
logger.info("ReplayKit2 event - broadcastPaused - persisting information on UserDefaults")
BBBSharedData
.getUserDefaults(appGroupName: self.appGroupName)
.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.broadcastPaused)
}
open override func broadcastResumed() {
logger.info("ReplayKit2 event - broadcastResumed")
logger.info("ReplayKit2 event - broadcastResumed - persisting information on UserDefaults")
BBBSharedData
.getUserDefaults(appGroupName: self.appGroupName)
.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.broadcastResumed)
}
open override func broadcastFinished() {
logger.info("ReplayKit2 event - broadcastFinished")
logger.info("ReplayKit2 event - broadcastFinished - persisting information on UserDefaults")
BBBSharedData
.getUserDefaults(appGroupName: self.appGroupName)
.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.broadcastFinished)
}
open override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
switch sampleBufferType {
case RPSampleBufferType.video:
logger.trace("ReplayKit2 event - processSampleBuffer(video)")
self.screenBroadcaster?.pushVideoFrame(sampleBuffer: sampleBuffer)
break
case RPSampleBufferType.audioApp:
logger.trace("ReplayKit2 event - processSampleBuffer(audioApp)")
break
case RPSampleBufferType.audioMic:
logger.trace("ReplayKit2 event - processSampleBuffer(audioMic)")
break
@unknown default:
// Handle other sample buffer types
fatalError("Unknown type of sample buffer")
}
}
}