UNPKG

@henteko/kumiki

Version:

A video generation tool that creates videos from JSON configurations

103 lines 3.17 kB
import crypto from 'node:crypto'; import fs from 'node:fs/promises'; import path from 'node:path'; import { getNarrationCacheDir } from '../utils/app-dirs.js'; import { logger } from '../utils/logger.js'; export class NarrationCacheService { cacheDir; constructor(cacheDir) { this.cacheDir = cacheDir || getNarrationCacheDir(); } async ensureCacheDir() { await fs.mkdir(this.cacheDir, { recursive: true }); } generateCacheKey(key) { const content = JSON.stringify({ text: key.text, voice: key.voice || {}, }); return crypto .createHash('sha256') .update(content) .digest('hex'); } getCachePath(key) { const hash = this.generateCacheKey(key); return path.join(this.cacheDir, `${hash}.wav`); } async exists(key) { const cachePath = this.getCachePath(key); try { await fs.access(cachePath); return true; } catch { return false; } } async get(key) { const cachePath = this.getCachePath(key); if (await this.exists(key)) { logger.debug('Narration cache hit', { text: key.text.substring(0, 50) + '...', cachePath }); return cachePath; } logger.debug('Narration cache miss', { text: key.text.substring(0, 50) + '...', cachePath }); return null; } async set(key, audioPath) { await this.ensureCacheDir(); const cachePath = this.getCachePath(key); // Copy audio file to cache await fs.copyFile(audioPath, cachePath); logger.debug('Narration cached', { text: key.text.substring(0, 50) + '...', cachePath }); return cachePath; } async clear() { try { const files = await fs.readdir(this.cacheDir); await Promise.all(files .filter(file => file.endsWith('.wav')) .map(file => fs.unlink(path.join(this.cacheDir, file)))); logger.info('Narration cache cleared'); } catch (error) { if (error.code !== 'ENOENT') { throw error; } } } async getCacheStats() { try { const files = await fs.readdir(this.cacheDir); let totalSize = 0; let count = 0; for (const file of files) { if (file.endsWith('.wav')) { const filePath = path.join(this.cacheDir, file); const stats = await fs.stat(filePath); totalSize += stats.size; count++; } } return { count, size: totalSize }; } catch (error) { if (error.code === 'ENOENT') { return { count: 0, size: 0 }; } throw error; } } } // Singleton instance export const narrationCacheService = new NarrationCacheService(); //# sourceMappingURL=narration-cache.js.map