Merge pull request #222 from EtienneLescot/fix/export-local-file-loading

fix: read local export sources through electron IPC
This commit is contained in:
Sid
2026-03-16 20:56:15 -07:00
committed by GitHub
4 changed files with 61 additions and 2 deletions
+7
View File
@@ -51,6 +51,13 @@ interface Window {
openVideoFilePicker: () => Promise<{ success: boolean; path?: string; canceled?: boolean }>;
setCurrentVideoPath: (path: string) => Promise<{ success: boolean }>;
getCurrentVideoPath: () => Promise<{ success: boolean; path?: string }>;
readBinaryFile: (filePath: string) => Promise<{
success: boolean;
data?: ArrayBuffer;
path?: string;
message?: string;
error?: string;
}>;
clearCurrentVideoPath: () => Promise<{ success: boolean }>;
saveProjectFile: (
projectData: unknown,
+23
View File
@@ -200,6 +200,29 @@ export function registerIpcHandlers(
}
});
ipcMain.handle("read-binary-file", async (_, inputPath: string) => {
try {
const normalizedPath = normalizeVideoSourcePath(inputPath);
if (!normalizedPath) {
return { success: false, message: "Invalid file path" };
}
const data = await fs.readFile(normalizedPath);
return {
success: true,
data: data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),
path: normalizedPath,
};
} catch (error) {
console.error("Failed to read binary file:", error);
return {
success: false,
message: "Failed to read binary file",
error: String(error),
};
}
});
ipcMain.handle("set-recording-state", (_, recording: boolean) => {
if (recording) {
stopCursorCapture();
+3
View File
@@ -60,6 +60,9 @@ contextBridge.exposeInMainWorld("electronAPI", {
getCurrentVideoPath: () => {
return ipcRenderer.invoke("get-current-video-path");
},
readBinaryFile: (filePath: string) => {
return ipcRenderer.invoke("read-binary-file", filePath);
},
clearCurrentVideoPath: () => {
return ipcRenderer.invoke("clear-current-video-path");
},
+28 -2
View File
@@ -32,11 +32,37 @@ export class StreamingVideoDecoder {
private cancelled = false;
private metadata: DecodedVideoInfo | null = null;
async loadMetadata(videoUrl: string): Promise<DecodedVideoInfo> {
private async loadSourceFile(videoUrl: string): Promise<{ file: File; blob: Blob }> {
const isRemoteUrl = /^(https?:|blob:|data:)/i.test(videoUrl);
if (!isRemoteUrl && window.electronAPI?.readBinaryFile) {
const result = await window.electronAPI.readBinaryFile(videoUrl);
if (!result.success || !result.data) {
throw new Error(result.message || result.error || "Failed to read source video");
}
const filename = (result.path || videoUrl).split(/[\\/]/).pop() || "video";
const blob = new Blob([result.data]);
return {
blob,
file: new File([blob], filename, { type: blob.type || "application/octet-stream" }),
};
}
const response = await fetch(videoUrl);
if (!response.ok) {
throw new Error(`Failed to fetch source video: ${response.status} ${response.statusText}`);
}
const blob = await response.blob();
const filename = videoUrl.split("/").pop() || "video";
const file = new File([blob], filename, { type: blob.type });
return {
blob,
file: new File([blob], filename, { type: blob.type }),
};
}
async loadMetadata(videoUrl: string): Promise<DecodedVideoInfo> {
const { file } = await this.loadSourceFile(videoUrl);
// Relative URL so it resolves correctly in both dev (http) and packaged (file://) builds
const wasmUrl = new URL("./wasm/web-demuxer.wasm", window.location.href).href;