David Liu

local tracks

... ... @@ -37,6 +37,7 @@ android {
}
kotlinOptions {
freeCompilerArgs = ["-Xinline-classes"]
jvmTarget = java_version
}
}
... ...
package io.livekit.android.room.track
class AudioOptions {
}
\ No newline at end of file
... ...
package io.livekit.android.room.track
data class DataTrackOptions(
val ordered: Boolean = true,
val maxPacketLifetime: Int = -1,
val maxRetransmits: Int = -1,
val name: String
)
... ...
package io.livekit.android.room.track
class LocalAudioTrack(
name: String,
audioOptions: AudioOptions? = null,
rtcTrack: org.webrtc.AudioTrack
) : AudioTrack(name, rtcTrack) {
var sid: Sid? = null
internal set
var audioOptions = audioOptions
private set
}
\ No newline at end of file
... ...
package io.livekit.android.room.track
import org.webrtc.DataChannel
import java.nio.ByteBuffer
class LocalDataTrack(
val options: DataTrackOptions,
rtcTrack: DataChannel
) : DataTrack(options.name, rtcTrack) {
var sid: Sid? = null
internal set
fun sendString(message: String) {
val byteBuffer = ByteBuffer.wrap(message.toByteArray())
val buffer = DataChannel.Buffer(byteBuffer, false)
rtcTrack.send(buffer)
}
fun sendBytes(byteBuffer: ByteBuffer) {
val buffer = DataChannel.Buffer(byteBuffer, true)
rtcTrack.send(buffer)
}
}
\ No newline at end of file
... ...
package io.livekit.android.room.track
import android.content.Context
import com.github.ajalt.timberkt.Timber
import org.webrtc.*
import java.util.*
class LocalVideoTrack(
private val capturer: VideoCapturer,
private val source: VideoSource,
name: String,
rtcTrack: org.webrtc.VideoTrack
) : VideoTrack(name, rtcTrack) {
var sid: Sid? = null
companion object {
internal fun track(
peerConnectionFactory: PeerConnectionFactory,
context: Context,
enabled: Boolean,
name: String
): LocalVideoTrack {
val source = peerConnectionFactory.createVideoSource(false)
val capturer = createVideoCapturer(context) ?: TODO()
val rootEglBase = EglBase.create()
capturer.initialize(
SurfaceTextureHelper.create("CaptureThread", rootEglBase.eglBaseContext),
context,
source.capturerObserver
)
val track = peerConnectionFactory.createVideoTrack(UUID.randomUUID().toString(), source)
track.setEnabled(enabled)
return LocalVideoTrack(
capturer = capturer,
source = source,
name = name,
rtcTrack = track,
)
}
private fun createVideoCapturer(context: Context): VideoCapturer? {
val videoCapturer: VideoCapturer? = if (Camera2Enumerator.isSupported(context)) {
createCameraCapturer(Camera2Enumerator(context))
} else {
createCameraCapturer(Camera1Enumerator(true))
}
if (videoCapturer == null) {
Timber.d { "Failed to open camera" }
return null
}
return videoCapturer
}
private fun createCameraCapturer(enumerator: CameraEnumerator): VideoCapturer? {
val deviceNames = enumerator.deviceNames
// First, try to find front facing camera
for (deviceName in deviceNames) {
if (enumerator.isFrontFacing(deviceName)) {
Timber.v { "Creating front facing camera capturer." }
val videoCapturer = enumerator.createCapturer(deviceName, null)
if (videoCapturer != null) {
return videoCapturer
}
}
}
// Front facing camera not found, try something else
for (deviceName in deviceNames) {
if (!enumerator.isFrontFacing(deviceName)) {
Timber.v { "Creating other camera capturer." }
val videoCapturer = enumerator.createCapturer(deviceName, null)
if (videoCapturer != null) {
return videoCapturer
}
}
}
return null
}
}
}
\ No newline at end of file
... ...