David Zhao

separate onJoin and onICEConnected to eliminate race conditions. clean up after …

…tracks upon disconnect
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
... ... @@ -25,6 +25,7 @@ class PublisherTransportObserver(
Timber.v { "onIceConnection new state: $newState" }
if (state == PeerConnection.IceConnectionState.CONNECTED && !engine.iceConnected) {
engine.iceConnected = true
engine.listener?.onICEConnected()
} else if (state == PeerConnection.IceConnectionState.FAILED) {
// when we publish tracks, some WebRTC versions will send out disconnected events periodically
engine.iceConnected = false
... ...
... ... @@ -221,8 +221,7 @@ constructor(
}
if (!sent) {
Timber.d { "error sending request: $request" }
throw IllegalStateException()
Timber.e { "error sending request: $request" }
}
}
... ...
... ... @@ -107,6 +107,7 @@ constructor(
interface Listener {
fun onJoin(response: LivekitRtc.JoinResponse)
fun onICEConnected()
fun onAddTrack(track: MediaStreamTrack, streams: Array<out MediaStream>)
// fun onPublishLocalTrack(cid: String, track: LivekitModels.TrackInfo)
fun onAddDataChannel(channel: DataChannel)
... ... @@ -136,7 +137,6 @@ constructor(
}
override fun onJoin(info: LivekitRtc.JoinResponse) {
val iceServers = mutableListOf<PeerConnection.IceServer>()
for(serverInfo in info.iceServersList){
val username = serverInfo.username ?: ""
... ... @@ -161,7 +161,6 @@ constructor(
Timber.e{" $it"}
}
}
listener?.onJoin(info)
val rtcConfig = PeerConnection.RTCConfiguration(iceServers).apply {
sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN
... ... @@ -194,6 +193,7 @@ constructor(
client.sendOffer(sdpOffer)
}
listener?.onJoin(info)
}
override fun onAnswer(sessionDescription: SessionDescription) {
... ...
... ... @@ -66,7 +66,6 @@ constructor(
}
fun disconnect() {
engine.close()
handleDisconnect()
}
... ... @@ -138,6 +137,10 @@ constructor(
}
private fun handleDisconnect() {
for (track in localParticipant?.tracks.values) {
track.track?.stop()
}
engine.close()
state = State.DISCONNECTED
listener?.onDisconnect(this, null)
}
... ... @@ -175,7 +178,9 @@ constructor(
getOrCreateRemoteParticipant(it.sid, it)
}
}
}
override fun onICEConnected() {
state = State.CONNECTED
connectContinuation?.resume(Unit)
connectContinuation = null
... ...
... ... @@ -20,6 +20,11 @@ class LocalVideoTrack(
capturer.startCapture(400, 400, 30)
}
override fun stop() {
capturer.stopCapture()
super.stop()
}
companion object {
internal fun createTrack(
peerConnectionFactory: PeerConnectionFactory,
... ... @@ -45,7 +50,6 @@ class LocalVideoTrack(
)
}
private fun createVideoCapturer(context: Context): VideoCapturer? {
val videoCapturer: VideoCapturer? = if (Camera2Enumerator.isSupported(context)) {
createCameraCapturer(Camera2Enumerator(context))
... ...
... ... @@ -5,7 +5,8 @@ import org.webrtc.VideoSink
import org.webrtc.VideoTrack
open class VideoTrack(name: String, override val rtcTrack: VideoTrack) :
MediaTrack(name, LivekitModels.TrackType.VIDEO, rtcTrack){
MediaTrack(name, LivekitModels.TrackType.VIDEO, rtcTrack) {
private val sinks: MutableList<VideoSink> = ArrayList();
var enabled: Boolean
get() = rtcTrack.enabled()
... ... @@ -13,7 +14,21 @@ open class VideoTrack(name: String, override val rtcTrack: VideoTrack) :
rtcTrack.setEnabled(value)
}
fun addRenderer(renderer: VideoSink) = rtcTrack.addSink(renderer)
fun addRenderer(renderer: VideoSink) {
sinks.add(renderer)
rtcTrack.addSink(renderer)
}
fun removeRenderer(renderer: VideoSink) {
sinks.remove(renderer)
rtcTrack.addSink(renderer)
}
fun removeRenderer(renderer: VideoSink) = rtcTrack.addSink(renderer)
override fun stop() {
for (sink in sinks) {
rtcTrack.removeSink(sink)
}
sinks.clear()
super.stop()
}
}
... ...