S3TVR-Demo / app /server.js
yalsaffar's picture
Updated Dockerfile for Hugging Face Spaces deployment
b941e8b
raw
history blame
4.25 kB
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++;
// Serve the audio file from the public directory
const publicAudioPath = path.join(publicDir, path.basename(result.audio_path));
fs.copyFileSync(result.audio_path, publicAudioPath);
res.status(200).json({ audio_path: `/public/${path.basename(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}`);
});