Skip to content

실시간 댄스 배틀 플랫폼 PLAY DANCE LIVE! (SW정글 나만의 무기를 갖기 프로젝트)

Notifications You must be signed in to change notification settings

ProdMoon/play-dance-live-dev

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PLAY DANCE LIVE!

JS badge React badge Springboot badge Redis badge MySQL badge

SW사관학교 정글 5기 Team Project (2022.12.22 ~ 2023.1.28)


서비스 소개

실시간 댄스 배틀 플랫폼

PLAY DANCE LIVE! 는 실시간으로 1대 1 릴레이 댄스 배틀을 펼치고, 시청할 수 있는 플랫폼입니다.

시연영상

서비스 소개

랜덤으로 나오는 댄스 챌린지를 소화하고 챔피언의 자리를 차지해라!

  • 랜덤으로 플레이 곡 선정

    랜덤룰렛

  • 챌린지 스타트! 실시간으로 응원하자

    실시간응원

  • 승자는 계속해서 플레이

    연승화면

포스터

포스터 저용량 복사


How To Deploy

배포 환경

AWS EC2 하나에 Frontend, Backend, Openvidu Deployment를 모두 올렸습니다.

서버 사양:

    AWS EC2 t2.medium (2 vcpu, 4 GiB)

    ubuntu 22.04 LTS (amd64)

    22GiB storage

Openvidu v2.25.0:

    Installation Mode: On Premises

Front-end:

    React v17.0.1 created by create-react-app

Back-end:

    Java SpringBoot v2.7.7 (Java 11)

기본적으로 openvidu 공식 문서의 Deployment on premises의 내용대로 진행한 후에 다음 내용을 참고합니다.

  • 여러분이 공식문서를 잘 따라왔다면, 다음 항목들이 완료되었을 것입니다.

    • Openvidu를 EC2에 잘 설치했습니다.

    • /opt/openvidu/.env 파일을 올바르게 설정했습니다. (아래의 도메인과 SSL 환경설정 부분을 참고하세요)

  • 그리고 여러분의 frontend 코드와 backend(application server) 코드를 약간 수정해주어야 합니다.

    • frontend/.env.production

      REACT_APP_HOST=domain.com
      

      domain.com 대신 여러분의 도메인 주소를 넣으세요.

    • backend에서 openvidu 관련 설정과 서버 포트 설정이 있을 겁니다. 서버 포트는 5000번으로 수정해주시고, OPENVIDU_URL은 다음과 같이 설정해 주세요.

      OPENVIDU_URL: http://localhost:5443/
      

      Note

      여러분이 코드를 이해했다면, 서버 포트를 5000번이 아닌 다른 포트로 매핑해도 상관없습니다.

  • 그리고 이제 nginx 환경설정을 약간 수정해야 합니다.

    • Openvidu 공식 문서: Modify nginx configuration의 내용을 참고하며 진행했습니다.

    • ./openvidu start 를 해서 openvidu와 nginx가 실행되고 있는 상태로 만듭니다.

    • 아래 코드를 실행하면 custom-nginx.conf, nginx.conf 파일이 /opt/openvidu 경로에 만들어집니다.

      sudo su
      cd /opt/openvidu
      docker-compose exec nginx cat /etc/nginx/conf.d/default.conf > custom-nginx.conf
      docker-compose exec nginx cat /etc/nginx/nginx.conf > nginx.conf
    • 이제 vi로 custom-nginx.conf를 수정해봅시다. (sudo 권한이 필요할 겁니다)

      많은 코드들이 있을텐데, yourapp과 관련된 설정만 수정해 보겠습니다.

      # Your App
      upstream yourapp {
          server localhost:5442;
      }
      
      upstream openviduserver {
          server localhost:5443;
      }
      
      # ...생략
      
      server {
          listen 443 ssl;
          listen [::]:443 ssl;
          server_name domain.com;
      
          # ...생략
      
          # Your App
          location / {
              proxy_pass http://yourapp;  #your app
          }
      
          # ...생략
      }

      기본적으로 location / 에 대해 5442 포트로 proxy_pass 되어 있습니다.

      저희는 react의 빌드된 파일을 node 서버가 5442번 포트에서 듣도록 하고, springboot 백엔드 서버를 tomcat이 5000번 포트에서 듣도록 설정했습니다.

      그리고 백엔드로의 요청은 모두 $host/api/… 형태가 되도록 작성했습니다.

      이에 맞게 파일을 수정해 보겠습니다.

      # Your App
      upstream frontendserver {
          server localhost:5442;
      }
      
      upstream openviduserver {
          server localhost:5443;
      }
      
      upstream backendserver {
          server localhost:5000;
      }
      
      # ...생략
      
      server {
          listen 443 ssl;
          listen [::]:443 ssl;
          server_name domain.com;
      
          # ...생략
      
          # Your App
          location / {
              proxy_pass http://frontendserver;
          }
      
          location /api/ {
              proxy_pass http://backendserver;
          }
      
          # ...생략
      }
    • 이제 /opt/openvidu/docker-compose.yml 파일에 다음 라인들을 추가해주고 openvidu를 재시작하면 됩니다.

      nginx:
              ...
              volumes:
                  ...
                  - ./custom-nginx.conf:/custom-nginx/custom-nginx.conf
                  - ./nginx.conf:/etc/nginx/nginx.conf

도메인과 SSL 환경설정

Let’s Encrypt 인증 방식

