正在显示
3 个修改的文件
包含
44 行增加
和
6 行删除
| @@ -79,12 +79,13 @@ class RemoteTrackPublication( | @@ -79,12 +79,13 @@ class RemoteTrackPublication( | ||
| 79 | } | 79 | } |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | - override var muted: Boolean = false | 82 | + override var muted: Boolean |
| 83 | + get() = super.muted | ||
| 83 | set(v) { | 84 | set(v) { |
| 84 | - if (field == v) { | 85 | + if (super.muted == v) { |
| 85 | return | 86 | return |
| 86 | } | 87 | } |
| 87 | - field = v | 88 | + super.muted = v |
| 88 | val participant = this.participant.get() as? RemoteParticipant ?: return | 89 | val participant = this.participant.get() as? RemoteParticipant ?: return |
| 89 | if (v) { | 90 | if (v) { |
| 90 | participant.onTrackMuted(this) | 91 | participant.onTrackMuted(this) |
| @@ -21,7 +21,9 @@ open class TrackPublication( | @@ -21,7 +21,9 @@ open class TrackPublication( | ||
| 21 | private set | 21 | private set |
| 22 | var kind: Track.Kind | 22 | var kind: Track.Kind |
| 23 | private set | 23 | private set |
| 24 | - open var muted: Boolean = false | 24 | + |
| 25 | + @get:FlowObservable | ||
| 26 | + open var muted: Boolean by flowDelegate(false) | ||
| 25 | internal set | 27 | internal set |
| 26 | open val subscribed: Boolean | 28 | open val subscribed: Boolean |
| 27 | get() { | 29 | get() { |
| @@ -8,8 +8,14 @@ import io.livekit.android.room.Room | @@ -8,8 +8,14 @@ import io.livekit.android.room.Room | ||
| 8 | import io.livekit.android.room.participant.Participant | 8 | import io.livekit.android.room.participant.Participant |
| 9 | import io.livekit.android.room.participant.ParticipantListener | 9 | import io.livekit.android.room.participant.ParticipantListener |
| 10 | import io.livekit.android.room.participant.RemoteParticipant | 10 | import io.livekit.android.room.participant.RemoteParticipant |
| 11 | -import io.livekit.android.room.track.* | 11 | +import io.livekit.android.room.track.RemoteTrackPublication |
| 12 | +import io.livekit.android.room.track.Track | ||
| 13 | +import io.livekit.android.room.track.VideoTrack | ||
| 12 | import io.livekit.android.sample.databinding.ParticipantItemBinding | 14 | import io.livekit.android.sample.databinding.ParticipantItemBinding |
| 15 | +import io.livekit.android.util.flow | ||
| 16 | +import kotlinx.coroutines.* | ||
| 17 | +import kotlinx.coroutines.flow.flatMapLatest | ||
| 18 | +import kotlinx.coroutines.flow.flowOf | ||
| 13 | 19 | ||
| 14 | class ParticipantItem( | 20 | class ParticipantItem( |
| 15 | val room: Room, | 21 | val room: Room, |
| @@ -17,6 +23,7 @@ class ParticipantItem( | @@ -17,6 +23,7 @@ class ParticipantItem( | ||
| 17 | ) : BindableItem<ParticipantItemBinding>() { | 23 | ) : BindableItem<ParticipantItemBinding>() { |
| 18 | 24 | ||
| 19 | private var boundVideoTrack: VideoTrack? = null | 25 | private var boundVideoTrack: VideoTrack? = null |
| 26 | + private var coroutineScope: CoroutineScope? = null | ||
| 20 | 27 | ||
| 21 | override fun initializeViewBinding(view: View): ParticipantItemBinding { | 28 | override fun initializeViewBinding(view: View): ParticipantItemBinding { |
| 22 | val binding = ParticipantItemBinding.bind(view) | 29 | val binding = ParticipantItemBinding.bind(view) |
| @@ -24,8 +31,34 @@ class ParticipantItem( | @@ -24,8 +31,34 @@ class ParticipantItem( | ||
| 24 | return binding | 31 | return binding |
| 25 | } | 32 | } |
| 26 | 33 | ||
| 34 | + private fun ensureCoroutineScope() { | ||
| 35 | + if (coroutineScope == null) { | ||
| 36 | + coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + | ||
| 27 | override fun bind(viewBinding: ParticipantItemBinding, position: Int) { | 40 | override fun bind(viewBinding: ParticipantItemBinding, position: Int) { |
| 28 | - viewBinding.identityText.text = participant.identity | 41 | + |
| 42 | + ensureCoroutineScope() | ||
| 43 | + coroutineScope?.launch { | ||
| 44 | + participant::identity.flow.collect { identity -> | ||
| 45 | + viewBinding.identityText.text = identity | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + coroutineScope?.launch { | ||
| 49 | + participant::audioTracks.flow | ||
| 50 | + .flatMapLatest { tracks -> | ||
| 51 | + val audioTrack = tracks.values.firstOrNull() | ||
| 52 | + if (audioTrack != null) { | ||
| 53 | + audioTrack::muted.flow | ||
| 54 | + } else { | ||
| 55 | + flowOf(true) | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + .collect { muted -> | ||
| 59 | + viewBinding.muteIndicator.visibility = if (muted) View.VISIBLE else View.INVISIBLE | ||
| 60 | + } | ||
| 61 | + } | ||
| 29 | participant.listener = object : ParticipantListener { | 62 | participant.listener = object : ParticipantListener { |
| 30 | override fun onTrackSubscribed( | 63 | override fun onTrackSubscribed( |
| 31 | track: Track, | 64 | track: Track, |
| @@ -67,6 +100,8 @@ class ParticipantItem( | @@ -67,6 +100,8 @@ class ParticipantItem( | ||
| 67 | } | 100 | } |
| 68 | 101 | ||
| 69 | override fun unbind(viewHolder: GroupieViewHolder<ParticipantItemBinding>) { | 102 | override fun unbind(viewHolder: GroupieViewHolder<ParticipantItemBinding>) { |
| 103 | + coroutineScope?.cancel() | ||
| 104 | + coroutineScope = null | ||
| 70 | super.unbind(viewHolder) | 105 | super.unbind(viewHolder) |
| 71 | boundVideoTrack?.removeRenderer(viewHolder.binding.renderer) | 106 | boundVideoTrack?.removeRenderer(viewHolder.binding.renderer) |
| 72 | boundVideoTrack = null | 107 | boundVideoTrack = null |
-
请 注册 或 登录 后发表评论