Skip to content

Instantly share code, notes, and snippets.

@skydoves
Last active January 27, 2023 05:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skydoves/4596d237682ea84d46f5a4ed2ef83749 to your computer and use it in GitHub Desktop.
Save skydoves/4596d237682ea84d46f5a4ed2ef83749 to your computer and use it in GitHub Desktop.
StreamPeerConnection
// Copyright 2023 Stream.IO, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
class StreamPeerConnection(
private val coroutineScope: CoroutineScope,
private val type: StreamPeerType,
private val mediaConstraints: MediaConstraints,
private val onStreamAdded: ((MediaStream) -> Unit)?,
private val onNegotiationNeeded: ((StreamPeerConnection, StreamPeerType) -> Unit)?,
private val onIceCandidate: ((IceCandidate, StreamPeerType) -> Unit)?,
private val onVideoTrack: ((RtpTransceiver?) -> Unit)?
) : PeerConnection.Observer {
suspend fun createOffer(): Result<SessionDescription> {
logger.d { "[createOffer] #sfu; #$typeTag; no args" }
return createValue { connection.createOffer(it, mediaConstraints) }
}
suspend fun createAnswer(): Result<SessionDescription> {
logger.d { "[createAnswer] #sfu; #$typeTag; no args" }
return createValue { connection.createAnswer(it, mediaConstraints) }
}
suspend fun setRemoteDescription(sessionDescription: SessionDescription): Result<Unit> {
logger.d { "[setRemoteDescription] #sfu; #$typeTag; answerSdp: ${sessionDescription.stringify()}" }
return setValue {
connection.setRemoteDescription(
it,
SessionDescription(
sessionDescription.type,
sessionDescription.description.mungeCodecs()
)
)
}.also {
pendingIceMutex.withLock {
pendingIceCandidates.forEach { iceCandidate ->
logger.i { "[setRemoteDescription] #sfu; #subscriber; pendingRtcIceCandidate: $iceCandidate" }
connection.addRtcIceCandidate(iceCandidate)
}
pendingIceCandidates.clear()
}
}
}
suspend fun setLocalDescription(sessionDescription: SessionDescription): Result<Unit> {
val sdp = SessionDescription(
sessionDescription.type,
sessionDescription.description.mungeCodecs()
)
logger.d { "[setLocalDescription] #sfu; #$typeTag; offerSdp: ${sessionDescription.stringify()}" }
return setValue { connection.setLocalDescription(it, sdp) }
}
suspend fun addIceCandidate(iceCandidate: IceCandidate): Result<Unit> {
if (connection.remoteDescription == null) {
logger.w { "[addIceCandidate] #sfu; #$typeTag; postponed (no remoteDescription): $iceCandidate" }
pendingIceMutex.withLock {
pendingIceCandidates.add(iceCandidate)
}
return Result.failure(RuntimeException("RemoteDescription is not set"))
}
logger.d { "[addIceCandidate] #sfu; #$typeTag; rtcIceCandidate: $iceCandidate" }
return connection.addRtcIceCandidate(iceCandidate).also {
logger.v { "[addIceCandidate] #sfu; #$typeTag; completed: $it" }
}
}
..
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment