mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-10-27 11:35:23 -07:00
fix(subtitles): follow mpv sub-delay in mining, sidebar, and navigation (#302)
This commit is contained in:
1 parent
d3a94536a8
commit
cc9af79d6e
25 files changed
+395
-54
No files matched your search
@@ -28,6 +28,7 @@ export async function setup() {
|
||||
],
|
||||
currentSubtitle: { text: '最初の台詞', startTime: 0, endTime: 1 },
|
||||
currentTimeSec: 0,
|
||||
subDelay: 0,
|
||||
config: {
|
||||
...SUBTITLE_DEFAULT_CONFIG.subtitleSidebar,
|
||||
enabled: true,
|
||||
|
||||
@@ -199,6 +199,7 @@ function createSidebarHarness(options: SidebarHarnessOptions = {}) {
|
||||
cues: options.cues ?? [{ startTime: 1, endTime: 2, text: 'first' }],
|
||||
currentSubtitle: options.currentSubtitle ?? { text: 'first', startTime: 1, endTime: 2 },
|
||||
currentTimeSec: 'currentTimeSec' in options ? (options.currentTimeSec ?? null) : 1.1,
|
||||
subDelay: 0,
|
||||
config: { ...DEFAULT_SIDEBAR_CONFIG, ...options.config },
|
||||
};
|
||||
const requests = { snapshot: 0, playback: 0 };
|
||||
@@ -226,8 +227,8 @@ function createSidebarHarness(options: SidebarHarnessOptions = {}) {
|
||||
},
|
||||
getSubtitleSidebarPlaybackState: async (): Promise<SubtitleSidebarPlaybackState> => {
|
||||
requests.playback += 1;
|
||||
const { sourceKey, cuesRevision, currentTimeSec, currentSubtitle } = snapshot;
|
||||
return { sourceKey, cuesRevision, currentTimeSec, currentSubtitle };
|
||||
const { sourceKey, cuesRevision, currentTimeSec, subDelay, currentSubtitle } = snapshot;
|
||||
return { sourceKey, cuesRevision, currentTimeSec, subDelay, currentSubtitle };
|
||||
},
|
||||
getPlaybackPaused: async () => false,
|
||||
sendMpvCommand: (command: MpvCommand) => {
|
||||
@@ -528,6 +529,16 @@ test('subtitle sidebar seeks to the selected cue start using the overlap-aware s
|
||||
assert.deepEqual(h.mpvCommands.at(-1), ['seek', 3.48, 'absolute+exact']);
|
||||
});
|
||||
|
||||
test('subtitle sidebar seeks to where mpv plays a sub-delay retimed cue', async () => {
|
||||
const h = createSidebarHarness();
|
||||
h.setSnapshot({ subDelay: 2 });
|
||||
await h.modal.openSubtitleSidebarModal();
|
||||
|
||||
h.modal.seekToCue({ startTime: 1, endTime: 2, text: 'first' });
|
||||
|
||||
assert.deepEqual(h.mpvCommands.at(-1), ['seek', 3.08, 'absolute+exact']);
|
||||
});
|
||||
|
||||
test('subtitle sidebar close reports hidden visibility and notifies the modal close', async () => {
|
||||
const h = createSidebarHarness();
|
||||
await h.modal.openSubtitleSidebarModal();
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
SubtitleMiningContext,
|
||||
SubtitleSidebarSnapshot,
|
||||
} from '../../types';
|
||||
import { toVideoClock } from '../../core/services/subtitle-clock.js';
|
||||
import { subtitleCueListSeekTime } from '../../core/services/subtitle-cue-navigation.js';
|
||||
import type { ModalStateReader, RendererContext } from '../context';
|
||||
import { syncOverlayMouseIgnoreState } from '../overlay-mouse-ignore.js';
|
||||
@@ -231,6 +232,8 @@ export function createSubtitleSidebarModal(
|
||||
let lastSubtitleSidebarLookupCueIndex = -1;
|
||||
let subtitleSourceKey: string | null = null;
|
||||
let subtitleCuesRevision: number | null = null;
|
||||
// Latest mpv `sub-delay` from main; cue times plus this are where mpv plays the cue.
|
||||
let subtitleSubDelay = 0;
|
||||
|
||||
function restoreEmbeddedSidebarPassthrough(): void {
|
||||
syncOverlayMouseIgnoreState(ctx);
|
||||
@@ -416,7 +419,7 @@ export function createSubtitleSidebarModal(
|
||||
function seekToCue(cue: SubtitleCue): void {
|
||||
window.electronAPI.sendMpvCommand([
|
||||
'seek',
|
||||
subtitleCueListSeekTime(ctx.state.subtitleSidebarCues, cue),
|
||||
toVideoClock(subtitleCueListSeekTime(ctx.state.subtitleSidebarCues, cue), subtitleSubDelay),
|
||||
'absolute+exact',
|
||||
]);
|
||||
}
|
||||
@@ -591,6 +594,7 @@ export function createSubtitleSidebarModal(
|
||||
const snapshot = await window.electronAPI.getSubtitleSidebarSnapshot();
|
||||
pollsSinceFullSnapshot = 0;
|
||||
subtitleCuesRevision = snapshot.cuesRevision;
|
||||
subtitleSubDelay = snapshot.subDelay;
|
||||
if (snapshot.sourceKey !== subtitleSourceKey) {
|
||||
clearSubtitleSidebarSelection(ctx.dom.subtitleSidebarList);
|
||||
lastSubtitleSidebarLookupCueIndex = -1;
|
||||
@@ -640,6 +644,7 @@ export function createSubtitleSidebarModal(
|
||||
await refreshSnapshot();
|
||||
return;
|
||||
}
|
||||
subtitleSubDelay = playback.subDelay;
|
||||
updateActiveCue(playback.currentSubtitle, playback.currentTimeSec);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user