main.25f9a19b.chunk.js.map
14.1 KB
{"version":3,"sources":["Login.js","tts.js","Channel.js","Body.js","App.js","reportWebVitals.js","index.js"],"names":["Login","AWS","config","region","credentials","CognitoIdentityCredentials","IdentityPoolId","polly","Polly","signatureVersion","audioQueue","audio","Audio","enqueueTTS","text","params","Presigner","getSynthesizeSpeechUrl","error","url","push","console","log","enableAudio","setInterval","paused","audioFile","shift","setAttribute","play","tts","socket","io","connect","on","event","emit","name","msg","Channel","props","channel","className","href","thumbnail","src","alt","game","view","isPlay","onClick","ChannelList","state","channels","xisPlaying","index","this","setState","map","changeState","React","Component","Body","App","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","document","getElementById"],"mappings":"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","file":"static/js/main.25f9a19b.chunk.js","sourcesContent":["import React from \"react\";\nimport \"./Login.css\";\n\nfunction Login(){ \n const OAuthUrl = `https://id.twitch.tv/oauth2/authorize?response_type=code&approval_prompt=auto&redirect_uri=http://localhost:3303/join&client_id=2d1gvcqyiyrk180qvnkec2fl23sv1o`; // oauth 인증용 url\n return (\n <div className=\"login\">\n <img \n src=\"https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg\"\n alt=\"\"\n />\n <a href={OAuthUrl}>Login to Twitch</a>\n </div>\n );\n}\n\nexport default Login;","import AWS from 'aws-sdk'\n// Polly를 사용하기 위한 자격증명을 설정한다.\nAWS.config.region = 'ap-northeast-2'; \nAWS.config.credentials = new AWS.CognitoIdentityCredentials({IdentityPoolId: 'ap-northeast-2:03db97c9-a857-45f3-be6e-3cf84d6f619b'});\nconst polly = new AWS.Polly({\n signatureVersion: 'v4',\n region: 'ap-northeast-2',\n});\n\nconst audioQueue = []\n// test data\n// const audioQueue = [\"https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3\", \"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3\", \"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3\"]\n\nconst audio = new Audio()\n\n// queue에서 작업(재생할 내용)을 0.5초마다 폴링하는 방식\nfunction enableAudio(){\n setInterval(()=>{\n // 앞선 tts 재생이 종료된 경우에만 새 tts를 실행\n if( !audio.paused){ return;}\n\n let audioFile = audioQueue.shift()\n // 재생할 게 있으면 재생\n if (audioFile){\n console.log(audioFile)\n audio.setAttribute(\"src\", audioFile)\n audio.play()\n }\n }, 500)\n}\n\nfunction enqueueTTS(text){\n let params = {\n 'Text': text,\n 'OutputFormat': 'mp3',\n 'VoiceId': 'Seoyeon'\n };\n let tts = new AWS.Polly.Presigner(params, polly)\n\n // tts로 변환한 음성 파일을 얻는다.\n tts.getSynthesizeSpeechUrl(params, function(error, url) {\n if (error) {\n } else {\n audioQueue.push(url)\n }\n })\n}\n\nconsole.log(\"테스트용 TTS 데이터를 주입합니다.\")\nenqueueTTS(`전에 data hazards에서 3가지 data-dependence를 배웠다. mips인 경우에는 in-order이라 True data dependency 문제밖에 안생겼었다\n\n근데 out-of-order 관점에서는 3개의 명령어가 동시에 fetch되는 경우를 생각해보자. \n\n만약 1, 3 line 순서 바뀌면 당연히 결과가 이상해진다. 전에 고려하지 못했던 output dependency 와 anti dependency 고려해줘야한다. `)\nenqueueTTS(\"복잡한 브랜치\")\nenqueueTTS(\"빵상 아주머니는 말씀하셨다.\")\nenqueueTTS(\"니가가라 하와이\")\n\nexport default {\n enableAudio,\n enqueueTTS, \n}\n","import React from \"react\";\nimport \"./Channel.css\";\nimport \"@material-ui/icons\"\nimport PersonIcon from \"@material-ui/icons/Person\";\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow';\nimport PauseIcon from '@material-ui/icons/Pause';\nimport { WatchOutlined } from \"@material-ui/icons\";\nimport io from 'socket.io-client'\nimport tts from './tts';\n\n// audioQueue에서 하나씩 뽑아서 재생한다.\ntts.enableAudio()\n\nconst socket = io.connect(\"http://localhost:3303\")\nsocket.on(\"connect\", event=>{\n // 테스트용으로 umi0410에게 입장.\n // 다른 거 아무거나 채널이름을 넣으면 되겠지만, 그렇게 하고싶으면 백엔드에서 인자설정을 해줘야함.\n socket.emit(\"joinRoom\", 'umi0410', '진수봇')\n})\n\n// 말해야할 메시지가 왔을 때. 이건 따로 Component와 묶지 않아도 알아서 실행됩니다.\nsocket.on('chat message', (name, msg)=>{\n console.log(msg)\n console.log(\"got message\")\n //tts를 audio로 변경해 audioQueue에 집어넣는다.\n tts.enqueueTTS(msg)\n})\n\n// 해당 채널을 재생하고자할 때 실행시켜주세요.\nconst listen = (channelName)=>{\n socket.emit(\"joinRoom\", channelName, \"dummy name\") // name이 뭔지 대연이도 잘 모름.\n}\n\n// 해당 채널을 재생 안하도록 할 때 실행시켜주세요.\nconst quit = (channelName)=>{\n socket.emit(\"leaveRoom\". channelName, \"dummy name\") // name이 뭔지 대연이도 잘 모름.\n}\n\nexport function Channel(props) {\n const channel = props.channel;\n\n return (\n <div className=\"channel\">\n <a href={channel.url} className=\"channel__url\">\n {channel.thumbnail && <img className=\"channel__thumbnail\" src={channel.thumbnail} alt=\"\"></img>}\n {!channel.thumbnail && <PersonIcon className=\"channel__icon\"/>}\n <div className=\"channel__box\">\n <div className=\"channel__info\">\n <div className=\"channel__name\">{channel.name}</div>\n <div className=\"channel__game\">{channel.game}</div>\n </div>\n <div className=\"channel__view\">{channel.view}</div>\n </div>\n </a>\n {channel.isPlay && <PauseIcon className=\"pause__icon\" onClick={props.onClick} />}\n {!channel.isPlay && <PlayArrowIcon className=\"play__icon\" onClick={props.onClick} />}\n </div>\n );\n}\n\nexport class ChannelList extends React.Component {\n constructor(props) {\n super(props);\n \n // data for test\n const test = [\n {\"name\": \"umi0410 진수\", \"view\": 123124124, \"game\": \"game2\" , \"url\": \"https://www.twitch.tv/umi0410\"},\n {\"name\": \"name1\", \"view\": 999, \"game\": \"game1\" ,\"url\": \"https://www.twitch.tv\", \"thumbnail\": \"https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg\"},\n {\"name\": \"name2\", \"view\": 123124124, \"game\": \"game2\" , \"url\": \"https://www.twitch.tv\"},\n {\"name\": \"name1\", \"view\": 999, \"game\": \"game1\" ,\"url\": \"https://www.twitch.tv\", \"thumbnail\": \"https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg\"},\n {\"name\": \"name2\", \"view\": 123124124, \"game\": \"game2\" , \"url\": \"https://www.twitch.tv\"},\n {\"name\": \"name1\", \"view\": 999, \"game\": \"game1\" ,\"url\": \"https://www.twitch.tv\", \"thumbnail\": \"https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg\"},\n {\"name\": \"name2\", \"view\": 123124124, \"game\": \"game2\" , \"url\": \"https://www.twitch.tv\"},\n {\"name\": \"name1\", \"view\": 999, \"game\": \"game1\" ,\"url\": \"https://www.twitch.tv\", \"thumbnail\": \"https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg\"},\n {\"name\": \"name2\", \"view\": 123124124, \"game\": \"game2\" , \"url\": \"https://www.twitch.tv\"},\n {\"name\": \"name1\", \"view\": 999, \"game\": \"game1\" ,\"url\": \"https://www.twitch.tv\", \"thumbnail\": \"https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg\"},\n {\"name\": \"name2\", \"view\": 123124124, \"game\": \"game2\" , \"url\": \"https://www.twitch.tv\"},\n \n ]\n\n this.state = {\n channels: test,\n xisPlaying: null,\n }\n }\n\n changeState(channel, index){\n const channels = this.state.channels;\n // 버튼을 누른 채널이 재생중일때\n if (channel.isPlay === true) {\n channels[index].isPlay = false;\n this.setState({\n channels: channels,\n xisPlaying: null,\n });\n }\n\n // 버튼을 누른 채널이 재생중이 아닐 때\n else {\n // xisPlaying이 null이 아닐 때\n if (this.state.xisPlaying !== null) {\n // 기존에 재생되던 채널의 isPlay를 false로, 클릭 이벤트가 발생한 채널의 isPlay를 true로 변경\n channels[this.state.xisPlaying].isPlay = false;\n channels[index].isPlay = true;\n }\n \n // xisPlaying이 null일 때\n else {\n channels[index].isPlay = true;\n }\n \n this.setState({\n channels: channels,\n xisPlaying: index,\n });\n }\n }\n\n render() {\n return (\n <div className=\"channel__list\">\n <div className=\"channel__list__title\"> CHANNEL LIST</div>\n <ul>\n {this.state.channels.map((channel, index) => (\n <li key={index}>\n <Channel \n channel={channel}\n onClick={ () => this.changeState(channel, index)}\n />\n <hr />\n </li>\n ))}\n </ul>\n </div>\n \n );\n }\n}","import React from \"react\";\nimport \"./Body.css\";\nimport {ChannelList} from \"./Channel.js\"\n\nfunction Body(){\n return (\n <div className=\"body\">\n <ChannelList />\n </div>\n );\n}\n\nexport default Body;","import './App.css';\nimport Login from \"./Login\";\nimport Body from \"./Body\";\n\nfunction App() {\n // let accessToken = null;\n let accessToken = 1;\n\n return (\n <div className=\"app\">\n {!accessToken && <Login />}\n {accessToken && <Body />}\n </div>\n );\n}\n\nexport default App;\n","const reportWebVitals = onPerfEntry => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nReactDOM.render(\n <React.StrictMode>\n <App />\n </React.StrictMode>,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}