다음과 같이 구현하고 싶을 때 사용할 수 있는 방식입니다.

  • 상업 서비스를 위해 openvidu를 사용하고 싶을 때 (물론 개발 목적으로도 가능)
  • Fully Qualified Domain Name(FQDN)으로 사용하고 싶을 때
  • 유효한 SSL 인증을 사용하고 싶을 때

구현을 위해서는 아래 내용에 따르세요.

  • 서버의 Public IP를 가리키는 FQDN을 등록하기

    • Type A 방식으로 public IP를 가리키는 DNS 등록을 하면 됩니다. (gabia 같은 곳에서 도메인 DNS 등록하는 것을 말함)
  • /opt/openvidu/.env 파일 수정하기

    • 파일을 다음 내용과 같이 수정하세요.
    DOMAIN_OR_PUBLIC_IP=example.openvidu.io  # 위에서 등록한 도메인을 적으면 됩니다.
    
    CERTIFICATE_TYPE=letsencrypt
    
    OPENVIDU_SECRET=YOUR_SECRET  # 임의의 비밀번호. 튜토리얼에서는 MY_SECRET 이었습니다.
    
    [email protected]  # let's encrypt를 활용하기 위해 이메일 주소를 적습니다.

tip: nginx 커스터마이징

location 사용법

NGINX의 proxy_pass 기능은 들어오는 요청을 받아서 특정 위치로 보내고, 다시 돌아오는 응답을 받아서 클라이언트에게 돌려주는 것까지 수행해줍니다. (정말 좋네요)

HTTP 서버에 요청을 전달하기 위해, location 블록 안에 proxy_pass를 지정해보세요.

location /some/path/ {
    proxy_pass http://www.example.com/link/;
}

자세한 사용 방법은 nginx 공식 문서를 참고하세요.


기술적 챌린지

춤과 음악의 싱크를 맞추기 위한 방식 고민

BEFORE : WebSocket을 이용한 Local Audio 재생 타이밍 동기화


문제점

  • 음악이 시작하는 타이밍에만 signal이 전달되므로, 중간에 들어오는 시청자는 신호를 받지 못함
  • 네트워크 지연으로 영상이 끊기게 되어도 음악은 계속 재생되기 때문에, 영상과 음악의 싱크가 어긋남

AFTER : WebAudio API를 이용하여 직접 mp3파일을 AudioSource로 사용


WebRTC 특성 상 mp3 파일을 직접 AudioSource로 사용할 수 없으나, WebAudio API를 이용하여 MediaStream을 생성하게 되면 가능해짐

영상과 음성이 한 스트림에 전송되므로 싱크 문제가 해결됨

  • 중간에 진입하는 시청자도 중간부터 영상과 음성의 동시 수신 가능
  • 영상이 끊겨도 음악과 싱크가 어긋나지 않음

팀원

문준호

junho github badge

Team Leader / 스트리밍, 진행 로직 설계


김다엘

dael github badge

Backend / 채팅, 소켓, 방송 데이터 관리


이강욱

kangwook github badge

Full Stack / 투표 시스템, 영상 레이아웃


정성현

sunghyun github badge

Backend / DB, 인증 인가 시스템


Off the Record

고민했던 부분

  • 두 명이 동시에 춤추기

    • 현재 'PLAY DANCE LIVE!' 는 두 명의 참가자가 번갈아가며 춤을 추는 형식. 기획적으로는 두 사람이 동시에 춤 대결을 펼치는 것이 더 흥미로운 지점이 많았지만, 기술적으로는 많은 어려움이 예상되어 일단 번갈아 추는 것을 목표로 구현하고 각자의 춤과 노래의 싱크를 맞추는데 신경을 많이 썼음. 간단하게 생각해본 방안으로는, 춤을 추는 두 사람은 서로 P2P로 연결해 같은 타이밍에 맞춰 춤을 출 수 있게 하고, 중계 서버는 이 둘이 보내는 stream을 실제 음원에 해당하는 하나의 타이밍을 통해 mixing한 후 산출된 stream을 시청자들에게 송출하는 방법을 시도해 볼 수 있음. 다만 이 경우 춤추는 두 사람과 시청자들 간에는 서버의 연산시간 만큼의 지연이 발생하게 됨.
  • 여러 개의 채널 중 골라서 입장하기

    • 하나의 배틀을 온전히 진행할 수 있게 된 후, 음악 장르별 채널을 다양화해(e.g. K-pop, 1990s, ...) 각 채널에서 서로 다른 배틀이 이루어질 수 있게 추가 기획을 한 바 있음. 추가적인 구현이 필요함.

발전시킬 부분

  • 어뷰징 방지
    • 투표 시스템을 악용해 반복문으로 투표 클릭 신호를 서버로 보내는 등의 어뷰징 행위를 방지해야 함. 버튼을 통한 api 요청에 '쿨타임' 같은 딜레이를 적용한다던지, 더 안전하게는 요청을 받는 서버가 같은 로그인 정보를 가진 요청에 대해 일정 시간내 최대 요청의 개수를 제한하는 방법이 있음.
  • 배틀 시간 운영
    • 시청자 대기열이 비어있는 상황을 피하고자 배틀 시간대를 지정하여 운영함. (e.g. 오후반은 1시에 시작. 저녁반은 21시에 시작.)


MIT License. 2023. codeEATERS. All rights reserved.

About

실시간 댄스 배틀 플랫폼 PLAY DANCE LIVE! (SW정글 나만의 무기를 갖기 프로젝트)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •