const express = require('express'); const multer = require('multer'); const path = require('path'); const fs = require('fs'); const { exec } = require('child_process'); const fetch = require('node-fetch'); const FormData = require('form-data'); const app = express(); const port = 3000; const uploadsDir = path.join(__dirname, 'uploads'); if (!fs.existsSync(uploadsDir)) { fs.mkdirSync(uploadsDir); } const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.json()); const getNextFolderNumber = () => { const folders = fs.readdirSync(uploadsDir).filter(file => fs.statSync(path.join(uploadsDir, file)).isDirectory()); const folderNumbers = folders.map(folder => parseInt(folder)).filter(num => !isNaN(num)); return folderNumbers.length > 0 ? Math.max(...folderNumbers) + 1 : 1; }; let sentenceIndex = 0; let audioPaths = []; app.post('/save-audio', upload.single('audio'), async (req, res) => { const nextFolderNumber = getNextFolderNumber(); const folderPath = path.join(uploadsDir, nextFolderNumber.toString()); if (!fs.existsSync(folderPath)) { fs.mkdirSync(folderPath, { recursive: true }); } const rawAudioPath = path.join(folderPath, `audio_${sentenceIndex}.webm`); const wavAudioPath = path.join(folderPath, `audio_${sentenceIndex}.wav`); const transcriptionPath = path.join(folderPath, `transcription_${sentenceIndex}.txt`); fs.writeFileSync(rawAudioPath, req.file.buffer); fs.writeFileSync(transcriptionPath, req.body.transcript); const ffmpegCommand = `ffmpeg -i ${rawAudioPath} -ar 44100 -ac 1 ${wavAudioPath}`; exec(ffmpegCommand, async (error, stdout, stderr) => { if (error) { console.error(`Error converting audio to WAV: ${stderr}`); return res.status(500).send('Error converting audio to WAV'); } fs.unlinkSync(rawAudioPath); const formData = new FormData(); formData.append('original_path', fs.createReadStream(wavAudioPath)); formData.append('text', req.body.transcript); formData.append('lang', 'en'); formData.append('target_lang', 'es'); try { const response = await fetch('http://localhost:8000/process-audio/', { method: 'POST', body: formData, headers: formData.getHeaders() }); if (response.ok) { const result = await response.json(); console.log(result); audioPaths.push(result.audio_path); sentenceIndex++; res.status(200).json({ audio_path: result.audio_path, translation: result.translation }); } else { console.error('Failed to process the file via FastAPI'); res.status(500).send('Failed to process the file via FastAPI'); } } catch (error) { console.error('Error calling FastAPI:', error); res.status(500).send('Error calling FastAPI'); } }); }); app.get('/concatenate-audio', (req, res) => { const folderPath = path.join(uploadsDir, getNextFolderNumber().toString()); const finalAudioPath = path.join(folderPath, 'final_audio.wav'); const concatCommand = `ffmpeg -y -i "concat:${audioPaths.join('|')}" -acodec copy ${finalAudioPath}`; exec(concatCommand, (concatError, concatStdout, concatStderr) => { if (concatError) { console.error(`Error concatenating audio files: ${concatStderr}`); return res.status(500).send('Error concatenating audio files'); } res.status(200).json({ audio_path: finalAudioPath }); }); }); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); });