TTs whisper
This commit is contained in:
119
backend/src/controllers/audio.controller.ts
Normal file
119
backend/src/controllers/audio.controller.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { Router } from 'express';
|
||||
import multer from 'multer';
|
||||
import { execFile } from 'child_process';
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import { writeFile, unlink } from 'fs';
|
||||
import { raspiService } from '../services/raspi.service.js';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
const writeFileAsync = promisify(writeFile);
|
||||
const unlinkAsync = promisify(unlink);
|
||||
|
||||
const router = Router();
|
||||
|
||||
const upload = multer({ storage: multer.memoryStorage() });
|
||||
|
||||
router.get('/incoming', async (_req, res) => {
|
||||
try {
|
||||
const result = await raspiService.listIncomingAudio();
|
||||
res.json(result);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||
res.status(500).json({ error: `List incoming failed: ${message}` });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/lock/:filename', async (req, res) => {
|
||||
try {
|
||||
const { filename } = req.params;
|
||||
const result = await raspiService.lockAudio({ filename });
|
||||
res.json(result);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||
res.status(500).json({ error: `Lock audio failed: ${message}` });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/unlock/:filename', async (req, res) => {
|
||||
try {
|
||||
const { filename } = req.params;
|
||||
const result = await raspiService.unlockAudio({ filename });
|
||||
res.json(result);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||
res.status(500).json({ error: `Unlock audio failed: ${message}` });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/cancel/:filename', async (req, res) => {
|
||||
try {
|
||||
const { filename } = req.params;
|
||||
const result = await raspiService.cancelAudio({ filename });
|
||||
res.json(result);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||
res.status(500).json({ error: `Cancel audio failed: ${message}` });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/process/:filename', async (req, res) => {
|
||||
try {
|
||||
const { filename } = req.params;
|
||||
const result = await raspiService.processAudio({ filename });
|
||||
res.json(result);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||
res.status(500).json({ error: `Process audio failed: ${message}` });
|
||||
}
|
||||
});
|
||||
|
||||
const whisperModel = process.env.WHISPER_MODEL ?? 'base';
|
||||
const whisperLanguage = process.env.WHISPER_LANGUAGE ?? 'ca';
|
||||
|
||||
router.post('/upload', upload.single('file'), async (req, res) => {
|
||||
let tmpFile: string | undefined;
|
||||
try {
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ error: 'No audio file provided' });
|
||||
}
|
||||
|
||||
const ext = req.file.originalname.split('.').pop()?.toLowerCase() || 'wav';
|
||||
tmpFile = join(tmpdir(), `quibot-audio-${Date.now()}.${ext}`);
|
||||
await writeFileAsync(tmpFile, req.file.buffer);
|
||||
|
||||
console.log(`[whisper] Model: ${whisperModel}, Language: ${whisperLanguage}, File: ${tmpFile}`);
|
||||
|
||||
const { stdout, stderr } = await execFileAsync('whisper', [
|
||||
tmpFile,
|
||||
'--model', whisperModel,
|
||||
'--language', whisperLanguage,
|
||||
'--output_format', 'txt',
|
||||
], { maxBuffer: 50 * 1024 * 1024 });
|
||||
|
||||
if (stderr) {
|
||||
console.log(`[whisper] stderr: ${stderr}`);
|
||||
}
|
||||
|
||||
const transcription = stdout.trim();
|
||||
|
||||
res.json({
|
||||
transcription,
|
||||
originalFilename: req.file.originalname,
|
||||
});
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : 'Unknown error';
|
||||
res.status(500).json({ error: `Audio transcription failed: ${message}` });
|
||||
} finally {
|
||||
if (tmpFile) {
|
||||
try {
|
||||
await unlinkAsync(tmpFile);
|
||||
} catch {
|
||||
// ignore cleanup errors
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user