David Liu

fill in leftover high level api stuff and update sample app usage

@@ -108,6 +108,18 @@ internal constructor( @@ -108,6 +108,18 @@ internal constructor(
108 return super.getTrackPublicationByName(name) as? LocalTrackPublication 108 return super.getTrackPublicationByName(name) as? LocalTrackPublication
109 } 109 }
110 110
  111 + suspend fun setCameraEnabled(enabled: Boolean){
  112 + setTrackEnabled(Track.Source.CAMERA, enabled)
  113 + }
  114 +
  115 + suspend fun setMicrophoneEnabled(enabled: Boolean){
  116 + setTrackEnabled(Track.Source.MICROPHONE, enabled)
  117 + }
  118 +
  119 + suspend fun setScreenShareEnabled(enabled: Boolean) {
  120 + setTrackEnabled(Track.Source.SCREEN_SHARE, enabled)
  121 + }
  122 +
111 private suspend fun setTrackEnabled( 123 private suspend fun setTrackEnabled(
112 source: Track.Source, 124 source: Track.Source,
113 enabled: Boolean, 125 enabled: Boolean,
@@ -122,6 +134,7 @@ internal constructor( @@ -122,6 +134,7 @@ internal constructor(
122 when (source) { 134 when (source) {
123 Track.Source.CAMERA -> { 135 Track.Source.CAMERA -> {
124 val track = createVideoTrack() 136 val track = createVideoTrack()
  137 + track.startCapture()
125 publishVideoTrack(track) 138 publishVideoTrack(track)
126 } 139 }
127 Track.Source.MICROPHONE -> { 140 Track.Source.MICROPHONE -> {
@@ -109,6 +109,25 @@ open class Participant(var sid: String, identity: String? = null) { @@ -109,6 +109,25 @@ open class Participant(var sid: String, identity: String? = null) {
109 return null 109 return null
110 } 110 }
111 111
  112 + fun isCameraEnabled(): Boolean {
  113 + val pub = getTrackPublication(Track.Source.CAMERA)
  114 + return isTrackPublicationEnabled(pub)
  115 + }
  116 +
  117 + fun isMicrophoneEnabled(): Boolean {
  118 + val pub = getTrackPublication(Track.Source.MICROPHONE)
  119 + return isTrackPublicationEnabled(pub)
  120 + }
  121 +
  122 + fun isScreenShareEnabled(): Boolean {
  123 + val pub = getTrackPublication(Track.Source.SCREEN_SHARE)
  124 + return isTrackPublicationEnabled(pub)
  125 + }
  126 +
  127 + private fun isTrackPublicationEnabled(pub: TrackPublication?): Boolean {
  128 + return !(pub?.muted ?: true)
  129 + }
  130 +
112 /** 131 /**
113 * @suppress 132 * @suppress
114 */ 133 */
@@ -87,7 +87,7 @@ class CallActivity : AppCompatActivity() { @@ -87,7 +87,7 @@ class CallActivity : AppCompatActivity() {
87 val room by viewModel.room.observeAsState() 87 val room by viewModel.room.observeAsState()
88 val participants by viewModel.remoteParticipants.observeAsState(emptyList()) 88 val participants by viewModel.remoteParticipants.observeAsState(emptyList())
89 val micEnabled by viewModel.micEnabled.observeAsState(true) 89 val micEnabled by viewModel.micEnabled.observeAsState(true)
90 - val videoEnabled by viewModel.videoEnabled.observeAsState(true) 90 + val videoEnabled by viewModel.cameraEnabled.observeAsState(true)
91 val flipButtonEnabled by viewModel.flipButtonVideoEnabled.observeAsState(true) 91 val flipButtonEnabled by viewModel.flipButtonVideoEnabled.observeAsState(true)
92 val screencastEnabled by viewModel.screencastEnabled.observeAsState(false) 92 val screencastEnabled by viewModel.screencastEnabled.observeAsState(false)
93 Content( 93 Content(
@@ -228,7 +228,7 @@ class CallActivity : AppCompatActivity() { @@ -228,7 +228,7 @@ class CallActivity : AppCompatActivity() {
228 ) 228 )
229 } 229 }
230 FloatingActionButton( 230 FloatingActionButton(
231 - onClick = { viewModel.setVideoEnabled(!videoEnabled) }, 231 + onClick = { viewModel.setCameraEnabled(!videoEnabled) },
232 backgroundColor = Color.DarkGray, 232 backgroundColor = Color.DarkGray,
233 ) { 233 ) {
234 val resource = 234 val resource =
@@ -11,10 +11,8 @@ import io.livekit.android.ConnectOptions @@ -11,10 +11,8 @@ import io.livekit.android.ConnectOptions
11 import io.livekit.android.LiveKit 11 import io.livekit.android.LiveKit
12 import io.livekit.android.room.Room 12 import io.livekit.android.room.Room
13 import io.livekit.android.room.RoomListener 13 import io.livekit.android.room.RoomListener
14 -import io.livekit.android.room.participant.AudioTrackPublishOptions  
15 import io.livekit.android.room.participant.Participant 14 import io.livekit.android.room.participant.Participant
16 import io.livekit.android.room.participant.RemoteParticipant 15 import io.livekit.android.room.participant.RemoteParticipant
17 -import io.livekit.android.room.participant.VideoTrackPublishOptions  
18 import io.livekit.android.room.track.* 16 import io.livekit.android.room.track.*
19 import kotlinx.coroutines.launch 17 import kotlinx.coroutines.launch
20 18
@@ -28,15 +26,13 @@ class CallViewModel( @@ -28,15 +26,13 @@ class CallViewModel(
28 private val mutableRemoteParticipants = MutableLiveData<List<RemoteParticipant>>() 26 private val mutableRemoteParticipants = MutableLiveData<List<RemoteParticipant>>()
29 val remoteParticipants: LiveData<List<RemoteParticipant>> = mutableRemoteParticipants 27 val remoteParticipants: LiveData<List<RemoteParticipant>> = mutableRemoteParticipants
30 28
31 - private var localAudioTrack: LocalAudioTrack? = null  
32 - private var localVideoTrack: LocalVideoTrack? = null  
33 private var localScreencastTrack: LocalScreencastVideoTrack? = null 29 private var localScreencastTrack: LocalScreencastVideoTrack? = null
34 30
35 private val mutableMicEnabled = MutableLiveData(true) 31 private val mutableMicEnabled = MutableLiveData(true)
36 val micEnabled = mutableMicEnabled.hide() 32 val micEnabled = mutableMicEnabled.hide()
37 33
38 - private val mutableVideoEnabled = MutableLiveData(true)  
39 - val videoEnabled = mutableVideoEnabled.hide() 34 + private val mutableCameraEnabled = MutableLiveData(true)
  35 + val cameraEnabled = mutableCameraEnabled.hide()
40 36
41 private val mutableFlipVideoButtonEnabled = MutableLiveData(true) 37 private val mutableFlipVideoButtonEnabled = MutableLiveData(true)
42 val flipButtonVideoEnabled = mutableFlipVideoButtonEnabled.hide() 38 val flipButtonVideoEnabled = mutableFlipVideoButtonEnabled.hide()
@@ -56,19 +52,11 @@ class CallViewModel( @@ -56,19 +52,11 @@ class CallViewModel(
56 52
57 // Create and publish audio/video tracks 53 // Create and publish audio/video tracks
58 val localParticipant = room.localParticipant 54 val localParticipant = room.localParticipant
59 - val audioTrack = localParticipant.createAudioTrack()  
60 - localParticipant.publishAudioTrack(audioTrack, AudioTrackPublishOptions(dtx = true))  
61 - this@CallViewModel.localAudioTrack = audioTrack  
62 - mutableMicEnabled.postValue(audioTrack.enabled) 55 + localParticipant.setMicrophoneEnabled(true)
  56 + mutableMicEnabled.postValue(localParticipant.isMicrophoneEnabled())
63 57
64 - val videoTrack = localParticipant.createVideoTrack()  
65 - localParticipant.publishVideoTrack(  
66 - videoTrack,  
67 - VideoTrackPublishOptions(simulcast = false)  
68 - )  
69 - videoTrack.startCapture()  
70 - this@CallViewModel.localVideoTrack = videoTrack  
71 - mutableVideoEnabled.postValue(videoTrack.enabled) 58 + localParticipant.setCameraEnabled(true)
  59 + mutableCameraEnabled.postValue(localParticipant.isCameraEnabled())
72 60
73 updateParticipants(room) 61 updateParticipants(room)
74 mutableRoom.value = room 62 mutableRoom.value = room
@@ -146,25 +134,31 @@ class CallViewModel( @@ -146,25 +134,31 @@ class CallViewModel(
146 } 134 }
147 135
148 fun setMicEnabled(enabled: Boolean) { 136 fun setMicEnabled(enabled: Boolean) {
149 - localAudioTrack?.enabled = enabled  
150 - mutableMicEnabled.postValue(enabled) 137 + viewModelScope.launch {
  138 + val localParticipant = room.value?.localParticipant ?: return@launch
  139 + localParticipant.setMicrophoneEnabled(enabled)
  140 + mutableMicEnabled.postValue(enabled)
  141 + }
151 } 142 }
152 143
153 - fun setVideoEnabled(enabled: Boolean) {  
154 - localVideoTrack?.enabled = enabled  
155 - mutableVideoEnabled.postValue(enabled) 144 + fun setCameraEnabled(enabled: Boolean) {
  145 + viewModelScope.launch {
  146 + val localParticipant = room.value?.localParticipant ?: return@launch
  147 + localParticipant.setMicrophoneEnabled(enabled)
  148 + mutableCameraEnabled.postValue(enabled)
  149 + }
156 } 150 }
157 151
158 fun flipVideo() { 152 fun flipVideo() {
159 room.value?.localParticipant?.let { participant -> 153 room.value?.localParticipant?.let { participant ->
160 - val videoTrack = participant.videoTracks.values  
161 - .firstOrNull() 154 + val videoTrack = participant.getTrackPublication(Track.Source.CAMERA)
162 ?.track as? LocalVideoTrack 155 ?.track as? LocalVideoTrack
163 ?: return@let 156 ?: return@let
164 157
165 val newOptions = when (videoTrack.options.position) { 158 val newOptions = when (videoTrack.options.position) {
166 CameraPosition.FRONT -> LocalVideoTrackOptions(position = CameraPosition.BACK) 159 CameraPosition.FRONT -> LocalVideoTrackOptions(position = CameraPosition.BACK)
167 CameraPosition.BACK -> LocalVideoTrackOptions(position = CameraPosition.FRONT) 160 CameraPosition.BACK -> LocalVideoTrackOptions(position = CameraPosition.FRONT)
  161 + else -> LocalVideoTrackOptions()
168 } 162 }
169 163
170 videoTrack.restartTrack(newOptions) 164 videoTrack.restartTrack(newOptions)