From 61620ad36bc1ccf56a9f274035b97639c7715bf4 Mon Sep 17 00:00:00 2001 From: James Ding Date: Thu, 25 Jun 2026 14:09:44 -0700 Subject: [PATCH] fix: stop hijacking .sln/.mts/.gsm developer files as media The Media file type registered raw and telephony audio extensions that collide with common developer files. Because the editor uses FileEditorPolicy.HIDE_DEFAULT_EDITOR, a matched file opens in the player with the text editor hidden, so the file cannot be viewed as text. - .sln (Asterisk signed-linear PCM) clobbered Visual Studio / Rider solution files (#78). Re-register the format under .slin, Asterisk's own non-colliding alias for the same headerless s16le stream, so raw signed-linear audio stays supported. - .mts (AVCHD transport stream) clobbered TypeScript ES-module sources. The container is still reachable via the already-registered .m2ts and .m2t, mirroring the earlier .ts removal (#45), so .mts is just dropped. - .gsm (raw GSM 06.10) clobbered ArchiCAD GDL objects; dropped. .au and .caf are kept: their only real alternative extensions (.snd, .caff) either collide worse (.snd vs X-Plane sound config) or do not reach actual files (.caff is effectively unused). Updates the three mirrored extension lists (frontend descriptor, MediaClassification, MediaTranscoder raw-audio hints) and adds regression tests locking .mts/.ts out of video and .slin (not .sln) as the signed-linear extension. Fixes #78 --- .../dev/twango/jetplay/transcode/MediaTranscoder.kt | 3 +-- .../main/resources/dev.twango.jetplay.frontend.xml | 2 +- .../dev/twango/jetplay/media/MediaClassification.kt | 7 +++---- .../twango/jetplay/media/MediaClassificationTest.kt | 13 ++++++++++++- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/backend/src/main/kotlin/dev/twango/jetplay/transcode/MediaTranscoder.kt b/backend/src/main/kotlin/dev/twango/jetplay/transcode/MediaTranscoder.kt index 7ec6a445..44cfec3b 100644 --- a/backend/src/main/kotlin/dev/twango/jetplay/transcode/MediaTranscoder.kt +++ b/backend/src/main/kotlin/dev/twango/jetplay/transcode/MediaTranscoder.kt @@ -33,8 +33,7 @@ object MediaTranscoder { "pcma" to RawAudioHint("alaw", 8000, 1), "alaw" to RawAudioHint("alaw", 8000, 1), "g722" to RawAudioHint("g722", 16000, 1), - "gsm" to RawAudioHint("gsm", 8000, 1), - "sln" to RawAudioHint("s16le", 8000, 1), + "slin" to RawAudioHint("s16le", 8000, 1), ) /** Must stay in sync with the shared classifier. */ diff --git a/frontend/src/main/resources/dev.twango.jetplay.frontend.xml b/frontend/src/main/resources/dev.twango.jetplay.frontend.xml index 2c9c10f9..b39d2156 100644 --- a/frontend/src/main/resources/dev.twango.jetplay.frontend.xml +++ b/frontend/src/main/resources/dev.twango.jetplay.frontend.xml @@ -7,7 +7,7 @@ + extensions="mp4;m4v;mkv;avi;mov;wmv;flv;webm;ogv;m2ts;m2t;3gp;ivf;mp3;wav;ogg;oga;opus;m4a;aac;wma;aiff;aif;flac;ac3;eac3;caf;adts;amr;au;pcmu;ulaw;pcma;alaw;g722;slin"/> diff --git a/shared/src/main/kotlin/dev/twango/jetplay/media/MediaClassification.kt b/shared/src/main/kotlin/dev/twango/jetplay/media/MediaClassification.kt index 0c140d97..d9af2a6a 100644 --- a/shared/src/main/kotlin/dev/twango/jetplay/media/MediaClassification.kt +++ b/shared/src/main/kotlin/dev/twango/jetplay/media/MediaClassification.kt @@ -3,7 +3,7 @@ package dev.twango.jetplay.media object MediaClassification { // Video extensions registered by the media file type in the frontend descriptor. - // .ts is excluded to avoid clobbering TypeScript files. + // .ts and .mts are excluded to avoid clobbering TypeScript files. private val VIDEO_EXTENSIONS = setOf( "mp4", "m4v", @@ -14,7 +14,6 @@ object MediaClassification { "flv", "webm", "ogv", - "mts", "m2ts", "m2t", "3gp", @@ -34,14 +33,14 @@ object MediaClassification { ) // Headerless raw codec streams that need explicit demuxer hints. + // Signed-linear uses .slin not .sln to avoid clashing with Visual Studio solution files. val rawAudioExtensions: Set = setOf( "pcmu", "ulaw", "pcma", "alaw", "g722", - "gsm", - "sln", + "slin", ) fun isVideo(extension: String): Boolean = extension.lowercase() in VIDEO_EXTENSIONS diff --git a/shared/src/test/kotlin/dev/twango/jetplay/media/MediaClassificationTest.kt b/shared/src/test/kotlin/dev/twango/jetplay/media/MediaClassificationTest.kt index c444757f..86daf4f2 100644 --- a/shared/src/test/kotlin/dev/twango/jetplay/media/MediaClassificationTest.kt +++ b/shared/src/test/kotlin/dev/twango/jetplay/media/MediaClassificationTest.kt @@ -64,11 +64,22 @@ class MediaClassificationTest { @Test fun transportStreamContainersClassifyAsVideo() { - assertTrue(MediaClassification.isVideo("mts")) assertTrue(MediaClassification.isVideo("m2ts")) assertTrue(MediaClassification.isVideo("m2t")) } + @Test + fun typeScriptExtensionsDoNotClassifyAsVideo() { + assertFalse(MediaClassification.isVideo("ts")) + assertFalse(MediaClassification.isVideo("mts")) + } + + @Test + fun signedLinearUsesNonCollidingExtension() { + assertTrue(MediaClassification.rawAudioExtensions.contains("slin")) + assertFalse(MediaClassification.rawAudioExtensions.contains("sln")) + } + @Test fun rawAudioExtensionsNeedTranscoding() { MediaClassification.rawAudioExtensions.forEach {