davidliu
Committed by GitHub

Add documentation for various undocumented methods (#427)

* KDocs for undocumented methods

* More KDocs

* spotless
正在显示 21 个修改的文件 包含 158 行增加38 行删除
@@ -26,6 +26,11 @@ import io.livekit.android.util.LKLog @@ -26,6 +26,11 @@ import io.livekit.android.util.LKLog
26 import io.livekit.android.util.LoggingLevel 26 import io.livekit.android.util.LoggingLevel
27 import timber.log.Timber 27 import timber.log.Timber
28 28
  29 +/**
  30 + * The main entry point into using LiveKit.
  31 + *
  32 + * @see [LiveKit.create]
  33 + */
29 object LiveKit { 34 object LiveKit {
30 /** 35 /**
31 * [LoggingLevel] to use for Livekit logs. Set to [LoggingLevel.OFF] to turn off logs. 36 * [LoggingLevel] to use for Livekit logs. Set to [LoggingLevel.OFF] to turn off logs.
@@ -17,7 +17,9 @@ @@ -17,7 +17,9 @@
17 package io.livekit.android 17 package io.livekit.android
18 18
19 import android.media.AudioAttributes 19 import android.media.AudioAttributes
  20 +import android.media.AudioFocusRequest
20 import android.media.AudioManager 21 import android.media.AudioManager
  22 +import android.media.AudioTrack
21 import io.livekit.android.audio.AudioFocusHandler 23 import io.livekit.android.audio.AudioFocusHandler
22 import io.livekit.android.audio.AudioHandler 24 import io.livekit.android.audio.AudioHandler
23 import io.livekit.android.audio.AudioProcessorOptions 25 import io.livekit.android.audio.AudioProcessorOptions
@@ -31,7 +33,6 @@ import livekit.org.webrtc.VideoEncoderFactory @@ -31,7 +33,6 @@ import livekit.org.webrtc.VideoEncoderFactory
31 import livekit.org.webrtc.audio.AudioDeviceModule 33 import livekit.org.webrtc.audio.AudioDeviceModule
32 import livekit.org.webrtc.audio.JavaAudioDeviceModule 34 import livekit.org.webrtc.audio.JavaAudioDeviceModule
33 import okhttp3.OkHttpClient 35 import okhttp3.OkHttpClient
34 -  
35 /** 36 /**
36 * Overrides to replace LiveKit internally used components with custom implementations. 37 * Overrides to replace LiveKit internally used components with custom implementations.
37 */ 38 */
@@ -138,8 +139,25 @@ class AudioOptions( @@ -138,8 +139,25 @@ class AudioOptions(
138 * Audio types for customizing the audio of LiveKit. 139 * Audio types for customizing the audio of LiveKit.
139 */ 140 */
140 sealed class AudioType( 141 sealed class AudioType(
  142 + /**
  143 + * The audio mode to use when playing audio through LiveKit.
  144 + *
  145 + * @see [AudioManager.setMode]
  146 + */
141 val audioMode: Int, 147 val audioMode: Int,
  148 + /**
  149 + * The audio attributes to use when playing audio through LiveKit.
  150 + *
  151 + * @see [AudioTrack]
  152 + * @see [AudioFocusRequest]
  153 + */
142 val audioAttributes: AudioAttributes, 154 val audioAttributes: AudioAttributes,
  155 + /**
  156 + * The audio attributes to use when playing audio through LiveKit on pre-O devices.
  157 + *
  158 + * @see [AudioTrack]
  159 + * @see [AudioManager.requestAudioFocus]
  160 + */
143 val audioStreamType: Int, 161 val audioStreamType: Int,
144 ) { 162 ) {
145 /** 163 /**
@@ -16,6 +16,9 @@ @@ -16,6 +16,9 @@
16 16
17 package io.livekit.android.audio 17 package io.livekit.android.audio
18 18
  19 +/**
  20 + * Options for audio processing.
  21 + */
19 data class AudioProcessorOptions( 22 data class AudioProcessorOptions(
20 /** 23 /**
21 * Audio processor for captured audio. 24 * Audio processor for captured audio.
@@ -51,6 +51,9 @@ interface CommunicationWorkaround { @@ -51,6 +51,9 @@ interface CommunicationWorkaround {
51 fun dispose() 51 fun dispose()
52 } 52 }
53 53
  54 +/**
  55 + * @suppress
  56 + */
54 class NoopCommunicationWorkaround 57 class NoopCommunicationWorkaround
55 @Inject 58 @Inject
56 constructor() : CommunicationWorkaround { 59 constructor() : CommunicationWorkaround {
@@ -77,7 +80,7 @@ constructor() : CommunicationWorkaround { @@ -77,7 +80,7 @@ constructor() : CommunicationWorkaround {
77 */ 80 */
78 @Singleton 81 @Singleton
79 @RequiresApi(Build.VERSION_CODES.R) 82 @RequiresApi(Build.VERSION_CODES.R)
80 -class CommunicationWorkaroundImpl 83 +internal class CommunicationWorkaroundImpl
81 @Inject 84 @Inject
82 constructor( 85 constructor(
83 @Named(InjectionNames.DISPATCHER_MAIN) 86 @Named(InjectionNames.DISPATCHER_MAIN)
1 /* 1 /*
2 - * Copyright 2023 LiveKit, Inc. 2 + * Copyright 2023-2024 LiveKit, Inc.
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -22,6 +22,9 @@ import kotlinx.coroutines.flow.MutableSharedFlow @@ -22,6 +22,9 @@ import kotlinx.coroutines.flow.MutableSharedFlow
22 import kotlinx.coroutines.flow.asSharedFlow 22 import kotlinx.coroutines.flow.asSharedFlow
23 import kotlinx.coroutines.launch 23 import kotlinx.coroutines.launch
24 24
  25 +/**
  26 + * @suppress
  27 + */
25 class BroadcastEventBus<T> : EventListenable<T> { 28 class BroadcastEventBus<T> : EventListenable<T> {
26 private val mutableEvents = MutableSharedFlow<T>(extraBufferCapacity = Int.MAX_VALUE) 29 private val mutableEvents = MutableSharedFlow<T>(extraBufferCapacity = Int.MAX_VALUE)
27 override val events = mutableEvents.asSharedFlow() 30 override val events = mutableEvents.asSharedFlow()
@@ -19,6 +19,10 @@ package io.livekit.android.events @@ -19,6 +19,10 @@ package io.livekit.android.events
19 import kotlinx.coroutines.flow.Flow 19 import kotlinx.coroutines.flow.Flow
20 import kotlinx.coroutines.flow.SharedFlow 20 import kotlinx.coroutines.flow.SharedFlow
21 21
  22 +/**
  23 + * An interface declaring that this object emits events that can be collected.
  24 + * @see [EventListenable.collect]
  25 + */
22 interface EventListenable<out T> { 26 interface EventListenable<out T> {
23 val events: SharedFlow<T> 27 val events: SharedFlow<T>
24 } 28 }
@@ -27,6 +27,7 @@ open class SurfaceViewRenderer : SurfaceViewRenderer, ViewVisibility.Notifier { @@ -27,6 +27,7 @@ open class SurfaceViewRenderer : SurfaceViewRenderer, ViewVisibility.Notifier {
27 constructor(context: Context, attrs: AttributeSet) : super(context, attrs) 27 constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
28 28
29 override var viewVisibility: ViewVisibility? = null 29 override var viewVisibility: ViewVisibility? = null
  30 +
30 override fun onVisibilityChanged(changedView: View, visibility: Int) { 31 override fun onVisibilityChanged(changedView: View, visibility: Int) {
31 super.onVisibilityChanged(changedView, visibility) 32 super.onVisibilityChanged(changedView, visibility)
32 viewVisibility?.recalculate() 33 viewVisibility?.recalculate()
@@ -77,6 +77,9 @@ constructor( @@ -77,6 +77,9 @@ constructor(
77 private val e2EEManagerFactory: E2EEManager.Factory, 77 private val e2EEManagerFactory: E2EEManager.Factory,
78 private val communicationWorkaround: CommunicationWorkaround, 78 private val communicationWorkaround: CommunicationWorkaround,
79 val audioProcessingController: AudioProcessingController, 79 val audioProcessingController: AudioProcessingController,
  80 + /**
  81 + * A holder for objects that are used internally within LiveKit.
  82 + */
80 val lkObjects: LKObjects, 83 val lkObjects: LKObjects,
81 networkCallbackManagerFactory: NetworkCallbackManagerFactory, 84 networkCallbackManagerFactory: NetworkCallbackManagerFactory,
82 private val audioDeviceModule: AudioDeviceModule, 85 private val audioDeviceModule: AudioDeviceModule,
@@ -46,6 +46,9 @@ internal class NetworkCallbackRegistryImpl(val connectivityManager: Connectivity @@ -46,6 +46,9 @@ internal class NetworkCallbackRegistryImpl(val connectivityManager: Connectivity
46 } 46 }
47 } 47 }
48 48
  49 +/**
  50 + * @suppress
  51 + */
49 interface NetworkCallbackManager : Closeable { 52 interface NetworkCallbackManager : Closeable {
50 fun registerCallback() 53 fun registerCallback()
51 fun unregisterCallback() 54 fun unregisterCallback()
@@ -19,6 +19,7 @@ package io.livekit.android.room.participant @@ -19,6 +19,7 @@ package io.livekit.android.room.participant
19 import android.Manifest 19 import android.Manifest
20 import android.content.Context 20 import android.content.Context
21 import android.content.Intent 21 import android.content.Intent
  22 +import androidx.annotation.VisibleForTesting
22 import com.google.protobuf.ByteString 23 import com.google.protobuf.ByteString
23 import dagger.assisted.Assisted 24 import dagger.assisted.Assisted
24 import dagger.assisted.AssistedFactory 25 import dagger.assisted.AssistedFactory
@@ -183,15 +184,29 @@ internal constructor( @@ -183,15 +184,29 @@ internal constructor(
183 return super.getTrackPublicationByName(name) as? LocalTrackPublication 184 return super.getTrackPublicationByName(name) as? LocalTrackPublication
184 } 185 }
185 186
  187 + /**
  188 + * If set to enabled, creates and publishes a camera video track if not already done, and starts the camera.
  189 + *
  190 + * If set to disabled, mutes and stops the camera.
  191 + */
186 suspend fun setCameraEnabled(enabled: Boolean) { 192 suspend fun setCameraEnabled(enabled: Boolean) {
187 setTrackEnabled(Track.Source.CAMERA, enabled) 193 setTrackEnabled(Track.Source.CAMERA, enabled)
188 } 194 }
189 195
  196 + /**
  197 + * If set to enabled, creates and publishes a microphone audio track if not already done, and unmutes the mic.
  198 + *
  199 + * If set to disabled, mutes the mic.
  200 + */
190 suspend fun setMicrophoneEnabled(enabled: Boolean) { 201 suspend fun setMicrophoneEnabled(enabled: Boolean) {
191 setTrackEnabled(Track.Source.MICROPHONE, enabled) 202 setTrackEnabled(Track.Source.MICROPHONE, enabled)
192 } 203 }
193 204
194 /** 205 /**
  206 + * If set to enabled, creates and publishes a screenshare video track.
  207 + *
  208 + * If set to disabled, unpublishes the screenshare video track.
  209 + *
195 * @param mediaProjectionPermissionResultData The resultData returned from launching 210 * @param mediaProjectionPermissionResultData The resultData returned from launching
196 * [MediaProjectionManager.createScreenCaptureIntent()](https://developer.android.com/reference/android/media/projection/MediaProjectionManager#createScreenCaptureIntent()). 211 * [MediaProjectionManager.createScreenCaptureIntent()](https://developer.android.com/reference/android/media/projection/MediaProjectionManager#createScreenCaptureIntent()).
197 * @throws IllegalArgumentException if attempting to enable screenshare without [mediaProjectionPermissionResultData] 212 * @throws IllegalArgumentException if attempting to enable screenshare without [mediaProjectionPermissionResultData]
@@ -260,6 +275,9 @@ internal constructor( @@ -260,6 +275,9 @@ internal constructor(
260 } 275 }
261 } 276 }
262 277
  278 + /**
  279 + * Publishes an audio track.
  280 + */
263 suspend fun publishAudioTrack( 281 suspend fun publishAudioTrack(
264 track: LocalAudioTrack, 282 track: LocalAudioTrack,
265 options: AudioTrackPublishOptions = AudioTrackPublishOptions( 283 options: AudioTrackPublishOptions = AudioTrackPublishOptions(
@@ -288,6 +306,9 @@ internal constructor( @@ -288,6 +306,9 @@ internal constructor(
288 ) 306 )
289 } 307 }
290 308
  309 + /**
  310 + * Publishes an video track.
  311 + */
291 suspend fun publishVideoTrack( 312 suspend fun publishVideoTrack(
292 track: LocalVideoTrack, 313 track: LocalVideoTrack,
293 options: VideoTrackPublishOptions = VideoTrackPublishOptions(null, videoTrackPublishDefaults), 314 options: VideoTrackPublishOptions = VideoTrackPublishOptions(null, videoTrackPublishDefaults),
@@ -571,6 +592,11 @@ internal constructor( @@ -571,6 +592,11 @@ internal constructor(
571 engine.updateSubscriptionPermissions(allParticipantsAllowed, participantTrackPermissions) 592 engine.updateSubscriptionPermissions(allParticipantsAllowed, participantTrackPermissions)
572 } 593 }
573 594
  595 + /**
  596 + * Unpublish a track.
  597 + *
  598 + * @param stopOnUnpublish if true, stops the track after unpublishing the track. Defaults to true.
  599 + */
574 fun unpublishTrack(track: Track, stopOnUnpublish: Boolean = true) { 600 fun unpublishTrack(track: Track, stopOnUnpublish: Boolean = true) {
575 val publication = localTrackPublications.firstOrNull { it.track == track } 601 val publication = localTrackPublications.firstOrNull { it.track == track }
576 if (publication === null) { 602 if (publication === null) {
@@ -633,6 +659,10 @@ internal constructor( @@ -633,6 +659,10 @@ internal constructor(
633 engine.sendData(dataPacket) 659 engine.sendData(dataPacket)
634 } 660 }
635 661
  662 + /**
  663 + * @suppress
  664 + */
  665 + @VisibleForTesting
636 override fun updateFromInfo(info: LivekitModels.ParticipantInfo) { 666 override fun updateFromInfo(info: LivekitModels.ParticipantInfo) {
637 super.updateFromInfo(info) 667 super.updateFromInfo(info)
638 668
@@ -773,7 +803,7 @@ internal constructor( @@ -773,7 +803,7 @@ internal constructor(
773 unpublishTrack(track) 803 unpublishTrack(track)
774 } 804 }
775 805
776 - fun prepareForFullReconnect() { 806 + internal fun prepareForFullReconnect() {
777 val pubs = localTrackPublications.toList() // creates a copy, so is safe from the following removal. 807 val pubs = localTrackPublications.toList() // creates a copy, so is safe from the following removal.
778 808
779 // Only set the first time we start a full reconnect. 809 // Only set the first time we start a full reconnect.
@@ -789,7 +819,7 @@ internal constructor( @@ -789,7 +819,7 @@ internal constructor(
789 } 819 }
790 } 820 }
791 821
792 - suspend fun republishTracks() { 822 + internal suspend fun republishTracks() {
793 val publish = republishes?.toList() ?: emptyList() 823 val publish = republishes?.toList() ?: emptyList()
794 republishes = null 824 republishes = null
795 825
@@ -807,6 +837,9 @@ internal constructor( @@ -807,6 +837,9 @@ internal constructor(
807 } 837 }
808 } 838 }
809 839
  840 + /**
  841 + * @suppress
  842 + */
810 fun cleanup() { 843 fun cleanup() {
811 for (pub in trackPublications.values) { 844 for (pub in trackPublications.values) {
812 val track = pub.track 845 val track = pub.track
@@ -825,6 +858,9 @@ internal constructor( @@ -825,6 +858,9 @@ internal constructor(
825 } 858 }
826 } 859 }
827 860
  861 + /**
  862 + * @suppress
  863 + */
828 override fun dispose() { 864 override fun dispose() {
829 cleanup() 865 cleanup()
830 super.dispose() 866 super.dispose()
@@ -965,6 +1001,9 @@ data class BackupVideoCodec( @@ -965,6 +1001,9 @@ data class BackupVideoCodec(
965 ) 1001 )
966 1002
967 abstract class BaseAudioTrackPublishOptions { 1003 abstract class BaseAudioTrackPublishOptions {
  1004 + /**
  1005 + * The target audioBitrate to use.
  1006 + */
968 abstract val audioBitrate: Int? 1007 abstract val audioBitrate: Int?
969 1008
970 /** 1009 /**
@@ -28,8 +28,18 @@ import io.livekit.android.room.track.TrackPublication @@ -28,8 +28,18 @@ import io.livekit.android.room.track.TrackPublication
28 import io.livekit.android.util.FlowObservable 28 import io.livekit.android.util.FlowObservable
29 import io.livekit.android.util.flow 29 import io.livekit.android.util.flow
30 import io.livekit.android.util.flowDelegate 30 import io.livekit.android.util.flowDelegate
31 -import kotlinx.coroutines.*  
32 -import kotlinx.coroutines.flow.* 31 +import kotlinx.coroutines.CoroutineDispatcher
  32 +import kotlinx.coroutines.CoroutineScope
  33 +import kotlinx.coroutines.SupervisorJob
  34 +import kotlinx.coroutines.cancel
  35 +import kotlinx.coroutines.flow.Flow
  36 +import kotlinx.coroutines.flow.SharingStarted
  37 +import kotlinx.coroutines.flow.combine
  38 +import kotlinx.coroutines.flow.flatMapLatest
  39 +import kotlinx.coroutines.flow.flowOf
  40 +import kotlinx.coroutines.flow.map
  41 +import kotlinx.coroutines.flow.stateIn
  42 +import kotlinx.coroutines.isActive
33 import kotlinx.serialization.Serializable 43 import kotlinx.serialization.Serializable
34 import livekit.LivekitModels 44 import livekit.LivekitModels
35 import java.util.Date 45 import java.util.Date
@@ -302,7 +312,6 @@ open class Participant( @@ -302,7 +312,6 @@ open class Participant(
302 /** 312 /**
303 * @suppress 313 * @suppress
304 */ 314 */
305 - @VisibleForTesting  
306 open fun updateFromInfo(info: LivekitModels.ParticipantInfo) { 315 open fun updateFromInfo(info: LivekitModels.ParticipantInfo) {
307 sid = Sid(info.sid) 316 sid = Sid(info.sid)
308 identity = Identity(info.identity) 317 identity = Identity(info.identity)
@@ -37,10 +37,13 @@ import livekit.org.webrtc.MediaStreamTrack @@ -37,10 +37,13 @@ import livekit.org.webrtc.MediaStreamTrack
37 import livekit.org.webrtc.RtpReceiver 37 import livekit.org.webrtc.RtpReceiver
38 import livekit.org.webrtc.VideoTrack 38 import livekit.org.webrtc.VideoTrack
39 39
  40 +/**
  41 + * A representation of a remote participant.
  42 + */
40 class RemoteParticipant( 43 class RemoteParticipant(
41 sid: Sid, 44 sid: Sid,
42 identity: Identity? = null, 45 identity: Identity? = null,
43 - val signalClient: SignalClient, 46 + internal val signalClient: SignalClient,
44 private val ioDispatcher: CoroutineDispatcher, 47 private val ioDispatcher: CoroutineDispatcher,
45 defaultDispatcher: CoroutineDispatcher, 48 defaultDispatcher: CoroutineDispatcher,
46 ) : Participant(sid, identity, defaultDispatcher) { 49 ) : Participant(sid, identity, defaultDispatcher) {
@@ -68,6 +71,9 @@ class RemoteParticipant( @@ -68,6 +71,9 @@ class RemoteParticipant(
68 71
69 private val coroutineScope = CloseableCoroutineScope(defaultDispatcher + SupervisorJob()) 72 private val coroutineScope = CloseableCoroutineScope(defaultDispatcher + SupervisorJob())
70 73
  74 + /**
  75 + * Get a track publication with the corresponding sid.
  76 + */
71 fun getTrackPublication(sid: String): RemoteTrackPublication? = trackPublications[sid] as? RemoteTrackPublication 77 fun getTrackPublication(sid: String): RemoteTrackPublication? = trackPublications[sid] as? RemoteTrackPublication
72 78
73 /** 79 /**
@@ -113,6 +113,9 @@ constructor( @@ -113,6 +113,9 @@ constructor(
113 113
114 private val closeableManager = CloseableManager() 114 private val closeableManager = CloseableManager()
115 115
  116 + /**
  117 + * Starts the [capturer] with the capture params contained in [options].
  118 + */
116 open fun startCapture() { 119 open fun startCapture() {
117 capturer.startCapture( 120 capturer.startCapture(
118 options.captureParams.width, 121 options.captureParams.width,
@@ -121,6 +124,9 @@ constructor( @@ -121,6 +124,9 @@ constructor(
121 ) 124 )
122 } 125 }
123 126
  127 + /**
  128 + * Stops the [capturer].
  129 + */
124 open fun stopCapture() { 130 open fun stopCapture() {
125 capturer.stopCapture() 131 capturer.stopCapture()
126 } 132 }
@@ -152,6 +158,10 @@ constructor( @@ -152,6 +158,10 @@ constructor(
152 } 158 }
153 } 159 }
154 160
  161 + /**
  162 + * If this is a camera track, switches to the new camera determined by [deviceId]
  163 + */
  164 + @Deprecated("Use LocalVideoTrack.switchCamera instead.", ReplaceWith("switchCamera(deviceId = deviceId)"))
155 fun setDeviceId(deviceId: String) { 165 fun setDeviceId(deviceId: String) {
156 restartTrack(options.copy(deviceId = deviceId)) 166 restartTrack(options.copy(deviceId = deviceId))
157 } 167 }
@@ -346,7 +356,7 @@ constructor( @@ -346,7 +356,7 @@ constructor(
346 } 356 }
347 } 357 }
348 358
349 - fun setPublishingCodecs(codecs: List<SubscribedCodec>): List<VideoCodec> { 359 + internal fun setPublishingCodecs(codecs: List<SubscribedCodec>): List<VideoCodec> {
350 LKLog.v { "setting publishing codecs: $codecs" } 360 LKLog.v { "setting publishing codecs: $codecs" }
351 361
352 // only enable simulcast codec for preferred codec set 362 // only enable simulcast codec for preferred codec set
@@ -21,6 +21,9 @@ import livekit.org.webrtc.AudioTrack @@ -21,6 +21,9 @@ import livekit.org.webrtc.AudioTrack
21 import livekit.org.webrtc.AudioTrackSink 21 import livekit.org.webrtc.AudioTrackSink
22 import livekit.org.webrtc.RtpReceiver 22 import livekit.org.webrtc.RtpReceiver
23 23
  24 +/**
  25 + * A representation of a remote audio track.
  26 + */
24 class RemoteAudioTrack( 27 class RemoteAudioTrack(
25 name: String, 28 name: String,
26 rtcTrack: AudioTrack, 29 rtcTrack: AudioTrack,
@@ -149,18 +149,27 @@ abstract class Track( @@ -149,18 +149,27 @@ abstract class Track(
149 149
150 data class Dimensions(val width: Int, val height: Int) 150 data class Dimensions(val width: Int, val height: Int)
151 151
  152 + /**
  153 + * Starts the track.
  154 + */
152 open fun start() { 155 open fun start() {
153 executeBlockingOnRTCThread { 156 executeBlockingOnRTCThread {
154 rtcTrack.setEnabled(true) 157 rtcTrack.setEnabled(true)
155 } 158 }
156 } 159 }
157 160
  161 + /**
  162 + * Stops the track.
  163 + */
158 open fun stop() { 164 open fun stop() {
159 executeBlockingOnRTCThread { 165 executeBlockingOnRTCThread {
160 rtcTrack.setEnabled(false) 166 rtcTrack.setEnabled(false)
161 } 167 }
162 } 168 }
163 169
  170 + /**
  171 + * Disposes the track. LiveKit will generally take care of disposing tracks for you.
  172 + */
164 open fun dispose() { 173 open fun dispose() {
165 executeBlockingOnRTCThread { 174 executeBlockingOnRTCThread {
166 rtcTrack.dispose() 175 rtcTrack.dispose()
@@ -30,6 +30,9 @@ abstract class VideoTrack(name: String, override val rtcTrack: VideoTrack) : @@ -30,6 +30,9 @@ abstract class VideoTrack(name: String, override val rtcTrack: VideoTrack) :
30 rtcTrack.setEnabled(value) 30 rtcTrack.setEnabled(value)
31 } 31 }
32 32
  33 + /**
  34 + * Add a [VideoSink] that will receive frames.
  35 + */
33 open fun addRenderer(renderer: VideoSink) { 36 open fun addRenderer(renderer: VideoSink) {
34 executeBlockingOnRTCThread { 37 executeBlockingOnRTCThread {
35 sinks.add(renderer) 38 sinks.add(renderer)
@@ -37,6 +40,9 @@ abstract class VideoTrack(name: String, override val rtcTrack: VideoTrack) : @@ -37,6 +40,9 @@ abstract class VideoTrack(name: String, override val rtcTrack: VideoTrack) :
37 } 40 }
38 } 41 }
39 42
  43 + /**
  44 + * Remove a previously added [VideoSink].
  45 + */
40 open fun removeRenderer(renderer: VideoSink) { 46 open fun removeRenderer(renderer: VideoSink) {
41 executeBlockingOnRTCThread { 47 executeBlockingOnRTCThread {
42 rtcTrack.removeSink(renderer) 48 rtcTrack.removeSink(renderer)
@@ -237,10 +237,20 @@ object CameraCapturerUtils { @@ -237,10 +237,20 @@ object CameraCapturerUtils {
237 return null 237 return null
238 } 238 }
239 239
  240 + /**
  241 + * An interface declaring a provider of camera capturers.
  242 + */
240 interface CameraProvider { 243 interface CameraProvider {
  244 + /**
  245 + * This acts as the priority of the CameraProvider when determining which provider to use (in order of highest to lowest).
  246 + */
241 val cameraVersion: Int 247 val cameraVersion: Int
242 fun provideEnumerator(context: Context): CameraEnumerator 248 fun provideEnumerator(context: Context): CameraEnumerator
243 fun provideCapturer(context: Context, options: LocalVideoTrackOptions, eventsHandler: CameraEventsDispatchHandler): VideoCapturer 249 fun provideCapturer(context: Context, options: LocalVideoTrackOptions, eventsHandler: CameraEventsDispatchHandler): VideoCapturer
  250 +
  251 + /**
  252 + * If the return value of this method is false, this provider will be skipped when querying providers to use.
  253 + */
244 fun isSupported(context: Context): Boolean 254 fun isSupported(context: Context): Boolean
245 } 255 }
246 } 256 }
@@ -20,6 +20,9 @@ import livekit.org.webrtc.CapturerObserver @@ -20,6 +20,9 @@ import livekit.org.webrtc.CapturerObserver
20 import livekit.org.webrtc.VideoFrame 20 import livekit.org.webrtc.VideoFrame
21 import livekit.org.webrtc.VideoSink 21 import livekit.org.webrtc.VideoSink
22 22
  23 +/**
  24 + * @suppress
  25 + */
23 class CaptureDispatchObserver : CapturerObserver { 26 class CaptureDispatchObserver : CapturerObserver {
24 private val observers = linkedSetOf<CapturerObserver>() 27 private val observers = linkedSetOf<CapturerObserver>()
25 private val sinks = linkedSetOf<VideoSink>() 28 private val sinks = linkedSetOf<VideoSink>()
@@ -19,6 +19,9 @@ package io.livekit.android.room.track.video @@ -19,6 +19,9 @@ package io.livekit.android.room.track.video
19 import android.hardware.camera2.CameraManager 19 import android.hardware.camera2.CameraManager
20 import livekit.org.webrtc.* 20 import livekit.org.webrtc.*
21 21
  22 +/**
  23 + * A [VideoCapturer] that declares that it can determine the actual size of the capture format it will use.
  24 + */
22 interface VideoCapturerWithSize : VideoCapturer { 25 interface VideoCapturerWithSize : VideoCapturer {
23 fun findCaptureFormat(width: Int, height: Int): Size 26 fun findCaptureFormat(width: Int, height: Int): Size
24 } 27 }
@@ -77,6 +77,10 @@ class ViewVisibility(private val view: View) : VideoSinkVisibility() { @@ -77,6 +77,10 @@ class ViewVisibility(private val view: View) : VideoSinkVisibility() {
77 scheduleRecalculate() 77 scheduleRecalculate()
78 } 78 }
79 79
  80 + /**
  81 + * Declares that this [View] will override [View.onVisibilityChanged] and call through to [recalculate],
  82 + * partaking in the [VideoSinkVisibility] system.
  83 + */
80 interface Notifier { 84 interface Notifier {
81 var viewVisibility: ViewVisibility? 85 var viewVisibility: ViewVisibility?
82 } 86 }
@@ -103,6 +107,9 @@ class ViewVisibility(private val view: View) : VideoSinkVisibility() { @@ -103,6 +107,9 @@ class ViewVisibility(private val view: View) : VideoSinkVisibility() {
103 ) 107 )
104 } 108 }
105 109
  110 + /**
  111 + * Recalculates whether this view's visibility has changed, and notifies observers if it has.
  112 + */
106 fun recalculate() { 113 fun recalculate() {
107 var shouldNotify = false 114 var shouldNotify = false
108 val newVisibility = isVisible() 115 val newVisibility = isVisible()
1 -/*  
2 - * Copyright 2024 LiveKit, Inc.  
3 - *  
4 - * Licensed under the Apache License, Version 2.0 (the "License");  
5 - * you may not use this file except in compliance with the License.  
6 - * You may obtain a copy of the License at  
7 - *  
8 - * http://www.apache.org/licenses/LICENSE-2.0  
9 - *  
10 - * Unless required by applicable law or agreed to in writing, software  
11 - * distributed under the License is distributed on an "AS IS" BASIS,  
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
13 - * See the License for the specific language governing permissions and  
14 - * limitations under the License.  
15 - */  
16 -  
17 -package io.livekit.android.util  
18 -  
19 -import android.os.Handler  
20 -import android.os.Looper  
21 -  
22 -fun Handler.runOrPost(r: Runnable) {  
23 - if (Looper.myLooper() == this.looper) {  
24 - r.run()  
25 - } else {  
26 - post(r)  
27 - }  
28 -}