Skip to content

동영상 재생 기술 의사선택 히스토리

arsgsg1 edited this page May 16, 2022 · 8 revisions

기술 의사선택 히스토리

필요한 조건

  1. 자바 or 스프링에서 지원하는 기술이어야 함
  2. http 프로토콜과 호환되어야 함

분석 과정

  1. 동영상 파일을 S3 버킷에 모두 저장하고, 요청마다 다운로드받게 하기
    1. 동영상을 모두 볼 것도 아닌데, 매번 full 영상을 다운로드받는건 네트워크 낭비라 판단
    2. 필요할 때마다 조금씩 가져올 순 없을까?
💡 리서치 결과 Device마다 영상을 호출하기 위한 프로토콜이 있다는걸 알게됨

HTTP Live Streming (HLS)

참고자료

https://d2.naver.com/helloworld/7122

https://luvstudy.tistory.com/173


개념 설명

HLS(HTTP Live Streaming)은 Apple이 2009년 제안한 방식이다.

웹을 이용하여 streaming을 하는 방식이다.

따라서 http protocol을 사용한다.

이로 인해 얻는 이점은 각각의 protocol의 호출에 대한 환경을 구축하는 비용이 필요한데 HLS는 http를 사용하기 때문에 웹서버 환경에서 바로 사용이 가능하여 구축에 용이하다는 이점이 있다.

HLS에서 사용되는 호출은 2가지인데 m3u8 과 ts이다.

m3u8은 재생할 목록에 대한 호출이며 ts는 대상 media 파일이다.

이 2가지 타입의 호출을 통해 media를 live streaming을 한다.

하지만 동영상은 용량이 어마어마하므로 압축이 필요하다. 따라서 ffmpeg란 오픈소스 압축 라이브러리를 사용하여 영상을 분할하여 전송한다.

이렇게 분할된 영상은 m3u8 포맷에 따라 ts (Transport Stream) 파일로 세그멘테이션된 파일들을 기록한다.

Untitled

💡 m3u8로 재생 목록을 얻어오고, 클라이언트는 위에서부터 순차적으로 요청하여 받아오면 되겠구나

코딩 방향

💡 **영상을 HLS로 인코딩하고 그 파일을 AWS의 S3에 업로드하여 cloud front에 배포되고 Javascript를 이용해서 사용자의 웹브라우져에서 다운받게 하자**
  1. 영상에 대한 정보 (영상 길이, 용량)는 어떻게 얻을 수 있나?
  2. m3u8, ts 파일을 응답으로 내려줘야 하는데, 변환하는 라이브러리가 있나?
  3. 서버는 분할된 ts 파일 중 어떤걸 저장해야 하지? 모두 저장해야 하나?
💡 ffmpeg 라이브러리

영상 및 이미지를 변환하고, 정보를 추출할 수 있는 오픈소스 라이브러리

영상 정보를 추출할 수도 있고, ts로 분할할 수도 있다. 단, docs를 읽어보니 커맨드라인으로 명령을 내려야 하는 것 같음.

Documentation

커맨드라인으로 명령을 직접 내리는게 불편하다.

다행히 자바로 이 라이브러리를 인터페이스화한 오픈소스가 있었다.

GitHub - bramp/ffmpeg-cli-wrapper: Java wrapper around the FFmpeg command line tool

덤으로 이걸 사용한 프로젝트를 찾았다.

GitHub - iamzin/SpringBoot-Project-Triport

동영상 변환 및 추출하는 예제 프로젝트를 하나 만들어보고, 프로덕션에 적용시키자.

참고 블로그: https://bcdragonfly.tistory.com/4

적용 결과

💡 각 파일별 역할

ffmpeg: 동영상을 변환 해주는 프로그램

ffprobe: 메타데이터를 추출해주는 프로그램

5분짜리 영상을 분할 단위 시간 2초로 설정하니 변환 작업이 5분 이상 걸림, 게다가 블로킹이기 때문에 대책이 필요하다

  • 영상 분할 단위는 실험에 따라 정해야 할 듯 (1분 영상을 10초 단위로 자르면 15초 정도 걸린다 함)
  • .m3u8 파일을 클라이언트에게 보내주면 video.js 라이브러리 내부에서 해당 파일을 분석하여 .ts 파일들을 요청하는 방식
  • 사용자 입장에서 동영상 분할은 블랙박스이고, 서비스 특성상 무조건 빠르게 응답되어야 함. 내부적인 처리 방식은 알 바가 아니다.
    • 비동기로 처리할 수 있는 방식을 고민해야 함.
      • 인코딩 담당 서버를 한 대 두는 방식도 괜찮을 것 같음
      • 아니면 AWS 람다를 사용해 이벤트 브릿지로 처리해도 괜찮을 듯
  • 화질에 따라 영상을 분할하는 것도 가능함.

결론: 동영상을 업로드 하기 위해 썸네일과 동영상 변환 단계를 먼저 거치도록 함

  • 유튜브에서도 동영상을 업로드 하기 위해선 변환 과정이 먼저 선행돼야 함.
  • 사용자가 업로드 버튼을 누르고 응답 없음 페이지를 보는 것보단 변환 과정을 무조건 거치게 만들어서 필요한 단계라 인식하게끔 만드는게 낫겠다 생각함.
  • 이를 위해 AWS 람다를 사용하기로 함.
  • 아직 사용자 수가 적기 때문에 24시간 돌아가는 EC2보단 사용한 시간만큼 요금을 내는 람다가 적절할 것 같다 생각함.

문제점

자세한 사항은 여기를 참고해주세요

요약: 실제 EC2에서 돌리는 것보다 실제 사용해보니 람다는 성능이 너무 느림. 일단은 임시로 서버 EC2에서 같이 돌리도록 함