Merge branch 'integration' into 'master'
1차 Integration 1차적으로 integration해서 테스트해봤습니다. 시험 앞두고 개발하느라 고생이 많습니다 모두 개인적으로 핸드폰으로 방송을 켜서 확인해본 결과 아주 1차적인 목표였던 번역과 번역 후 말하기 기능은 동작했습니다. 개선해야할 사항은 * 번역한 텍스트만 `chat message` 이벤트를 emit하도록 설정. 일반 텍스트나 번역 전의 텍스트는 필요하지 않을 듯합니다. * backend 설정 유연하게. server의 README.md에 잘못 표기된 내용이나 오타가 많습니다. 그리고 .env에서도 필요 없는 환경변수는 없애거나 혹시 모를 용도를 표기해주셨으면 합니다. * **frontend와 backend의 oauth 로그인 설정**. 이 설정이 되어야 백엔드에서도 인증 처리를 한 뒤 청취 가능한 채널 목록을 관리할 수 있을 것 같습니다. * backend에서 `/channels` channel list api, frontend에서 해당 api를 이용해 채널 리스트 업데이트 기능이 추가되어야할 것 같습니다. See merge request !11
Showing
11 changed files
with
115 additions
and
44 deletions
This diff could not be displayed because it is too large.
... | @@ -8,9 +8,11 @@ | ... | @@ -8,9 +8,11 @@ |
8 | "@testing-library/jest-dom": "^5.11.4", | 8 | "@testing-library/jest-dom": "^5.11.4", |
9 | "@testing-library/react": "^11.1.0", | 9 | "@testing-library/react": "^11.1.0", |
10 | "@testing-library/user-event": "^12.1.10", | 10 | "@testing-library/user-event": "^12.1.10", |
11 | + "aws-sdk": "^2.804.0", | ||
11 | "react": "^17.0.1", | 12 | "react": "^17.0.1", |
12 | "react-dom": "^17.0.1", | 13 | "react-dom": "^17.0.1", |
13 | "react-scripts": "4.0.1", | 14 | "react-scripts": "4.0.1", |
15 | + "socket.io-client": "^3.0.3", | ||
14 | "web-vitals": "^0.2.4" | 16 | "web-vitals": "^0.2.4" |
15 | }, | 17 | }, |
16 | "scripts": { | 18 | "scripts": { | ... | ... |
... | @@ -5,6 +5,31 @@ import PersonIcon from "@material-ui/icons/Person"; | ... | @@ -5,6 +5,31 @@ import PersonIcon from "@material-ui/icons/Person"; |
5 | import PlayArrowIcon from '@material-ui/icons/PlayArrow'; | 5 | import PlayArrowIcon from '@material-ui/icons/PlayArrow'; |
6 | import PauseIcon from '@material-ui/icons/Pause'; | 6 | import PauseIcon from '@material-ui/icons/Pause'; |
7 | import { WatchOutlined } from "@material-ui/icons"; | 7 | import { WatchOutlined } from "@material-ui/icons"; |
8 | +import io from 'socket.io-client' | ||
9 | +import tts from './tts'; | ||
10 | + | ||
11 | +const socket = io.connect("http://localhost:3000") | ||
12 | +socket.on("connect", event=>{ | ||
13 | + // 테스트용으로 umi0410에게 입장. | ||
14 | + // 다른 거 아무거나 채널이름을 넣으면 되겠지만, 그렇게 하고싶으면 백엔드에서 인자설정을 해줘야함. | ||
15 | + socket.emit("joinRoom", 'umi0410', '진수봇') | ||
16 | +}) | ||
17 | + | ||
18 | +// 말해야할 메시지가 왔을 때. 이건 따로 Component와 묶지 않아도 알아서 실행됩니다. | ||
19 | +socket.on('chat message', (name, msg)=>{ | ||
20 | + console.log(msg) | ||
21 | + tts.speak(msg) | ||
22 | +}) | ||
23 | + | ||
24 | +// 해당 채널을 재생하고자할 때 실행시켜주세요. | ||
25 | +const listen = (channelName)=>{ | ||
26 | + socket.emit("joinRoom", channelName, "dummy name") // name이 뭔지 대연이도 잘 모름. | ||
27 | +} | ||
28 | + | ||
29 | +// 해당 채널을 재생 안하도록 할 때 실행시켜주세요. | ||
30 | +const quit = (channelName)=>{ | ||
31 | + socket.emit("leaveRoom". channelName, "dummy name") // name이 뭔지 대연이도 잘 모름. | ||
32 | +} | ||
8 | 33 | ||
9 | export function Channel(props) { | 34 | export function Channel(props) { |
10 | const channel = props.channel; | 35 | const channel = props.channel; |
... | @@ -34,6 +59,7 @@ export class ChannelList extends React.Component { | ... | @@ -34,6 +59,7 @@ export class ChannelList extends React.Component { |
34 | 59 | ||
35 | // data for test | 60 | // data for test |
36 | const test = [ | 61 | const test = [ |
62 | + {"name": "umi0410 진수", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv/umi0410"}, | ||
37 | {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, | 63 | {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, |
38 | {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, | 64 | {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, |
39 | {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, | 65 | {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, |
... | @@ -44,6 +70,7 @@ export class ChannelList extends React.Component { | ... | @@ -44,6 +70,7 @@ export class ChannelList extends React.Component { |
44 | {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, | 70 | {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, |
45 | {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, | 71 | {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, |
46 | {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, | 72 | {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, |
73 | + | ||
47 | ] | 74 | ] |
48 | 75 | ||
49 | this.state = { | 76 | this.state = { | ... | ... |
frontend/src/tts.js
0 → 100644
1 | +import AWS from 'aws-sdk' | ||
2 | +// Polly를 사용하기 위한 자격증명을 설정한다. | ||
3 | +AWS.config.region = 'ap-northeast-2'; | ||
4 | +AWS.config.credentials = new AWS.CognitoIdentityCredentials({IdentityPoolId: 'ap-northeast-2:03db97c9-a857-45f3-be6e-3cf84d6f619b'}); | ||
5 | +const polly = new AWS.Polly({ | ||
6 | + signatureVersion: 'v4', | ||
7 | + region: 'ap-northeast-2', | ||
8 | +}); | ||
9 | + | ||
10 | +function speak(text){ | ||
11 | + let params = { | ||
12 | + 'Text': text, | ||
13 | + 'OutputFormat': 'mp3', | ||
14 | + 'VoiceId': 'Seoyeon' | ||
15 | + }; | ||
16 | + let tts = new AWS.Polly.Presigner(params, polly) | ||
17 | + | ||
18 | + // tts로 변환한 음성 파일을 얻는다. | ||
19 | + tts.getSynthesizeSpeechUrl(params, function(error, url) { | ||
20 | + if (error) { | ||
21 | + } else { | ||
22 | + setTimeout(()=>{ | ||
23 | + console.log("실행") | ||
24 | + let audio = new Audio(url) | ||
25 | + audio.play() | ||
26 | + // .then(delete audio); | ||
27 | + }, 3000) | ||
28 | + } | ||
29 | + }) | ||
30 | +} | ||
31 | +export default { | ||
32 | + "speak": speak, | ||
33 | +} |
frontend/src/websocket.js
0 → 100644
File mode changed
1 | -// const tmi = require('tmi.js'); | 1 | +const tmi = require('tmi.js'); |
2 | -// const papago = require('./openAPIs/papago_api') | 2 | +const papago = require('./openAPIs/papago_api') |
3 | -// const ttlserver = require('../socket_server') | 3 | +const ttlserver = require('../socket_server') |
4 | - | 4 | + |
5 | -// // Define configuration options | 5 | +// Define configuration options |
6 | -// var opts = { | 6 | +var opts = { |
7 | -// identity: { | 7 | + identity: { |
8 | -// username: process.env.BOT_USERNAME, | 8 | + username: process.env.BOT_USERNAME, |
9 | -// password: process.env.OAUTH_TOKEN | 9 | + password: process.env.OAUTH_TOKEN |
10 | -// }, | 10 | + }, |
11 | -// channels: [ | 11 | + channels: [ |
12 | -// 'bachelorchuckchuck' | 12 | + 'bachelorchuckchuck' |
13 | -// ] | 13 | + ] |
14 | -// }; | 14 | +}; |
15 | - | 15 | + |
16 | -// // Create a client with our options | 16 | +// Create a client with our options |
17 | -// const client = new tmi.client(opts); | 17 | +const client = new tmi.client(opts); |
18 | - | 18 | + |
19 | -// // Register our event handlers (defined below) | 19 | +// Register our event handlers (defined below) |
20 | -// client.on('message', onMessageHandler); | 20 | +client.on('message', onMessageHandler); |
21 | -// client.on('connected', onConnectedHandler); | 21 | +client.on('connected', onConnectedHandler); |
22 | - | 22 | + |
23 | -// // Connect to Twitch: | 23 | +// Connect to Twitch: |
24 | -// client.connect(); | 24 | +client.connect(); |
25 | - | 25 | + |
26 | -// // Called every time a message comes in | 26 | +// Called every time a message comes in |
27 | -// function onMessageHandler (target, context, msg, self) { | 27 | +function onMessageHandler (target, context, msg, self) { |
28 | -// if (self) { return; } // Ignore messages from the bot | 28 | + if (self) { return; } // Ignore messages from the bot |
29 | 29 | ||
30 | -// client.say(target, `/color `+changecolor()); | 30 | + client.say(target, `/color `+changecolor()); |
31 | -// papago.detectchat(msg, client, target); | 31 | + papago.detectchat(msg, client, target); |
32 | 32 | ||
33 | -// if(msg == '척척학사'){ | 33 | + if(msg == '척척학사'){ |
34 | -// client.say(target, `안녕하세요 척척학사의 방송입니다.`); | 34 | + client.say(target, `안녕하세요 척척학사의 방송입니다.`); |
35 | -// } | 35 | + } |
36 | 36 | ||
37 | -// } | 37 | +} |
38 | 38 | ||
39 | -// exports.addChannel = (channel) =>{ | 39 | +exports.addChannel = (channel) =>{ |
40 | -// opts.channels.append(channel); | 40 | + opts.channels.append(channel); |
41 | -// } | 41 | +} |
42 | 42 | ||
43 | -// // Called every time the bot connects to Twitch chat | 43 | +// Called every time the bot connects to Twitch chat |
44 | -// function onConnectedHandler (addr, port) { | 44 | +function onConnectedHandler (addr, port) { |
45 | -// console.log(`* Connected to ${addr}:${port}`); | 45 | + console.log(`* Connected to ${addr}:${port}`); |
46 | -// } | 46 | +} | ... | ... |
... | @@ -4,11 +4,13 @@ | ... | @@ -4,11 +4,13 @@ |
4 | "description": "twitch translator chatbot & tts server dev", | 4 | "description": "twitch translator chatbot & tts server dev", |
5 | "main": "socket_server.js", | 5 | "main": "socket_server.js", |
6 | "scripts": { | 6 | "scripts": { |
7 | + "start": "node socket_server.js", | ||
7 | "test": "echo \"Error: no test specified\" && exit 1" | 8 | "test": "echo \"Error: no test specified\" && exit 1" |
8 | }, | 9 | }, |
9 | "author": "Daeyeonkim97", | 10 | "author": "Daeyeonkim97", |
10 | "license": "ISC", | 11 | "license": "ISC", |
11 | "dependencies": { | 12 | "dependencies": { |
13 | + "cors": "^2.8.5", | ||
12 | "dotenv": "^8.2.0", | 14 | "dotenv": "^8.2.0", |
13 | "ejs": "^3.1.5", | 15 | "ejs": "^3.1.5", |
14 | "express": "^4.17.1", | 16 | "express": "^4.17.1", | ... | ... |
1 | const config = require('./config/config') | 1 | const config = require('./config/config') |
2 | 2 | ||
3 | const app = require('express')(); | 3 | const app = require('express')(); |
4 | +const cors = require('cors') | ||
5 | +app.use(cors()) //express 기본 응답에 대한 cors | ||
4 | const http = require('http').Server(app); | 6 | const http = require('http').Server(app); |
5 | -const io = require('socket.io')(http); | 7 | +const io = require('socket.io')(http, { |
8 | + cors:{ | ||
9 | + origin: "*", | ||
10 | + } | ||
11 | +}); | ||
6 | const papago = require('./openAPIs/papago_api'); | 12 | const papago = require('./openAPIs/papago_api'); |
7 | 13 | ||
8 | const tmi = require('tmi.js'); | 14 | const tmi = require('tmi.js'); | ... | ... |
-
Please register or login to post a comment