diff --git a/desktop-app/src/main/kotlin/com/miruplay/tv/desktop/MiruPlayDesktopComposeApp.kt b/desktop-app/src/main/kotlin/com/miruplay/tv/desktop/MiruPlayDesktopComposeApp.kt index 4283267a..d57898d3 100644 --- a/desktop-app/src/main/kotlin/com/miruplay/tv/desktop/MiruPlayDesktopComposeApp.kt +++ b/desktop-app/src/main/kotlin/com/miruplay/tv/desktop/MiruPlayDesktopComposeApp.kt @@ -611,7 +611,7 @@ internal fun MiruPlayDesktopComposeApp( var logUploadTokenInput by remember { mutableStateOf("") } var mediaPath by remember { mutableStateOf(desktopInitialMediaPathFromEnvironment()) } var subtitlePath by remember { mutableStateOf("") } - var subtitleOverrideMediaPath by remember { mutableStateOf(null) } + var subtitleOverrideKey by remember { mutableStateOf?>(null) } var startSeconds by remember { mutableStateOf("0") } var fullscreen by remember { mutableStateOf(false) } var keepOpen by remember { mutableStateOf(false) } @@ -828,6 +828,7 @@ internal fun MiruPlayDesktopComposeApp( loadIndexed: Boolean, ) { val sourceInfo = activationState.sourceInfo + subtitleOverrideKey = null activeSourceId = sourceInfo.id val source = desktopSourceFromInfo(sourceInfo) activeSource = source @@ -1043,7 +1044,7 @@ internal fun MiruPlayDesktopComposeApp( ): DesktopPlaybackLaunchRequest { val playbackMediaSource = sourceOverride ?: activeSource val playbackSourceId = sourceIdOverride ?: activeSourceId - val hasSubtitleOverride = subtitleOverrideMediaPath == path + val hasSubtitleOverride = subtitleOverrideKey == (playbackSourceId to path.trim()) val manualSubtitlePath = subtitlePath.takeIf { hasSubtitleOverride }.orEmpty() val indexedPath = episodeId ?.takeIf { it.substringBefore(':').toLongOrNull() == playbackSourceId } @@ -1128,7 +1129,7 @@ internal fun MiruPlayDesktopComposeApp( startSeconds = PlaybackTimingConventions.formatMpvStartSeconds(result.data.source.startPosition) if (path != previousMediaPath) { subtitlePath = "" - subtitleOverrideMediaPath = null + subtitleOverrideKey = null } saveDesktopPlaybackStartProgress( session = result.data.session, @@ -2620,7 +2621,7 @@ internal fun MiruPlayDesktopComposeApp( subtitlePath = subtitlePath, onSubtitlePathChange = { subtitlePath = it - subtitleOverrideMediaPath = mediaPath + subtitleOverrideKey = activeSourceId to mediaPath.trim() }, startSeconds = startSeconds, onStartSecondsChange = { startSeconds = it }, diff --git a/player-mpv-android/src/main/kotlin/is/xyz/mpv/MiruMpvSurfaceView.kt b/player-mpv-android/src/main/kotlin/is/xyz/mpv/MiruMpvSurfaceView.kt index a0ad6f6d..d8ffef12 100644 --- a/player-mpv-android/src/main/kotlin/is/xyz/mpv/MiruMpvSurfaceView.kt +++ b/player-mpv-android/src/main/kotlin/is/xyz/mpv/MiruMpvSurfaceView.kt @@ -212,12 +212,13 @@ class MiruMpvSurfaceView @JvmOverloads constructor( MPVLib.observeProperty("pause", MPVLib.MpvFormat.MPV_FORMAT_FLAG) MPVLib.observeProperty("eof-reached", MPVLib.MpvFormat.MPV_FORMAT_FLAG) MPVLib.observeProperty("track-list/count", MPVLib.MpvFormat.MPV_FORMAT_INT64) + MPVLib.observeProperty("sid", MPVLib.MpvFormat.MPV_FORMAT_STRING) } override fun eventProperty(property: String) = Unit override fun eventProperty(property: String, value: Long) { - if (property == "track-list/count") onSubtitleTracksChanged?.invoke(this) + if (property == "track-list/count") notifySubtitleTracksChanged() } override fun eventProperty(property: String, value: Boolean) { @@ -227,7 +228,15 @@ class MiruMpvSurfaceView @JvmOverloads constructor( } } - override fun eventProperty(property: String, value: String) = Unit + override fun eventProperty(property: String, value: String) { + if (property == "sid") notifySubtitleTracksChanged() + } + + private fun notifySubtitleTracksChanged() { + post { + if (initialized) onSubtitleTracksChanged?.invoke(this) + } + } override fun eventProperty(property: String, value: Double) { when (property) { diff --git a/scanner/src/test/kotlin/com/miruplay/tv/scanner/MlipLibraryIndexImporterTest.kt b/scanner/src/test/kotlin/com/miruplay/tv/scanner/MlipLibraryIndexImporterTest.kt index 70bee260..e0f80a58 100644 --- a/scanner/src/test/kotlin/com/miruplay/tv/scanner/MlipLibraryIndexImporterTest.kt +++ b/scanner/src/test/kotlin/com/miruplay/tv/scanner/MlipLibraryIndexImporterTest.kt @@ -437,13 +437,14 @@ class MlipLibraryIndexImporterTest { database.execSQL("CREATE TABLE series_genre (series_id INTEGER NOT NULL, genre_id INTEGER NOT NULL)") database.execSQL("CREATE TABLE series_external_id (series_id INTEGER NOT NULL, provider INTEGER NOT NULL, value TEXT NOT NULL)") database.execSQL("CREATE TABLE episode_external_id (episode_id INTEGER NOT NULL, provider INTEGER NOT NULL, value TEXT NOT NULL)") - database.execSQL("CREATE TABLE capability (key TEXT PRIMARY KEY, value TEXT NOT NULL)") + database.execSQL("CREATE TABLE capability (name TEXT PRIMARY KEY, enabled INTEGER NOT NULL)") + database.execSQL("INSERT INTO capability (name, enabled) VALUES ('subtitle', ${if (includeExternalSubtitles) 1 else 0})") if (includeReleaseDate) { database.execSQL("CREATE TABLE series_release_date (series_id INTEGER PRIMARY KEY, air_date TEXT NOT NULL)") database.execSQL("INSERT INTO series_release_date (series_id, air_date) VALUES (1, '2024-04-03')") } if (includeExternalSubtitles) { - database.execSQL("CREATE TABLE media_subtitle (media_file_id INTEGER NOT NULL, path TEXT NOT NULL, language TEXT, title TEXT, sort_order INTEGER NOT NULL DEFAULT 0)") + database.execSQL("CREATE TABLE media_subtitle (id INTEGER PRIMARY KEY, media_file_id INTEGER NOT NULL, path TEXT NOT NULL, language TEXT, title TEXT, sort_order INTEGER NOT NULL DEFAULT 0, FOREIGN KEY(media_file_id) REFERENCES media_file(id) ON DELETE CASCADE, UNIQUE(media_file_id, path))") database.execSQL("INSERT INTO media_subtitle (media_file_id, path, language, title, sort_order) VALUES (100, 'Series/01.en.srt', 'en', 'English', 2), (100, 'Series/01.zh-CN.ass', 'zh-CN', '简体中文', 1)") } database.execSQL("INSERT INTO series (id, uuid, title, original_title, summary, year, series_type) VALUES (1, 'series-uuid', '中文标题', 'Original Title', '简介', 2024, 1)")