Closed Kuki93 closed 1 year ago
package io.agora.api.example
import io.agora.rtc2.*
interface IRtcChannel {
fun joinChannel(channelName: String, upMic: Boolean = false, mute: Boolean = true, speaker: Boolean = true) fun levelChannel() fun upMic(): Boolean fun downMic(): Boolean fun setEnableSpeakerphone(enabled: Boolean): Boolean
}
private fun destroyRtcEngine() { // post RtcEngine.destroy() }
class RtcChannelImpl( channelName: String, private val defaultSpeakerphone: Boolean = true, audioProfile: Constants.AudioProfile = Constants.AudioProfile.DEFAULT, audioScenario: Constants.AudioScenario = Constants.AudioScenario.CHATROOM, ) : IRtcEngineEventHandler(), IRtcChannel {
@Volatile private var isDestroy = false private val state: State = State(channelName) private val rtcEngine by lazy(LazyThreadSafetyMode.NONE) { val config = RtcEngineConfig() config.mEventHandler = this config.mChannelProfile = Constants.CHANNEL_PROFILE_CLOUD_GAMING RtcEngine.create(config).also { it.setDefaultAudioRoutetoSpeakerphone(defaultSpeakerphone) it.setAudioProfile(audioProfile.ordinal) it.setAudioScenario(audioScenario.ordinal) } } override fun joinChannel(channelName: String, upMic: Boolean, mute: Boolean, speaker: Boolean) { if (isDestroy) { return } // enableLocalAudio: 是否启动麦克风采集并创建本地音频流。
// muteLocalAudioStream: 是否发布本地音频流。 // muteRemoteAudioStream: 是否接收并播放远端音频流。 // muteAllRemoteAudioStreams: 是否接收并播放所有远端音频流。 val options = ChannelMediaOptions() options.autoSubscribeAudio = true options.clientRoleType = if (upMic) Constants.CLIENT_ROLE_BROADCASTER else Constants.CLIENT_ROLE_AUDIENCE options.channelProfile = Constants.CHANNEL_PROFILE_CLOUD_GAMING
state.joinState = TState(true, Status.InProgress) state.upMicState = TState(upMic, Status.InProgress) if (defaultSpeakerphone == speaker) { state.speakerState = TState(speaker, Status.InProgress) } val ret = rtcEngine.joinChannel("", channelName, 0, options) if (ret == 0) { } } override fun levelChannel() { if (isDestroy) { return } isDestroy = true rtcEngine.leaveChannel() destroyRtcEngine() } override fun upMic(): Boolean { if (isDestroy) { return false } return rtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER) == 0 } override fun downMic(): Boolean { if (isDestroy) { return false } return rtcEngine.setClientRole(Constants.CLIENT_ROLE_AUDIENCE) == 0 } override fun setEnableSpeakerphone(enabled: Boolean): Boolean { if (isDestroy) { return false } return rtcEngine.setEnableSpeakerphone(enabled) == 0 } override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) { super.onJoinChannelSuccess(channel, uid, elapsed) } override fun onRejoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) { super.onRejoinChannelSuccess(channel, uid, elapsed) } override fun onUserJoined(uid: Int, elapsed: Int) { super.onUserJoined(uid, elapsed) } override fun onUserOffline(uid: Int, reason: Int) { super.onUserOffline(uid, reason) } override fun onConnectionLost() { super.onConnectionLost() } override fun onClientRoleChanged(oldRole: Int, newRole: Int, newRoleOptions: ClientRoleOptions?) { super.onClientRoleChanged(oldRole, newRole, newRoleOptions) } override fun onClientRoleChangeFailed(reason: Int, currentRole: Int) { super.onClientRoleChangeFailed(reason, currentRole) } override fun onConnectionStateChanged(state: Int, reason: Int) { super.onConnectionStateChanged(state, reason) if (Constants.CONNECTION_STATE_DISCONNECTED == state) { // 网络连接中断 if (reason == Constants.CONNECTION_CHANGED_JOIN_FAILED) { } } } private data class State( var channel: String = "", var token: String = "", var joinState: TState<Boolean> = TState(false), var upMicState: TState<Boolean> = TState(false), var muteState: TState<Boolean> = TState(false), var speakerState: TState<Boolean> = TState(false), ) { } private data class TState<T>(val value: T, val status: Status = Status.Idea) private sealed class Status { object Idea : Status() object InProgress : Status() object Success : Status() class Error(val exception: Exception) : Status() }
package io.agora.api.example
import io.agora.rtc2.*
interface IRtcChannel {
}
private fun destroyRtcEngine() { // post RtcEngine.destroy() }
class RtcChannelImpl( channelName: String, private val defaultSpeakerphone: Boolean = true, audioProfile: Constants.AudioProfile = Constants.AudioProfile.DEFAULT, audioScenario: Constants.AudioScenario = Constants.AudioScenario.CHATROOM, ) : IRtcEngineEventHandler(), IRtcChannel {
// muteLocalAudioStream: 是否发布本地音频流。 // muteRemoteAudioStream: 是否接收并播放远端音频流。 // muteAllRemoteAudioStreams: 是否接收并播放所有远端音频流。 val options = ChannelMediaOptions() options.autoSubscribeAudio = true options.clientRoleType = if (upMic) Constants.CLIENT_ROLE_BROADCASTER else Constants.CLIENT_ROLE_AUDIENCE options.channelProfile = Constants.CHANNEL_PROFILE_CLOUD_GAMING
}