volume panel; copilot instructions
This commit is contained in:
@ -8,6 +8,17 @@ let pythonBackend = null;
|
||||
const isDev = !app.isPackaged;
|
||||
const BACKEND_PORT = 8642;
|
||||
|
||||
function getProjectDirectory() {
|
||||
const fs = require('fs');
|
||||
// Keep project files alongside the TalkEdit workspace in development.
|
||||
// electron/main.js lives under <repo>/electron, so repo root is ../
|
||||
const projectsDir = path.join(__dirname, '..', 'Projects');
|
||||
if (!fs.existsSync(projectsDir)) {
|
||||
fs.mkdirSync(projectsDir, { recursive: true });
|
||||
}
|
||||
return projectsDir;
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1400,
|
||||
@ -92,7 +103,9 @@ ipcMain.handle('dialog:saveFile', async (_event, options) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('dialog:openProject', async () => {
|
||||
const projectDir = getProjectDirectory();
|
||||
const result = await dialog.showOpenDialog(mainWindow, {
|
||||
defaultPath: projectDir,
|
||||
properties: ['openFile'],
|
||||
filters: [
|
||||
{ name: 'AI Video Editor Project', extensions: ['aive'] },
|
||||
@ -101,6 +114,18 @@ ipcMain.handle('dialog:openProject', async () => {
|
||||
return result.canceled ? null : result.filePaths[0];
|
||||
});
|
||||
|
||||
ipcMain.handle('dialog:saveProject', async (_event, options) => {
|
||||
const projectDir = getProjectDirectory();
|
||||
const result = await dialog.showSaveDialog(mainWindow, {
|
||||
defaultPath: path.join(projectDir, 'project.aive'),
|
||||
filters: [
|
||||
{ name: 'AI Video Editor Project', extensions: ['aive'] },
|
||||
],
|
||||
...options,
|
||||
});
|
||||
return result.canceled ? null : result.filePath;
|
||||
});
|
||||
|
||||
ipcMain.handle('safe-storage:encrypt', (_event, data) => {
|
||||
if (safeStorage.isEncryptionAvailable()) {
|
||||
return safeStorage.encryptString(data).toString('base64');
|
||||
@ -119,6 +144,48 @@ ipcMain.handle('get-backend-url', () => {
|
||||
return `http://localhost:${BACKEND_PORT}`;
|
||||
});
|
||||
|
||||
ipcMain.handle('backend:ensureModel', async (_event, modelName) => {
|
||||
// Python backend downloads models lazily during transcription.
|
||||
// Keep this IPC for compatibility with existing renderer flow.
|
||||
return modelName;
|
||||
});
|
||||
|
||||
ipcMain.handle('backend:transcribe', async (_event, payload) => {
|
||||
const filePath = payload?.filePath;
|
||||
const modelName = payload?.modelName || 'base';
|
||||
const language = payload?.language;
|
||||
|
||||
if (!filePath) {
|
||||
throw new Error('Missing file path for transcription');
|
||||
}
|
||||
|
||||
const res = await fetch(`http://127.0.0.1:${BACKEND_PORT}/transcribe`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
file_path: filePath,
|
||||
model: modelName,
|
||||
language,
|
||||
use_gpu: true,
|
||||
use_cache: true,
|
||||
diarize: false,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
let detail = `${res.status} ${res.statusText}`;
|
||||
try {
|
||||
const body = await res.json();
|
||||
if (body?.detail) detail = `${detail}: ${body.detail}`;
|
||||
} catch (_err) {
|
||||
// ignore JSON parse errors for non-JSON responses
|
||||
}
|
||||
throw new Error(`Transcription failed: ${detail}`);
|
||||
}
|
||||
|
||||
return await res.json();
|
||||
});
|
||||
|
||||
ipcMain.handle('fs:readFile', async (_event, filePath) => {
|
||||
const fs = require('fs');
|
||||
return fs.readFileSync(filePath, 'utf-8');
|
||||
|
||||
Reference in New Issue
Block a user