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 | -} |
-
请 注册 或 登录 后发表评论