David Liu

Protocol 3 speaker changes

@@ -176,7 +176,8 @@ constructor( @@ -176,7 +176,8 @@ constructor(
176 fun onIceReconnected() 176 fun onIceReconnected()
177 fun onAddTrack(track: MediaStreamTrack, streams: Array<out MediaStream>) 177 fun onAddTrack(track: MediaStreamTrack, streams: Array<out MediaStream>)
178 fun onUpdateParticipants(updates: List<LivekitModels.ParticipantInfo>) 178 fun onUpdateParticipants(updates: List<LivekitModels.ParticipantInfo>)
179 - fun onUpdateSpeakers(speakers: List<LivekitModels.SpeakerInfo>) 179 + fun onActiveSpeakersUpdate(speakers: List<LivekitModels.SpeakerInfo>)
  180 + fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>)
180 fun onDisconnect(reason: String) 181 fun onDisconnect(reason: String)
181 fun onFailToConnect(error: Exception) 182 fun onFailToConnect(error: Exception)
182 fun onUserPacket(packet: LivekitModels.UserPacket, kind: LivekitModels.DataPacket.Kind) 183 fun onUserPacket(packet: LivekitModels.UserPacket, kind: LivekitModels.DataPacket.Kind)
@@ -195,7 +196,7 @@ constructor( @@ -195,7 +196,7 @@ constructor(
195 } 196 }
196 } 197 }
197 198
198 - //---------------------------------- RTCClient.Listener --------------------------------------// 199 + //---------------------------------- SignalClient.Listener --------------------------------------//
199 200
200 override fun onJoin(info: LivekitRtc.JoinResponse) { 201 override fun onJoin(info: LivekitRtc.JoinResponse) {
201 val iceServers = mutableListOf<PeerConnection.IceServer>() 202 val iceServers = mutableListOf<PeerConnection.IceServer>()
@@ -369,8 +370,8 @@ constructor( @@ -369,8 +370,8 @@ constructor(
369 listener?.onUpdateParticipants(updates) 370 listener?.onUpdateParticipants(updates)
370 } 371 }
371 372
372 - override fun onActiveSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>) {  
373 - listener?.onUpdateSpeakers(speakers) 373 + override fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>) {
  374 + listener?.onSpeakersChanged(speakers)
374 } 375 }
375 376
376 override fun onClose(reason: String, code: Int) { 377 override fun onClose(reason: String, code: Int) {
@@ -403,7 +404,7 @@ constructor( @@ -403,7 +404,7 @@ constructor(
403 val dp = LivekitModels.DataPacket.parseFrom(buffer.data) 404 val dp = LivekitModels.DataPacket.parseFrom(buffer.data)
404 when (dp.valueCase) { 405 when (dp.valueCase) {
405 LivekitModels.DataPacket.ValueCase.SPEAKER -> { 406 LivekitModels.DataPacket.ValueCase.SPEAKER -> {
406 - listener?.onUpdateSpeakers(dp.speaker.speakersList) 407 + listener?.onActiveSpeakersUpdate(dp.speaker.speakersList)
407 } 408 }
408 LivekitModels.DataPacket.ValueCase.USER -> { 409 LivekitModels.DataPacket.ValueCase.USER -> {
409 listener?.onUserPacket(dp.user, dp.kind) 410 listener?.onUserPacket(dp.user, dp.kind)
@@ -110,7 +110,7 @@ constructor( @@ -110,7 +110,7 @@ constructor(
110 return participant 110 return participant
111 } 111 }
112 112
113 - private fun handleSpeakerUpdate(speakerInfos: List<LivekitModels.SpeakerInfo>) { 113 + private fun handleActiveSpeakersUpdate(speakerInfos: List<LivekitModels.SpeakerInfo>) {
114 val speakers = mutableListOf<Participant>() 114 val speakers = mutableListOf<Participant>()
115 val seenSids = mutableSetOf<String>() 115 val seenSids = mutableSetOf<String>()
116 val localParticipant = localParticipant 116 val localParticipant = localParticipant
@@ -148,6 +148,37 @@ constructor( @@ -148,6 +148,37 @@ constructor(
148 listener?.onActiveSpeakersChanged(speakers, this) 148 listener?.onActiveSpeakersChanged(speakers, this)
149 } 149 }
150 150
  151 + private fun handleSpeakersChanged(speakerInfos: List<LivekitModels.SpeakerInfo>) {
  152 + val updatedSpeakers = mutableMapOf<String, Participant>()
  153 + activeSpeakers.forEach {
  154 + updatedSpeakers[it.sid] = it
  155 + }
  156 +
  157 + speakerInfos.forEach { speaker ->
  158 + val participant = if(speaker.sid == localParticipant.sid) {
  159 + localParticipant
  160 + } else {
  161 + remoteParticipants[speaker.sid]
  162 + } ?: return@forEach
  163 +
  164 + participant.audioLevel = speaker.level
  165 + participant.isSpeaking = speaker.active
  166 +
  167 + if(speaker.active) {
  168 + updatedSpeakers[speaker.sid] = participant
  169 + } else {
  170 + updatedSpeakers.remove(speaker.sid)
  171 + }
  172 + }
  173 +
  174 + val updatedSpeakersList = updatedSpeakers.values.toList()
  175 + .sortedBy { it.audioLevel }
  176 +
  177 + mutableActiveSpeakers.clear()
  178 + mutableActiveSpeakers.addAll(updatedSpeakersList)
  179 + listener?.onActiveSpeakersChanged(updatedSpeakersList, this)
  180 + }
  181 +
151 private fun reconnect() { 182 private fun reconnect() {
152 if (state == State.RECONNECTING) { 183 if (state == State.RECONNECTING) {
153 return 184 return
@@ -290,8 +321,15 @@ constructor( @@ -290,8 +321,15 @@ constructor(
290 /** 321 /**
291 * @suppress 322 * @suppress
292 */ 323 */
293 - override fun onUpdateSpeakers(speakers: List<LivekitModels.SpeakerInfo>) {  
294 - handleSpeakerUpdate(speakers) 324 + override fun onActiveSpeakersUpdate(speakers: List<LivekitModels.SpeakerInfo>) {
  325 + handleActiveSpeakersUpdate(speakers)
  326 + }
  327 +
  328 + /**
  329 + * @suppress
  330 + */
  331 + override fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>) {
  332 + handleSpeakersChanged(speakers)
295 } 333 }
296 334
297 /** 335 /**
@@ -3,6 +3,7 @@ package io.livekit.android.room @@ -3,6 +3,7 @@ package io.livekit.android.room
3 import com.github.ajalt.timberkt.Timber 3 import com.github.ajalt.timberkt.Timber
4 import com.google.protobuf.util.JsonFormat 4 import com.google.protobuf.util.JsonFormat
5 import io.livekit.android.ConnectOptions 5 import io.livekit.android.ConnectOptions
  6 +import io.livekit.android.Version
6 import io.livekit.android.dagger.InjectionNames 7 import io.livekit.android.dagger.InjectionNames
7 import io.livekit.android.room.track.Track 8 import io.livekit.android.room.track.Track
8 import io.livekit.android.util.safe 9 import io.livekit.android.util.safe
@@ -46,7 +47,11 @@ constructor( @@ -46,7 +47,11 @@ constructor(
46 token: String, 47 token: String,
47 options: ConnectOptions?, 48 options: ConnectOptions?,
48 ) { 49 ) {
49 - var wsUrlString = "$url/rtc?protocol=$PROTOCOL_VERSION&access_token=$token" 50 + var wsUrlString = "$url/rtc" +
  51 + "?protocol=$PROTOCOL_VERSION" +
  52 + "&access_token=$token" +
  53 + "&sdk=$SDK_TYPE" +
  54 + "&version=${Version.CLIENT_VERSION}"
50 isReconnecting = false 55 isReconnecting = false
51 if (options != null) { 56 if (options != null) {
52 wsUrlString += "&auto_subscribe=" 57 wsUrlString += "&auto_subscribe="
@@ -318,8 +323,8 @@ constructor( @@ -318,8 +323,8 @@ constructor(
318 LivekitRtc.SignalResponse.MessageCase.TRACK_PUBLISHED -> { 323 LivekitRtc.SignalResponse.MessageCase.TRACK_PUBLISHED -> {
319 listener?.onLocalTrackPublished(response.trackPublished) 324 listener?.onLocalTrackPublished(response.trackPublished)
320 } 325 }
321 - LivekitRtc.SignalResponse.MessageCase.SPEAKER -> {  
322 - listener?.onActiveSpeakersChanged(response.speaker.speakersList) 326 + LivekitRtc.SignalResponse.MessageCase.SPEAKERS_CHANGED -> {
  327 + listener?.onSpeakersChanged(response.speakersChanged.speakersList)
323 } 328 }
324 LivekitRtc.SignalResponse.MessageCase.JOIN -> { 329 LivekitRtc.SignalResponse.MessageCase.JOIN -> {
325 Timber.d { "received unexpected extra join message?" } 330 Timber.d { "received unexpected extra join message?" }
@@ -327,6 +332,12 @@ constructor( @@ -327,6 +332,12 @@ constructor(
327 LivekitRtc.SignalResponse.MessageCase.LEAVE -> { 332 LivekitRtc.SignalResponse.MessageCase.LEAVE -> {
328 listener?.onLeave() 333 listener?.onLeave()
329 } 334 }
  335 + LivekitRtc.SignalResponse.MessageCase.MUTE -> {
  336 + //TODO
  337 + }
  338 + LivekitRtc.SignalResponse.MessageCase.ROOM_UPDATE -> {
  339 + //TODO
  340 + }
330 LivekitRtc.SignalResponse.MessageCase.MESSAGE_NOT_SET, 341 LivekitRtc.SignalResponse.MessageCase.MESSAGE_NOT_SET,
331 null -> { 342 null -> {
332 Timber.v { "empty messageCase!" } 343 Timber.v { "empty messageCase!" }
@@ -347,7 +358,7 @@ constructor( @@ -347,7 +358,7 @@ constructor(
347 fun onTrickle(candidate: IceCandidate, target: LivekitRtc.SignalTarget) 358 fun onTrickle(candidate: IceCandidate, target: LivekitRtc.SignalTarget)
348 fun onLocalTrackPublished(response: LivekitRtc.TrackPublishedResponse) 359 fun onLocalTrackPublished(response: LivekitRtc.TrackPublishedResponse)
349 fun onParticipantUpdate(updates: List<LivekitModels.ParticipantInfo>) 360 fun onParticipantUpdate(updates: List<LivekitModels.ParticipantInfo>)
350 - fun onActiveSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>) 361 + fun onSpeakersChanged(speakers: List<LivekitModels.SpeakerInfo>)
351 fun onClose(reason: String, code: Int) 362 fun onClose(reason: String, code: Int)
352 fun onLeave() 363 fun onLeave()
353 fun onError(error: Exception) 364 fun onError(error: Exception)
@@ -358,6 +369,7 @@ constructor( @@ -358,6 +369,7 @@ constructor(
358 const val SD_TYPE_OFFER = "offer" 369 const val SD_TYPE_OFFER = "offer"
359 const val SD_TYPE_PRANSWER = "pranswer" 370 const val SD_TYPE_PRANSWER = "pranswer"
360 const val PROTOCOL_VERSION = 2 371 const val PROTOCOL_VERSION = 2
  372 + const val SDK_TYPE = "android"
361 373
362 private fun iceServer(url: String) = 374 private fun iceServer(url: String) =
363 PeerConnection.IceServer.builder(url).createIceServer() 375 PeerConnection.IceServer.builder(url).createIceServer()