fix: preserve caption timing and media lifecycle across failures

This commit is contained in:
webadderall
2026-09-21 20:33:13 +10:00
parent fc3c69c2a9
commit f43d137ef5
8 changed files with 103 additions and 6 deletions
@@ -184,6 +184,12 @@ export function useRecordingLibrary(
const { project, timeline, ui, appearance } = current.current;
if (project.videoSourcePath !== source)
throw new Error("The project changed while importing. Add the recordings again.");
// Commit ownership before exposing the source to project saves or renderer teardown.
const committed = await window.electronAPI.finishRecordingImport(media.path);
if (!committed.success)
throw new Error(committed.error || "Could not finalize imported media");
if (current.current.project.videoSourcePath !== source)
throw new Error("The project changed while importing. Add the recordings again.");
ui.clipInitializedRef.current = true;
ui.autoFullTrackClipIdRef.current = null;
ui.autoFullTrackClipEndMsRef.current = null;
+10
View File
@@ -53,6 +53,16 @@ describe("resolveMediaElementSource", () => {
expect(result.src).toBe("http://127.0.0.1:4321/video?path=%2Ftmp%2Fexample%20clip.mp4");
});
it.each([
"failure",
"exception",
])("keeps the existing media URL after refresh %s", async (mode) => {
if (mode === "failure") getLocalMediaUrl.mockResolvedValueOnce({ success: false, url: "" });
else getLocalMediaUrl.mockRejectedValueOnce(new Error("Server unavailable"));
const resource = "http://127.0.0.1:43123/video?path=%2Ftmp%2Fexample.mp4";
expect((await resolveMediaElementSource(resource)).src).toBe(resource);
});
it("leaves remote URLs untouched", async () => {
const result = await resolveMediaElementSource("https://example.com/video.mp4");
+4 -2
View File
@@ -87,11 +87,13 @@ export async function resolveMediaResourceUrl(resource: string): Promise<string>
return result.url;
}
} catch {
// Fall through to a file URL when the local media server is unavailable.
// Preserve an existing media URL if refreshing the server URL fails.
}
}
return /^file:\/\//i.test(resource) ? resource : toFileUrl(localFilePath);
return /^file:\/\//i.test(resource) || isLocalMediaServerUrl(resource)
? resource
: toFileUrl(localFilePath);
}
async function createReadableMediaResourceFile(resource: string): Promise<File> {