life-todo

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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 };