davidliu
Committed by GitHub

restart video track api (#10)

... ... @@ -78,8 +78,8 @@ internal constructor(
listOf(this.sid)
)
// TODO: sendEncodings to customize
val transceiver =
engine.publisher.peerConnection.addTransceiver(track.rtcTrack, transInit)
val transceiver = engine.publisher.peerConnection.addTransceiver(track.rtcTrack, transInit)
track.transceiver = transceiver
if (transceiver == null) {
publishListener?.onPublishFailure(TrackException.PublishException("null sender returned from peer connection"))
... ... @@ -108,8 +108,8 @@ internal constructor(
listOf(this.sid)
)
// TODO: video encodings & simulcast
val transceiver =
engine.publisher.peerConnection.addTransceiver(track.rtcTrack, transInit)
val transceiver = engine.publisher.peerConnection.addTransceiver(track.rtcTrack, transInit)
track.transceiver = transceiver
if (transceiver == null) {
publishListener?.onPublishFailure(TrackException.PublishException("null sender returned from peer connection"))
... ...
... ... @@ -2,6 +2,8 @@ package io.livekit.android.room.track
import org.webrtc.MediaConstraints
import org.webrtc.PeerConnectionFactory
import org.webrtc.RtpSender
import org.webrtc.RtpTransceiver
import java.util.*
/**
... ... @@ -19,6 +21,10 @@ class LocalAudioTrack(
rtcTrack.setEnabled(value)
}
internal var transceiver: RtpTransceiver? = null
private val sender: RtpSender?
get() = transceiver?.sender
companion object {
internal fun createTrack(
factory: PeerConnectionFactory,
... ...
... ... @@ -11,20 +11,32 @@ import java.util.*
* [startCapture] should be called before use.
*/
class LocalVideoTrack(
private val capturer: VideoCapturer,
private val source: VideoSource,
private var capturer: VideoCapturer,
private var source: VideoSource,
name: String,
private val options: LocalVideoTrackOptions,
rtcTrack: org.webrtc.VideoTrack
var options: LocalVideoTrackOptions,
rtcTrack: org.webrtc.VideoTrack,
private val peerConnectionFactory: PeerConnectionFactory,
private val context: Context,
private val eglBase: EglBase,
) : VideoTrack(name, rtcTrack) {
val dimensions: Dimensions
init {
dimensions = Dimensions(options.captureParams.width, options.captureParams.height)
}
override var rtcTrack: org.webrtc.VideoTrack = rtcTrack
internal set
val dimensions: Dimensions =
Dimensions(options.captureParams.width, options.captureParams.height)
internal var transceiver: RtpTransceiver? = null
private val sender: RtpSender?
get() = transceiver?.sender
fun startCapture() {
capturer.startCapture(options.captureParams.width, options.captureParams.height, options.captureParams.maxFps)
capturer.startCapture(
options.captureParams.width,
options.captureParams.height,
options.captureParams.maxFps
)
}
override fun stop() {
... ... @@ -32,6 +44,40 @@ class LocalVideoTrack(
super.stop()
}
fun restartTrack(options: LocalVideoTrackOptions = LocalVideoTrackOptions()) {
val newTrack = createTrack(
peerConnectionFactory,
context,
name,
options,
eglBase
)
val oldCapturer = capturer
val oldSource = source
val oldRtcTrack = rtcTrack
oldCapturer.stopCapture()
oldCapturer.dispose()
oldSource.dispose()
// sender owns rtcTrack, so it'll take care of disposing it.
oldRtcTrack.setEnabled(false)
// migrate video sinks to the new track
for (sink in sinks) {
oldRtcTrack.removeSink(sink)
newTrack.addRenderer(sink)
}
capturer = newTrack.capturer
source = newTrack.source
rtcTrack = newTrack.rtcTrack
this.options = options
startCapture()
sender?.setTrack(newTrack.rtcTrack, true)
}
companion object {
internal fun createTrack(
peerConnectionFactory: PeerConnectionFactory,
... ... @@ -55,6 +101,9 @@ class LocalVideoTrack(
options = options,
name = name,
rtcTrack = track,
peerConnectionFactory = peerConnectionFactory,
context = context,
eglBase = rootEglBase,
)
}
... ...
package io.livekit.android.room.track
import livekit.LivekitModels
import org.webrtc.VideoSink
import org.webrtc.VideoTrack
open class VideoTrack(name: String, override val rtcTrack: VideoTrack) :
Track(name, Kind.VIDEO, rtcTrack) {
private val sinks: MutableList<VideoSink> = ArrayList();
internal val sinks: MutableList<VideoSink> = ArrayList();
var enabled: Boolean
get() = rtcTrack.enabled()
... ...
... ... @@ -12,8 +12,10 @@ import io.livekit.android.room.Room
import io.livekit.android.room.RoomListener
import io.livekit.android.room.participant.Participant
import io.livekit.android.room.participant.RemoteParticipant
import io.livekit.android.room.track.CameraPosition
import io.livekit.android.room.track.LocalAudioTrack
import io.livekit.android.room.track.LocalVideoTrack
import io.livekit.android.room.track.LocalVideoTrackOptions
import kotlinx.coroutines.launch
class CallViewModel(
... ... @@ -118,7 +120,19 @@ class CallViewModel(
}
fun flipVideo() {
// TODO
room.value?.localParticipant?.let { participant ->
val videoTrack = participant.videoTracks.values
.firstOrNull()
?.track as? LocalVideoTrack
?: return@let
val newOptions = when (videoTrack.options.position) {
CameraPosition.FRONT -> LocalVideoTrackOptions(position = CameraPosition.BACK)
CameraPosition.BACK -> LocalVideoTrackOptions(position = CameraPosition.FRONT)
}
videoTrack.restartTrack(newOptions)
}
}
}
... ...
... ... @@ -4,7 +4,6 @@ import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
... ...