AgoraIO / API-Examples

Play with AgoraSDK and have fun! Everything you need to start learning Agora.
296 stars 218 forks source link

demo #346

Closed Kuki93 closed 1 year ago

Kuki93 commented 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()
}

}