UNPKG

nwhisper

Version:

Native Node.js bindings for OpenAI's Whisper using whisper.cpp. High-performance local speech-to-text with custom model support.

76 lines 3.52 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertToWavType = exports.checkIfFileExists = void 0; const node_fs_1 = __importDefault(require("node:fs")); const node_path_1 = __importDefault(require("node:path")); const shelljs_1 = __importDefault(require("shelljs")); const checkIfFileExists = (filePath) => { if (!node_fs_1.default.existsSync(filePath)) { throw new Error(`[nwhisper] Error: No such file: ${filePath}`); } }; exports.checkIfFileExists = checkIfFileExists; async function isValidWavHeader(filePath) { return new Promise((resolve, reject) => { const readable = node_fs_1.default.createReadStream(filePath, { end: 43 }); let data = Buffer.alloc(0); readable.on('data', (chunk) => { const bufferChunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); data = Buffer.concat([data, bufferChunk]); }); readable.on('end', () => { const isWav = data.toString('binary', 0, 4) === 'RIFF' || data.toString('binary', 0, 4) === 'RIFX'; if (!isWav) { resolve(false); return; } if (data.length >= 28) { const sampleRate = data.readUInt32LE(24); resolve(sampleRate === 16000); } else { resolve(false); } }); readable.on('error', err => reject(err)); }); } const convertToWavType = async (inputFilePath, logger = console) => { const fileExtension = node_path_1.default.extname(inputFilePath).toLowerCase(); logger.debug(`[nwhisper] Checking if the file is a valid WAV: ${inputFilePath}`); if (fileExtension === '.wav') { const isWav = await isValidWavHeader(inputFilePath); if (isWav) { logger.debug(`[nwhisper] File is a valid WAV file.`); return inputFilePath; } else { logger.debug(`[nwhisper] File has a .wav extension but is not a valid WAV, overwriting...`); // Use a temporary file to avoid overwrite conflicts const tempFile = `${inputFilePath}.temp.wav`; const command = `ffmpeg -nostats -loglevel error -y -i "${inputFilePath}" -ar 16000 -ac 1 -c:a pcm_s16le "${tempFile}"`; const result = shelljs_1.default.exec(command); if (result.code !== 0) { throw new Error(`[nwhisper] Failed to convert audio file: ${result.stderr}`); } node_fs_1.default.renameSync(tempFile, inputFilePath); return inputFilePath; } } else { // Convert to a new WAV file const outputFilePath = node_path_1.default.join(node_path_1.default.dirname(inputFilePath), `${node_path_1.default.basename(inputFilePath, fileExtension)}.wav`); logger.debug(`[nwhisper] Converting to a new WAV file: ${outputFilePath}`); const command = `ffmpeg -nostats -loglevel error -y -i "${inputFilePath}" -ar 16000 -ac 1 -c:a pcm_s16le "${outputFilePath}"`; const result = shelljs_1.default.exec(command); if (result.code !== 0) { throw new Error(`[nwhisper] Failed to convert audio file: ${result.stderr}`); } return outputFilePath; } }; exports.convertToWavType = convertToWavType; //# sourceMappingURL=utils.js.map