// // Agora.swift // SodaLive // // Created by klaus on 2023/08/14. // import Foundation import AgoraRtcKit import AgoraRtmKit final class Agora { static let shared = Agora() func initialize() { initRtcEngine() initRtmClient() } func deInit() { deInitRtcEngine() deInitRtmClient() } // MARK: RTC var rtcEngine: AgoraRtcEngineKit? var rtcEngineDelegate: AgoraRtcEngineDelegate? func initRtcEngine() { rtcEngine = AgoraRtcEngineKit.sharedEngine(withAppId: AGORA_APP_ID, delegate: rtcEngineDelegate) rtcEngine?.setChannelProfile(.liveBroadcasting) rtcEngine?.enableAudio() rtcEngine?.enableAudioVolumeIndication(500, smooth: 3, reportVad: true) } func deInitRtcEngine() { if let rtcEngine = rtcEngine { rtcEngine.leaveChannel(nil) DispatchQueue.global(qos: .userInitiated).async { AgoraRtcEngineKit.destroy() } } rtcEngine = nil } func joinRtcChannel(rtcToken: String, channelName: String) { let userId = UserDefaults.int(forKey: .userId) rtcEngine?.joinChannel( byToken: rtcToken, channelId: channelName, info: nil, uid: UInt(userId), joinSuccess: nil ) rtcEngine?.setAudioProfile(.musicHighQualityStereo) rtcEngine?.setAudioScenario(.gameStreaming) } func setRole(role: AgoraClientRole) { self.rtcEngine?.setClientRole(role) } func mute(_ isMute: Bool) { rtcEngine?.muteLocalAudioStream(isMute) } func speakerMute(_ isMute: Bool) { rtcEngine?.muteAllRemoteAudioStreams(isMute) } // MARK: RTM var rtmKit: AgoraRtmKit? var rtmChannel: AgoraRtmChannel? var rtmDelegate: AgoraRtmDelegate? func initRtmClient() { rtmKit = AgoraRtmKit(appId: AGORA_APP_ID, delegate: rtmDelegate) } func deInitRtmClient() { rtmChannel?.leave(completion: nil) rtmKit?.logout(completion: nil) rtmChannel = nil rtmKit = nil } func rtmLogin( creatorId: Int, rtmToken: String, channelName: String, rtmChannelDelegate: AgoraRtmChannelDelegate, onConnectSuccess: @escaping (Bool) -> Void, onConnectFail: @escaping () -> Void ) { if rtmChannel != nil { return } let userId = UserDefaults.int(forKey: .userId) rtmChannel = rtmKit?.createChannel( withId: channelName, delegate: rtmChannelDelegate ) rtmKit?.login( byToken: rtmToken, user: String(userId), completion: { [unowned self] loginErrorCode in if loginErrorCode == .ok { self.rtmChannel?.join(completion: { joinChannelErrorCode in if joinChannelErrorCode == .channelErrorOk { if userId == creatorId { self.setRole(role: .broadcaster) } else { self.setRole(role: .audience) } onConnectSuccess(userId == creatorId) } else { onConnectFail() } }) } else { onConnectFail() } } ) } func sendMessageToPeer(peerId: String, rawMessage: Data, completion: AgoraRtmSendPeerMessageBlock?) { let option = AgoraRtmSendMessageOptions() option.enableOfflineMessaging = false option.enableHistoricalMessaging = false let message = AgoraRtmRawMessage(rawData: rawMessage, description: "") rtmKit?.send(message, toPeer: peerId, completion: completion) } func sendRawMessageToPeer(peerId: String, rawMessage: LiveRoomChatRawMessage, completion: AgoraRtmSendPeerMessageBlock? = nil, fail: (() -> Void)? = nil) { let encoder = JSONEncoder() let jsonMessageData = try? encoder.encode(rawMessage) let option = AgoraRtmSendMessageOptions() option.enableOfflineMessaging = false option.enableHistoricalMessaging = false if let jsonMessageData = jsonMessageData { let message = AgoraRtmRawMessage(rawData: jsonMessageData, description: "") rtmKit?.send(message, toPeer: peerId, sendMessageOptions: option, completion: completion) } else { if let fail = fail { fail() } } } func sendMessageToGroup(textMessage: String, completion: @escaping AgoraRtmSendChannelMessageBlock) { let message = AgoraRtmMessage(text: textMessage) rtmChannel?.send(message, completion: completion) } func sendRawMessageToGroup(rawMessage: LiveRoomChatRawMessage, completion: AgoraRtmSendChannelMessageBlock? = nil, fail: (() -> Void)? = nil) { let encoder = JSONEncoder() let jsonMessageData = try? encoder.encode(rawMessage) if let jsonMessageData = jsonMessageData { let message = AgoraRtmRawMessage(rawData: jsonMessageData, description: "") rtmChannel?.send(message, completion: completion) } else { if let fail = fail { fail() } } } }