<aside> hls는 HTTP Live Streaming의 줄임말로 온라인 영상 스트리밍을 위한 프로토콜입니다.

hls을 사용하면 작은 조각조각들을 미리미리 받을 수 있는데 유저의 네트워크 상태에 따라 최적의 품질로 다음 조각을 받아올 수도 있고, 큰 영상을 한 번에 받아오는 게 아니기 때문에 빠르게 재생을 할 수 있습니다. 이미 영상 및 음원을 업로드할 때 대용량으로 업로드가 가능하도록 정책이 되어 있었기 때문에 빠르게 또 유연하게 영상을 보여주는 것에는 hls가 최선의 선택이었습니다.

</aside>

영상을 재생하면서 청크 단위로 서버에게 리소스를 요청하는 상황입니다.
해당 이미지는 GIF 이미지로 PDF시 정적인 이미지로 대체되며, 자세한 내용은 노션에서 확인 할수 있습니다.

영상을 재생하면서 청크 단위로 서버에게 리소스를 요청하는 상황입니다. 해당 이미지는 GIF 이미지로 PDF시 정적인 이미지로 대체되며, 자세한 내용은 노션에서 확인 할수 있습니다.

클라이언트 부분

먼저 큰 틀은 다음과 같습니다. hls.js 라이브러리를 가져와 hls 인스턴스를 초기화합니다.

image.png

대부분의 경우 브라우저가 hls를 지원하고 있고 만약 지원한다면 콘텐츠 유형을 'application/x-mpegURL'로 하고 사파리 브라우저 같은 경우에는 또 다르게 콘텐츠 유형을 적용해야 합니다.

image.png

서버로부터 현재 사용자가 보려는 영상의 idx를 전달합니다. 그리고 클라이언트는 m3u8 형식의 데이터를 응답받습니다. (음원 nft의 소유권이 존재하는 사람과 관리자만 풀로 영상 재생이 가능하고 그게 아니라면 10초 영상 제한을 두었습니다. 관련 인증은 아래 서버 코드에 작성되어 있습니다.)

응답받은 m3u8 파일을 btoa(m3u8)을 통해서 Base64로 인코딩하고 loadSource를 통해 hls 미디어 플레이어에 전달이 됩니다. hls 미디어 플레이어는 스크립트로 가져온 라이브러리 hls 미디어 플레이어이며, 이 라이브러리가 내부적으로 인코딩된 m3u8을 읽어 hls 서버로 데이터 요청을 합니다.

m3u8 데이터 형식은 다음 와 같습니다.

image.png

여러 개의 메타데이터 중에 #EXT-X-TARGETDURATION:1와 #EXTINF:1.000가 헷갈리는데,

작은 비디오 또는 오디오 조각(세그먼트)을 만들 때

#EXT-X-TARGETDURATION:1는 세그먼트를 만들 때 최대 얼마나 길게 할 수 있을까요?를 말하고 10이라면 각 세그먼트가 10초 이내여야 하고 1이라면 1초 이내여야 합니다.

#EXTINF:1.000는 다음 세그먼트는 얼마나 길까요?를 말하고 10.000이라면 다음 세그먼트가 10초 동안 계속됨을 의미합니다.

#EXT-X-TARGETDURATION는 세그먼트의 최대 길이를, #EXTINF는 다음 세그먼트의 길이를 나타냅니다.