mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-08 23:54:39 +00:00
fix(desktop): fix macOS VLC bundled discovery and video rendering
MacOsVlcDiscoverer.setPluginPath() called LibC.INSTANCE.setenv() via
JNA, but macOS 13+ uses versioned symbols (setenv$3b99ba0d) that JNA
can't resolve, breaking all video playback without system VLC.
Changes:
- Replace LibC.setenv with direct JNA Function.getFunction("c","setenv")
call that bypasses the problematic interface binding
- Store discoveredPluginPath for --plugin-path factory arg fallback
- Add -Dvlc.plugin.path JVM property as ultimate fallback
- Delete stale VLC plugin cache on macOS before factory creation
- Pass --plugin-path to audio factory too when env var fails
- Add jdk.unsupported module to jlink (VLCJ ByteBufferFactory needs
sun.misc.Unsafe for video frame buffer allocation)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
935ad84ac3
commit
de5dc34cb7
+36
-3
@@ -55,6 +55,9 @@ object VlcjPlayerPool {
|
||||
private val idleThumbPlayers = ConcurrentLinkedQueue<EmbeddedMediaPlayer>()
|
||||
private const val MAX_THUMB_POOL_SIZE = 2
|
||||
|
||||
// Cached plugin path for audio factory creation (set during init)
|
||||
private var cachedPluginPath: String? = null
|
||||
|
||||
// Audio player pool (shared factory with --no-video)
|
||||
private var audioFactory: MediaPlayerFactory? = null
|
||||
private val allAudioPlayers = mutableListOf<MediaPlayer>()
|
||||
@@ -76,12 +79,13 @@ object VlcjPlayerPool {
|
||||
|
||||
return try {
|
||||
// Try bundled VLC first, then fall through to system VLC
|
||||
val macOsDiscoverer = MacOsVlcDiscoverer()
|
||||
val discovery =
|
||||
try {
|
||||
val nd =
|
||||
NativeDiscovery(
|
||||
BundledVlcDiscoverer(),
|
||||
MacOsVlcDiscoverer(),
|
||||
macOsDiscoverer,
|
||||
)
|
||||
val found = nd.discover()
|
||||
if (found) {
|
||||
@@ -99,7 +103,34 @@ object VlcjPlayerPool {
|
||||
val systemDiscovery = NativeDiscovery().discover()
|
||||
println("VLC: system discovery ${if (systemDiscovery) "succeeded" else "failed"}")
|
||||
}
|
||||
val f = MediaPlayerFactory("--no-xlib")
|
||||
|
||||
// Delete stale VLC plugin cache on macOS to avoid spam warnings
|
||||
if ("mac" in System.getProperty("os.name").lowercase()) {
|
||||
try {
|
||||
val cacheDir = java.io.File(System.getProperty("user.home"), "Library/Caches/org.videolan.vlc")
|
||||
cacheDir.listFiles()?.filter { it.name.startsWith("plugins") }?.forEach { it.delete() }
|
||||
} catch (_: Throwable) {
|
||||
// Best-effort cache cleanup
|
||||
}
|
||||
}
|
||||
|
||||
// Build factory args — add --plugin-path fallback if env var wasn't set
|
||||
val factoryArgs = mutableListOf("--no-xlib")
|
||||
if (!macOsDiscoverer.envVarSet) {
|
||||
val pluginPath =
|
||||
macOsDiscoverer.discoveredPluginPath
|
||||
?: System.getProperty("vlc.plugin.path")
|
||||
?: VlcResourceResolver.findVlcDir()?.let { "${it.absolutePath}/plugins" }
|
||||
if (pluginPath != null) {
|
||||
factoryArgs += "--plugin-path=$pluginPath"
|
||||
println("VLC: using --plugin-path fallback: $pluginPath")
|
||||
}
|
||||
}
|
||||
|
||||
cachedPluginPath = macOsDiscoverer.discoveredPluginPath
|
||||
?: System.getProperty("vlc.plugin.path")
|
||||
|
||||
val f = MediaPlayerFactory(*factoryArgs.toTypedArray())
|
||||
factory = f
|
||||
available.set(true)
|
||||
println("VLC: MediaPlayerFactory created successfully")
|
||||
@@ -184,7 +215,9 @@ object VlcjPlayerPool {
|
||||
|
||||
val af =
|
||||
audioFactory ?: try {
|
||||
MediaPlayerFactory("--no-video", "--no-xlib").also { audioFactory = it }
|
||||
val audioArgs = mutableListOf("--no-video", "--no-xlib")
|
||||
cachedPluginPath?.let { audioArgs += "--plugin-path=$it" }
|
||||
MediaPlayerFactory(*audioArgs.toTypedArray()).also { audioFactory = it }
|
||||
} catch (_: Throwable) {
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user