77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
import process from "node:process";
|
|
import { mkdir } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { spawn } from "node:child_process";
|
|
|
|
import { loadConfig } from "./config.js";
|
|
import { resolveDockerCommand } from "./docker-runtime.js";
|
|
import { Logger } from "./logger.js";
|
|
import { MeloTtsService } from "./services/melo-tts.js";
|
|
|
|
async function run(command: string, args: string[], cwd = process.cwd()): Promise<void> {
|
|
const env = { ...process.env };
|
|
if (path.isAbsolute(command)) {
|
|
const dockerBinDir = path.dirname(command);
|
|
const currentPath = env.PATH ?? env.Path ?? "";
|
|
env.PATH = `${dockerBinDir}${path.delimiter}${currentPath}`;
|
|
}
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
const child = spawn(command, args, {
|
|
cwd,
|
|
stdio: "inherit",
|
|
windowsHide: true,
|
|
shell: process.platform === "win32" && !path.isAbsolute(command),
|
|
env,
|
|
});
|
|
|
|
child.on("error", (error) => {
|
|
if ((error as NodeJS.ErrnoException).code === "ENOENT" && command === "docker") {
|
|
reject(new Error("Docker를 찾지 못했습니다. Docker Desktop을 설치하고 실행한 뒤 다시 시도하세요."));
|
|
return;
|
|
}
|
|
reject(error);
|
|
});
|
|
child.on("exit", (code) => {
|
|
if (code === 0) {
|
|
resolve();
|
|
return;
|
|
}
|
|
reject(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "null"}`));
|
|
});
|
|
});
|
|
}
|
|
|
|
export async function setupTts(): Promise<void> {
|
|
const config = loadConfig();
|
|
const logger = new Logger(config.DEBUG ? config.LOG_LEVEL : "error");
|
|
const docker = await resolveDockerCommand(config);
|
|
const dockerContext = path.resolve(process.cwd(), "docker", "melotts");
|
|
const cacheDir = path.resolve(process.cwd(), config.TTS_CACHE_DIR);
|
|
const outputDir = path.resolve(process.cwd(), config.TTS_OUTPUT_DIR);
|
|
|
|
await mkdir(cacheDir, { recursive: true });
|
|
await mkdir(outputDir, { recursive: true });
|
|
|
|
console.log(`MeloTTS Docker 이미지 빌드: ${config.TTS_IMAGE}`);
|
|
await run(docker, ["build", "-t", config.TTS_IMAGE, dockerContext]);
|
|
|
|
const tts = new MeloTtsService(config, logger);
|
|
|
|
console.log("MeloTTS 모델 워밍업...");
|
|
try {
|
|
await tts.warmup();
|
|
} finally {
|
|
await tts.destroy().catch(() => undefined);
|
|
}
|
|
|
|
console.log("로컬 TTS 환경 준비 완료");
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
void setupTts().catch((error) => {
|
|
console.error(error instanceof Error ? error.message : String(error));
|
|
process.exit(1);
|
|
});
|
|
}
|