transcribe.js (1677B)
1 const { spawn } = require('child_process'); 2 const fs = require('fs'); 3 const path = require('path'); 4 const https = require('https'); 5 const http = require('http'); 6 7 const SCRIPT = path.join(__dirname, '..', 'scripts', 'transcribe.py'); 8 const TMP_DIR = path.join(__dirname, '..', 'data', 'tmp'); 9 10 function downloadFile(url, dest) { 11 return new Promise((resolve, reject) => { 12 fs.mkdirSync(path.dirname(dest), { recursive: true }); 13 const file = fs.createWriteStream(dest); 14 const client = url.startsWith('https') ? https : http; 15 client.get(url, (res) => { 16 res.pipe(file); 17 file.on('finish', () => file.close(resolve)); 18 }).on('error', (err) => { 19 fs.unlink(dest, () => {}); 20 reject(err); 21 }); 22 }); 23 } 24 25 function runWhisper(audioPath) { 26 return new Promise((resolve, reject) => { 27 const env = { ...process.env }; 28 const proc = spawn('python3', [SCRIPT, audioPath], { env }); 29 30 let stdout = ''; 31 let stderr = ''; 32 proc.stdout.on('data', (d) => { stdout += d; }); 33 proc.stderr.on('data', (d) => { stderr += d; }); 34 35 proc.on('close', (code) => { 36 if (code !== 0) { 37 reject(new Error(`transcribe.py exited ${code}: ${stderr.trim()}`)); 38 } else { 39 resolve(stdout.trim()); 40 } 41 }); 42 }); 43 } 44 45 async function transcribeVoice(bot, fileId) { 46 fs.mkdirSync(TMP_DIR, { recursive: true }); 47 const tmpPath = path.join(TMP_DIR, `${fileId}.ogg`); 48 49 try { 50 const fileUrl = await bot.getFileLink(fileId); 51 await downloadFile(fileUrl, tmpPath); 52 const text = await runWhisper(tmpPath); 53 return text; 54 } finally { 55 fs.unlink(tmpPath, () => {}); 56 } 57 } 58 59 module.exports = { transcribeVoice };