Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
xuning
/
livekitAndroidXuningTest
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
David Zhao
2021-03-27 23:42:43 -0700
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
63fd06aa28cbe02ba2c4d3c69e5333ccea9c4fa9
63fd06aa
1 parent
cd8eac76
feature: mute support, selective track handling
显示空白字符变更
内嵌
并排对比
正在显示
9 个修改的文件
包含
258 行增加
和
39 行删除
livekit-android-sdk/src/main/java/io/livekit/android/room/RTCClient.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/Room.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/participant/LocalParticipant.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/participant/Participant.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/participant/RemoteParticipant.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/track/LocalTrackPublication.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/track/RemoteTrackPublication.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/track/TrackPublication.kt
sample-app/src/main/java/io/livekit/android/sample/ParticipantItem.kt
livekit-android-sdk/src/main/java/io/livekit/android/room/RTCClient.kt
查看文件 @
63fd06a
...
...
@@ -180,6 +180,32 @@ constructor(
sendRequest(request)
}
fun sendUpdateTrackSettings(sid: String, disabled: Boolean, videoQuality: LivekitRtc.VideoQuality) {
val trackSettings = LivekitRtc.UpdateTrackSettings.newBuilder()
.setTrackSids(0, sid)
.setDisabled(disabled)
.setQuality(videoQuality)
val request = LivekitRtc.SignalRequest.newBuilder()
.setTrackSetting(trackSettings)
.build()
sendRequest(request)
}
fun sendUpdateSubscription(sid: String, subscribe: Boolean, videoQuality: LivekitRtc.VideoQuality) {
val subscription = LivekitRtc.UpdateSubscription.newBuilder()
.setTrackSids(0, sid)
.setSubscribe(subscribe)
.setQuality(videoQuality)
val request = LivekitRtc.SignalRequest.newBuilder()
.setSubscription(subscription)
.build()
sendRequest(request)
}
fun sendRequest(request: LivekitRtc.SignalRequest) {
Timber.v { "sending request: $request" }
if (!isConnected || currentWs == null) {
...
...
livekit-android-sdk/src/main/java/io/livekit/android/room/Room.kt
查看文件 @
63fd06a
...
...
@@ -9,9 +9,7 @@ import io.livekit.android.room.participant.LocalParticipant
import io.livekit.android.room.participant.Participant
import io.livekit.android.room.participant.ParticipantListener
import io.livekit.android.room.participant.RemoteParticipant
import io.livekit.android.room.track.DataTrack
import io.livekit.android.room.track.Track
import io.livekit.android.room.track.TrackPublication
import io.livekit.android.room.track.*
import io.livekit.android.room.util.unpackedTrackLabel
import livekit.LivekitModels
import livekit.LivekitRtc
...
...
@@ -92,9 +90,9 @@ constructor(
}
participant = if (info != null) {
RemoteParticipant(info)
RemoteParticipant(
engine.client,
info)
} else {
RemoteParticipant(sid, null)
RemoteParticipant(
engine.client,
sid, null)
}
participant.internalListener = this
mutableRemoteParticipants[sid] = participant
...
...
@@ -258,24 +256,34 @@ constructor(
listener?.onMetadataChanged(participant, prevMetadata, this)
}
/** @suppress */
override fun onTrackMuted(publication: TrackPublication, participant: Participant) {
listener?.onTrackMuted(publication, participant, this)
}
/** @suppress */
override fun onTrackUnmuted(publication: TrackPublication, participant: Participant) {
listener?.onTrackUnmuted(publication, participant, this)
}
/**
* @suppress
*/
override fun onTrackPublished(publication: TrackPublication, participant: RemoteParticipant) {
override fun onTrackPublished(publication:
Remote
TrackPublication, participant: RemoteParticipant) {
listener?.onTrackPublished(publication, participant, this)
}
/**
* @suppress
*/
override fun onTrackUnpublished(publication: TrackPublication, participant: RemoteParticipant) {
override fun onTrackUnpublished(publication:
Remote
TrackPublication, participant: RemoteParticipant) {
listener?.onTrackUnpublished(publication, participant, this)
}
/**
* @suppress
*/
override fun onTrackSubscribed(track: Track, publication: TrackPublication, participant: RemoteParticipant) {
override fun onTrackSubscribed(track: Track, publication:
Remote
TrackPublication, participant: RemoteParticipant) {
listener?.onTrackSubscribed(track, publication, participant, this)
}
...
...
@@ -295,7 +303,7 @@ constructor(
*/
override fun onTrackUnsubscribed(
track: Track,
publication: TrackPublication,
publication:
Remote
TrackPublication,
participant: RemoteParticipant
) {
listener?.onTrackUnsubscribed(track, publication, participant, this)
...
...
@@ -366,6 +374,22 @@ interface RoomListener {
fun onMetadataChanged(participant: Participant, prevMetadata: String?, room: Room) {}
/**
* The participant was muted.
*
* For the local participant, the callback will be called if setMute was called on the
* [LocalTrackPublication], or if the server has requested the participant to be muted
*/
fun onTrackMuted(publication: TrackPublication, participant: Participant, room: Room) {}
/**
* The participant was unmuted.
*
* For the local participant, the callback will be called if setMute was called on the
* [LocalTrackPublication], or if the server has requested the participant to be muted
*/
fun onTrackUnmuted(publication: TrackPublication, participant: Participant, room: Room) {}
/**
* When a new track is published to room after the local participant has joined. It will
* not fire for tracks that are already published
*/
...
...
livekit-android-sdk/src/main/java/io/livekit/android/room/participant/LocalParticipant.kt
查看文件 @
63fd06a
...
...
@@ -15,7 +15,7 @@ class LocalParticipant
internal constructor(
@Assisted
info: LivekitModels.ParticipantInfo,
private
val engine: RTCEngine,
internal
val engine: RTCEngine,
private val peerConnectionFactory: PeerConnectionFactory,
private val context: Context,
private val eglBase: EglBase,
...
...
@@ -72,7 +72,7 @@ internal constructor(
return
}
val publication =
TrackPublication(trackInfo, track
)
val publication =
LocalTrackPublication(trackInfo, track, this
)
addTrackPublication(publication)
publishListener?.onPublishSuccess(publication)
}
...
...
@@ -102,7 +102,7 @@ internal constructor(
return
}
val publication =
TrackPublication(trackInfo, track
)
val publication =
LocalTrackPublication(trackInfo, track, this
)
addTrackPublication(publication)
publishListener?.onPublishSuccess(publication)
}
...
...
@@ -120,7 +120,7 @@ internal constructor(
val cid = track.name
val trackInfo =
engine.addTrack(cid = cid, name = track.name, track.kind)
val publication =
TrackPublication(trackInfo, track
)
val publication =
LocalTrackPublication(trackInfo, track, this
)
val config = DataChannel.Init().apply {
ordered = track.options.ordered
...
...
@@ -159,15 +159,27 @@ internal constructor(
}
}
override fun updateFromInfo(info: LivekitModels.ParticipantInfo) {
super.updateFromInfo(info)
// detect tracks that have been muted on the server side, apply those changes
for (ti in info.tracksList) {
val publication = this.tracks[ti.sid] as? LocalTrackPublication ?: continue
if (ti.muted != publication.muted) {
publication.setMuted(ti.muted)
}
}
}
private fun <T> unpublishMediaTrack(
track: T,
sid: String
) where T : MediaTrack {
val senders = engine
?
.publisher?.peerConnection?.senders ?: return
val senders = engine.publisher?.peerConnection?.senders ?: return
for (sender in senders) {
val t = sender.track() ?: continue
if (t == track.rtcTrack) {
engine
?
.publisher?.peerConnection?.removeTrack(sender)
engine.publisher?.peerConnection?.removeTrack(sender)
}
}
}
...
...
livekit-android-sdk/src/main/java/io/livekit/android/room/participant/Participant.kt
查看文件 @
63fd06a
...
...
@@ -60,7 +60,7 @@ open class Participant(var sid: String, identity: String? = null) {
/**
* @suppress
*/
open fun updateFromInfo(info: LivekitModels.ParticipantInfo) {
internal
open fun updateFromInfo(info: LivekitModels.ParticipantInfo) {
sid = info.sid
identity = info.identity
participantInfo = info
...
...
@@ -92,6 +92,7 @@ open class Participant(var sid: String, identity: String? = null) {
interface ParticipantListener {
// all participants
/**
* When a participant's metadata is updated, fired for all participants
*/
...
...
@@ -102,13 +103,44 @@ interface ParticipantListener {
*/
fun onSpeakingChanged(participant: Participant) {}
fun onTrackPublished(publication: TrackPublication, participant: RemoteParticipant) {}
fun onTrackUnpublished(publication: TrackPublication, participant: RemoteParticipant) {}
/**
* The participant was muted.
*
* For the local participant, the callback will be called if setMute was called on the
* [LocalTrackPublication], or if the server has requested the participant to be muted
*/
fun onTrackMuted(publication: TrackPublication, participant: Participant) {}
/**
* The participant was unmuted.
*
* For the local participant, the callback will be called if setMute was called on the
* [LocalTrackPublication], or if the server has requested the participant to be muted
*/
fun onTrackUnmuted(publication: TrackPublication, participant: Participant) {}
fun onEnable(publication: TrackPublication, participant: RemoteParticipant) {}
fun onDisable(publication: TrackPublication, participant: RemoteParticipant) {}
// remote participants
/**
* When a new track is published to room after the local participant has joined.
*
* It will not fire for tracks that are already published
*/
fun onTrackPublished(publication: RemoteTrackPublication, participant: RemoteParticipant) {}
/**
* A [RemoteParticipant] has unpublished a track
*/
fun onTrackUnpublished(publication: RemoteTrackPublication, participant: RemoteParticipant) {}
fun onTrackSubscribed(track: Track, publication: TrackPublication, participant: RemoteParticipant) {}
/**
* Subscribed to a new track
*/
fun onTrackSubscribed(track: Track, publication: RemoteTrackPublication, participant: RemoteParticipant) {}
/**
* Error had occurred while subscribing to a track
*/
fun onTrackSubscriptionFailed(
sid: String,
exception: Exception,
...
...
@@ -116,20 +148,24 @@ interface ParticipantListener {
) {
}
/**
* A subscribed track is no longer available.
* Clients should listen to this event and handle cleanup
*/
fun onTrackUnsubscribed(
track: Track,
publication: TrackPublication,
publication:
Remote
TrackPublication,
participant: RemoteParticipant
) {
}
/**
* Data was received on a data track
*/
fun onDataReceived(
data: ByteBuffer,
dataTrack: DataTrack,
participant: RemoteParticipant
) {
}
fun switchedOffVideo(track: VideoTrack, publication: TrackPublication, participant: RemoteParticipant) {}
fun switchedOnVideo(track: VideoTrack, publication: TrackPublication, participant: RemoteParticipant) {}
}
\ No newline at end of file
...
...
livekit-android-sdk/src/main/java/io/livekit/android/room/participant/RemoteParticipant.kt
查看文件 @
63fd06a
package io.livekit.android.room.participant
import com.github.ajalt.timberkt.Timber
import io.livekit.android.room.RTCClient
import io.livekit.android.room.track.*
import io.livekit.android.util.CloseableCoroutineScope
import kotlinx.coroutines.SupervisorJob
...
...
@@ -11,21 +12,21 @@ import org.webrtc.AudioTrack
import org.webrtc.DataChannel
import org.webrtc.MediaStreamTrack
import org.webrtc.VideoTrack
import java.nio.ByteBuffer
class RemoteParticipant(
sid: String, name: String? = null
val rtcClient: RTCClient,
sid: String, name: String? = null,
) : Participant(sid, name) {
/**
* @suppress
*/
constructor(
info: LivekitModels.ParticipantInfo) : this(
info.sid, info.identity) {
constructor(
rtcClient: RTCClient, info: LivekitModels.ParticipantInfo) : this(rtcClient,
info.sid, info.identity) {
updateFromInfo(info)
}
private val coroutineScope = CloseableCoroutineScope(SupervisorJob())
fun getTrackPublication(sid: String):
TrackPublication? = tracks[sid]
fun getTrackPublication(sid: String):
RemoteTrackPublication? = tracks[sid] as? RemoteTrackPublication
/**
* @suppress
...
...
@@ -34,15 +35,15 @@ class RemoteParticipant(
val hadInfo = hasInfo
super.updateFromInfo(info)
val validTrackPublication = mutableMapOf<String, TrackPublication>()
val newTrackPublications = mutableMapOf<String, TrackPublication>()
val validTrackPublication = mutableMapOf<String, RemoteTrackPublication>()
val newTrackPublications = mutableMapOf<String, RemoteTrackPublication>()
for (trackInfo in info.tracksList) {
val trackSid = trackInfo.sid
var publication = getTrackPublication(trackSid)
if (publication == null) {
publication =
TrackPublication(trackInfo
)
publication =
RemoteTrackPublication(trackInfo, participant = this
)
newTrackPublications[trackSid] = publication
addTrackPublication(publication)
...
...
@@ -119,7 +120,7 @@ class RemoteParticipant(
.setName(name)
.setType(LivekitModels.TrackType.DATA)
.build()
publication =
TrackPublication(info = trackInfo
)
publication =
RemoteTrackPublication(info = trackInfo, participant = this
)
addTrackPublication(publication)
if (hasInfo) {
internalListener?.onTrackPublished(publication, this)
...
...
@@ -151,7 +152,7 @@ class RemoteParticipant(
}
fun unpublishTrack(trackSid: String, sendUnpublish: Boolean = false) {
val publication = tracks.remove(trackSid) ?: return
val publication = tracks.remove(trackSid)
as? RemoteTrackPublication
?: return
when (publication.kind) {
LivekitModels.TrackType.AUDIO -> audioTracks.remove(trackSid)
LivekitModels.TrackType.VIDEO -> videoTracks.remove(trackSid)
...
...
livekit-android-sdk/src/main/java/io/livekit/android/room/track/LocalTrackPublication.kt
0 → 100644
查看文件 @
63fd06a
package io.livekit.android.room.track
import io.livekit.android.room.participant.LocalParticipant
import livekit.LivekitModels
class LocalTrackPublication(info: LivekitModels.TrackInfo,
track: Track? = null,
participant: LocalParticipant? = null) : TrackPublication(info, track, participant) {
/**
* Mute or unmute the current track. Muting the track would stop audio or video from being
* transmitted to the server, and notify other participants in the room.
*/
fun setMuted(muted: Boolean) {
if (muted == this.muted) {
return
}
val mediaTrack = track as? MediaTrack ?: return
mediaTrack.rtcTrack.setEnabled(!muted)
this.muted = muted
// send updates to server
val participant = this.participant.get() as? LocalParticipant ?: return
participant.engine.updateMuteStatus(sid, muted)
if (muted) {
participant.listener?.onTrackMuted(this, participant)
participant.internalListener?.onTrackMuted(this, participant)
} else {
participant.listener?.onTrackUnmuted(this, participant)
participant.internalListener?.onTrackUnmuted(this, participant)
}
}
}
...
...
livekit-android-sdk/src/main/java/io/livekit/android/room/track/RemoteTrackPublication.kt
0 → 100644
查看文件 @
63fd06a
package io.livekit.android.room.track
import io.livekit.android.room.participant.RemoteParticipant
import livekit.LivekitModels
import livekit.LivekitRtc
class RemoteTrackPublication(info: LivekitModels.TrackInfo,
track: Track? = null, participant:
RemoteParticipant? = null): TrackPublication(info, track, participant) {
private var unsubscribed: Boolean = false
private var disabled: Boolean = false
private var videoQuality: LivekitRtc.VideoQuality = LivekitRtc.VideoQuality.HIGH
override val subscribed: Boolean
get() {
if (unsubscribed) {
return false
}
return super.subscribed
}
override var muted: Boolean = false
set(v) {
if (field == v) {
return
}
field = v
val participant = this.participant.get() as? RemoteParticipant ?: return
if (v) {
participant.listener?.onTrackMuted(this, participant)
participant.internalListener?.onTrackMuted(this, participant)
} else {
participant.listener?.onTrackUnmuted(this, participant)
participant.internalListener?.onTrackUnmuted(this, participant)
}
}
/**
* subscribe or unsubscribe from this track
*/
fun setSubscribed(subscribed: Boolean) {
unsubscribed = !subscribed
val participant = this.participant.get() as? RemoteParticipant ?: return
participant.rtcClient.sendUpdateSubscription(sid, !unsubscribed, videoQuality)
}
/**
* disable server from sending down data for this track
*
* this is useful when the participant is off screen, you may disable streaming down their
* video to reduce bandwidth requirements
*/
fun setEnabled(enabled: Boolean) {
disabled = !enabled
sendUpdateTrackSettings()
}
/**
* for tracks that support simulcasting, adjust subscribed quality
*
* this indicates the highest quality the client can accept. if network bandwidth does not
* allow, server will automatically reduce quality to optimize for uninterrupted video
*/
fun setVideoQuality(quality: LivekitRtc.VideoQuality) {
videoQuality = quality
sendUpdateTrackSettings()
}
private fun sendUpdateTrackSettings() {
val participant = this.participant.get() as? RemoteParticipant ?: return
participant.rtcClient.sendUpdateTrackSettings(sid, disabled, videoQuality)
}
}
\ No newline at end of file
...
...
livekit-android-sdk/src/main/java/io/livekit/android/room/track/TrackPublication.kt
查看文件 @
63fd06a
package io.livekit.android.room.track
import io.livekit.android.room.participant.Participant
import livekit.LivekitModels
import java.lang.ref.WeakReference
open class TrackPublication(info: LivekitModels.TrackInfo, track: Track?
= null
) {
open class TrackPublication(info: LivekitModels.TrackInfo, track: Track?
, participant: Participant?
) {
var track: Track? = track
internal set
var name: String
...
...
@@ -11,14 +13,21 @@ open class TrackPublication(info: LivekitModels.TrackInfo, track: Track? = null)
private set
var kind: LivekitModels.TrackType
private set
var muted: Boolean
private set
open var muted: Boolean = false
internal set
open val subscribed: Boolean
get() {
return track != null
}
var participant: WeakReference<Participant>;
init {
sid = info.sid
name = info.name
kind = info.type
muted = info.muted
this.participant = WeakReference(participant)
}
fun updateFromInfo(info: LivekitModels.TrackInfo) {
...
...
@@ -26,7 +35,6 @@ open class TrackPublication(info: LivekitModels.TrackInfo, track: Track? = null)
name = info.name
kind = info.type
// TODO: forward mute status to listener
muted = info.muted
}
}
...
...
sample-app/src/main/java/io/livekit/android/sample/ParticipantItem.kt
查看文件 @
63fd06a
...
...
@@ -30,7 +30,7 @@ class ParticipantItem(
remoteParticipant.listener = object : ParticipantListener {
override fun onTrackSubscribed(
track: Track,
publication: TrackPublication,
publication:
Remote
TrackPublication,
participant: RemoteParticipant
) {
if (track is VideoTrack) {
...
...
请
注册
或
登录
后发表评论