const axios = require('axios');
const OpenAI = require('openai');
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
async function callGPTApi(keyword) {
const prompt =
`대한민국 대학교 강의에서 ${keyword}의 사전적 의미를 128자 이내로 답변해줘`;
try {
const chatCompletion = await openai.chat.completions.create({
messages: [{ role: 'user', content: prompt }],
model: 'gpt-3.5-turbo',
});
console.log(chatCompletion.choices[0].message);
if (chatCompletion && chatCompletion.choices) {
return chatCompletion.choices[0].message.content;
} else {
console.error('Invalid response structure:', chatCompletion);
return 'Error: Invalid response structure';
}
} catch (error) {
console.error('Error in API call:', error);
return `Error: ${error.message}`;
}
}
function processNLText(clientSocket, textData) {
return new Promise(async (resolve, reject) => {
try {
const response = await axios.post(
process.env.FLASK_HOST + '/process',
textData,
{ headers: { 'Content-Type': 'application/json' } }
);
const nlpResponse = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
const unProcessedText = nlpResponse.unProcessedText;
for (let i = 0; i < unProcessedText.length; i++) {
if (unProcessedText[i][1] === 'comment') {
const keyword = unProcessedText[i][0];
const description = await callGPTApi(keyword);
console.log(keyword + ' : ' + description);
nlpResponse.unProcessedText[i][2] = description;
}
}
clientSocket.emit('NLPResult', nlpResponse);
resolve();
} catch (error) {
console.error('Error in NLProcessing ', error);
reject(error);
}
});
}
위 코드로 ChatGPT API 요청 로직을 구현한다.
특정 음성 데이터가 위처럼 여러번 반복해서 해석되는 오류가 발생하였다.
try {
// Force fs.writefile to Sync
const buffer = Buffer.from(audioBlob);
await fs.promises.writeFile(tempInputPath, buffer);
// console.log(tempInputPath);
await convertToWav(tempInputPath, tempOutputPath);
const form = new FormData();
form.append('audio', fs.createReadStream(tempOutputPath));
const response = await axios.post(process.env.FLASK_HOST + '/transcribe', form, { headers: form.getHeaders() });
if (response.data.length <= 50) {
console.log("Transcription result : " + response.data);
clientSocket.emit('recognitionResult', response.data);
}
fs.unlinkSync(tempInputPath);
fs.unlinkSync(tempOutputPath);
resolve();
} catch (error) {
if (fs.existsSync(tempInputPath)) fs.unlinkSync(tempInputPath);
if (fs.existsSync(tempOutputPath)) fs.unlinkSync(tempOutputPath);
console.error('Error in transcription ', error);
reject(error);
}
이는 response.data.length
를 조건에 맞게 Frontend로 돌려주어 해결하였다.
...
this.sendTextDataInterval = setInterval(async () => {
if (this.preProcessedLen != this.scriptData.length) {
// 데이터를 잘라서 NLP 모델에 보내는 로직
if (this.lineCount >= 10) {
const arrStart = this.preProcessedLen;
const arrEnd = this.scriptData.length;
const unProcessedText = this.scriptData.slice(arrStart, arrEnd);
const sumText = unProcessedText.map(data => { return data[0]; }).join(' ');
const textData = JSON.stringify({
arrStart: arrStart,
arrEnd: arrEnd,
unProcessedText: unProcessedText,
sumText: sumText
});
this.socket.emit('nlProcessing', textData);
this.lineCount = 0;
this.preProcessedLen = this.scriptData.length
}
}
}, 5000);
...
words.forEach(word => {
if (word.trim() !== '') {
const tmp = [word, "none", ""];
this.scriptData.push(tmp);
// 줄바꿈 로직 추가
if (word.endsWith('.')) {
this.lineCount++;
this.scriptData.push(["", "br", ""]);
this.scriptData.push(["", "br", ""]);
}
}
});
this.lineCount >= 10
조건을 통해 10줄씩 데이터를 끊어서 NLP 모델로 전송해주었다.