Spaces:
Sleeping
Sleeping
const express = require('express'); | |
const multer = require('multer'); | |
const FormData = require('form-data'); | |
const axios = require('axios'); // 使用 axios 替换 node-fetch | |
const fetch = require('node-fetch'); // 保留用于翻译接口 | |
const app = express(); | |
const port = 3000; | |
const storage = multer.memoryStorage(); | |
const upload = multer({ storage: storage }); | |
app.use(express.json()); | |
app.use(express.urlencoded({ extended: true })); | |
app.use((req, res, next) => { | |
res.header('Access-Control-Allow-Origin', '*'); | |
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); | |
next(); | |
}); | |
const PYTHON_ASR_SERVICE_URL = 'http://localhost:5001/transcribe'; | |
// ASR Endpoint: 使用 axios 重写,确保超时正确生效 | |
app.post('/asr', upload.single('audio'), async (req, res) => { | |
console.log("Received ASR request, proxying to Python service with axios..."); | |
if (!req.file) { | |
return res.status(400).json({ error: 'No audio file uploaded.' }); | |
} | |
try { | |
const form = new FormData(); | |
form.append('audio', req.file.buffer, { | |
filename: req.file.originalname, | |
contentType: req.file.mimetype, | |
}); | |
const langCode = req.body.sourceLang.split('-')[0]; | |
form.append('language', langCode); | |
console.log(`Forwarding audio buffer with language '${langCode}'...`); | |
// 使用 axios 发送请求,并设置一个可靠的60秒超时 | |
const asrResponse = await axios.post(PYTHON_ASR_SERVICE_URL, form, { | |
headers: form.getHeaders(), | |
timeout: 60000 // 60秒超时,作用于整个请求 | |
}); | |
const asrData = asrResponse.data; | |
console.log(`Transcription result: "${asrData.transcript}"`); | |
res.json({ transcript: asrData.transcript }); | |
} catch (error) { | |
if (error.code === 'ECONNABORTED') { | |
console.error("Failed to process ASR request: Axios request timed out."); | |
res.status(504).json({ error: 'Request to ASR service timed out.' }); | |
} else { | |
console.error("Failed to process ASR request:", error.message); | |
res.status(500).json({ error: error.message }); | |
} | |
} | |
}); | |
// Translate Endpoint (保持不变) | |
app.post('/translate', async (req, res) => { | |
const { text, sourceLang, targetLang } = req.body; | |
if (!text || !sourceLang || !targetLang) { | |
return res.status(400).json({ error: 'Missing text, sourceLang, or targetLang' }); | |
} | |
const source = sourceLang.split('-')[0]; | |
const target = targetLang.split('-')[0]; | |
if (source === target) { | |
return res.json({ translatedText: text }); | |
} | |
const apiUrl = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${source}&tl=${target}&dt=t&q=${encodeURIComponent(text)}`; | |
try { | |
const response = await fetch(apiUrl); | |
const data = await response.json(); | |
if (data && data[0] && data[0][0] && data[0][0][0]) { | |
const translatedText = data[0].map(segment => segment[0]).join(''); | |
res.json({ translatedText }); | |
} else { | |
throw new Error('Unexpected API response from translation service'); | |
} | |
} catch (error) { | |
console.error('Translation request error:', error.message); | |
res.status(500).json({ error: 'Translation failed' }); | |
} | |
}); | |
app.get('/', (req, res) => { | |
res.status(200).send('Node.js server is running and healthy!'); | |
}); | |
app.listen(port, () => { | |
console.log(`Node.js proxy server listening at http://localhost:${port}`); | |
}); | |