From e4bee3fdfab9e0767940fc1f0d2cea3357e4d676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Wed, 27 Nov 2024 14:12:02 +0100 Subject: [PATCH] Review KDoc in `ch.srgssr.pillarbox.player` --- .../player/PillarboxBandwidthMeter.kt | 5 +- .../pillarbox/player/PillarboxBuilder.kt | 96 +++++++-------- .../pillarbox/player/PillarboxExoPlayer.kt | 8 ++ .../pillarbox/player/PillarboxLoadControl.kt | 11 +- .../pillarbox/player/PillarboxPlayer.kt | 58 +++++----- .../player/PillarboxPreloadManager.kt | 36 +++--- .../player/PillarboxRenderersFactory.kt | 5 +- .../player/PillarboxTrackSelector.kt | 5 +- .../pillarbox/player/PlayerCallbackFlow.kt | 109 +++++++++++++----- .../pillarbox/player/PreloadConfiguration.kt | 6 +- 10 files changed, 207 insertions(+), 132 deletions(-) diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBandwidthMeter.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBandwidthMeter.kt index c4231fd82..3de4efa6f 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBandwidthMeter.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBandwidthMeter.kt @@ -9,9 +9,10 @@ import androidx.media3.exoplayer.upstream.BandwidthMeter import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter /** - * Preconfigured [BandwidthMeter] for Pillarbox. + * Provides a pre-configured instance of [BandwidthMeter] suitable for use within Pillarbox. * - * @param context The [Context] needed to create the [BandwidthMeter]. + * @param context The [Context] required for initializing the [BandwidthMeter]. + * @return A [BandwidthMeter] ready for use within Pillarbox. */ @Suppress("FunctionName") fun PillarboxBandwidthMeter(context: Context): BandwidthMeter { diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBuilder.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBuilder.kt index a8cdeb0b3..8dbb4f843 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBuilder.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxBuilder.kt @@ -36,13 +36,20 @@ import kotlin.time.Duration.Companion.ZERO import kotlin.time.Duration.Companion.milliseconds /** - * Marker for Pillarbox's DSL. + * Marks a class or function as part of the Pillarbox DSL (Domain Specific Language). + * + * This annotation serves as a marker for the Kotlin compiler, enabling DSL-specific features like type-safe builders and improved code completion. + * Applying this annotation to a class or function indicates that it's intended to be used within the context of the Pillarbox DSL. + * + * This annotation is primarily intended for internal use within the Pillarbox library. */ @DslMarker annotation class PillarboxDsl /** - * Builder to create a new instance of [PillarboxExoPlayer]. + * A builder class for creating instances of [PillarboxExoPlayer]. + * + * This builder provides a fluent API for configuring various aspects of the player, such as asset loaders, coroutine context, seek increments, ... */ @PillarboxDsl @Suppress("TooManyFunctions") @@ -61,16 +68,16 @@ abstract class PillarboxBuilder { private var preloadConfiguration = ExoPlayer.PreloadConfiguration.DEFAULT /** - * Add an [AssetLoader] to the [PillarboxExoPlayer]. + * Registers a custom [AssetLoader] with the [PillarboxExoPlayer]. * - * @param assetLoader The [assetLoader] to add. + * @param assetLoader The [AssetLoader] to add. */ fun addAssetLoader(assetLoader: AssetLoader) { assetLoaders.add(assetLoader) } /** - * Add an [AssetLoader] to the [PillarboxExoPlayer]. + * Registers a custom [AssetLoader] with the [PillarboxExoPlayer]. * * @receiver The [AssetLoader] to add. */ @@ -79,9 +86,11 @@ abstract class PillarboxBuilder { } /** - * Set the internal [Clock] used by the player. + * Sets the internal [Clock] used by the player. * - * @param clock The internal clock used by the player. + * **Note:** this function is intended for internal use and should not be called by applications. + * + * @param clock The [Clock] instance to be used by the player. */ @VisibleForTesting @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @@ -90,41 +99,41 @@ abstract class PillarboxBuilder { } /** - * Set the coroutine context used by the player. + * Sets the [CoroutineContext] used by the player. * - * @param coroutineContext The coroutine context used by the player. + * @param coroutineContext The [CoroutineContext] to be used by the player. */ fun coroutineContext(coroutineContext: CoroutineContext) { this.coroutineContext = coroutineContext } /** - * Set the load control used by the player. + * Sets the [LoadControl] used by the player. * - * @param loadControl The load control used by the player. + * @param loadControl The [LoadControl] to be used by the player. */ fun loadControl(loadControl: LoadControl) { this.loadControl = loadControl } /** - * Set the [Player.getMaxSeekToPreviousPosition] value. + * Sets the maximum duration the player can seek backward when using [Player.seekToPrevious]. * - * @param maxSeekToPreviousPosition The [Player.getMaxSeekToPreviousPosition] value. + * @param maxSeekToPreviousPosition The maximum duration to seek backward. */ fun maxSeekToPreviousPosition(maxSeekToPreviousPosition: Duration) { this.maxSeekToPreviousPosition = maxSeekToPreviousPosition } /** - * Disable the monitoring for this player + * Disables the monitoring for this player. */ fun disableMonitoring() { monitoring = NoOp() } /** - * Make the monitoring logs all events to Logcat, using the default config. + * Logs all monitoring events to Logcat. * * @param type [Logcat]. */ @@ -135,11 +144,11 @@ abstract class PillarboxBuilder { } /** - * Make the monitoring sends all events to a remote server. + * Configures the monitoring to send all events to a remote server. * - * @param endpointUrl The endpoint receiving monitoring messages. - * @param httpClient The [HttpClient] to use to send the events. - * @param coroutineScope The scope used to send the monitoring message. + * @param endpointUrl The URL of the endpoint responsible for receiving monitoring messages. + * @param httpClient The [HttpClient] instance used for transmitting events to the endpoint. + * @param coroutineScope The [CoroutineScope] which manages the coroutine responsible for sending monitoring messages. */ fun monitoring( endpointUrl: String, @@ -152,12 +161,12 @@ abstract class PillarboxBuilder { } /** - * Configure the monitoring for this player. + * Configures monitoring for this player. * - * @param Config The type of the config to create. - * @param Factory The type of the [MonitoringMessageHandlerFactory]. - * @param type The type of [MonitoringMessageHandler] to use. - * @param createConfig The configuration builder to create the [MonitoringMessageHandler]. + * @param Config The type of the configuration object used to setup the monitoring handler. + * @param Factory The type of the [MonitoringMessageHandlerFactory] used to create the monitoring handler. + * @param type The type of [MonitoringMessageHandler] to create. + * @param createConfig A lambda that returns a configuration of type [Config]. */ fun > monitoring( type: MonitoringMessageHandlerType, @@ -167,48 +176,41 @@ abstract class PillarboxBuilder { } /** - * Set the [Looper] to use for playback. + * Sets the [Looper] used by the player. * - * @param playbackLooper The [Looper] used for playback. + * @param playbackLooper The [Looper] to be used by the player. */ fun playbackLooper(playbackLooper: Looper) { this.playbackLooper = playbackLooper } /** - * Set the seek back increment duration. + * Sets the duration by which the player seeks backward when performing a "seek backward" operation. * - * @param seekBackwardIncrement The seek back increment duration. + * @param seekBackwardIncrement The duration to seek backward by. */ fun seekBackwardIncrement(seekBackwardIncrement: Duration) { this.seekBackwardIncrement = seekBackwardIncrement } /** - * Set the seek forward increment duration. + * Sets the duration by which the player seeks forward when performing a "seek forward" action. * - * @param seekForwardIncrement The seek forward increment duration. + * @param seekForwardIncrement The duration to seek forward by. */ fun seekForwardIncrement(seekForwardIncrement: Duration) { this.seekForwardIncrement = seekForwardIncrement } /** - * Set the [ExoPlayer.PreloadConfiguration] used by the player. + * Sets the [ExoPlayer.PreloadConfiguration] used by the player. * - * @param preloadConfiguration The [ExoPlayer.PreloadConfiguration]. + * @param preloadConfiguration The [ExoPlayer.PreloadConfiguration] to be used by the player. */ fun preloadConfiguration(preloadConfiguration: ExoPlayer.PreloadConfiguration) { this.preloadConfiguration = preloadConfiguration } - /** - * Create a new instance of [PillarboxExoPlayer]. - * - * @param context The [Context]. - * - * @return A new instance of [PillarboxExoPlayer]. - */ internal fun create(context: Context): PillarboxExoPlayer { return PillarboxExoPlayer( context = context, @@ -221,7 +223,9 @@ abstract class PillarboxBuilder { } /** - * Create a new instance of [ExoPlayer.Builder], used internally by [PillarboxExoPlayer]. + * Creates the instance of [ExoPlayer.Builder], that will be used internally by [PillarboxExoPlayer]. + * + * Subclasses can override this method to customize the [ExoPlayer.Builder] further, but they **MUST** ensure to call the super implementation. * * @param context The [Context]. * @@ -256,19 +260,21 @@ abstract class PillarboxBuilder { } /** - * Factory used to create instances of [PillarboxBuilder]. + * Defines a factory for creating instances of [PillarboxBuilder]. * - * @param Builder The type of [PillarboxBuilder] to create. + * @param Builder The type of [PillarboxBuilder] that this factory creates. */ interface PlayerConfig { /** - * Create a new instance of [Builder]. + * Creates a new instance of the [Builder] class. + * + * @return A new instance of the [Builder]. */ fun create(): Builder } /** - * Default implementation used to create simple [PillarboxExoPlayer]. + * Default configuration for creating a [PillarboxExoPlayer], which closely matches an [ExoPlayer]. */ object Default : PlayerConfig { override fun create(): Builder { @@ -276,7 +282,7 @@ object Default : PlayerConfig { } /** - * Default implementation used to create simple [PillarboxExoPlayer]. + * A builder class for creating and configuring a [PillarboxExoPlayer]. */ class Builder : PillarboxBuilder() { init { diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxExoPlayer.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxExoPlayer.kt index 94bf07516..1d07a8b23 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxExoPlayer.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxExoPlayer.kt @@ -38,6 +38,14 @@ import kotlin.coroutines.CoroutineContext /** * Create a new instance of [PillarboxExoPlayer]. * + * **Usage** + * ```kotlin + * val player = PillarboxExoPlayer(context, Default) { + * addAssetLoader(MyAssetLoader()) + * coroutineContext(Dispatchers.Main) + * } + * ``` + * * @param Builder The type of the [PillarboxBuilder]. * @param context The [Context]. * @param type The [PlayerConfig]. diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxLoadControl.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxLoadControl.kt index e58cfec1b..43aee9add 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxLoadControl.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxLoadControl.kt @@ -20,9 +20,9 @@ import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds /** - * Pillarbox [LoadControl] implementation that optimize content loading. + * A [LoadControl] implementation tailored for Pillarbox, optimizing content loading. * - * @param bufferDurations Buffer durations to set [DefaultLoadControl.Builder.setBufferDurationsMs]. + * @param bufferDurations Buffer durations to customize the internal [DefaultLoadControl]'s behavior. * @param allocator The [DefaultAllocator] to use in the internal [DefaultLoadControl]. */ class PillarboxLoadControl( @@ -91,14 +91,13 @@ class PillarboxLoadControl( } /** - * Buffer durations to use for [DefaultLoadControl.Builder.setBufferDurationsMs]. + * Represents the buffer durations used by [DefaultLoadControl.Builder.setBufferDurationsMs]. * * @property minBufferDuration The minimum duration of media that the player will attempt to ensure is buffered at all times. * @property maxBufferDuration The maximum duration of media that the player will attempt to buffer. * @property bufferForPlayback The duration of media that must be buffered for playback to start or resume following a user action such as a seek. - * @property bufferForPlaybackAfterRebuffer The default duration of media that must be buffered for playback to resume after a rebuffer. - * A rebuffer is defined to be caused by buffer depletion rather than a user action. - * @constructor Create empty Buffer durations + * @property bufferForPlaybackAfterRebuffer The duration of media that must be buffered for playback to resume after a rebuffer. A rebuffer is + * defined to be caused by buffer depletion rather than a user action. */ data class BufferDurations( val minBufferDuration: Duration = DefaultLoadControl.DEFAULT_MIN_BUFFER_MS.milliseconds, diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPlayer.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPlayer.kt index aa0e91cfe..f4a9c1a9b 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPlayer.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPlayer.kt @@ -16,65 +16,67 @@ import ch.srgssr.pillarbox.player.asset.timeRange.Credit */ interface PillarboxPlayer : Player { /** - * Listener + * A listener for events specific to Pillarbox. */ interface Listener : Player.Listener { /** - * On smooth seeking enabled changed + * Called when the smooth seeking enabled state changes. * - * @param smoothSeekingEnabled The new value of [PillarboxPlayer.smoothSeekingEnabled] + * @param smoothSeekingEnabled Whether smooth seeking is enabled. */ fun onSmoothSeekingEnabledChanged(smoothSeekingEnabled: Boolean) {} /** - * On tracking enabled changed + * Called when the tracking state changes. * - * @param trackingEnabled The new value of [PillarboxPlayer.trackingEnabled] + * @param trackingEnabled Whether tracking is enabled. */ fun onTrackingEnabledChanged(trackingEnabled: Boolean) {} /** - * `onChapterChanged` is called when either: - * - The player position changes while playing automatically. - * - The use seeks to a new position. - * - The playlist changes. + * Called when the current chapter changes. This can occur due to several reasons: * - * @param chapter `null` when the current position is not in a chapter. + * - **Automatic playback:** the player's position progresses naturally during playback and enters a new chapter. + * - **Seeking:** the user manually seeks to a new position within the content, landing within a different chapter. + * - **Playlist change:** the current playlist is changed, potentially resulting in a different set of chapters and a new active chapter. + * + * @param chapter The currently active [Chapter]. This will be `null` if the current playback position is not within any defined chapter. */ fun onChapterChanged(chapter: Chapter?) {} /** - * On blocked time range reached + * Called when the player reaches a blocked time range. * - * @param blockedTimeRange The [BlockedTimeRange] reached by the player. + * @param blockedTimeRange The [BlockedTimeRange] representing the time range that the player has reached. */ fun onBlockedTimeRangeReached(blockedTimeRange: BlockedTimeRange) {} /** - * `onCreditChanged` is called when either: - * - The player position changes while playing automatically. - * - The use seeks to a new position. - * - The playlist changes. + * Called when the current credit changes. This can occur due to several reasons: + * + * - **Automatic playback:** the player's position progresses naturally during playback and enters a new chapter. + * - **Seeking:** the user manually seeks to a new position within the content, landing within a different chapter. + * - **Playlist change:** the current playlist is changed, potentially resulting in a different set of chapters and a new active chapter. * - * @param credit `null` when the current position is not in a Credit. + * @param credit The currently active [Credit]. This will be `null` if the current playback position is not within any defined credit. */ fun onCreditChanged(credit: Credit?) {} } /** - * Smooth seeking enabled + * Controls whether smooth seeking behavior is enabled. * - * When [smoothSeekingEnabled] is true, next seek events is send only after the current is done. + * When this property is `true`, subsequent seek events are sent only after the current seek operation is completed. * - * To have the best result it is important to - * 1) Pause the player while seeking. - * 2) Set the [ExoPlayer.setSeekParameters] to [SeekParameters.CLOSEST_SYNC]. + * For optimal results, it is important to: + * 1. Pause the player during seek operations. + * 2. Set the player's seek parameters to [SeekParameters.CLOSEST_SYNC] using [ExoPlayer.setSeekParameters]. */ var smoothSeekingEnabled: Boolean /** - * Enable or disable MediaItem tracking + * Controls whether media item tracking is enabled. */ var trackingEnabled: Boolean @@ -82,27 +84,27 @@ interface PillarboxPlayer : Player { companion object { /** - * Event Blocked Time Range Reached. + * Event indicating that a blocked time range has been reached. */ const val EVENT_BLOCKED_TIME_RANGE_REACHED = 100 /** - * The current [Chapter] has changed. + * Event indicating that the current [Chapter] has changed. */ const val EVENT_CHAPTER_CHANGED = 101 /** - * The current [Credit] Changed. + * Event indicating that the current [Credit] has changed. */ const val EVENT_CREDIT_CHANGED = 102 /** - * [trackingEnabled] has changed. + * Event indicating that the media item [tracking state][trackingEnabled] has changed. */ const val EVENT_TRACKING_ENABLED_CHANGED = 103 /** - * [smoothSeekingEnabled] has changed. + * Event indicating that the [smooth seeking state][smoothSeekingEnabled] has changed. */ const val EVENT_SMOOTH_SEEKING_ENABLED_CHANGED = 104 } diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPreloadManager.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPreloadManager.kt index fae7a0b9f..fe5b83e34 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPreloadManager.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxPreloadManager.kt @@ -25,9 +25,9 @@ import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds /** - * Helper class for the Media3's [DefaultPreloadManager]. + * Helper class for Media3's [DefaultPreloadManager] that simplifies preloading of media items for [PillarboxExoPlayer]. * - * @param context The current [Context]. + * @param context The [Context]. * @param targetPreloadStatusControl The [TargetPreloadStatusControl] to decide when to preload an item and for how long. * @param mediaSourceFactory The [PillarboxMediaSourceFactory] to create each [MediaSource]. * @param trackSelector The [TrackSelector] for this preload manager. @@ -62,15 +62,16 @@ class PillarboxPreloadManager( } /** - * Get the count of [MediaSource] currently managed by this preload manager. + * Gets the count of the [MediaSource]s currently being managed by the preload manager. * + * @return The count of the [MediaSource]s. * @see DefaultPreloadManager.getSourceCount */ val sourceCount: Int get() = preloadManager.sourceCount /** - * Playback looper to use with PillarboxExoPlayer. + * The [Looper] associated with the [Thread] on which playback operations are performed by the [PillarboxExoPlayer]. */ val playbackLooper: Looper @@ -89,7 +90,7 @@ class PillarboxPreloadManager( } /** - * Add a [MediaItem] with its [rankingData] to the preload manager. + * Adds a [MediaItem] with its [rankingData] to the preload manager. * * @param mediaItem The [MediaItem] to add. * @param rankingData The ranking data that is associated with the [mediaItem]. @@ -100,7 +101,7 @@ class PillarboxPreloadManager( } /** - * Add a [MediaSource] with its [rankingData] to the preload manager. + * Adds a [MediaSource] with its [rankingData] to the preload manager. * * @param mediaSource The [MediaSource] to add. * @param rankingData The ranking data that is associated with the [mediaSource]. @@ -114,7 +115,7 @@ class PillarboxPreloadManager( * Returns the [MediaSource] for the given [MediaItem]. * * @param mediaItem The [MediaItem]. - * @return The source for the give [mediaItem] if it is managed by the preload manager, `null` otherwise. + * @return The source for the given [mediaItem] if it is managed by the preload manager, `null` otherwise. * @see DefaultPreloadManager.getMediaSource */ fun getMediaSource(mediaItem: MediaItem): MediaSource? { @@ -122,7 +123,7 @@ class PillarboxPreloadManager( } /** - * Invalidate the current preload manager. + * Invalidates the current preload progress, and triggers a new preload progress based on the new priorities of the managed [MediaSource]s. * * @see DefaultPreloadManager.invalidate */ @@ -131,7 +132,7 @@ class PillarboxPreloadManager( } /** - * Release the preload manager. + * Releases the preload manager. * The preload manager must not be used after calling this method. * * @see DefaultPreloadManager.release @@ -142,7 +143,7 @@ class PillarboxPreloadManager( } /** - * Remove a [MediaItem] from the preload manager. + * Removes a [MediaItem] from the preload manager. * * @param mediaItem The [MediaItem] to remove. * @return `true` if the preload manager is holding a [MediaSource] of the given [MediaItem] and it has been removed, `false` otherwise. @@ -153,7 +154,7 @@ class PillarboxPreloadManager( } /** - * Remove a [MediaSource] from the preload manager. + * Removes a [MediaSource] from the preload manager. * * @param mediaSource The [MediaSource] to remove. * @return `true` if the preload manager is holding the given [MediaSource] and it has been removed, `false` otherwise. @@ -164,7 +165,7 @@ class PillarboxPreloadManager( } /** - * Reset the preload manager. All sources that the preload manager is holding will be released. + * Resets the preload manager. All sources that the preload manager is holding will be released. * * @see DefaultPreloadManager.reset */ @@ -173,8 +174,15 @@ class PillarboxPreloadManager( } /** - * Default implementation of [TargetPreloadStatusControl] that will preload the first second of the `n ± 1` item, and the first half-second of - * the `n ± 2,3` item, where `n` is the index of the current item. + * Default implementation of [TargetPreloadStatusControl] that manages the preload status of items based on their proximity to the currently + * playing item. + * + * This implementation uses a simple distance-based strategy: + * - The item immediately before or after the current item (offset of 1) is preloaded to 1 second. + * - The items two or three positions away from the current item (offset of 2 or 3) are preloaded to 0.5 seconds. + * - All other items are not preloaded. + * + * This strategy aims to preload content that is likely to be played soon, reducing buffering and improving playback smoothness. */ @Suppress("MagicNumber") inner class DefaultTargetPreloadStatusControl : TargetPreloadStatusControl { diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxRenderersFactory.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxRenderersFactory.kt index ce58af8e2..e126ba61b 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxRenderersFactory.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxRenderersFactory.kt @@ -9,9 +9,10 @@ import androidx.media3.exoplayer.DefaultRenderersFactory import androidx.media3.exoplayer.RenderersFactory /** - * Preconfigured [RenderersFactory] for Pillarbox. + * Provides a pre-configured instance of [RenderersFactory] suitable for use within Pillarbox. * - * @param context The [Context] needed to create the [RenderersFactory]. + * @param context The [Context] required for initializing the [RenderersFactory]. + * @return A [RenderersFactory] ready for use within Pillarbox. */ @Suppress("FunctionName") fun PillarboxRenderersFactory(context: Context): RenderersFactory { diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxTrackSelector.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxTrackSelector.kt index c5a910278..206caab92 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxTrackSelector.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PillarboxTrackSelector.kt @@ -11,9 +11,10 @@ import androidx.media3.exoplayer.trackselection.TrackSelector import ch.srgssr.pillarbox.player.extension.setPreferredAudioRoleFlagsToAccessibilityManagerSettings /** - * Preconfigured [TrackSelector] for Pillarbox. + * Provides a pre-configured instance of [TrackSelector] suitable for use within Pillarbox. * - * @param context The [Context] needed to create the [TrackSelector]. + * @param context The [Context] required for initializing the [TrackSelector]. + * @return A [TrackSelector] ready for use within Pillarbox. */ @Suppress("FunctionName") fun PillarboxTrackSelector(context: Context): TrackSelector { diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PlayerCallbackFlow.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PlayerCallbackFlow.kt index 61e220619..75671a46e 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PlayerCallbackFlow.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PlayerCallbackFlow.kt @@ -44,7 +44,9 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds /** - * Playback state [Player.getPlaybackState] as flow. + * Collects the [playback state][Player.getPlaybackState] as a [Flow]. + * + * @return A [Flow] emitting the playback state. */ fun Player.playbackStateAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -57,7 +59,9 @@ fun Player.playbackStateAsFlow(): Flow = callbackFlow { } /** - * PlayerError [Player.getPlayerError] as Flow. + * Collects the [playback error][Player.getPlayerError] as a [Flow]. + * + * @return A [Flow] emitting the playback error. */ fun Player.playerErrorAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -70,7 +74,9 @@ fun Player.playerErrorAsFlow(): Flow = callbackFlow { } /** - * Is playing [Player.isPlaying] as Flow. + * Collects whether the player [is playing][Player.isPlaying] as a [Flow]. + * + * @return A [Flow] emitting whether the player is playing. */ fun Player.isPlayingAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -83,7 +89,9 @@ fun Player.isPlayingAsFlow(): Flow = callbackFlow { } /** - * Duration [Player.getDuration] as Flow. + * Collects the [duration][Player.getDuration] as a [Flow]. + * + * @return A [Flow] emitting the duration. */ fun Player.durationAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -102,7 +110,9 @@ fun Player.durationAsFlow(): Flow = callbackFlow { } /** - * Playback speed [Player.getPlaybackSpeed] as Flow. + * Collects the [playback speed][Player.getPlaybackSpeed] as a [Flow]. + * + * @return A [Flow] emitting the playback speed. */ fun Player.getPlaybackSpeedAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -115,7 +125,9 @@ fun Player.getPlaybackSpeedAsFlow(): Flow = callbackFlow { } /** - * Available commands [Player.getAvailableCommands] as Flow. + * Collects the [available commands][Player.getAvailableCommands] as a [Flow]. + * + * @return A [Flow] emitting the available commands. */ fun Player.availableCommandsAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -128,7 +140,9 @@ fun Player.availableCommandsAsFlow(): Flow = callbackFlow { } /** - * Shuffle mode enabled [Player.getShuffleModeEnabled] as Flow. + * Collects whether the [shuffle mode is enabled][Player.getShuffleModeEnabled] as a [Flow]. + * + * @return A [Flow] emitting whether the shuffle mode is enabled. */ fun Player.shuffleModeEnabledAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -141,7 +155,9 @@ fun Player.shuffleModeEnabledAsFlow(): Flow = callbackFlow { } /** - * Media item count [Player.getMediaItemCount] as Flow. + * Collects the [media item count][Player.getMediaItemCount] as a [Flow]. + * + * @return A [Flow] emitting the media item count. */ fun Player.mediaItemCountAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -160,8 +176,10 @@ fun Player.mediaItemCountAsFlow(): Flow = callbackFlow { } /** - * Ticker emits event every [interval] when [Player.isPlaying] is true. - * Emit a value once at least once. + * Emits an event every [interval] while the [Player] is playing. + * + * @param interval The time interval between emissions. + * @return A [Flow] that emits at the specified interval while the player is playing. */ @OptIn(ExperimentalCoroutinesApi::class) fun Player.tickerWhilePlayingAsFlow( @@ -174,8 +192,10 @@ fun Player.tickerWhilePlayingAsFlow( } /** - * Current position of the player updates every [updateInterval] when it is playing. - * Send current position once if not playing. + * Collects the [current position][Player.getCurrentPosition] of the player as a [Flow]. + * + * @param updateInterval The time interval between emissions, if the player is playing. + * @return A [Flow] emitting the current position of the player, in milliseconds. */ fun Player.currentPositionAsFlow(updateInterval: Duration = DefaultUpdateInterval): Flow = merge( @@ -200,9 +220,10 @@ private fun Player.positionChangedFlow(): Flow = callbackFlow { }.distinctUntilChanged() /** - * Current buffered percentage as flow [Player.getBufferedPercentage] + * Collects the [buffered percentage][Player.getBufferedPercentage] as a [Flow]. * - * @param updateInterval The update interval + * @param updateInterval The time interval between emissions, if the player is playing. + * @return A [Flow] emitting the buffered percentage. */ @Suppress("MagicNumber") fun Player.currentBufferedPercentageAsFlow( @@ -212,7 +233,9 @@ fun Player.currentBufferedPercentageAsFlow( } /** - * Current media metadata as flow [Player.getCurrentMediaItem] + * Collects the [current media item][Player.getCurrentMediaItem] as a [Flow]. + * + * @return A [Flow] emitting the current media item. */ fun Player.currentMediaItemAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -231,9 +254,10 @@ fun Player.currentMediaItemAsFlow(): Flow = callbackFlow { } /** - * Current media metadata as flow [Player.getMediaMetadata] + * Collects the [media metadata][Player.getMediaMetadata] as a [Flow]. * - * @param withPlaylistMediaMetadata try to listen [Player.Listener.onPlaylistMetadataChanged] too. + * @param withPlaylistMediaMetadata Whether to listen to [Player.Listener.onPlaylistMetadataChanged] too. + * @return A [Flow] emitting the media metadata. */ fun Player.currentMediaMetadataAsFlow(withPlaylistMediaMetadata: Boolean = false): Flow = callbackFlow { val listener = object : Listener { @@ -252,7 +276,9 @@ fun Player.currentMediaMetadataAsFlow(withPlaylistMediaMetadata: Boolean = false } /** - * Get current media item index as flow [Player.getCurrentMediaItemIndex] + * Collects the [current media item index][Player.getCurrentMediaItemIndex] as a [Flow]. + * + * @return A [Flow] emitting the current media item index. */ fun Player.getCurrentMediaItemIndexAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -271,7 +297,9 @@ fun Player.getCurrentMediaItemIndexAsFlow(): Flow = callbackFlow { } /** - * Get current media items as flow [Player.getCurrentMediaItems] + * Collects the [current media items][Player.getCurrentMediaItems] as a [Flow]. + * + * @return A [Flow] emitting the current media items. */ fun Player.getCurrentMediaItemsAsFlow(): Flow> = callbackFlow { val listener = object : Listener { @@ -284,7 +312,9 @@ fun Player.getCurrentMediaItemsAsFlow(): Flow> = callbackFlow { } /** - * Get video size as flow [Player.getVideoSize] + * Collects the [video size][Player.getVideoSize] as a [Flow]. + * + * @return A [Flow] emitting the video size. */ fun Player.videoSizeAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -297,9 +327,10 @@ fun Player.videoSizeAsFlow(): Flow = callbackFlow { } /** - * Get aspect ratio of the current video as [Flow]. + * Collects the aspect ratio of the current video as a [Flow]. * - * @param defaultAspectRatio The aspect ratio when the video size is unknown, or for audio content. + * @param defaultAspectRatio The default aspect ration when the video size is unknown, or the content is not a video. + * @return A [Flow] emitting the aspect ratio. */ fun Player.getAspectRatioAsFlow(defaultAspectRatio: Float): Flow { return combine( @@ -313,7 +344,9 @@ fun Player.getAspectRatioAsFlow(defaultAspectRatio: Float): Flow { } /** - * Get track selection parameters as flow [Player.getTrackSelectionParameters] + * Collects the [track selection parameters][Player.getTrackSelectionParameters] as a [Flow]. + * + * @return A [Flow] emitting the track selection parameters. */ fun Player.getTrackSelectionParametersAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -327,7 +360,9 @@ fun Player.getTrackSelectionParametersAsFlow(): Flow = } /** - * Get current tracks as flow [Player.getCurrentTracks] + * Collects the [current tracks][Player.getCurrentTracks] as a [Flow]. + * + * @return A [Flow] emitting the current tracks. */ fun Player.getCurrentTracksAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -340,7 +375,9 @@ fun Player.getCurrentTracksAsFlow(): Flow = callbackFlow { } /** - * Play when ready as flow [Player.getPlayWhenReady] + * Collects the [play when ready state][Player.getPlayWhenReady] as a [Flow]. + * + * @return A [Flow] emitting the play when ready state. */ fun Player.playWhenReadyAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -353,7 +390,9 @@ fun Player.playWhenReadyAsFlow(): Flow = callbackFlow { } /** - * @return `true` if current media item is a live stream. + * Collects whether the current media item [is a live stream][Player.isCurrentMediaItemLive] as a [Flow]. + * + * @return A [Flow] emitting whether the current media item is a live stream. */ fun Player.isCurrentMediaItemLiveAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -366,7 +405,9 @@ fun Player.isCurrentMediaItemLiveAsFlow(): Flow = callbackFlow { }.distinctUntilChanged() /** - * @return The current default position as flow. + * Collects the timeline's default position, in milliseconds, as a [Flow]. + * + * @return A [Flow] emitting the timeline's default position, in milliseconds. * @see Timeline.Window.getDefaultPositionMs */ fun Player.getCurrentDefaultPositionAsFlow(): Flow = callbackFlow { @@ -395,7 +436,9 @@ fun Player.getCurrentDefaultPositionAsFlow(): Flow = callbackFlow { }.distinctUntilChanged() /** - * @return Get the current chapter as flow, when the current chapter changes. + * Collects the [current chapter][Player.getChapterAtPosition] as a [Flow]. + * + * @return A [Flow] emitting the current chapter. */ fun Player.getCurrentChapterAsFlow(): Flow = callbackFlow { val listener = object : PillarboxPlayer.Listener { @@ -408,7 +451,9 @@ fun Player.getCurrentChapterAsFlow(): Flow = callbackFlow { } /** - * @return Get the current credit as flow, when the credit changes. + * Collects the [current credit][Player.getCreditAtPosition] as a [Flow]. + * + * @return A [Flow] emitting the current credit. */ fun Player.getCurrentCreditAsFlow(): Flow = callbackFlow { val listener = object : PillarboxPlayer.Listener { @@ -421,7 +466,9 @@ fun Player.getCurrentCreditAsFlow(): Flow = callbackFlow { } /** - * @return Get the current [PlaybackMetrics] as a [Flow]. + * Collects the [current playback metrics][PillarboxExoPlayer.getCurrentMetrics] as a [Flow]. + * + * @return A [Flow] emitting the current metrics. */ fun PillarboxExoPlayer.currentMetricsAsFlow(): Flow = callbackFlow { val listener = object : Listener { @@ -451,6 +498,6 @@ private fun Tracks.getVideoAspectRatioOrNull(): Float? { } /** - * Default update interval. + * The default interval between [Flow] emissions. */ val DefaultUpdateInterval = 1.seconds diff --git a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PreloadConfiguration.kt b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PreloadConfiguration.kt index 85a45ec53..ebdc67e5b 100644 --- a/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PreloadConfiguration.kt +++ b/pillarbox-player/src/main/java/ch/srgssr/pillarbox/player/PreloadConfiguration.kt @@ -9,8 +9,10 @@ import androidx.media3.exoplayer.ExoPlayer.PreloadConfiguration import kotlin.time.Duration /** - * @param targetPreloadDuration The target duration to preload or `null` to disable preloading. - * @return [PreloadConfiguration] + * Creates a [PreloadConfiguration] instance using a [Duration]. + * + * @param targetPreloadDuration The target duration to preload. If `null`, preloading will be disabled. + * @return A [PreloadConfiguration] instance with the specified preload duration. */ fun PreloadConfiguration(targetPreloadDuration: Duration?): PreloadConfiguration { return PreloadConfiguration(targetPreloadDuration?.inWholeMicroseconds ?: C.TIME_UNSET)