David Liu

PeerConnectionTransport

package io.livekit.android.room
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import org.webrtc.*
class PeerConnectionTransport
@AssistedInject
constructor(
config: PeerConnection.RTCConfiguration,
listener: PeerConnection.Observer,
@Assisted connectionFactory: PeerConnectionFactory
) {
val peerConnection: PeerConnection = connectionFactory.createPeerConnection(
config,
listener
) ?: throw IllegalStateException("peer connection creation failed?")
val pendingCandidates = mutableListOf<IceCandidate>()
fun addIceCandidate(candidate: IceCandidate) {
if (peerConnection.remoteDescription != null) {
peerConnection.addIceCandidate(candidate)
} else {
pendingCandidates.add(candidate)
}
}
fun setRemoteDescription(sd: SessionDescription) {
peerConnection.setRemoteDescription(object : SdpObserver {
override fun onCreateSuccess(p0: SessionDescription?) {
}
override fun onSetSuccess() {
pendingCandidates.forEach { pending ->
peerConnection.addIceCandidate(pending)
}
pendingCandidates.clear()
}
override fun onCreateFailure(p0: String?) {
}
override fun onSetFailure(p0: String?) {
}
}, sd)
}
fun close() {
peerConnection.close()
}
}
\ No newline at end of file
... ...
... ... @@ -13,10 +13,11 @@ import okhttp3.WebSocket
import okhttp3.WebSocketListener
import okio.ByteString
import org.webrtc.IceCandidate
import org.webrtc.PeerConnection
import org.webrtc.SessionDescription
import javax.inject.Inject
internal class RTCClient
class RTCClient
@Inject
constructor(
private val websocketFactory: WebSocket.Factory,
... ... @@ -28,7 +29,7 @@ constructor(
private var currentWs: WebSocket? = null
var listener: Listener? = null
fun connect(
fun join(
host: String,
token: String,
isSecure: Boolean,
... ... @@ -166,7 +167,7 @@ constructor(
val request = Rtc.SignalRequest.newBuilder()
.setAddTrack(addTrackRequest)
.build()
sendRequest(request)
}
... ... @@ -240,5 +241,16 @@ constructor(
const val SD_TYPE_ANSWER = "answer"
const val SD_TYPE_OFFER = "offer"
const val SD_TYPE_PRANSWER = "pranswer"
private fun iceServer(url: String) =
PeerConnection.IceServer.builder(url).createIceServer()
val DEFAULT_ICE_SERVERS = listOf(
iceServer("stun:stun.l.google.com:19302"),
iceServer("stun:stun1.l.google.com:19302"),
iceServer("stun:stun2.l.google.com:19302"),
iceServer("stun:stun3.l.google.com:19302"),
iceServer("stun:stun4.l.google.com:19302"),
)
}
}
\ No newline at end of file
... ...
package io.livekit.android.room
internal class RTCEngine {
import org.webrtc.PeerConnection
import javax.inject.Inject
class RTCEngine
@Inject
constructor(
private val client: RTCClient
) {
init {
val rtcConfig = PeerConnection.RTCConfiguration(RTCClient.DEFAULT_ICE_SERVERS).apply {
sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN
continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY
}
}
suspend fun join(url: String, token: String, isSecure: Boolean) {
client.join(url, token, isSecure)
}
}
\ No newline at end of file
... ...
package io.livekit.android.room
class Room(
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.livekit.android.ConnectOptions
class Room
@AssistedInject
constructor(
private val connectOptions: ConnectOptions,
@Assisted private val engine: RTCEngine,
) {
suspend fun connect() {
engine.join(connectOptions)
}
}
\ No newline at end of file
... ...