### Player State Configuration Example Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md A comprehensive example demonstrating how to configure the `VideoPlayerState`. This includes setting initial playback parameters, cache configurations, and other runtime options. ```kotlin val playerState = rememberVideoPlayerState( initialPlaybackParameters = PlaybackParameters( volume = 0.8f, speed = 1.2f ), cacheConfig = CacheConfig( maxCacheSize = 100 * 1024 * 1024, // 100 MB isMemoryCacheEnabled = true ), audioMode = AudioMode.Normal ) ``` -------------------------------- ### Usage Example for VideoPlayerSurfacePreview Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-composables.md Demonstrates how to use the VideoPlayerSurface composable within a preview function. This example shows a typical setup for previewing the player's UI. ```kotlin @Preview @Composable fun PlayerPreview() { VideoPlayerSurface( playerState = PreviewableVideoPlayerState(), modifier = Modifier.fillMaxSize() ) } ``` -------------------------------- ### Complete Video Player Example Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/quick-reference.md A comprehensive example demonstrating a full video player UI with controls, loading states, error handling, and various player configurations. ```kotlin @Composable fun FullPlayer() { val playerState = rememberVideoPlayerState() Column(modifier = Modifier.fillMaxSize()) { // Video surface with overlay Box( modifier = Modifier .weight(1f) .fillMaxWidth(), contentAlignment = Alignment.Center ) { VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), overlay = { Box(modifier = Modifier.fillMaxSize()) { // Controls Row( modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() .background(Color.Black.copy(alpha = 0.5f)) .padding(8.dp) ) { Button(onClick = { playerState.play() }) { Text("Play") } Button(onClick = { playerState.pause() }) { Text("Pause") } Text(playerState.positionText, color = Color.White) } } } ) if (playerState.isLoading) { CircularProgressIndicator() } } // Control panel Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) { // Play button Button(onClick = { playerState.openUri("http://example.com/video.mp4") }) { Text("Load Video") } // Volume slider Slider( value = playerState.volume, onValueChange = { playerState.volume = it }, valueRange = 0f..1f ) // Speed slider Slider( value = playerState.playbackSpeed, onValueChange = { playerState.playbackSpeed = it }, valueRange = 0.25f..2.0f ) // Loop toggle Checkbox( checked = playerState.loop, onCheckedChange = { playerState.loop = it } ) } // Error display playerState.error?.let { error -> Text( "Error: ${error.message}", color = Color.Red ) } } } ``` -------------------------------- ### SubtitleDisplay Usage Example Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-composables.md Demonstrates how to use the SubtitleDisplay composable with a predefined list of subtitle cues and a specific current playback time. ```kotlin import io.github.kdroidfilter.composemediaplayer.subtitle.SubtitleCue import io.github.kdroidfilter.composemediaplayer.subtitle.SubtitleCueList val cueList = SubtitleCueList(listOf( SubtitleCue(0, 5000, "First subtitle"), SubtitleCue(5000, 10000, "Second subtitle"), )) SubtitleDisplay( subtitles = cueList, currentTimeMs = 3000, // Displays "First subtitle" ) ``` -------------------------------- ### AudioMode Usage Examples Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Demonstrates different AudioMode configurations for exclusive focus, mixing, ducking, and ambient playback on iOS. ```kotlin // Exclusive audio focus (default) val playerState = rememberVideoPlayerState(audioMode = AudioMode()) ``` ```kotlin // Mix with other audio val playerState = rememberVideoPlayerState( audioMode = AudioMode(interruptionMode = InterruptionMode.MixWithOthers) ) ``` ```kotlin // Duck other audio val playerState = rememberVideoPlayerState( audioMode = AudioMode(interruptionMode = InterruptionMode.DuckOthers) ) ``` ```kotlin // Ambient mode on iOS val playerState = rememberVideoPlayerState( audioMode = AudioMode( interruptionMode = InterruptionMode.MixWithOthers, playsInSilentMode = false ) ) ``` -------------------------------- ### Complete Player Configuration and UI Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/configuration.md Use this example to initialize the player with custom audio and cache settings. It includes a UI for controlling volume, playback speed, subtitles, and looping. ```kotlin @Composable fun FullyConfiguredPlayer() { // Initialize with custom audio and cache settings val playerState = rememberVideoPlayerState( audioMode = AudioMode( interruptionMode = InterruptionMode.DuckOthers, playsInSilentMode = true ), cacheConfig = CacheConfig( enabled = true, maxCacheSizeBytes = 200L * 1024L * 1024L ) ) var selectedVideoUrl by remember { mutableStateOf("") } Column(modifier = Modifier.fillMaxSize()) { // Video surface with content scaling and subtitles Box( modifier = Modifier .weight(1f) .fillMaxWidth(), contentAlignment = Alignment.Center ) { VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop, overlay = { ComposeSubtitleLayer( currentTimeMs = (playerState.currentTime * 1000).toLong(), durationMs = (playerState.duration * 1000).toLong(), isPlaying = playerState.isPlaying, subtitleTrack = playerState.currentSubtitleTrack, subtitlesEnabled = playerState.subtitlesEnabled, textStyle = playerState.subtitleTextStyle, backgroundColor = playerState.subtitleBackgroundColor ) } ) } // Control panel Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) { // Volume control Row(verticalAlignment = Alignment.CenterVertically) { Text("Volume: ${(playerState.volume * 100).toInt()}%") Slider( value = playerState.volume, onValueChange = { playerState.volume = it }, valueRange = 0f..1f, modifier = Modifier.weight(1f).padding(8.dp) ) } // Speed control Row(verticalAlignment = Alignment.CenterVertically) { Text("Speed: ${String.format("%.2f", playerState.playbackSpeed)}x") Slider( value = playerState.playbackSpeed, onValueChange = { playerState.playbackSpeed = it }, valueRange = 0.25f..2.0f, modifier = Modifier.weight(1f).padding(8.dp) ) } // Subtitle toggle Row { Checkbox( checked = playerState.subtitlesEnabled, onCheckedChange = { playerState.subtitlesEnabled = it } ) Text("Subtitles") } // Loop toggle Row { Checkbox( checked = playerState.loop, onCheckedChange = { playerState.loop = it } ) Text("Loop") } } } } ``` -------------------------------- ### Usage Example for AutoUpdatingSubtitleDisplay Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-composables.md Demonstrates how to integrate the AutoUpdatingSubtitleDisplay composable within a media player UI. It shows how to obtain player state and subtitle cues to pass to the display. ```kotlin @Composable fun PlayerWithAutoUpdatingSubtitles() { val playerState = rememberVideoPlayerState() val cueList = remember { SubtitleCueList(...) } AutoUpdatingSubtitleDisplay( subtitles = cueList, currentTimeMs = (playerState.currentTime * 1000).toLong(), isPlaying = playerState.isPlaying, ) } ``` -------------------------------- ### Complete Video Player Implementation Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-surface.md This example demonstrates a full video player implementation using the VideoPlayerSurface. It includes custom controls for playback, subtitle selection, loading indicators, and error display. Use this as a reference for integrating the player into your application. ```kotlin import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Pause import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.Subtitles import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.google.android.exoplayer2.util.Log import com.kdroid.composemediaplayer.VideoPlayerSurface import com.kdroid.composemediaplayer.rememberVideoPlayerState @Composable fun CompleteVideoPlayer(initialUrl: String) { val playerState = rememberVideoPlayerState() var showSubtitleDialog by remember { mutableStateOf(false) } LaunchedEffect(initialUrl) { playerState.openUri(initialUrl) } Column(modifier = Modifier.fillMaxSize()) { Box( modifier = Modifier .weight(1f) .fillMaxWidth(), contentAlignment = Alignment.Center ) { VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop, overlay = { // Custom controls Box(modifier = Modifier.fillMaxSize()) { // Title Text( playerState.metadata.title ?: "Video Player", modifier = Modifier .align(Alignment.TopStart) .padding(16.dp), color = Color.White, fontSize = 20.sp ) // Playback controls Row( modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() .background(Color.Black.copy(alpha = 0.5f)) .padding(8.dp), horizontalArrangement = Arrangement.SpaceAround ) { IconButton(onClick = { playerState.play() }) { Icon(Icons.Default.PlayArrow, "Play", Color.White) } IconButton(onClick = { playerState.pause() }) { Icon(Icons.Default.Pause, "Pause", Color.White) } IconButton(onClick = { showSubtitleDialog = true }) { Icon(Icons.Default.Subtitles, "Subtitles", Color.White) } } } } ) // Loading indicator if (playerState.isLoading) { CircularProgressIndicator(color = Color.White) } } // Error display playerState.error?.let { Surface(color = Color.Red, modifier = Modifier.fillMaxWidth()) { Text( "Error: ${it.message}", color = Color.White, modifier = Modifier.padding(8.dp) ) } } } } ``` -------------------------------- ### Dynamic Subtitle Loading and Selection Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-composables.md Illustrates how to dynamically load and switch between different subtitle tracks based on user interaction. This example uses buttons to select subtitle languages and sources. ```kotlin import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import io.github.kdroidfilter.composemediaplayer.player.VideoPlayerSurface import io.github.kdroidfilter.composemediaplayer.player.rememberVideoPlayerState import io.github.kdroidfilter.composemediaplayer.subtitle.ComposeSubtitleLayer import io.github.kdroidfilter.composemediaplayer.subtitle.SubtitleTrack @Composable fun PlayerWithDynamicSubtitles() { val playerState = rememberVideoPlayerState() var selectedTrack by remember { mutableStateOf(null) } Column(modifier = Modifier.fillMaxSize()) { Box( modifier = Modifier .weight(1f) .fillMaxWidth(), contentAlignment = Alignment.Center ) { VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), overlay = { ComposeSubtitleLayer( currentTimeMs = (playerState.currentTime * 1000).toLong(), durationMs = (playerState.duration * 1000).toLong(), isPlaying = playerState.isPlaying, subtitleTrack = selectedTrack, subtitlesEnabled = selectedTrack != null, ) } ) } // Subtitle selection buttons Row(modifier = Modifier.fillMaxWidth().padding(8.dp)) { Button(onClick = { selectedTrack = SubtitleTrack( label = "English", language = "en", src = "https://example.com/en.vtt" ) }) { Text("English") } Button(onClick = { selectedTrack = SubtitleTrack( label = "Français", language = "fr", src = "https://example.com/fr.vtt" ) }) { Text("Français") } Button(onClick = { selectedTrack = null }) { Text("None") } } } } ``` -------------------------------- ### Basic Player Usage Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md A fundamental example of integrating the `VideoPlayerSurface` composable into your Jetpack Compose UI. This sets up a basic video player interface. ```kotlin @Composable fun BasicPlayer(playerState: VideoPlayerState) { VideoPlayerSurface(playerState = playerState) } ``` -------------------------------- ### Start or Resume Playback Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Use this method to begin or continue video playback. It's often used conditionally to avoid restarting playback if the video is already playing. ```kotlin fun play() ``` ```kotlin if (!playerState.isPlaying) playerState.play() ``` -------------------------------- ### Subtitle Cue List Example Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Demonstrates the `SubtitleCueList` which holds a collection of `SubtitleCue` objects. The `getActiveCues()` method is useful for retrieving cues that should be displayed at the current playback time. ```kotlin val cueList = SubtitleCueList(listOf(cue1, cue2)) val activeCues = cueList.getActiveCues(currentTimeMs) ``` -------------------------------- ### Player with Subtitles Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Example of integrating subtitle display with the video player. This involves using `ComposeSubtitleLayer` to render subtitles synchronized with the video playback. ```kotlin @Composable fun PlayerWithSubtitles(playerState: VideoPlayerState) { VideoPlayerSurface(playerState = playerState) { ComposeSubtitleLayer(playerState = playerState) } } ``` -------------------------------- ### Play Video from URL Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/README.MD Open and play a video directly from a URL. The video will automatically start playing by default, or can be kept paused initially. ```kotlin // Open a video and automatically start playing (default behavior) playerState.openUri("http://example.com/video.mp4") ``` ```kotlin // Open a video but keep it paused initially playerState.openUri("http://example.com/video.mp4", InitialPlayerState.PAUSE) ``` -------------------------------- ### Open Local File Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Opens a local video file using a `PlatformFile` object from FileKit. Playback can be set to auto-play or start paused. ```kotlin fun openFile( file: PlatformFile, initializeplayerState: InitialPlayerState = InitialPlayerState.PLAY, ) ``` ```kotlin val file = FileKit.openFilePicker(type = FileKitType.Video) file?.let { playerState.openFile(it) } ``` -------------------------------- ### Subtitle Cue Example Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Shows the structure of a `SubtitleCue`, representing a single subtitle entry with its timing and text content. The `isActive()` method helps determine if a cue is currently visible. ```kotlin val cue = SubtitleCue( startTimeMs = 5000, endTimeMs = 10000, text = "This is a subtitle cue." ) if (cue.isActive(currentTimeMs)) { // Display cue text } ``` -------------------------------- ### Play Video from Local File Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/README.MD Play a local video file using `FileKit` to open a file picker. The video can start playing automatically or remain paused. ```kotlin val file = FileKit.openFilePicker(type = FileKitType.Video) ``` ```kotlin // Open a file and automatically start playing (default behavior) file?.let { playerState.openFile(it) } ``` ```kotlin // Open a file but keep it paused initially file?.let { playerState.openFile(it, InitialPlayerState.PAUSE) } ``` -------------------------------- ### Basic Compose Media Player Integration Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/README.MD A minimal example of integrating the Compose Media Player into a Jetpack Compose application. Includes UI elements for video display, playback controls, and opening video URLs. ```kotlin @Composable fun App() { val playerState = rememberVideoPlayerState() MaterialTheme { Column(modifier = Modifier.fillMaxSize().padding(8.dp)) { // Video Surface Box( modifier = Modifier.weight(1f).fillMaxWidth(), contentAlignment = Alignment.Center ) { VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize() ) } Spacer(modifier = Modifier.height(8.dp)) // Playback Controls Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) { Button(onClick = { playerState.play() }) { Text("Play") } Button(onClick = { playerState.pause() }) { Text("Pause") } } Spacer(modifier = Modifier.height(8.dp)) // Open Video URL buttons Row( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() ) { Button( onClick = { val url = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" playerState.openUri(url) // Default: auto-play } ) { Text("Play Video") } Button( onClick = { val url = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" playerState.openUri(url, InitialPlayerState.PAUSE) // Open paused } ) { Text("Load Video Paused") } } Spacer(modifier = Modifier.height(8.dp)) // Volume Control Text("Volume: ${(playerState.volume * 100).toInt()}%") Slider( value = playerState.volume, onValueChange = { playerState.volume = it }, valueRange = 0f..1f ) } } } ``` -------------------------------- ### Handle Source Errors Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Provides an example of handling source-related errors, such as file not found (404) or access forbidden (403). This helps in gracefully informing the user about content access issues. ```kotlin val sourceError = SourceError.NotFound(url = "/video.mp4") when (sourceError) { is SourceError.NotFound -> { // Show "File not found" message } is SourceError.Forbidden -> { // Show "Access denied" message } else -> { // Show generic error } } ``` -------------------------------- ### PreviewableVideoPlayerState Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md A mock implementation of VideoPlayerState for use in previews and tests. It provides default values for all player state properties, simplifying the setup of UI components. ```kotlin data class PreviewableVideoPlayerState( override val hasMedia: Boolean = true, override val isPlaying: Boolean = true, override val isLoading: Boolean = false, override var volume: Float = 1f, override var sliderPos: Float = 500f, override var userDragging: Boolean = false, override var loop: Boolean = true, override var playbackSpeed: Float = 1f, override val positionText: String = "00:05", override val durationText: String = "00:10", override val currentTime: Double = 5000.0, override val duration: Double = 10.0, override var isFullscreen: Boolean = false, override val aspectRatio: Float = 1.7f, // ... other properties with defaults ) : VideoPlayerState ``` -------------------------------- ### Find GStreamer Packages Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/mediaplayer/src/jvmMain/native/linux/CMakeLists.txt Uses pkg-config to find the required GStreamer libraries and their include directories. Ensure GStreamer development files are installed. ```cmake # Find GStreamer via pkg-config find_package(PkgConfig REQUIRED) pkg_check_modules(GST REQUIRED gstreamer-1.0 gstreamer-app-1.0 gstreamer-video-1.0 ) ``` -------------------------------- ### Player Preview Composable Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md An example of how to use PreviewableVideoPlayerState within a Composable function to render a preview of the VideoPlayerSurface. This allows for easy visualization of the player's UI with specific states. ```kotlin @Preview @Composable fun PlayerPreview() { VideoPlayerSurface( playerState = PreviewableVideoPlayerState( isPlaying = true, positionText = "01:23" ) ) } ``` -------------------------------- ### Configure Audio Mode Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md Customize audio behavior using `AudioMode`. This example sets the interruption mode to `DuckOthers` and disables playback in silent mode. ```kotlin rememberVideoPlayerState( audioMode = AudioMode( interruptionMode = InterruptionMode.DuckOthers, playsInSilentMode = false ) ) ``` -------------------------------- ### Player with Codec Error Handling Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/errors.md Demonstrates how to display a user-friendly message when a `CodecError` occurs during video playback. This example shows conditional UI rendering based on the error type. ```kotlin @Composable fun PlayerWithErrorHandling() { val playerState = rememberVideoPlayerState() Box(modifier = Modifier.fillMaxSize()) { VideoPlayerSurface(playerState = playerState) playerState.error?.let { error -> when (error) { is VideoPlayerError.CodecError -> { Surface( color = Color.Red, modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() ) { Text( "Codec not supported: ${error.message}", color = Color.White, modifier = Modifier.padding(16.dp) ) } } else -> {} } } } } ``` -------------------------------- ### Define Initial Player State Enum Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Use this enum to specify whether the media player should start playing or remain paused upon opening a media file or URI. Defaults to PLAY. ```kotlin enum class InitialPlayerState { PLAY, PAUSE, } ``` -------------------------------- ### Get Fullscreen Status Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Retrieve the current fullscreen status of the player. This is a read-only property. ```kotlin var isFullscreen: Boolean ``` -------------------------------- ### Get Total Media Duration in Seconds Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Retrieves the total duration of the video in seconds. ```kotlin val duration: Double ``` -------------------------------- ### Get Current Playback Time in Seconds Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Retrieves the current playback position of the video in seconds. ```kotlin val currentTime: Double ``` -------------------------------- ### Create and Select Subtitle Tracks Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Shows how to instantiate `SubtitleTrack` objects for different languages and how to select a track for display or disable subtitles entirely. ```kotlin val englishTrack = SubtitleTrack( label = "English", language = "en", src = "https://example.com/subtitles-en.vtt" ) val frenchTrack = SubtitleTrack( label = "Français", language = "fr", src = "https://example.com/subtitles-fr.srt" ) // Select a subtitle track playerState.selectSubtitleTrack(englishTrack) // Disable subtitles playerState.disableSubtitles() // or selectSubtitleTrack(null) ``` -------------------------------- ### Get Picture-in-Picture Active Status Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Check if the player is currently active in Picture-in-Picture (PiP) mode. This is a read-only property. ```kotlin var isPipActive: Boolean ``` -------------------------------- ### Playback Control Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md Offers a set of functions to control the playback of the media. These include starting, stopping, pausing, and seeking. ```APIDOC ## Playback Control ### `play()` **Description**: Starts or resumes playback of the media. ### `pause()` **Description**: Pauses the current playback. ### `stop()` **Description**: Stops the playback and resets the player to the beginning. ### `restart()` **Description**: Stops the current playback and immediately restarts it from the beginning. ### `seekTo(value)` **Description**: Seeks to a specific position in the media. `value` should be a time in milliseconds. ### `seekStart(value)` **Description**: Seeks to a position relative to the start of the media. `value` should be a time in milliseconds. ### `seekFinished()` **Description**: Seeks to the end of the media. ``` -------------------------------- ### State Flow Initialization Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md Illustrates the initialization of the `VideoPlayerState` and its platform-specific implementation, leading to various playback states and features. ```kotlin rememberVideoPlayerState() └── Platform-specific implementation (Android: DefaultVideoPlayerState) ├── ExoPlayer / AVPlayer / Media Foundation / GStreamer ├── Playback state (isPlaying, volume, speed, etc.) ├── Media metadata (duration, resolution, etc.) ├── Subtitle management └── Error handling ``` -------------------------------- ### Open Media Source Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Shows how to open media from different sources like URIs, files, or assets using the video player's state. Ensure the correct `InitialPlayerState` is used to control whether playback begins immediately. ```kotlin playerState.openUri("https://example.com/media.mp4") playerState.openFile("/path/to/local/media.mp4") playerState.openAsset("assets/media.mp4", InitialPlayerState.PLAY) ``` -------------------------------- ### Open Media with Initial Player State Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Demonstrates how to open media files, URIs, or assets with a specified initial playback state. The default behavior is to auto-play. ```kotlin // Auto-play (default) playerState.openUri("http://example.com/video.mp4") // Equivalent to: playerState.openUri("http://example.com/video.mp4", InitialPlayerState.PLAY) // Open paused playerState.openUri("http://example.com/video.mp4", InitialPlayerState.PAUSE) // Same for openFile and openAsset playerState.openFile(file, InitialPlayerState.PAUSE) playerState.openAsset("video.mp4", InitialPlayerState.PAUSE) ``` -------------------------------- ### Get Video Aspect Ratio Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Retrieve the aspect ratio of the video content. This is a read-only property used for scaling calculations. ```kotlin val aspectRatio: Float ``` -------------------------------- ### Get Formatted Total Media Duration Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Retrieves the total duration of the video formatted as a human-readable string, such as '00:10' or '01:30:00'. ```kotlin val durationText: String ``` -------------------------------- ### Create a Video Player Instance Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/quick-reference.md Use `rememberVideoPlayerState` to create and remember the player's state within a composable. Then, attach the state to `VideoPlayerSurface` to render the video. ```kotlin import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview @Composable fun MyPlayer() { val playerState = rememberVideoPlayerState() VideoPlayerSurface(playerState = playerState) } ``` -------------------------------- ### Get Formatted Current Playback Position Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Retrieves the current playback position formatted as a human-readable string, such as '00:05' or '01:23:45'. ```kotlin val positionText: String ``` -------------------------------- ### Quick Reference Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md A concise overview of common API patterns, properties, methods, and constants. ```APIDOC ## Quick Reference API ### Description Provides a quick lookup for common API elements and usage patterns. ### Contents - Common API patterns. - Properties and methods at a glance. - Constants and enums. - A complete minimal example. ### Related Files - `[quick-reference.md](./quick-reference.md)` ``` -------------------------------- ### Get Current Video Player Error Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Retrieves the current error state of the video player. Returns null if no error has occurred. ```kotlin val error: VideoPlayerError? ``` -------------------------------- ### Commit User-Driven Seek Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Finalizes a seek operation that was started with seekStart(). This performs the actual seek on the player and ends the user-dragging state. ```kotlin fun seekFinished() ``` -------------------------------- ### Basic Video Player in Jetpack Compose Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md Demonstrates how to create a simple video player with a play button. Use `rememberVideoPlayerState()` for automatic resource management within Composables. ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.Row import androidx.compose.ui.Alignment @Composable fun SimplePlayer() { val playerState = rememberVideoPlayerState() Column(modifier = Modifier.fillMaxSize()) { VideoPlayerSurface( playerState = playerState, modifier = Modifier.weight(1f).fillMaxWidth() ) Button(onClick = { playerState.openUri("http://example.com/video.mp4") }) { Text("Play") } } } ``` -------------------------------- ### Video Player Surface with Content Scaling Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-surface.md Demonstrates how to use the contentScale parameter to control how the video fits the surface. Use ContentScale.Crop to fill the surface and allow cropping, or other options like ContentScale.Fit. ```kotlin @Composable fun ScaledPlayer() { val playerState = rememberVideoPlayerState() VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop // Fill surface, allow cropping ) } ``` -------------------------------- ### Define SubtitleCue Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Represents a single subtitle cue with start and end times, and the text content. Use this for individual subtitle entries. ```kotlin @Immutable data class SubtitleCue( val startTime: Long, val endTime: Long, val text: String, ) { fun isActive(currentTimeMs: Long): Boolean } ``` -------------------------------- ### Usage of VideoMetadata fields Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Demonstrates how to access and print various metadata fields. Use ?.let to safely handle nullable values. ```kotlin val metadata = playerState.metadata metadata.title?.let { println("Title: $it") } metadata.duration?.let { println("Duration: ${it}ms") } metadata.width?.let { w -> metadata.height?.let { h -> println("Resolution: ${w}x${h}") } } metadata.bitrate?.let { println("Bitrate: ${it}bps") } metadata.frameRate?.let { println("Frame Rate: ${it}fps") } metadata.mimeType?.let { println("MIME Type: $it") } metadata.audioChannels?.let { println("Audio Channels: $it") } metadata.audioSampleRate?.let { println("Sample Rate: ${it}Hz") } ``` -------------------------------- ### Video Player with Playback Controls Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md Shows how to implement a video player with integrated playback controls (play, pause) and a time display. The overlay parameter allows custom UI elements to be placed on top of the video surface. ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.Row import androidx.compose.ui.Alignment @Composable fun PlayerWithControls() { val playerState = rememberVideoPlayerState() VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), overlay = { Row( modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() .padding(8.dp) ) { Button(onClick = { playerState.play() }) { Text("Play") } Button(onClick = { playerState.pause() }) { Text("Pause") } Text("${playerState.positionText} / ${playerState.durationText}") } } ) } ``` -------------------------------- ### Open Media from Various Sources Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/quick-reference.md Open media from a URL, local file, or app assets using the `openUri`, `openFile`, or `openAsset` methods. You can also specify an initial playback state like `PAUSE` when opening from a URL. ```kotlin // From URL playerState.openUri("http://example.com/video.mp4") // From URL, start paused playerState.openUri("http://example.com/video.mp4", InitialPlayerState.PAUSE) // From local file playerState.openFile(platformFile) // From app assets playerState.openAsset("video.mp4") ``` -------------------------------- ### Validate URL Format Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/errors.md Check if a URL string starts with a valid scheme before attempting to open it. This prevents errors caused by malformed URIs. ```kotlin fun isValidUrl(url: String): Boolean = url.startsWith("http://") || url.startsWith("https://") || url.startsWith("asset://") || url.startsWith("file://") ``` -------------------------------- ### ContentScale Options for VideoPlayerSurface Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Demonstrates different `ContentScale` options for the `VideoPlayerSurface`. This controls how the video is scaled and fitted within the surface bounds. ```kotlin VideoPlayerSurface( state = playerState, contentScale = ContentScale.Crop // Options: Fit, FillBounds, Crop, etc. ) ``` -------------------------------- ### Initial Player State Constants Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/quick-reference.md Specifies the initial playback state of the player when it is opened. ```kotlin InitialPlayerState.PLAY // Auto-play after opening InitialPlayerState.PAUSE // Start paused ``` -------------------------------- ### Compose Media Player Properties Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/quick-reference.md This section lists the properties of the Compose Media Player, indicating their type, and whether they are readable (Get) or writable (Set). ```APIDOC ## Properties This section details the properties available for the Compose Media Player. ### Property List | Property | Type | Get | Set | |---|---|---|---| | hasMedia | Boolean | ✓ | — | | isPlaying | Boolean | ✓ | — | | isLoading | Boolean | ✓ | — | | volume | Float | ✓ | ✓ | | playbackSpeed | Float | ✓ | ✓ | | loop | Boolean | ✓ | ✓ | | sliderPos | Float | ✓ | ✓ | | userDragging | Boolean | ✓ | ✓ | | currentTime | Double | ✓ | — | | duration | Double | ✓ | — | | positionText | String | ✓ | — | | durationText | String | ✓ | — | | error | VideoPlayerError? | ✓ | — | | metadata | VideoMetadata | ✓ | — | | isFullscreen | Boolean | ✓ | ✓ | | aspectRatio | Float | ✓ | — | | isPipSupported | Boolean | ✓ | — | | isPipActive | Boolean | ✓ | ✓ | | isPipEnabled | Boolean | ✓ | ✓ | | subtitlesEnabled | Boolean | ✓ | ✓ | | currentSubtitleTrack | SubtitleTrack? | ✓ | — | | subtitleTextStyle | TextStyle | ✓ | ✓ | | subtitleBackgroundColor | Color | ✓ | ✓ | ``` -------------------------------- ### Player with Custom Overlay Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Demonstrates how to add a custom overlay on top of the video player using the `VideoPlayerSurface`. This is useful for displaying custom controls or information. ```kotlin @Composable fun PlayerWithOverlay(playerState: VideoPlayerState) { VideoPlayerSurface(playerState = playerState) { // Custom overlay content here CustomControls(playerState = playerState) } } ``` -------------------------------- ### Configuration Options Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md Various configuration settings to customize player behavior, such as audio handling, caching, content scaling, and surface types. ```APIDOC ## Configuration ### `AudioMode` **Description**: Defines the behavior of the player regarding audio interruptions. This is applicable only on Android and iOS platforms. ### `CacheConfig` **Description**: Configures the video caching mechanism to improve playback performance and reduce network usage. This is applicable only on Android and iOS platforms. ### `ContentScale` **Description**: Specifies how the video content should be scaled to fit the player surface. Options include `Fit`, `Crop`, `FillBounds`, `Inside`, and `None`. ### `SurfaceType` **Description**: Determines the type of surface used for rendering video. Options are `TextureView` or `SurfaceView`, applicable only on Android. ``` -------------------------------- ### seekStart Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Initiates a user-driven seek interaction, updating the visual position without committing the seek. ```APIDOC ## seekStart ### Description Begins a user-driven seek interaction (e.g., slider drag). Updates the visual slider position without performing the actual seek on the player. Must be followed by `seekFinished()` to commit the seek. ### Method ```kotlin fun seekStart(value: Float) ``` ### Parameters #### Path Parameters - **value** (Float) - Required - The target seek position (0.0–1000.0) ### Request Example ```kotlin Slider( value = playerState.sliderPos, onValueChange = { playerState.seekStart(it) }, onValueChangeFinished = { playerState.seekFinished() }, valueRange = 0f..1000f ) ``` ``` -------------------------------- ### Get Current Playback Position (Normalized) Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Access the current playback position as a normalized value between 0.0 and 1000.0. Use seek functions to modify this value. ```kotlin var sliderPos: Float ``` -------------------------------- ### Get Active Cues from SubtitleCueList Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Returns all subtitle cues from the list that should be displayed at the given time. Useful for rendering subtitles based on the current playback position. ```kotlin fun getActiveCues(currentTimeMs: Long): List ``` -------------------------------- ### Video Player Surface with Custom Overlay UI Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-surface.md Shows how to add a custom overlay to the VideoPlayerSurface, including playback controls and a fullscreen button. The overlay composable receives the player state for interaction. ```kotlin @Composable fun PlayerWithControls() { val playerState = rememberVideoPlayerState() VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), overlay = { Box(modifier = Modifier.fillMaxSize()) { // Custom controls at bottom Row( modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() .background(Color.Black.copy(alpha = 0.5f)) .padding(8.dp), horizontalArrangement = Arrangement.SpaceBetween ) { Button(onClick = { playerState.play() }) { Text("Play") } Button(onClick = { playerState.pause() }) { Text("Pause") } Text(playerState.positionText, color = Color.White) } // Fullscreen button at top-right if (playerState.isFullscreen) { IconButton( onClick = { playerState.toggleFullscreen() }, modifier = Modifier.align(Alignment.TopEnd).padding(16.dp) ) { Icon( imageVector = Icons.Default.FullscreenExit, contentDescription = "Exit Fullscreen", tint = Color.White ) } } } } ) } ``` -------------------------------- ### Cache Configuration Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/INDEX.md Shows how to configure caching behavior for media playback using `CacheConfig`. This allows specifying cache size and other related parameters. ```kotlin val cacheConfig = CacheConfig( maxCacheSize = 1024 * 1024 * 100L // 100 MB ) // Apply cacheConfig to player initialization or state ``` -------------------------------- ### Configure Video Caching Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/README.md Set up video caching by providing a `CacheConfig` to `rememberVideoPlayerState`. This enables caching and specifies the maximum cache size in bytes. ```kotlin rememberVideoPlayerState( cacheConfig = CacheConfig( enabled = true, maxCacheSizeBytes = 200L * 1024L * 1024L ) ) ``` -------------------------------- ### VideoPlayerSurface with Custom Overlay Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/configuration.md Demonstrates how to provide a custom composable function to the 'overlay' parameter for adding custom UI elements like controls, loading indicators, or subtitles. ```kotlin VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), overlay = { // Custom overlay content Box(modifier = Modifier.fillMaxSize()) { // Always visible, even in fullscreen CustomControls(playerState = playerState) LoadingIndicator(playerState = playerState) SubtitleDisplay(playerState = playerState) } } ) ``` -------------------------------- ### Compose Video Player with Subtitles Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-surface.md Demonstrates how to integrate subtitles with the VideoPlayerSurface using Compose. Ensure playerState is properly managed and passed to ComposeSubtitleLayer. ```kotlin import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.viewinterop.AndroidView @Composable fun PlayerWithSubtitles() { val playerState = rememberVideoPlayerState() Box(modifier = Modifier.fillMaxSize()) { VideoPlayerSurface( playerState = playerState, modifier = Modifier.fillMaxSize(), overlay = { ComposeSubtitleLayer( currentTimeMs = (playerState.currentTime * 1000).toLong(), durationMs = (playerState.duration * 1000).toLong(), isPlaying = playerState.isPlaying, subtitleTrack = playerState.currentSubtitleTrack, subtitlesEnabled = playerState.subtitlesEnabled, modifier = Modifier.fillMaxSize(), textStyle = playerState.subtitleTextStyle, backgroundColor = playerState.subtitleBackgroundColor ) } ) } } ``` -------------------------------- ### Check SubtitleCue Activity Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/types.md Checks if a subtitle cue is active at a given time. The cue is considered active if the current time falls within its start and end times (inclusive). ```kotlin fun isActive(currentTimeMs: Long): Boolean ``` -------------------------------- ### Compose UI with UnknownError Handling Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/errors.md Demonstrates how to display a Snackbar with a user-friendly message when an UnknownError occurs. Includes a dismiss action and logging for debugging. ```kotlin @Composable fun PlayerWithGenericErrorHandling() { val playerState = rememberVideoPlayerState() Box(modifier = Modifier.fillMaxSize()) { VideoPlayerSurface(playerState = playerState) playerState.error?.let { error -> if (error is VideoPlayerError.UnknownError) { // Log for debugging LaunchedEffect(error) { println("Unknown error occurred: ${error.message}") // Could send to crash reporting service } Snackbar( modifier = Modifier .align(Alignment.BottomCenter) .padding(16.dp), action = { Button(onClick = { playerState.clearError() }) { Text("Dismiss") } } ) { Text("An unexpected error occurred. Please try again.") } } } } } ``` -------------------------------- ### Filter Subtitles by Time Range Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/subtitle-parsing.md Filters a list of subtitle cues to include only those that fall completely within a specified start and end time in milliseconds. Returns a new `SubtitleCueList`. ```kotlin fun filterSubtitlesByRange( cueList: SubtitleCueList, startMs: Long, endMs: Long ): SubtitleCueList { val filtered = cueList.cues.filter { it.startTime >= startMs && it.endTime <= endMs } return SubtitleCueList(filtered) } ``` -------------------------------- ### Configure Minimal Cache for Low-End Devices Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/configuration.md Set up a minimal cache with a maximum size of 25 MB for low-end devices. ```kotlin val playerState = rememberVideoPlayerState( cacheConfig = CacheConfig( enabled = true, maxCacheSizeBytes = 25L * 1024L * 1024L // 25 MB ) ) ``` -------------------------------- ### Open Application Asset Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Opens a media file bundled within the application. This method is supported on Android and iOS. It may throw an `UnsupportedOperationException` on platforms that do not support asset loading. ```kotlin fun openAsset( fileName: String, initializeplayerState: InitialPlayerState = InitialPlayerState.PLAY, ): Unit ``` -------------------------------- ### createVideoPlayerState Source: https://github.com/kdroidfilter/composemediaplayer/blob/master/_autodocs/api-reference-video-player-state.md Creates a platform-specific video player state instance. This function is an `expect` declaration, returning the appropriate implementation for the current platform. Manual lifecycle management is required when used outside a Composable. ```APIDOC ## createVideoPlayerState ### Description Creates a platform-specific video player state instance. This is a platform-specific expect function that returns the appropriate implementation for the current platform (Android, iOS, macOS, Windows, Linux, or Web). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```kotlin val state = createVideoPlayerState() try { state.openUri("http://example.com/video.mp4") } finally { state.dispose() } ``` ### Response #### Success Response - **playerState** (`VideoPlayerState`) - A platform-specific implementation of `VideoPlayerState`. #### Response Example None explicitly provided in source, but the return type is `VideoPlayerState`. ### Note Manual lifecycle management is required when using this function outside a Composable. Always call `dispose()` when done. ```