diff --git a/src/core/services/mpv-protocol.test.ts b/src/core/services/mpv-protocol.test.ts index 17d37745..490038d1 100644 --- a/src/core/services/mpv-protocol.test.ts +++ b/src/core/services/mpv-protocol.test.ts @@ -399,17 +399,25 @@ test('dispatchMpvProtocolMessage pauses on sub-end when pendingPauseAtSubEnd is test('dispatchMpvProtocolMessage pauses at the sub-delay retimed sub-end', async () => { let pauseAtTime: number | null = null; + let subDelay = 1.5; const { deps } = createDeps({ getPendingPauseAtSubEnd: () => true, - getCurrentSubDelay: () => 1.5, + getCurrentSubDelay: () => subDelay, + setCurrentSubDelay: (next) => { + subDelay = next; + }, + getPauseAtTime: () => pauseAtTime, setPauseAtTime: (next) => { pauseAtTime = next; }, }); await dispatchMpvProtocolMessage({ event: 'property-change', name: 'sub-end', data: 42 }, deps); - assert.equal(pauseAtTime, 43.5); + + // Retiming before the replay reaches its end moves the pause with the line. + await dispatchMpvProtocolMessage({ event: 'property-change', name: 'sub-delay', data: 2 }, deps); + assert.equal(pauseAtTime, 44); }); test('dispatchMpvProtocolMessage updates current time before emitting time-pos change', async () => { diff --git a/src/core/services/mpv-protocol.ts b/src/core/services/mpv-protocol.ts index d67c709a..d0bbb7bb 100644 --- a/src/core/services/mpv-protocol.ts +++ b/src/core/services/mpv-protocol.ts @@ -277,8 +277,15 @@ export async function dispatchMpvProtocolMessage( end: deps.getCurrentSubEnd(), }); } else if (msg.name === 'sub-delay') { - const delay = typeof msg.data === 'number' ? msg.data : Number(msg.data); - deps.setCurrentSubDelay(Number.isFinite(delay) ? delay : 0); + const parsed = typeof msg.data === 'number' ? msg.data : Number(msg.data); + const delay = Number.isFinite(parsed) ? parsed : 0; + // A scheduled replay pause sits at the line's end on the video clock; retiming + // mid-replay moves that end, so the pause moves with it. + const pauseAtTime = deps.getPauseAtTime(); + if (pauseAtTime !== null) { + deps.setPauseAtTime(pauseAtTime + delay - deps.getCurrentSubDelay()); + } + deps.setCurrentSubDelay(delay); } else if (msg.name === 'secondary-sub-text') { const nextSubText = (msg.data as string) || ''; deps.setCurrentSecondarySubText(nextSubText);