{"id":25510083,"url":"https://github.com/kdroidFilter/ComposeMediaPlayer","last_synced_at":"2025-11-23T02:30:14.835Z","repository":{"id":272879584,"uuid":"918046791","full_name":"kdroidFilter/ComposeMediaPlayer","owner":"kdroidFilter","description":"Compose Media Player is a video player library designed for Compose Multiplatform, supporting multiple platforms including Android, macOS, Windows, and Linux.","archived":false,"fork":false,"pushed_at":"2025-02-11T10:45:13.000Z","size":7711,"stargazers_count":67,"open_issues_count":6,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-11T11:35:02.492Z","etag":null,"topics":["android","audio-visualization","compose-multiplatform","customizable-ui","jetpack-compose","kotlin","linux","macos","media-controls","multiplatform","open-source","video-player","windows"],"latest_commit_sha":null,"homepage":"https://kdroidfilter.github.io/ComposeMediaPlayer/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kdroidFilter.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-17T06:29:26.000Z","updated_at":"2025-02-11T10:45:11.000Z","dependencies_parsed_at":"2025-01-17T07:29:07.682Z","dependency_job_id":"44511cfd-eadc-425e-bf50-4358fbf5ae42","html_url":"https://github.com/kdroidFilter/ComposeMediaPlayer","commit_stats":null,"previous_names":["kdroidfilter/compose-media-player","kdroidfilter/composemediaplayer"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdroidFilter%2FComposeMediaPlayer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdroidFilter%2FComposeMediaPlayer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdroidFilter%2FComposeMediaPlayer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kdroidFilter%2FComposeMediaPlayer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kdroidFilter","download_url":"https://codeload.github.com/kdroidFilter/ComposeMediaPlayer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239627234,"owners_count":19670844,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","audio-visualization","compose-multiplatform","customizable-ui","jetpack-compose","kotlin","linux","macos","media-controls","multiplatform","open-source","video-player","windows"],"created_at":"2025-02-19T09:07:20.240Z","updated_at":"2025-11-23T02:30:14.764Z","avatar_url":"https://github.com/kdroidFilter.png","language":"Kotlin","readme":"# 🎥 Compose Media Player\n\n**Compose Media Player** is a video player library designed for Compose Multiplatform, supporting multiple platforms including Android, macOS, Windows, and Linux. It is the first fully functional multiplatform video player for Compose for Desktop that requires no additional software installations. The library leverages:\n\n- **GStreamer** for Linux\n- **MFPlayer** for Windows\n- **JavaFX** for macOS\n- **Media3** for Android\n\n## 🚀 Live Demo\n\nTry the online demo here : [🎥 Live Demo](https://kdroidfilter.github.io/ComposeMediaPlayer/sample/)\n\n## ✨ Features\n\n- **Multiplatform Support**: Works seamlessly on Android, macOS, Windows, Linux and Compose Web (Wasm).\n- **File and URL Support**: Play videos from local files or directly from URLs.\n- **Media Controls**: Includes play, pause, loop toggle, volume control, loop playback and timeline slider.\n- **Custom Video Player UI**: Fully customizable using Compose Multiplatform.\n- **Audio Levels**: Displays left and right audio levels in real time.\n- **Error handling** Simple error handling for network or playback issues.\n\n## ✨ Supported Formats\n\n| Video Format | Windows | macOS | Linux | Android |\n|--------------|---------|-------|-------|---------|\n| MP4 (H.264)  | ✅       | ✅     | ✅     | ✅       |\n| AVI          | ✅       | ❌     | ✅     | ✅       |\n| MKV          | ?       | ?     | ?     | ?       |\n| MOV          | ✅       | ❌     | ✅     | ?       |\n| FLV          | ?       | ?     | ?     | ?       |\n| WEBM         | ?       | ?     | ?     | ?       |\n| WMV          | ✅       | ?     | ?     | ?       |\n| 3GP          | ?       | ?     | ?     | ?       |\n\n\n## 🔧 Installation\n\nTo add Compose Media Player to your project, include the following dependency in your `build.gradle.kts` file:\n\n```kotlin\ndependencies {\n    implementation(\"io.github.kdroidfilter:composemediaplayer:0.3.0\")\n}\n```\n\n\u003e [!IMPORTANT]\n\u003eIt is necessary (for now) to add the following Maven repository to your dependencies because Compose Media Player relies on a snapshot version of the [FileKt core](https://github.com/vinceglb/FileKit/tree/main/filekit-core):\n\n```kotlin\nrepositories {\n    maven(\"https://s01.oss.sonatype.org/content/repositories/snapshots/\")\n}\n```\n\nFor more information, visit: [FileKt on GitHub](https://github.com/vinceglb/FileKit/)\n\n\u003e [!IMPORTANT]\n\u003e Currently, you also need to manually include JavaFX dependencies if your application is also intended for macOS.\n\n```kotlin\nval osName = System.getProperty(\"os.name\").lowercase(Locale.getDefault())\nval osArch = System.getProperty(\"os.arch\").lowercase(Locale.getDefault())\n\nval javafxVersion = \"22.0.1\"\n\njvmMain.dependencies {\n    implementation(compose.desktop.currentOs)\n    if (osName.contains(\"mac\")) {\n        val macClassifier = if (osArch.contains(\"aarch64\")) \"mac-aarch64\" else \"mac\"\n        implementation(\"org.openjfx:javafx-base:${javafxVersion}:${macClassifier}\")\n        implementation(\"org.openjfx:javafx-graphics:${javafxVersion}:${macClassifier}\")\n        implementation(\"org.openjfx:javafx-swing:${javafxVersion}:${macClassifier}\")\n        implementation(\"org.openjfx:javafx-media:${javafxVersion}:${macClassifier}\")\n    }\n}\n```\n\n\u003e [!WARNING]\n\u003e JavaFX Warning on macOS: A warning message may appear during runtime:\n\n  ```\n  Jan 20, 2025 7:24:02 AM com.sun.javafx.application.PlatformImpl startup\n  WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @367d4c06'\n  ```\n\nThis warning does not appear to cause any functional issues but is under investigation.\n\n## 🚀 Getting Started\n\n### Initialization\n\nBefore using Compose Media Player, you need to create a state for the video player using the `rememberVideoPlayerState` function:\n\n```kotlin\nval playerState = rememberVideoPlayerState()\n```\n\n### Displaying the Video Surface\n\nAfter initializing the player state, you can display the surface of the video using `VideoPlayerSurface`:\n\n```kotlin\n// Video Surface\nBox(\n    modifier = Modifier.weight(1f).fillMaxWidth(),\n    contentAlignment = Alignment.Center\n) {\n    VideoPlayerSurface(\n        playerState = playerState,\n        modifier = Modifier.fillMaxSize()\n    )\n}\n```\n\n### Video Playback via URL or Local Files\n\nYou can play a video by providing a direct URL:\n\n```kotlin\nplayerState.openUri(\"http://example.com/video.mp4\")\n```\n\nTo play a local video file, please refer to [example](sample/composeApp/src/commonMain/kotlin/sample/app/App.kt) using [FileKt](https://github.com/vinceglb/FileKit).\n\n\n### Full Controls\n\n- **Play and Pause**:\n\nYou can detect the current playback state via `playerState.isPlaying` and configure a Play/Pause button as follows:\n\n```kotlin\nButton(onClick = {\n    if (playerState.isPlaying) {\n        playerState.pause()\n        println(\"Playback paused\")\n    } else {\n        playerState.play()\n        println(\"Playback started\")\n    }\n}) {\n    Text(if (playerState.isPlaying) \"Pause\" else \"Play\")\n}\n```\n\n- **Stop**:\n\n```kotlin\nplayerState.stop()\nprintln(\"Playback stopped\")\n```\n\n- **Volume**:\n\n```kotlin\nplayerState.volume = 0.5f // Set volume to 50%\nprintln(\"Volume set to 50%\")\n```\n\n- **Loop Playback**:\n\n```kotlin\nplayerState.loop = true // Enable loop playback\nprintln(\"Loop playback enabled\")\n```\n\n### Progress Indicators\n\nTo display and control playback progress:\n\n```kotlin\nSlider(\n    value = playerState.sliderPos,\n    onValueChange = {\n        playerState.sliderPos = it\n        playerState.userDragging = true\n        println(\"Position changed: $it\")\n    },\n    onValueChangeFinished = {\n        playerState.userDragging = false\n        playerState.seekTo(playerState.sliderPos)\n        println(\"Position finalized: ${playerState.sliderPos}\")\n    },\n    valueRange = 0f..1000f\n)\n```\n\n### Display Left and Right Volume Levels\n\nTo display audio levels:\n\n```kotlin\nprintln(\"Left level: ${playerState.leftLevel.toInt()}%, Right level: ${playerState.rightLevel.toInt()}%\")\n```\n\n### Error Handling\n\nIn case of an error, you can display it using `println`:\n\n```kotlin\nplayerState.error?.let { error -\u003e\n    println(\"Error detected: ${error.message}\")\n    playerState.clearError()\n}\n```\n\n### Loadind Indicator\n\nTo detect if the video is buffering:\n\n```kotlin \nif (playerState.isLoading) {\n    CircularProgressIndicator()\n}\n````\n\u003e [!IMPORTANT]\n\u003e This feature is actually on Beta, so it may not work as expected. It's not actually work on Windows and MacOS.\n\n### Using Subtitles\n\nCompose Media Player supports adding subtitles from both URLs and local files. \n\u003e [!IMPORTANT]\n\u003e This feature is actually not supported on Windows and Mac.\n\n#### 🎯 Adding Subtitles from url or local file\n\nYou can add subtitles by specifying a URL:\n\n```kotlin\nval track = SubtitleTrack(\n    label = \"English Subtitles\",\n    language = \"en\",\n    src = \"https://example.com/subtitles.vtt\"\n)\nplayerState.selectSubtitleTrack(track)\n```\n\n#### ❌ Disabling Subtitles\n\nTo disable subtitles:\n\n```kotlin\nplayerState.disableSubtitles()\n```\n\n\n### 📋 Basic Example\n\nHere is a minimal example of how to integrate the Compose Media Player into your Compose application with a hardcoded URL:\n\n```kotlin\n@Composable\nfun App() {\n    val playerState = rememberVideoPlayerState()\n\n    MaterialTheme {\n        Column(modifier = Modifier.fillMaxSize().padding(8.dp)) {\n\n            // Video Surface\n            Box(\n                modifier = Modifier.weight(1f).fillMaxWidth(),\n                contentAlignment = Alignment.Center\n            ) {\n                VideoPlayerSurface(\n                    playerState = playerState,\n                    modifier = Modifier.fillMaxSize()\n                )\n            }\n\n            Spacer(modifier = Modifier.height(8.dp))\n\n            // Playback Controls\n            Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {\n                Button(onClick = { playerState.play() }) { Text(\"Play\") }\n                Button(onClick = { playerState.pause() }) { Text(\"Pause\") }\n            }\n\n            Spacer(modifier = Modifier.height(8.dp))\n\n            // Open Video URL\n            Button(\n                onClick = {\n                    val url = \"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4\"\n                    playerState.openUri(url)\n                }\n            ) {\n                Text(\"Open Video\")\n            }\n\n            Spacer(modifier = Modifier.height(8.dp))\n\n            // Volume Control\n            Text(\"Volume: ${(playerState.volume * 100).toInt()}%\")\n            Slider(\n                value = playerState.volume,\n                onValueChange = { playerState.volume = it },\n                valueRange = 0f..1f\n            )\n        }\n    }\n}\n```\n\n## 📄 License\n\nCompose Media Player is licensed under the MIT License. See [LICENSE](LICENSE) for details.\n\n## 📊 Roadmap\n\n- **Buffering Detection**: Implement functionality to detect and handle buffering events during playback via an `isLoading` state.\n- **iOS and WebAssembly (WasmJS) Support**: Expand support to additional platforms to enhance compatibility.\n- **Audio Player**: Introduce a standalone audio player for handling audio-only content.\n- **Player with Separate Audio and Video Streams**: Add functionality to support different audio and video streams for advanced playback scenarios.\n- **Metadata Support**: Add support for extracting the following metadata:\n    - Title\n    - Artist\n    - Duration (in milliseconds)\n    - Video resolution (width and height)\n    - Bitrate (in bits per second)\n    - Frame rate\n    - MIME type\n    - Audio channels\n    - Audio sample rate\n\n\n## 🟎️ Screenshots of the [Demo App](sample/composeApp/src/commonMain/kotlin/sample/app/App.kt)\n\n### Windows\n![Windows Sample](assets/screenshots/windows_sample.png)\n\n### Linux\n![Linux Sample](assets/screenshots/linux_sample.png)\n\n### Android\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/screenshots/android_sample.png\" alt=\"Android Sample\" height=\"500\"\u003e\n\u003c/p\u003e\n\n\n\n\n","funding_links":[],"categories":["Libraries"],"sub_categories":["🍎 Compose UI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FkdroidFilter%2FComposeMediaPlayer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FkdroidFilter%2FComposeMediaPlayer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FkdroidFilter%2FComposeMediaPlayer/lists"}