David Liu

Protocol 3 speaker changes

... ... @@ -176,7 +176,8 @@ constructor(
fun onIceReconnected()
fun onAddTrack(track: MediaStreamTrack, streams: Array<out MediaStream>)
fun onUpdateParticipants(updates: List<LivekitModels.ParticipantInfo>)
fun onUpdateSpeakers(speakers: List<LivekitModels.SpeakerInfo>)
fun onActiveSpeakersUpdate(speakers: List<LivekitModels.SpeakerInfo>)
fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>)
fun onDisconnect(reason: String)
fun onFailToConnect(error: Exception)
fun onUserPacket(packet: LivekitModels.UserPacket, kind: LivekitModels.DataPacket.Kind)
... ... @@ -195,7 +196,7 @@ constructor(
}
}
//---------------------------------- RTCClient.Listener --------------------------------------//
//---------------------------------- SignalClient.Listener --------------------------------------//
override fun onJoin(info: LivekitRtc.JoinResponse) {
val iceServers = mutableListOf<PeerConnection.IceServer>()
... ... @@ -369,8 +370,8 @@ constructor(
listener?.onUpdateParticipants(updates)
}
override fun onActiveSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>) {
listener?.onUpdateSpeakers(speakers)
override fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>) {
listener?.onSpeakersChanged(speakers)
}
override fun onClose(reason: String, code: Int) {
... ... @@ -403,7 +404,7 @@ constructor(
val dp = LivekitModels.DataPacket.parseFrom(buffer.data)
when (dp.valueCase) {
LivekitModels.DataPacket.ValueCase.SPEAKER -> {
listener?.onUpdateSpeakers(dp.speaker.speakersList)
listener?.onActiveSpeakersUpdate(dp.speaker.speakersList)
}
LivekitModels.DataPacket.ValueCase.USER -> {
listener?.onUserPacket(dp.user, dp.kind)
... ...
... ... @@ -110,7 +110,7 @@ constructor(
return participant
}
private fun handleSpeakerUpdate(speakerInfos: List<LivekitModels.SpeakerInfo>) {
private fun handleActiveSpeakersUpdate(speakerInfos: List<LivekitModels.SpeakerInfo>) {
val speakers = mutableListOf<Participant>()
val seenSids = mutableSetOf<String>()
val localParticipant = localParticipant
... ... @@ -148,6 +148,37 @@ constructor(
listener?.onActiveSpeakersChanged(speakers, this)
}
private fun handleSpeakersChanged(speakerInfos: List<LivekitModels.SpeakerInfo>) {
val updatedSpeakers = mutableMapOf<String, Participant>()
activeSpeakers.forEach {
updatedSpeakers[it.sid] = it
}
speakerInfos.forEach { speaker ->
val participant = if(speaker.sid == localParticipant.sid) {
localParticipant
} else {
remoteParticipants[speaker.sid]
} ?: return@forEach
participant.audioLevel = speaker.level
participant.isSpeaking = speaker.active
if(speaker.active) {
updatedSpeakers[speaker.sid] = participant
} else {
updatedSpeakers.remove(speaker.sid)
}
}
val updatedSpeakersList = updatedSpeakers.values.toList()
.sortedBy { it.audioLevel }
mutableActiveSpeakers.clear()
mutableActiveSpeakers.addAll(updatedSpeakersList)
listener?.onActiveSpeakersChanged(updatedSpeakersList, this)
}
private fun reconnect() {
if (state == State.RECONNECTING) {
return
... ... @@ -290,8 +321,15 @@ constructor(
/**
* @suppress
*/
override fun onUpdateSpeakers(speakers: List<LivekitModels.SpeakerInfo>) {
handleSpeakerUpdate(speakers)
override fun onActiveSpeakersUpdate(speakers: List<LivekitModels.SpeakerInfo>) {
handleActiveSpeakersUpdate(speakers)
}
/**
* @suppress
*/
override fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>) {
handleSpeakersChanged(speakers)
}
/**
... ...
... ... @@ -3,6 +3,7 @@ package io.livekit.android.room
import com.github.ajalt.timberkt.Timber
import com.google.protobuf.util.JsonFormat
import io.livekit.android.ConnectOptions
import io.livekit.android.Version
import io.livekit.android.dagger.InjectionNames
import io.livekit.android.room.track.Track
import io.livekit.android.util.safe
... ... @@ -46,7 +47,11 @@ constructor(
token: String,
options: ConnectOptions?,
) {
var wsUrlString = "$url/rtc?protocol=$PROTOCOL_VERSION&access_token=$token"
var wsUrlString = "$url/rtc" +
"?protocol=$PROTOCOL_VERSION" +
"&access_token=$token" +
"&sdk=$SDK_TYPE" +
"&version=${Version.CLIENT_VERSION}"
isReconnecting = false
if (options != null) {
wsUrlString += "&auto_subscribe="
... ... @@ -318,8 +323,8 @@ constructor(
LivekitRtc.SignalResponse.MessageCase.TRACK_PUBLISHED -> {
listener?.onLocalTrackPublished(response.trackPublished)
}
LivekitRtc.SignalResponse.MessageCase.SPEAKER -> {
listener?.onActiveSpeakersChanged(response.speaker.speakersList)
LivekitRtc.SignalResponse.MessageCase.SPEAKERS_CHANGED -> {
listener?.onSpeakersChanged(response.speakersChanged.speakersList)
}
LivekitRtc.SignalResponse.MessageCase.JOIN -> {
Timber.d { "received unexpected extra join message?" }
... ... @@ -327,6 +332,12 @@ constructor(
LivekitRtc.SignalResponse.MessageCase.LEAVE -> {
listener?.onLeave()
}
LivekitRtc.SignalResponse.MessageCase.MUTE -> {
//TODO
}
LivekitRtc.SignalResponse.MessageCase.ROOM_UPDATE -> {
//TODO
}
LivekitRtc.SignalResponse.MessageCase.MESSAGE_NOT_SET,
null -> {
Timber.v { "empty messageCase!" }
... ... @@ -347,7 +358,7 @@ constructor(
fun onTrickle(candidate: IceCandidate, target: LivekitRtc.SignalTarget)
fun onLocalTrackPublished(response: LivekitRtc.TrackPublishedResponse)
fun onParticipantUpdate(updates: List<LivekitModels.ParticipantInfo>)
fun onActiveSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>)
fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>)
fun onClose(reason: String, code: Int)
fun onLeave()
fun onError(error: Exception)
... ... @@ -358,6 +369,7 @@ constructor(
const val SD_TYPE_OFFER = "offer"
const val SD_TYPE_PRANSWER = "pranswer"
const val PROTOCOL_VERSION = 2
const val SDK_TYPE = "android"
private fun iceServer(url: String) =
PeerConnection.IceServer.builder(url).createIceServer()
... ...