📢 공지합니다
이 게시글은 메인 페이지에 항상 고정되어 표시됩니다.
이번시간에는 스프링과 파이썬 스크립트를 잇는 작업을 실시하겠다.
먼저 스프링은 자바 진영이어서 파이썬에서 만든 기능을 쓸 수 없다... .
사용할려면 API를 통해 이어야 되는데 어떻게 할지 막막했다.
일단 필자는 위 사진과 같이 확성기 아이콘을 누르면 아래 뉴스 본문을 읽어주게 하는 것이 목표다.
즉 스프링에서 확성기 아이콘을 누르면 AJAX를 통해 실시간으로 뉴스 본문의 데이터가 이동하고
해당 데이터는 TTS 파이썬 스크립트로 이동하면 된다.
<script>
var speaker = false;
$(document).ready(function () {
$('#executeScript').click(function () {
if (!speaker) {
// speaker가 false일 때만 실행되도록
speaker = true;
$.ajax({
type: "POST",
url: "/run-tts",
data: {
"newsId": $("#originalContent").text()
},
success: function (data) {
alert("TTS 종료합니다.")
}
});
} else {
// speaker가 이미 true인 경우에 실행되도록
speaker = false;
// speaker를 false로 변경할 때 해당 URL을 끊습니다.
$.ajax({
type: "POST",
url: "/cancel-tts",
success: function (data) {
// 성공적으로 취소되었을 때 실행되는 코드를 작성합니다.
},
error: function (xhr, status, error) {
// 오류가 발생했을 때 실행되는 코드를 작성합니다.
console.error("TTS 취소 요청 중 오류가 발생하였습니다.", error);
}
});
}
});
});
</script>
확성기 아이콘을 누를때 실행되는 JS이다.
일단 if에서는 확성기 아이콘을 누를때 /run-tts로 이동하게 되고 else에서는 확성기 아이콘을 한번 더 누를때 종료해야되므로 /cancel-tts로 이동하게 된다.
<script>
// 페이지 이동을 감지하는 이벤트 핸들러
window.addEventListener('beforeunload', function (event) {
// AJAX 요청을 보냅니다.
$.ajax({
type: "POST",
url: "/cancel-tts2",
async: true,
success: function (data) {
console.log("TTS 취소 요청이 성공적으로 전송되었습니다.");
},
error: function (xhr, status, error) {
console.error("TTS 취소 요청 중 오류가 발생하였습니다.", error);
}
});
});
</script>
추가로 페이지를 이동할때는 당연히 TTS가 종료되어야 하므로 위 코드와 같이 페이지 이동이 감지되면
/cancel-tts2로 이동하게 된다. 물론 /cancel-tts2 와 /cancel-tts 둘의 기능은 똑같다. 그냥 구분하기 위해 이름만 바꿔놓았다.
자 이제 핵심코드들이다.
private Process ttsProcess; // TTS 스크립트를 실행할 프로세스
일단 먼저 컨트롤러에서 위와 같이 변수를 설정해두어야 된다. 프로세스가 있어야지 TTS를 취소할 수 있기 문이다.
@PostMapping("/run-tts")
@ResponseBody
public void postTTSScript(@RequestParam("newsId") String content) {
try {
// 파이썬 스크립트를 실행하는 명령어
String[] command = {"python", "C:/Users/chltm/PycharmProjects/amcn_AI/tts/tts.py", content};
// 프로세스 빌더를 사용하여 명령어 실행
ProcessBuilder processBuilder = new ProcessBuilder(command);
ttsProcess = processBuilder.start();
// 실행 결과를 읽어오기 위해 BufferedReader 사용
BufferedReader reader = new BufferedReader(new InputStreamReader(ttsProcess.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
log.info(line);
}
// 에러 출력 읽기
BufferedReader errorReader = new BufferedReader(new InputStreamReader(ttsProcess.getErrorStream()));
while ((line = errorReader.readLine()) != null) {
log.info(line);
}
// 프로세스 종료 상태 확인
int exitCode = ttsProcess.waitFor();
log.info(String.valueOf(exitCode));
} catch (Exception e) {
e.printStackTrace();
}
}
자 여기가 핵심코드들이다. TTS 아이콘을 누르면 실행되는 rest api이다.
// 파이썬 스크립트를 실행하는 명령어
String[] command = {"python", "C:/Users/chltm/PycharmProjects/amcn_AI/tts/tts.py", content};
// 프로세스 빌더를 사용하여 명령어 실행
ProcessBuilder processBuilder = new ProcessBuilder(command);
ttsProcess = processBuilder.start();
이 코드들 빼고 나머지는 필요가 없다. 아래 코드들은 그냥 log 정보를 얻기 위해서이지 실행하는데에 있어서는 필요가 없다.
이젠 저 코드에서 content 즉 넘어온 뉴스 본문데이터가 내 로컬에 저장되어있는 tts.py로 이동하게 된다.
def speak(content):
engine = pyttsx3.init()
engine.setProperty('rate', 230)
engine.say(content)
engine.runAndWait()
if __name__ == "__main__":
if len(sys.argv) > 1:
content = sys.argv[1]
speak(content)
else:
print("No content provided")
여기가 해당 tts.py 스크립트이다. 여기서 목소리가 나오게 되고 저 라이브러리를 사용하기 위해서는
import sys
import pyttsx3
pip install 해서 위 2가지를 설치해주면된다.
// POST 요청을 받아 파이썬 스크립트 실행 취소
@PostMapping("/cancel-tts")
@ResponseBody
public void cancelTTSScript() {
if (ttsProcess != null) {
ttsProcess.destroy(); // 파이썬 스크립트 실행 프로세스를 종료
log.info("TTS script execution canceled.");
} else {
log.info("No TTS script is currently running.");
}
}
// POST 요청을 받아 파이썬 스크립트 실행 취소
@PostMapping("/cancel-tts2")
@ResponseBody
public void cancelTTSScriptOther() {
log.info("하이");
if (ttsProcess != null) {
ttsProcess.destroy(); // 파이썬 스크립트 실행 프로세스를 종료
log.info("TTS script execution canceled.");
} else {
log.info("No TTS script is currently running.");
}
}
자 이제 아이콘을 한번 더 눌러 취소하거나 다른 페이지로 이동할 때 취소하면 위 해당 url로 넘어오게 되고
프로세스를 종료하기 위해 destory를 사용하면 TTS가 종료가 되는것을 확인할 수 있다.
물론 쟝고나 플라스크를 해서 통신해도 되고 자이썬을 이용해서 통신해도 되지만 위 방법이 제일 깔끔해서 위와 같이 코드를 작성했다.
@PostMapping("/run-tts")
@ResponseBody
public void postTTSScriptV2(@RequestParam("newsId") String content) {
try {
RestTemplate restTemplate = new RestTemplate();
String url = "http://127.0.0.1:8000/tts";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
JSONObject request = new JSONObject();
request.put("content", content);
HttpEntity<String> entity = new HttpEntity<>(request.toString(), headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
System.out.println("Response: " + response.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}
from fastapi import FastAPI
import asyncio
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from gtts import gTTS
import playsound
import pyttsx3
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.post('/tts')
async def tts(request: Request):
try:
content = await request.json()
if 'content' in content:
# TTS 엔진 초기화
engine = pyttsx3.init()
engine.setProperty('rate', 230)
engine.say(content)
engine.runAndWait()
# print(content)
# tts = gTTS(text=content['content'], lang='ko')
# tts.save("gg.mp3")
# playsound.playsound('gg')
# print("===")
return JSONResponse({"status": "success"}, status_code=200)
else:
raise HTTPException(status_code=400, detail="No content provided")
except Exception as e:
return JSONResponse({"status": "error", "message": str(e)}, status_code=500)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
위 코드는 스프링과 플라스크 서버간의 통신 방법 코드이다.
애초에 언어가 다른 자바와 파이썬을 상호작용하는 것의 어려움이 있었지만 나름 쉬웠고 할만했다.
인텔리제이에서 파이썬 사용하기 (0) | 2024.08.04 |
---|---|
스프링 소셜 로그인 구현하기(네이버, 카카오, OAuth2.0) (0) | 2024.07.09 |
스프링과 Open AI DALL-E-3 API 연결 (0) | 2024.05.30 |
KoBart 모델을 활용한 요약 모델 만들기 (1) | 2024.05.30 |
스프링 & AJAX를 활용한 실시간 메일 인증 (1) | 2024.05.15 |