diff --git a/server/src/routes/generate.ts b/server/src/routes/generate.ts index 374ca29..4747199 100644 --- a/server/src/routes/generate.ts +++ b/server/src/routes/generate.ts @@ -14,6 +14,7 @@ import { cleanupJob, getJobRawResponse, downloadAudioToBuffer, + resolvePythonPath, } from '../services/acestep.js'; import { getStorageProvider } from '../services/storage/factory.js'; @@ -557,12 +558,12 @@ router.post('/format', authMiddleware, async (req: AuthenticatedRequest, res: Re const { spawn } = await import('child_process'); - const ACESTEP_DIR = process.env.ACESTEP_PATH || '/home/ambsd/Desktop/aceui/ACE-Step-1.5'; + const ACESTEP_DIR = process.env.ACESTEP_PATH || path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../ACE-Step-1.5'); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const SCRIPTS_DIR = path.join(__dirname, '../../scripts'); const FORMAT_SCRIPT = path.join(SCRIPTS_DIR, 'format_sample.py'); - const pythonPath = path.join(ACESTEP_DIR, '.venv', 'bin', 'python'); + const pythonPath = resolvePythonPath(ACESTEP_DIR); const args = [ FORMAT_SCRIPT, diff --git a/server/src/services/acestep.ts b/server/src/services/acestep.ts index ab449dc..9aa5fdb 100644 --- a/server/src/services/acestep.ts +++ b/server/src/services/acestep.ts @@ -1,5 +1,6 @@ -import { writeFile, mkdir, copyFile, rm, stat } from 'fs/promises'; +import { writeFile, mkdir, copyFile, rm, stat, access } from 'fs/promises'; import { spawn, execSync } from 'child_process'; +import { existsSync } from 'fs'; import path from 'path'; // Get audio duration using ffprobe @@ -35,6 +36,29 @@ function resolveAceStepPath(): string { return path.resolve(__dirname, '../../../../ACE-Step-1.5'); } +// Resolve Python path cross-platform (supports venv and portable installations) +export function resolvePythonPath(baseDir: string): string { + // Allow explicit override via env var + if (process.env.PYTHON_PATH) { + return process.env.PYTHON_PATH; + } + + const isWindows = process.platform === 'win32'; + const pythonExe = isWindows ? 'python.exe' : 'python'; + + // Check for portable installation first (python_embeded) + const portablePath = path.join(baseDir, 'python_embeded', pythonExe); + if (existsSync(portablePath)) { + return portablePath; + } + + // Standard venv path (different structure on Windows vs Unix) + if (isWindows) { + return path.join(baseDir, '.venv', 'Scripts', pythonExe); + } + return path.join(baseDir, '.venv', 'bin', 'python'); +} + const ACESTEP_DIR = resolveAceStepPath(); const SCRIPTS_DIR = path.join(__dirname, '../../scripts'); const PYTHON_SCRIPT = path.join(SCRIPTS_DIR, 'simple_generate.py'); @@ -431,8 +455,7 @@ interface PythonResult { function runPythonGeneration(scriptArgs: string[]): Promise { return new Promise((resolve) => { - // Use the ACE-Step venv's Python directly - const pythonPath = path.join(ACESTEP_DIR, '.venv', 'bin', 'python'); + const pythonPath = resolvePythonPath(ACESTEP_DIR); const args = [PYTHON_SCRIPT, ...scriptArgs]; const proc = spawn(pythonPath, args, {