fix(subtitles): improve secondary subtitle extraction and display (#215)

This commit is contained in:
2026-08-23 01:56:49 -07:00
committed by GitHub
parent 0a0aa3ec98
commit 509dc5bf7f
20 changed files with 503 additions and 37 deletions
+10 -4
View File
@@ -588,9 +588,10 @@ import {
import { buildSubtitleSidebarSourceKey } from './main/runtime/subtitle-prefetch-source';
import { createSubtitlePrefetchInitController } from './main/runtime/subtitle-prefetch-init';
import {
createCachedInternalSubtitleTrackExtractor,
loadSubtitleSourceText,
extractInternalSubtitleTrackToTempFile,
} from './main/runtime/internal-subtitle-extraction';
import { createRemoteMediaPathDetector } from './main/runtime/network-media-path';
import { applyCharacterDictionarySelection } from './main/character-dictionary-selection';
import { getSubsyncConfig } from './subsync/utils';
@@ -2054,10 +2055,13 @@ const subtitlePrefetchInitController = createSubtitlePrefetchInitController({
}
},
});
const cachedInternalSubtitleTrackExtractor = createCachedInternalSubtitleTrackExtractor();
const detectRemoteMediaPath = createRemoteMediaPathDetector();
const resolveActiveSubtitleSidebarSourceHandler = createResolveActiveSubtitleSidebarSourceHandler({
getFfmpegPath: () => configService.getConfig().subsync.ffmpeg_path.trim() || 'ffmpeg',
isRemoteMediaPath: detectRemoteMediaPath,
extractInternalSubtitleTrack: (ffmpegPath, videoPath, track) =>
extractInternalSubtitleTrackToTempFile(ffmpegPath, videoPath, track),
cachedInternalSubtitleTrackExtractor.extract(ffmpegPath, videoPath, track),
logDebug: (message) => logger.debug(message),
});
@@ -2086,8 +2090,8 @@ const refreshSubtitlePrefetchFromActiveTrackHandler =
// Remote media has no extractable on-disk track to fall back to, so a transient
// resolve miss (sid briefly 'no', a cycle onto an embedded stream track) would
// otherwise drop a working cue list for the rest of the episode.
shouldKeepExistingCuesOnMissingSource: (videoPath) =>
isYoutubeMediaPath(videoPath) || isRemoteMediaPath(videoPath),
shouldKeepExistingCuesOnMissingSource: async (videoPath) =>
isYoutubeMediaPath(videoPath) || (await detectRemoteMediaPath(videoPath)),
subtitlePrefetchInitController,
resolveActiveSubtitleSidebarSource: (input) => resolveActiveSubtitleSidebarSourceHandler(input),
logDebug: (message) => logger.debug(message),
@@ -3962,6 +3966,7 @@ const {
appState.yomitanSettingsWindow = null;
},
stopJellyfinRemoteSession: () => stopJellyfinRemoteSession(),
cleanupInternalSubtitleTrackCache: () => cachedInternalSubtitleTrackExtractor.clear(),
cleanupYoutubeSubtitleTempDirs: () => youtubeFlowRuntime.cleanupSubtitleTempDirs(),
cleanupYoutubeMediaCache: () => youtubeMediaCache.cleanup(),
cleanupJellyfinSubtitleCache: () => cleanupJellyfinSubtitleCache(),
@@ -4522,6 +4527,7 @@ const {
appState.activeParsedSubtitleMediaPath,
);
if ((normalizedPath || null) !== previousPath) {
cachedInternalSubtitleTrackExtractor.clear();
secondarySubtitleTrackController.reset();
const resetSubtitlePayload = { text: '', tokens: null };
const frequencyDictionary = configService.getConfig().subtitleStyle.frequencyDictionary;