Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,11 @@ dependencies {

## 📊 Compatibility Table

| Library Version | Kotlin Version |
|-----------------|----------------|
| 0.7.10 | 2.1.21 |
| 0.7.11 | 2.2.0 |
| Library Version | Kotlin Version | Compose Version |
|-----------------|----------------|-----------------|
| 0.8.3 | 2.2.20 | 1.9.0 |
| 0.7.11 | 2.2.0 | 1.8.2 |
| 0.7.10 | 2.1.21 | 1.8.2 |

## 🚀 Getting Started

Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Gradle
org.gradle.jvmargs=-Xmx8G
# Enable native access to avoid Java 21+ warnings from Gradle native-platform (System::load)
org.gradle.jvmargs=-Xmx8G --enable-native-access=ALL-UNNAMED
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.daemon=true
Expand Down
16 changes: 8 additions & 8 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

androidcontextprovider = "1.0.1"
cocoapods = "1.9.0"
filekit = "0.10.0"
filekit = "0.11.0"
gst1JavaCore = "1.4.0"
kermit = "2.0.6"
kotlin = "2.2.10"
agp = "8.9.3"
kermit = "2.0.8"
kotlin = "2.2.20"
agp = "8.12.3"
kotlinx-coroutines = "1.10.2"
kotlinxBrowserWasmJs = "0.3"
kotlinxDatetime = "0.7.1-0.6.x-compat"
compose = "1.8.2"
androidx-activityCompose = "1.10.1"
media3Exoplayer = "1.7.1"
compose = "1.9.0"
androidx-activityCompose = "1.11.0"
media3Exoplayer = "1.8.0"
jna = "5.17.0"
platformtoolsDarkmodedetector = "0.5.0"
platformtoolsDarkmodedetector = "0.6.1"
slf4jSimple = "2.0.17"


Expand Down
54 changes: 54 additions & 0 deletions mediaplayer/ComposeMediaPlayer.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Pod::Spec.new do |spec|
spec.name = 'ComposeMediaPlayer'
spec.version = 'null'
spec.homepage = 'https://github.com/kdroidFilter/Compose-Media-Player'
spec.source = { :http=> ''}
spec.authors = ''
spec.license = ''
spec.summary = 'A multiplatform video player library for Compose applications'
spec.vendored_frameworks = 'build/cocoapods/framework/ComposeMediaPlayer.framework'
spec.libraries = 'c++'



if !Dir.exist?('build/cocoapods/framework/ComposeMediaPlayer.framework') || Dir.empty?('build/cocoapods/framework/ComposeMediaPlayer.framework')
raise "

Kotlin framework 'ComposeMediaPlayer' doesn't exist yet, so a proper Xcode project can't be generated.
'pod install' should be executed after running ':generateDummyFramework' Gradle task:

./gradlew :mediaplayer:generateDummyFramework

Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)"
end

spec.xcconfig = {
'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO',
}

spec.pod_target_xcconfig = {
'KOTLIN_PROJECT_PATH' => ':mediaplayer',
'PRODUCT_MODULE_NAME' => 'ComposeMediaPlayer',
}

spec.script_phases = [
{
:name => 'Build ComposeMediaPlayer',
:execution_position => :before_compile,
:shell_path => '/bin/sh',
:script => <<-SCRIPT
if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then
echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\""
exit 0
fi
set -ev
REPO_ROOT="$PODS_TARGET_SRCROOT"
"$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \
-Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \
-Pkotlin.native.cocoapods.archs="$ARCHS" \
-Pkotlin.native.cocoapods.configuration="$CONFIGURATION"
SCRIPT
}
]
spec.resources = ['build/compose/cocoapods/compose-resources']
end
2 changes: 1 addition & 1 deletion mediaplayer/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ kotlin {

android {
namespace = "io.github.kdroidfilter.composemediaplayer"
compileSdk = 35
compileSdk = 36

defaultConfig {
minSdk = 21
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.delay
import kotlinx.datetime.Clock
import kotlin.time.TimeSource

/**
* A composable function that displays subtitles.
Expand Down Expand Up @@ -104,12 +104,11 @@ fun AutoUpdatingSubtitleDisplay(
// Periodically update display time when playing
LaunchedEffect(isPlaying, currentTimeMs) {
if (isPlaying) {
var lastUpdateTime = Clock.System.now().toEpochMilliseconds()
var mark = TimeSource.Monotonic.markNow()
while (true) {
delay(16) // ~60fps
val now = Clock.System.now().toEpochMilliseconds()
val elapsed = now - lastUpdateTime
lastUpdateTime = now
val elapsed = mark.elapsedNow().inWholeMilliseconds
mark = TimeSource.Monotonic.markNow()
displayTimeMs += elapsed
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package io.github.kdroidfilter.composemediaplayer.util

import kotlinx.datetime.Instant
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import kotlin.time.Duration.Companion.seconds

/**
* Formats a given time into either "HH:MM:SS" (if hours > 0) or "MM:SS".
Expand Down
4 changes: 2 additions & 2 deletions sample/composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ kotlin {

android {
namespace = "sample.app"
compileSdk = 35
compileSdk = 36

defaultConfig {
minSdk = 21
targetSdk = 35
targetSdk = 36

applicationId = "sample.app.androidApp"
versionCode = 1
Expand Down
3 changes: 2 additions & 1 deletion sample/iosApp/iosApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
A9D80A052AAB5CDE006C8738 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
alwaysOutOfDate = 1;
files = (
);
inputFileListPaths = (
Expand All @@ -126,7 +127,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd \"$SRCROOT/..\"\n./../gradlew :sample:composeApp:embedAndSignAppleFrameworkForXcode\n";
shellScript = "set -eo pipefail\n# Ensure we run from the iOS project folder's parent (sample)\ncd \"$SRCROOT/..\"\n\n# Prefer JDK 17 (or 21) for Gradle, if available\nif command -v /usr/libexec/java_home >/dev/null 2>&1; then\n export JAVA_HOME=$(/usr/libexec/java_home -v 17 2>/dev/null || /usr/libexec/java_home -v 21 2>/dev/null || true)\nfi\n\n# Run Gradle task to build and embed the Kotlin framework for Xcode\n./../gradlew :sample:composeApp:embedAndSignAppleFrameworkForXcode --no-configuration-cache --stacktrace --info\n";
};
/* End PBXShellScriptBuildPhase section */

Expand Down
21 changes: 21 additions & 0 deletions sample/iosApp/iosApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>

<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
</dict>
</array>
</dict>
</dict>

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
Expand Down
30 changes: 24 additions & 6 deletions sample/iosApp/iosApp/iosApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,35 @@ import ComposeApp

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
if let window = window {
window.rootViewController = MainKt.MainViewController()
window.makeKeyAndVisible()
}
// Additional initialization if needed
return true
}

// Provide a scene configuration for connecting scenes (iOS 13+)
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
let config = UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
config.delegateClass = SceneDelegate.self
config.sceneClass = UIWindowScene.self
return config
}
}

// MARK: - UIScene support
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = MainKt.MainViewController()
window.makeKeyAndVisible()
self.window = window
}
}
Loading