#! /usr/bin/env node // Javascript layer for using the whisper.cpp built-in model downloader scripts // // npx whisper-node download import shell from 'shelljs'; import readlineSync from 'readline-sync'; import {DEFAULT_MODEL, NODE_MODULES_MODELS_PATH} from './constants' const MODELS_LIST = [ "tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large-v1", "large" ]; const askModel = async () => { const answer = await readlineSync.question(`\n[whisper-node] Enter model name (e.g. 'base.en') or 'cancel' to exit\n(ENTER for base.en): `) if (answer === "cancel") { console.log("[whisper-node] Exiting model downloader. Run again with: 'npx whisper-node download'"); process.exit(0); } // user presses enter else if (answer === "") { console.log("[whisper-node] Going with", DEFAULT_MODEL); return DEFAULT_MODEL; } else if (!MODELS_LIST.includes(answer)) { console.log("\n[whisper-node] FAIL: Name not found. Check your spelling OR quit wizard and use custom model."); // re-ask question return await askModel(); } return answer; } export default async function downloadModel() { try { // shell.exec("echo $PWD"); shell.cd(NODE_MODULES_MODELS_PATH); console.log(` | Model | Disk | RAM | |-----------|--------|---------| | tiny | 75 MB | ~390 MB | | tiny.en | 75 MB | ~390 MB | | base | 142 MB | ~500 MB | | base.en | 142 MB | ~500 MB | | small | 466 MB | ~1.0 GB | | small.en | 466 MB | ~1.0 GB | | medium | 1.5 GB | ~2.6 GB | | medium.en | 1.5 GB | ~2.6 GB | | large-v1 | 2.9 GB | ~4.7 GB | | large | 2.9 GB | ~4.7 GB | `); // ensure running in correct path if (!shell.which("./download-ggml-model.sh")) { throw "whisper-node downloader is not being run from the correct path! cd to project root and run again." } const modelName = await askModel(); // default is .sh let scriptPath = "./download-ggml-model.sh" // windows .cmd version if(process.platform === 'win32') scriptPath = "download-ggml-model.cmd"; shell.exec(`${scriptPath} ${modelName}`); // TODO: add check in case download-ggml-model doesn't return a successful download. // to prevent continuing to compile; that makes it harder for user to see which script failed. console.log("[whisper-node] Attempting to compile model..."); // move up directory, run make in whisper.cpp shell.cd("../") // this has to run in whichever directory the model is located in?? shell.exec("make"); process.exit(0); } catch (error) { console.log("ERROR Caught in downloadModel") console.log(error); return error; } } // runs after being called in package.json downloadModel();