Skip to content

Instantly share code, notes, and snippets.

@amrfarid140
Created May 22, 2019 22:59
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 amrfarid140/7ad77b50af7c5b120b819a17bc0deaff to your computer and use it in GitHub Desktop.
Save amrfarid140/7ad77b50af7c5b120b819a17bc0deaff to your computer and use it in GitHub Desktop.
package me.amryousef.homedoor.common
import android.app.Application
import android.content.Context
import org.webrtc.Camera2Enumerator
import org.webrtc.EglBase
import org.webrtc.IceCandidate
import org.webrtc.MediaConstraints
import org.webrtc.PeerConnection
import org.webrtc.PeerConnectionFactory
import org.webrtc.SdpObserver
import org.webrtc.SessionDescription
import org.webrtc.SurfaceTextureHelper
import org.webrtc.SurfaceViewRenderer
import org.webrtc.VideoCapturer
import org.webrtc.VideoSource
import org.webrtc.VideoTrack
class RTCClient(context: Application) {
companion object {
private const val LOCAL_TRACK_ID = "local_track"
}
private val iceServer = listOf(
PeerConnection.IceServer.builder("stun:stun.l.google.com:19302")
.createIceServer()
)
private val peerConnectionFactory: PeerConnectionFactory
private val videoCapturer: VideoCapturer
private val localVideoSource: VideoSource
private val localVideoTrack: VideoTrack
private val rootEglBase: EglBase
private var peerConnection: PeerConnection? = null
init {
val peerConnectionFactoryOption =
PeerConnectionFactory.InitializationOptions.builder(context)
.setEnableInternalTracer(true)
.setFieldTrials("WebRTC-H264HighProfile/Enabled/")
.createInitializationOptions()
PeerConnectionFactory.initialize(peerConnectionFactoryOption)
peerConnectionFactory = PeerConnectionFactory
.builder()
.createPeerConnectionFactory()
videoCapturer = getVideoCapturer(context)
localVideoSource = peerConnectionFactory.createVideoSource(false)
rootEglBase = EglBase.create()
val surfaceTextureHelper = SurfaceTextureHelper.create(Thread.currentThread().name, rootEglBase.eglBaseContext)
(videoCapturer as VideoCapturer).initialize(surfaceTextureHelper, context, localVideoSource.capturerObserver)
videoCapturer.startCapture(320, 240, 30)
localVideoTrack = peerConnectionFactory.createVideoTrack(LOCAL_TRACK_ID, localVideoSource)
}
private fun getVideoCapturer(context: Context) =
Camera2Enumerator(context).run {
deviceNames.find {
isFrontFacing(it)
}?.let {
createCapturer(it, null)
} ?: throw IllegalStateException()
}
fun initSurfaceView(view: SurfaceViewRenderer) = view.run {
setMirror(true)
setEnableHardwareScaler(true)
init(rootEglBase.eglBaseContext, null)
}
fun displayLocalVideoTrack(view: SurfaceViewRenderer) =
localVideoTrack.addSink(view)
fun startCall(observer: PeerConnection.Observer, sdpObserver: SdpObserver) =
peerConnectionFactory.call(observer, sdpObserver)
private fun PeerConnectionFactory.call(
observer: PeerConnection.Observer,
sdpObserver: SdpObserver
) {
peerConnection = createPeerConnection(
iceServer,
object : PeerConnection.Observer by observer {
override fun onIceCandidate(p0: IceCandidate?) {
observer.onIceCandidate(p0)
}
}
)
peerConnection?.addStream(
createLocalMediaStream("local").apply {
addTrack(localVideoTrack)
}
)
peerConnection?.generateOffer(sdpObserver)
}
private fun PeerConnection.generateOffer(sdpObserver: SdpObserver) {
val constraints = MediaConstraints().apply {
mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"))
}
createOffer(object : SdpObserver by sdpObserver {
override fun onCreateSuccess(desc: SessionDescription?) {
setLocalDescription(object : SdpObserver {
override fun onSetFailure(p0: String?) {
}
override fun onSetSuccess() {
}
override fun onCreateSuccess(p0: SessionDescription?) {
}
override fun onCreateFailure(p0: String?) {
}
}, desc)
sdpObserver.onCreateSuccess(desc)
}
}, constraints)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment