diff --git a/frontend/src/main/kotlin/dev/twango/jetplay/editor/MediaLoader.kt b/frontend/src/main/kotlin/dev/twango/jetplay/editor/MediaLoader.kt index 37d4d070..5bfff62c 100644 --- a/frontend/src/main/kotlin/dev/twango/jetplay/editor/MediaLoader.kt +++ b/frontend/src/main/kotlin/dev/twango/jetplay/editor/MediaLoader.kt @@ -134,8 +134,7 @@ class MediaLoader( } private fun maybeSendMediaInfo() { - if (source.isRemote) return - if (source.extension.lowercase() in MediaClassification.rawAudioExtensions) return + if (!source.canProbeMediaInfo) return scope.launch { val info = MediaAccessor.getInstance().extractMediaInfo(fileId, projectId) if (info != null && !bridge.disposed) bridge.sendMediaInfo(info) diff --git a/frontend/src/main/kotlin/dev/twango/jetplay/media/EditorMediaSource.kt b/frontend/src/main/kotlin/dev/twango/jetplay/media/EditorMediaSource.kt index 4cea74f9..d3add6ad 100644 --- a/frontend/src/main/kotlin/dev/twango/jetplay/media/EditorMediaSource.kt +++ b/frontend/src/main/kotlin/dev/twango/jetplay/media/EditorMediaSource.kt @@ -12,6 +12,9 @@ class EditorMediaSource(val file: VirtualFile) { val needsTranscoding: Boolean = MediaClassification.needsTranscoding(extension) val isRemote: Boolean = file.fileSystem !is LocalFileSystem + // Header probing runs host-side, so remote files stay eligible; raw headerless codecs can't be probed. + val canProbeMediaInfo: Boolean = extension !in MediaClassification.rawAudioExtensions + /** Non-null only when the bytes are readable in this process. */ fun localFileOrNull(): File? = if (!isRemote) runCatching { file.toNioPath().toFile() }.getOrNull()?.takeIf { it.isFile } else null diff --git a/frontend/src/test/kotlin/dev/twango/jetplay/media/EditorMediaSourceTest.kt b/frontend/src/test/kotlin/dev/twango/jetplay/media/EditorMediaSourceTest.kt index 3f45f5e6..c78a50a8 100644 --- a/frontend/src/test/kotlin/dev/twango/jetplay/media/EditorMediaSourceTest.kt +++ b/frontend/src/test/kotlin/dev/twango/jetplay/media/EditorMediaSourceTest.kt @@ -1,6 +1,7 @@ package dev.twango.jetplay.media import com.intellij.openapi.vfs.LocalFileSystem +import com.intellij.testFramework.LightVirtualFile import com.intellij.testFramework.fixtures.BasePlatformTestCase import java.nio.file.Files @@ -38,4 +39,16 @@ class EditorMediaSourceTest : BasePlatformTestCase() { assertFalse(source.needsTranscoding) assertEquals("mp3", source.extension) } + + // A LightVirtualFile isn't backed by LocalFileSystem, standing in for a Remote Dev / Gateway file. + fun testRemoteFileStaysEligibleForMediaInfo() { + val remote = EditorMediaSource(LightVirtualFile("song.mp3")) + assertTrue("a non-LocalFileSystem file must read as remote", remote.isRemote) + assertTrue("media-info probing runs host-side, so a remote file must stay eligible", remote.canProbeMediaInfo) + } + + fun testRawAudioIsNotEligibleForMediaInfo() { + val raw = EditorMediaSource(LightVirtualFile("call.pcmu")) + assertFalse("headerless raw codecs can't be probed", raw.canProbeMediaInfo) + } }