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'); const publicDir = path.join(__dirname, 'public'); if (!fs.existsSync(uploadsDir)) { fs.mkdirSync(uploadsDir, { recursive: true }); } if (!fs.existsSync(publicDir)) { fs.mkdirSync(publicDir, { recursive: true }); } const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); app.use(express.static(publicDir)); 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++; // Copy the audio file to the public directory const publicAudioPath = path.join(publicDir, `generated_audio_${sentenceIndex}.wav`); fs.copyFile(result.audio_path, publicAudioPath, (err) => { if (err) { console.error('Error copying audio file to public directory:', err); return res.status(500).send('Error copying audio file to public directory'); } res.status(200).json({ audio_path: `generated_audio_${sentenceIndex}.wav`, 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('/download-audio', (req, res) => { const filePath = path.join(publicDir, req.query.file_path); res.download(filePath); }); 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}`); });