提交
This commit is contained in:
818
TUIKit/TUIRoomKit/Source/View/Model/EngineManager.swift
Normal file
818
TUIKit/TUIRoomKit/Source/View/Model/EngineManager.swift
Normal file
@@ -0,0 +1,818 @@
|
||||
//
|
||||
// EngineManager.swift
|
||||
// TUIRoomKit
|
||||
//
|
||||
// Created by WesleyLei on 2022/9/22.
|
||||
// Copyright © 2022 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import TUICore
|
||||
import RTCRoomEngine
|
||||
#if canImport(TXLiteAVSDK_TRTC)
|
||||
import TXLiteAVSDK_TRTC
|
||||
#elseif canImport(TXLiteAVSDK_Professional)
|
||||
import TXLiteAVSDK_Professional
|
||||
#endif
|
||||
|
||||
class EngineManager: NSObject {
|
||||
static private(set) var shared = EngineManager()
|
||||
|
||||
private(set) lazy var store: RoomStore = {
|
||||
let store = RoomStore()
|
||||
return store
|
||||
}()
|
||||
|
||||
private(set) var roomEngine = TUIRoomEngine.sharedInstance()
|
||||
|
||||
private lazy var eventDispatcher: RoomEventDispatcher = {
|
||||
let eventDispatcher = RoomEventDispatcher()
|
||||
return eventDispatcher
|
||||
}()
|
||||
private lazy var observer: TRTCObserver = {
|
||||
let observer = TRTCObserver()
|
||||
return observer
|
||||
}()
|
||||
private lazy var conferenceListObserver: ConferenceListObserver = {
|
||||
return ConferenceListObserver()
|
||||
}()
|
||||
private lazy var conferenceListManager: TUIConferenceListManager? = {
|
||||
guard let listManager = roomEngine.getExtension(extensionType: .conferenceListManager) as? TUIConferenceListManager else { return nil }
|
||||
return listManager
|
||||
}()
|
||||
private let takeSeatTimeOutNumber: Double = 60
|
||||
private let openRemoteDeviceTimeOutNumber: Double = 15
|
||||
private let rootRouter: RoomRouter = RoomRouter.shared
|
||||
private var isLoginEngine: Bool = false
|
||||
private let appGroupString: String = "com.tencent.TUIRoomTXReplayKit-Screen"
|
||||
|
||||
override private init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
deinit {
|
||||
debugPrint("deinit \(self)")
|
||||
}
|
||||
|
||||
func setSelfInfo(userName: String, avatarURL: String, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
store.currentUser.userName = userName
|
||||
store.currentUser.avatarUrl = avatarURL
|
||||
TUIRoomEngine.setSelfInfo(userName: userName, avatarUrl: avatarURL) {
|
||||
onSuccess()
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
debugPrint("---setSelfInfo,code:\(code),message:\(message)")
|
||||
}
|
||||
}
|
||||
|
||||
func createRoom(roomInfo: TUIRoomInfo, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
roomInfo.name = transferConferenceName(conferenceName: roomInfo.name)
|
||||
if !isLoginEngine {
|
||||
self.login(sdkAppId: Int(TUILogin.getSdkAppID()), userId: TUILogin.getUserID() ?? "", userSig: TUILogin.getUserSig() ?? "")
|
||||
{ [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.isLoginEngine = true
|
||||
self.createEngineRoom(roomInfo: roomInfo, onSuccess: onSuccess, onError: onError)
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
}
|
||||
} else {
|
||||
createEngineRoom(roomInfo: roomInfo, onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
}
|
||||
|
||||
func enterRoom(roomId: String, options: TUIEnterRoomOptions? = nil, enableAudio: Bool, enableVideo: Bool, isSoundOnSpeaker: Bool,
|
||||
onSuccess: @escaping TUIRoomInfoBlock, onError: @escaping TUIErrorBlock) {
|
||||
store.videoSetting.isCameraOpened = enableVideo
|
||||
store.audioSetting.isSoundOnSpeaker = isSoundOnSpeaker
|
||||
setFramework()
|
||||
if !isLoginEngine {
|
||||
self.login(sdkAppId: Int(TUILogin.getSdkAppID()), userId: TUILogin.getUserID() ?? "", userSig: TUILogin.getUserSig() ?? "")
|
||||
{ [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.isLoginEngine = true
|
||||
self.enterEngineRoom(roomId: roomId, options: options, enableAudio: enableAudio, onSuccess: onSuccess, onError: onError)
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
}
|
||||
} else {
|
||||
enterEngineRoom(roomId: roomId, options: options, enableAudio: enableAudio, onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
}
|
||||
|
||||
func exitRoom(onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.exitRoom(syncWaiting: false) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.handleExitRoomResult()
|
||||
onSuccess?()
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.handleExitRoomResult()
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func destroyRoom(onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.destroyRoom { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.handleDestroyRoomResult()
|
||||
onSuccess?()
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.handleDestroyRoomResult()
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func destroyEngineManager() {
|
||||
removeEngineObserver()
|
||||
unsubLogoutNotification()
|
||||
store = RoomStore()
|
||||
}
|
||||
|
||||
func muteLocalAudio() {
|
||||
roomEngine.muteLocalAudio()
|
||||
}
|
||||
|
||||
func unmuteLocalAudio(onSuccess:TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.unmuteLocalAudio {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func openLocalMicrophone(onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
let actionBlock = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.roomEngine.openLocalMicrophone(self.store.audioSetting.audioQuality) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.store.audioSetting.isMicOpened = true
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
if RoomCommon.checkAuthorMicStatusIsDenied() {
|
||||
actionBlock()
|
||||
} else {
|
||||
RoomCommon.micStateActionWithPopCompletion { granted in
|
||||
if granted {
|
||||
actionBlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func closeLocalCamera() {
|
||||
store.videoSetting.isCameraOpened = false
|
||||
roomEngine.closeLocalCamera()
|
||||
}
|
||||
|
||||
func openLocalCamera(onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
let actionBlock = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.store.videoSetting.isCameraOpened = true
|
||||
self.roomEngine.openLocalCamera(isFront: self.store.videoSetting.isFrontCamera, quality:
|
||||
self.store.videoSetting.videoQuality) {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
if RoomCommon.checkAuthorCamaraStatusIsDenied() {
|
||||
actionBlock()
|
||||
} else {
|
||||
RoomCommon.cameraStateActionWithPopCompletion { granted in
|
||||
if granted {
|
||||
actionBlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func switchCamera() {
|
||||
store.videoSetting.isFrontCamera = !store.videoSetting.isFrontCamera
|
||||
roomEngine.getMediaDeviceManager().switchCamera(store.videoSetting.isFrontCamera)
|
||||
}
|
||||
|
||||
func switchMirror() {
|
||||
store.videoSetting.isMirror = !store.videoSetting.isMirror
|
||||
let params = TRTCRenderParams()
|
||||
params.mirrorType = store.videoSetting.isMirror ? .enable : .disable
|
||||
setLocalRenderParams(params: params)
|
||||
}
|
||||
|
||||
func muteAllAudioAction(isMute: Bool, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
store.roomInfo.isMicrophoneDisableForAllUser = isMute
|
||||
roomEngine.disableDeviceForAllUserByAdmin(device: .microphone, isDisable:
|
||||
store.roomInfo.isMicrophoneDisableForAllUser) {
|
||||
onSuccess()
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func muteAllVideoAction(isMute: Bool, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
store.roomInfo.isCameraDisableForAllUser = isMute
|
||||
roomEngine.disableDeviceForAllUserByAdmin(device: .camera, isDisable:
|
||||
store.roomInfo.isCameraDisableForAllUser) {
|
||||
onSuccess()
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func takeUserOnSeatByAdmin(userId: String, timeout: Double,
|
||||
onAccepted: @escaping TUIRequestAcceptedBlock,
|
||||
onRejected: @escaping TUIRequestRejectedBlock,
|
||||
onCancelled: @escaping TUIRequestCancelledBlock,
|
||||
onTimeout: @escaping TUIRequestTimeoutBlock,
|
||||
onError: @escaping TUIRequestErrorBlock) {
|
||||
roomEngine.takeUserOnSeatByAdmin(-1, userId: userId, timeout: timeout) { requestId, userId in
|
||||
onAccepted(requestId, userId)
|
||||
} onRejected: { requestId, userId, message in
|
||||
onRejected( requestId, userId, message)
|
||||
} onCancelled: { requestId, userId in
|
||||
onCancelled(requestId, userId)
|
||||
} onTimeout: { requestId, userId in
|
||||
onTimeout(requestId, userId)
|
||||
} onError: { requestId, userId, code, message in
|
||||
onError(requestId, userId, code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func setAudioRoute(isSoundOnSpeaker: Bool) {
|
||||
store.audioSetting.isSoundOnSpeaker = isSoundOnSpeaker
|
||||
let route: TUIAudioRoute = isSoundOnSpeaker ? .speakerphone : .earpiece
|
||||
roomEngine.getMediaDeviceManager().setAudioRoute(route)
|
||||
}
|
||||
|
||||
func takeSeat(onAccepted: TUIRequestAcceptedBlock? = nil,
|
||||
onRejected: TUIRequestRejectedBlock? = nil,
|
||||
onCancelled: TUIRequestCancelledBlock? = nil,
|
||||
onTimeout: TUIRequestTimeoutBlock? = nil,
|
||||
onError: TUIRequestErrorBlock? = nil) -> TUIRequest {
|
||||
let request = self.roomEngine.takeSeat(-1, timeout: takeSeatTimeOutNumber) { [weak self] requestId, userId in
|
||||
guard let self = self else { return }
|
||||
self.store.currentUser.isOnSeat = true
|
||||
self.store.selfTakeSeatRequestId = nil
|
||||
onAccepted?(requestId, userId)
|
||||
} onRejected: { [weak self] requestId, userId, message in
|
||||
guard let self = self else { return }
|
||||
self.store.selfTakeSeatRequestId = nil
|
||||
onRejected?(requestId, userId, message)
|
||||
} onCancelled: { [weak self] requestId, userId in
|
||||
guard let self = self else { return }
|
||||
self.store.selfTakeSeatRequestId = nil
|
||||
onCancelled?(requestId, userId)
|
||||
} onTimeout: { [weak self] requestId, userId in
|
||||
guard let self = self else { return }
|
||||
self.store.selfTakeSeatRequestId = nil
|
||||
onTimeout?(requestId, userId)
|
||||
} onError: { [weak self] requestId, userId, code, message in
|
||||
guard let self = self else { return }
|
||||
self.store.selfTakeSeatRequestId = nil
|
||||
onError?(requestId, userId, code, message)
|
||||
}
|
||||
store.selfTakeSeatRequestId = request.requestId
|
||||
return request
|
||||
}
|
||||
|
||||
func cancelTakeSeatRequest() {
|
||||
guard let requestId = store.selfTakeSeatRequestId else { return }
|
||||
cancelRequest(requestId)
|
||||
store.selfTakeSeatRequestId = nil
|
||||
}
|
||||
|
||||
func fetchRoomInfo(roomId: String ,onSuccess: TUIRoomInfoBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.fetchRoomInfo(roomId: roomId, roomType: .conference) { [weak self] roomInfo in
|
||||
guard let self = self, let roomInfo = roomInfo else { return }
|
||||
if roomId == self.store.roomInfo.roomId {
|
||||
self.store.initialRoomInfo(roomInfo)
|
||||
}
|
||||
onSuccess?(roomInfo)
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
debugPrint("fetchRoomInfo,code:\(code), message:\(message)")
|
||||
}
|
||||
}
|
||||
|
||||
func setLocalRenderParams(params: TRTCRenderParams) {
|
||||
roomEngine.getTRTCCloud().setLocalRenderParams(params)
|
||||
}
|
||||
|
||||
func setGSensorMode(mode: TRTCGSensorMode) {
|
||||
roomEngine.getTRTCCloud().setGSensorMode(mode)
|
||||
}
|
||||
|
||||
func setLocalVideoView(streamType: TUIVideoStreamType, view: UIView?) {
|
||||
roomEngine.setLocalVideoView(streamType: streamType, view: view)
|
||||
}
|
||||
|
||||
func changeUserRole(userId: String, role: TUIRole, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
roomEngine.changeUserRole(userId: userId, role: role, onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
|
||||
func responseRemoteRequest(_ requestId: String, agree: Bool, onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.responseRemoteRequest(requestId, agree: agree) {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func getUserInfo(_ userId: String, onSuccess: @escaping TUIUserInfoBlock, onError: @escaping TUIErrorBlock) {
|
||||
roomEngine.getUserInfo(userId, onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
|
||||
func stopScreenCapture() {
|
||||
roomEngine.stopScreenCapture()
|
||||
}
|
||||
|
||||
func setVideoEncoder(videoQuality: TUIVideoQuality? = nil, bitrate: Int? = nil, fps: Int? = nil) {
|
||||
let param = TUIRoomVideoEncoderParams()
|
||||
store.videoSetting.videoQuality = videoQuality ?? store.videoSetting.videoQuality
|
||||
param.videoResolution = store.videoSetting.videoQuality
|
||||
store.videoSetting.videoBitrate = bitrate ?? store.videoSetting.videoBitrate
|
||||
param.bitrate = store.videoSetting.videoBitrate
|
||||
store.videoSetting.videoFps = fps ?? store.videoSetting.videoFps
|
||||
param.fps = store.videoSetting.videoFps
|
||||
roomEngine.updateVideoQualityEx(streamType: .cameraStream, params: param)
|
||||
}
|
||||
|
||||
func cancelRequest(_ requestId: String, onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.cancelRequest(requestId) {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func leaveSeat(onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.leaveSeat {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func startScreenCapture() {
|
||||
roomEngine.startScreenCapture(appGroup: appGroupString)
|
||||
}
|
||||
|
||||
func stopPlayRemoteVideo(userId: String, streamType: TUIVideoStreamType) {
|
||||
roomEngine.stopPlayRemoteVideo(userId: userId, streamType: streamType)
|
||||
}
|
||||
|
||||
func setRemoteVideoView(userId: String, streamType: TUIVideoStreamType, view: UIView?) {
|
||||
roomEngine.setRemoteVideoView(userId: userId, streamType: streamType, view: view)
|
||||
}
|
||||
|
||||
func startPlayRemoteVideo(userId: String, streamType: TUIVideoStreamType, onSuccess: TUISuccessBlock? = nil,
|
||||
onLoading: TUIPlayOnLoadingBlock? = nil, onError: TUIPlayOnErrorBlock? = nil) {
|
||||
roomEngine.startPlayRemoteVideo(userId: userId, streamType: streamType, onPlaying: { _ in
|
||||
guard let onSuccess = onSuccess else { return }
|
||||
onSuccess()
|
||||
}, onLoading: { userId in
|
||||
guard let onLoading = onLoading else { return }
|
||||
onLoading(userId)
|
||||
}, onError: { userId, code, message in
|
||||
guard let onError = onError else { return }
|
||||
onError(userId, code, message)
|
||||
})
|
||||
}
|
||||
|
||||
func setAudioCaptureVolume(_ captureVolume: Int) {
|
||||
store.audioSetting.captureVolume = captureVolume
|
||||
roomEngine.getTRTCCloud().setAudioCaptureVolume(captureVolume)
|
||||
}
|
||||
|
||||
func setAudioPlayoutVolume(_ playVolume: Int) {
|
||||
store.audioSetting.playVolume = playVolume
|
||||
roomEngine.getTRTCCloud().setAudioPlayoutVolume(playVolume)
|
||||
}
|
||||
|
||||
func enableAudioVolumeEvaluation(isVolumePrompt: Bool) {
|
||||
store.audioSetting.volumePrompt = isVolumePrompt
|
||||
if isVolumePrompt {
|
||||
roomEngine.getTRTCCloud().enableAudioVolumeEvaluation(300, enable_vad: true)
|
||||
} else {
|
||||
roomEngine.getTRTCCloud().enableAudioVolumeEvaluation(0, enable_vad: false)
|
||||
}
|
||||
}
|
||||
|
||||
func closeRemoteDeviceByAdmin(userId: String, device: TUIMediaDevice, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
roomEngine.closeRemoteDeviceByAdmin(userId: userId, device: device, onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
|
||||
func openRemoteDeviceByAdmin(userId: String, device: TUIMediaDevice,
|
||||
onAccepted: TUIRequestAcceptedBlock? = nil,
|
||||
onRejected: TUIRequestRejectedBlock? = nil,
|
||||
onCancelled: TUIRequestCancelledBlock? = nil,
|
||||
onTimeout: TUIRequestTimeoutBlock? = nil,
|
||||
onError: TUIRequestErrorBlock? = nil) {
|
||||
roomEngine.openRemoteDeviceByAdmin(userId: userId, device: device, timeout: openRemoteDeviceTimeOutNumber, onAccepted: { requestId, userId in
|
||||
onAccepted?(requestId, userId)
|
||||
}, onRejected: { requestId, userId, message in
|
||||
onRejected?(requestId, userId, message)
|
||||
}, onCancelled: { requestId, userId in
|
||||
onCancelled?(requestId, userId)
|
||||
}, onTimeout: { requestId, userId in
|
||||
onTimeout?(requestId, userId)
|
||||
}) { requestId, userId, code, message in
|
||||
onError?(requestId, userId, code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func disableSendingMessageByAdmin(userId: String, isDisable: Bool, onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.disableSendingMessageByAdmin(userId: userId, isDisable: isDisable) {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func kickUserOffSeatByAdmin(userId: String, onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.kickUserOffSeatByAdmin(-1, userId: userId) {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func kickRemoteUserOutOfRoom(userId: String, onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
roomEngine.kickRemoteUserOutOfRoom(userId) {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func initUserList(onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
self.getUserList(nextSequence: 0, localUserList: []) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if self.store.roomInfo.isSeatEnabled {
|
||||
self.getSeatList {
|
||||
onSuccess?()
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
} else {
|
||||
onSuccess?()
|
||||
}
|
||||
} onError: { code, message in
|
||||
onError?(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func updateVideoQuality(quality: TUIVideoQuality) {
|
||||
roomEngine.updateVideoQuality(quality)
|
||||
}
|
||||
|
||||
func enableGravitySensor(enable: Bool) {
|
||||
roomEngine.enableGravitySensor(enable: enable)
|
||||
}
|
||||
|
||||
func setVideoResolutionMode(streamType: TUIVideoStreamType, resolutionMode: TUIResolutionMode) {
|
||||
roomEngine.setVideoResolutionMode(streamType: streamType, resolutionMode: resolutionMode)
|
||||
}
|
||||
|
||||
func changeRaiseHandNoticeState(isShown: Bool) {
|
||||
store.isShownRaiseHandNotice = isShown
|
||||
}
|
||||
|
||||
func setRemoteRenderParams(userId: String, streamType: TRTCVideoStreamType, params: TRTCRenderParams) {
|
||||
roomEngine.getTRTCCloud().setRemoteRenderParams(userId, streamType: streamType, params: params)
|
||||
}
|
||||
|
||||
func updateSeatApplicationList() {
|
||||
roomEngine.getSeatApplicationList { [weak self] list in
|
||||
guard let self = self else { return }
|
||||
self.store.setInviteSeatList(list: list)
|
||||
} onError: { code, message in
|
||||
debugPrint("getSeatApplicationList,code:\(code),message:\(message)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
extension EngineManager {
|
||||
private func login(sdkAppId: Int, userId: String, userSig: String, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
V2TIMManager.sharedInstance().initSDK(Int32(sdkAppId), config: V2TIMSDKConfig())
|
||||
store.currentUser.userId = userId
|
||||
TUIRoomEngine.login(sdkAppId: sdkAppId, userId: userId, userSig: userSig) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.isLoginEngine = true
|
||||
onSuccess()
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
private func createEngineRoom(roomInfo: TUIRoomInfo, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
guard !store.isEnteredRoom else {
|
||||
if store.roomInfo.roomId == roomInfo.roomId {
|
||||
RoomVideoFloatView.dismiss()
|
||||
onSuccess()
|
||||
} else {
|
||||
onError(.failed, .inAnotherRoomText)
|
||||
}
|
||||
return
|
||||
}
|
||||
self.store.roomInfo = roomInfo
|
||||
self.roomEngine.createRoom(roomInfo) {
|
||||
onSuccess()
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.destroyEngineManager()
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
private func transferConferenceName(conferenceName: String?) -> String {
|
||||
if let confName = conferenceName, !confName.isEmpty {
|
||||
return confName
|
||||
}
|
||||
let selfInfo = TUIRoomEngine.getSelfInfo()
|
||||
let name: String = selfInfo.userName.isEmpty ? selfInfo.userId : selfInfo.userName
|
||||
return name + .quickConferenceText
|
||||
}
|
||||
|
||||
private func enterEngineRoom(roomId: String, options: TUIEnterRoomOptions? = nil, enableAudio: Bool, onSuccess: @escaping TUIRoomInfoBlock, onError: @escaping TUIErrorBlock) {
|
||||
guard !store.isEnteredRoom else {
|
||||
if store.roomInfo.roomId == roomId {
|
||||
onSuccess(store.roomInfo)
|
||||
} else {
|
||||
onError(.failed, .inAnotherRoomText)
|
||||
}
|
||||
return
|
||||
}
|
||||
if let options = options {
|
||||
roomEngine.enterRoom(roomId, roomType: .conference, options: options) { [weak self] roomInfo in
|
||||
guard let self = self else { return }
|
||||
guard let roomInfo = roomInfo else { return }
|
||||
self.handleEnterRoomResult(roomInfo: roomInfo, enableAudio: enableAudio, onSuccess: onSuccess, onError: onError)
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.destroyEngineManager()
|
||||
onError(code, message)
|
||||
}
|
||||
} else {
|
||||
roomEngine.enterRoom(roomId) { [weak self] roomInfo in
|
||||
guard let self = self else { return }
|
||||
guard let roomInfo = roomInfo else { return }
|
||||
self.handleEnterRoomResult(roomInfo: roomInfo, enableAudio: enableAudio, onSuccess: onSuccess, onError: onError)
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.destroyEngineManager()
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleEnterRoomResult(roomInfo: TUIRoomInfo, enableAudio: Bool, onSuccess: @escaping TUIRoomInfoBlock, onError: @escaping TUIErrorBlock) {
|
||||
//Update the room entry data stored
|
||||
addEngineObserver()
|
||||
store.initialRoomInfo(roomInfo)
|
||||
store.initialRoomCurrentUser()
|
||||
//Initialize user list
|
||||
initUserList()
|
||||
//Initialize video settings
|
||||
initLocalVideoState()
|
||||
subLogoutNotification()
|
||||
updateSeatApplicationList()
|
||||
if !isNeededAutoTakeSeat() {
|
||||
operateLocalMicrophone(enableAudio: enableAudio)
|
||||
updateCameraState()
|
||||
store.initalEnterRoomMessage()
|
||||
onSuccess(roomInfo)
|
||||
} else {
|
||||
autoTakeSeatForOwner { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.operateLocalMicrophone(enableAudio: enableAudio)
|
||||
self.updateCameraState()
|
||||
self.store.initalEnterRoomMessage()
|
||||
onSuccess(roomInfo)
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.destroyEngineManager()
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateCameraState() {
|
||||
if store.roomInfo.isSeatEnabled && !store.currentUser.isOnSeat {
|
||||
store.videoSetting.isCameraOpened = false
|
||||
return
|
||||
}
|
||||
operateLocalCamera()
|
||||
}
|
||||
|
||||
private func isNeededAutoTakeSeat() -> Bool {
|
||||
return store.roomInfo.isSeatEnabled && store.currentUser.userId == store.roomInfo.ownerId
|
||||
}
|
||||
|
||||
private func autoTakeSeatForOwner(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
_ = self.takeSeat() { _,_ in
|
||||
onSuccess()
|
||||
} onError: { _, _, code, message in
|
||||
if code == .alreadyInSeat {
|
||||
onSuccess()
|
||||
} else {
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func isPushLocalAudioStream(enableAudio: Bool) -> Bool {
|
||||
if !enableAudio {
|
||||
return false
|
||||
}
|
||||
if store.roomInfo.isMicrophoneDisableForAllUser, store.currentUser.userId != store.roomInfo.ownerId {
|
||||
return false
|
||||
}
|
||||
if store.roomInfo.isSeatEnabled, store.currentUser.userId != store.roomInfo.ownerId {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func operateLocalMicrophone(enableAudio: Bool ,onSuccess: TUISuccessBlock? = nil, onError: TUIErrorBlock? = nil) {
|
||||
if isPushLocalAudioStream(enableAudio: enableAudio) {
|
||||
openLocalMicrophone()
|
||||
} else if RoomCommon.checkAuthorMicStatusIsDenied() {
|
||||
muteLocalAudio()
|
||||
openLocalMicrophone()
|
||||
}
|
||||
}
|
||||
|
||||
private func operateLocalCamera() {
|
||||
let openLocalCameraActionBlock = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
setLocalVideoView(streamType: .cameraStream, view: nil)
|
||||
openLocalCamera()
|
||||
}
|
||||
if store.videoSetting.isCameraOpened && !store.roomInfo.isCameraDisableForAllUser {
|
||||
if RoomCommon.checkAuthorCamaraStatusIsDenied() {
|
||||
openLocalCameraActionBlock()
|
||||
} else {
|
||||
RoomCommon.cameraStateActionWithPopCompletion { granted in
|
||||
if granted {
|
||||
openLocalCameraActionBlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func initLocalVideoState() {
|
||||
setVideoParam()
|
||||
enableGravitySensor(enable: true)
|
||||
setGSensorMode(mode: .uiFixLayout)
|
||||
let resolutionMode: TUIResolutionMode = isLandscape ? .landscape : .portrait
|
||||
setVideoResolutionMode(streamType: .cameraStream, resolutionMode: resolutionMode)
|
||||
}
|
||||
|
||||
private func setVideoParam() {
|
||||
setVideoEncoder(videoQuality: store.videoSetting.videoQuality, bitrate: store.videoSetting.videoBitrate,
|
||||
fps: store.videoSetting.videoFps)
|
||||
let params = TRTCRenderParams()
|
||||
params.fillMode = .fill
|
||||
params.rotation = ._0
|
||||
setLocalRenderParams(params: params)
|
||||
}
|
||||
|
||||
private func getUserList(nextSequence: Int, localUserList: [UserEntity], onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
roomEngine.getUserList(nextSequence: nextSequence) { [weak self] list, nextSequence in
|
||||
guard let self = self else { return }
|
||||
var localUserList = localUserList
|
||||
list.forEach { userInfo in
|
||||
if userInfo.userName.isEmpty {
|
||||
userInfo.userName = userInfo.userId
|
||||
}
|
||||
let userModel = UserEntity()
|
||||
userModel.update(userInfo: userInfo)
|
||||
localUserList.append(userModel)
|
||||
}
|
||||
if nextSequence != 0 {
|
||||
self.getUserList(nextSequence: nextSequence, localUserList: localUserList, onSuccess: onSuccess, onError: onError)
|
||||
} else {
|
||||
self.store.attendeeList = localUserList
|
||||
onSuccess()
|
||||
if !self.store.roomInfo.isSeatEnabled {
|
||||
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewVideoSeatView, param: [:])
|
||||
}
|
||||
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewUserList, param: [:])
|
||||
EngineEventCenter.shared.notifyEngineEvent(event: .onGetUserListFinished, param: [:])
|
||||
}
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
debugPrint("getUserList:code:\(code),message:\(message)")
|
||||
}
|
||||
}
|
||||
|
||||
private func getSeatList(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
roomEngine.getSeatList { [weak self] seatList in
|
||||
guard let self = self else { return }
|
||||
self.store.initialSeatList(seatList: seatList)
|
||||
self.store.initialOffSeatList()
|
||||
onSuccess()
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
debugPrint("getSeatList:code:\(code),message:\(message)")
|
||||
}
|
||||
}
|
||||
|
||||
private func addEngineObserver() {
|
||||
roomEngine.addObserver(eventDispatcher)
|
||||
roomEngine.getTRTCCloud().addDelegate(observer)
|
||||
conferenceListManager?.addObserver(conferenceListObserver)
|
||||
}
|
||||
|
||||
private func removeEngineObserver() {
|
||||
roomEngine.removeObserver(eventDispatcher)
|
||||
roomEngine.getTRTCCloud().removeDelegate(observer)
|
||||
conferenceListManager?.removeObserver(conferenceListObserver)
|
||||
}
|
||||
|
||||
private func subLogoutNotification() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleLogout),
|
||||
name: NSNotification.Name.TUILogoutSuccess, object: nil)
|
||||
}
|
||||
|
||||
private func unsubLogoutNotification() {
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.TUILogoutSuccess, object: nil)
|
||||
}
|
||||
|
||||
@objc private func handleLogout() {
|
||||
destroyEngineManager()
|
||||
}
|
||||
|
||||
private func handleDestroyRoomResult() {
|
||||
destroyEngineManager()
|
||||
EngineEventCenter.shared.notifyEngineEvent(event: .onDestroyedRoom, param: [ "roomId" : store.roomInfo.roomId ])
|
||||
}
|
||||
|
||||
private func handleExitRoomResult() {
|
||||
destroyEngineManager()
|
||||
EngineEventCenter.shared.notifyEngineEvent(event: .onExitedRoom, param: [ "roomId" : store.roomInfo.roomId ])
|
||||
}
|
||||
|
||||
}
|
||||
// MARK: - TUIExtensionProtocol
|
||||
|
||||
extension EngineManager: TUIExtensionProtocol {
|
||||
func getExtensionInfo(_ key: String, param: [AnyHashable: Any]?) -> [AnyHashable: Any] {
|
||||
guard let param = param else {
|
||||
return [:]
|
||||
}
|
||||
|
||||
guard let roomId: String = param["roomId"] as? String else {
|
||||
return [:]
|
||||
}
|
||||
|
||||
if key == gRoomEngineKey {
|
||||
return [key: roomEngine]
|
||||
} else if key == gRoomInfoKey {
|
||||
return [key: store.roomInfo]
|
||||
} else if key == gLocalUserInfoKey {
|
||||
return [key: store.currentUser]
|
||||
} else {
|
||||
return [:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - setFramework
|
||||
extension EngineManager {
|
||||
fileprivate static let TUIRoomKitFrameworkValue = 1
|
||||
fileprivate static let TUIRoomKitComponentValue = 18
|
||||
fileprivate static let IMComponentValue = 19
|
||||
fileprivate static let TUIRoomKitLanguageValue = 3
|
||||
private func setFramework() {
|
||||
let componentValue = store.isImAccess ? EngineManager.IMComponentValue : EngineManager.TUIRoomKitComponentValue
|
||||
let jsonStr = """
|
||||
{
|
||||
"api":"setFramework",
|
||||
"params":{
|
||||
"framework":\(EngineManager.TUIRoomKitFrameworkValue),
|
||||
"component":\(componentValue),
|
||||
"language":\(EngineManager.TUIRoomKitLanguageValue)
|
||||
}
|
||||
}
|
||||
"""
|
||||
TUIRoomEngine.callExperimentalAPI(jsonStr: jsonStr)
|
||||
}
|
||||
}
|
||||
|
||||
private extension String {
|
||||
static var inAnotherRoomText: String {
|
||||
localized("You are already in another conference")
|
||||
}
|
||||
static var quickConferenceText: String {
|
||||
localized("'s quick meeting")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user