diff --git a/MPVKit/Sources/DesktopMPVBridge/Bridge.swift b/MPVKit/Sources/DesktopMPVBridge/Bridge.swift index a191ddda..d64d3019 100644 --- a/MPVKit/Sources/DesktopMPVBridge/Bridge.swift +++ b/MPVKit/Sources/DesktopMPVBridge/Bridge.swift @@ -27,6 +27,11 @@ public func nuvio_player_create() -> UnsafeMutableRawPointer { return Unmanaged.passRetained(p).toOpaque() } +@_cdecl("nuvio_player_prewarm") +public func nuvio_player_prewarm() { + NuvioPlayerPrewarmer.shared.prewarm() +} + @_cdecl("nuvio_player_destroy") public func nuvio_player_destroy(_ ptr: UnsafeMutableRawPointer) { let p = Unmanaged.fromOpaque(ptr).takeRetainedValue() diff --git a/MPVKit/Sources/DesktopMPVBridge/NuvioPlayerPrewarmer.swift b/MPVKit/Sources/DesktopMPVBridge/NuvioPlayerPrewarmer.swift new file mode 100644 index 00000000..739b7563 --- /dev/null +++ b/MPVKit/Sources/DesktopMPVBridge/NuvioPlayerPrewarmer.swift @@ -0,0 +1,20 @@ +import AppKit + +final class NuvioPlayerPrewarmer { + static let shared = NuvioPlayerPrewarmer() + + private var started = false + + private init() { + } + + func prewarm() { + DispatchQueue.main.async { + guard !self.started else { return } + self.started = true + let view = NuvioMPVView(frame: NSRect(x: 0, y: 0, width: 16, height: 16)) + view.setup() + view.destroyPlayer() + } + } +} diff --git a/composeApp/src/desktopMain/kotlin/com/nuvio/app/DesktopApp.kt b/composeApp/src/desktopMain/kotlin/com/nuvio/app/DesktopApp.kt index 8209a362..69885685 100644 --- a/composeApp/src/desktopMain/kotlin/com/nuvio/app/DesktopApp.kt +++ b/composeApp/src/desktopMain/kotlin/com/nuvio/app/DesktopApp.kt @@ -1,8 +1,10 @@ package com.nuvio.app import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.window.Window import androidx.compose.ui.window.application +import com.nuvio.app.features.player.prewarmDesktopPlaybackBackend import java.awt.Color as AwtColor private val DesktopWindowBackground = AwtColor(0x0D, 0x0D, 0x0D) @@ -27,7 +29,11 @@ fun main() { onDispose { } } + LaunchedEffect(Unit) { + prewarmDesktopPlaybackBackend() + } + App() } } -} \ No newline at end of file +} diff --git a/composeApp/src/desktopMain/kotlin/com/nuvio/app/features/player/DesktopPlaybackPrewarmer.desktop.kt b/composeApp/src/desktopMain/kotlin/com/nuvio/app/features/player/DesktopPlaybackPrewarmer.desktop.kt new file mode 100644 index 00000000..5334eca4 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/nuvio/app/features/player/DesktopPlaybackPrewarmer.desktop.kt @@ -0,0 +1,24 @@ +package com.nuvio.app.features.player + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.withContext +import java.util.concurrent.atomic.AtomicBoolean + +private val desktopPlaybackPrewarmStarted = AtomicBoolean(false) + +internal suspend fun prewarmDesktopPlaybackBackend() { + val osName = System.getProperty("os.name").orEmpty().lowercase() + if (!osName.contains("mac")) return + if (!desktopPlaybackPrewarmStarted.compareAndSet(false, true)) return + + val bridge = withContext(Dispatchers.IO) { + runCatching { MacOSMPVBridgeLib.INSTANCE }.getOrNull() + } ?: return + + delay(1_500) + + withContext(Dispatchers.IO) { + runCatching { bridge.nuvio_player_prewarm() } + } +} diff --git a/composeApp/src/desktopMain/kotlin/com/nuvio/app/features/player/MacOSNativePlayerBridge.desktop.kt b/composeApp/src/desktopMain/kotlin/com/nuvio/app/features/player/MacOSNativePlayerBridge.desktop.kt index 1705f427..9d63c22c 100644 --- a/composeApp/src/desktopMain/kotlin/com/nuvio/app/features/player/MacOSNativePlayerBridge.desktop.kt +++ b/composeApp/src/desktopMain/kotlin/com/nuvio/app/features/player/MacOSNativePlayerBridge.desktop.kt @@ -37,6 +37,7 @@ internal interface MacOSMPVBridgeLib : Library { } fun nuvio_player_create(): Pointer + fun nuvio_player_prewarm() fun nuvio_player_destroy(player: Pointer) fun nuvio_player_show(player: Pointer)