HTTP Live Streaming (HLS) 알아보기
실제 사용해본 게 아닌 자료 정리 수준입니다.
video streaming과 관련하여 HTTP Request Header의 Range에 대해 이전 글에서 살펴보았었다.
2022.02.25 - [Study/Java] - Spring MVC에서 video streaming 하기
그렇다면 cctv 같은 현재 live 상태인 영상을 streaming 하려면 어떻게 해야 할까?
일단 각 device의 영상을 호출하기 위한 protocol이 있는데 RTSP (Real-Time Streaming Protocol) RTP (Real-Time Transport Protocol) RTMP (Real-Time Messaging Protocol) 등 여러 가지가 있다.
이 protocol 들은 각각에 따라 단방향, 양방향, 계층의 사용이 다르거나 암호화 여부 등 제각각이다.
여러 media device를 사용하기 위해 만들어진 여러 protocol들이 있다 정도로 이해하였다.
HTTP Live Streaming
HLS(HTTP Live Streaming)은 Apple이 2009년 제안한 방식이다.
특정적으로는 웹을 이용하여 streaming을 하는 방식이다.
따라서 http protocol을 사용한다.
이로 인해 얻는 이점은 이전에 열거한 여러 protocol의 경우 각각의 protocol의 호출에 대한 환경을 구축하는 비용이 필요한데 HLS는 http를 사용하기 때문에 웹서버 환경에서 바로 사용이 가능하여 구축에 용이하다는 이점이 있다.
HLS에서 사용되는 호출은 2가지인데 m3u8 과 ts이다.
m3u8은 재생할 목록에 대한 호출이며 ts는 대상 media 파일이다.
이 2가지 타입의 호출을 통해 media를 live streaming을 한다.
m3u8 파일
media player를 사용하면 재생할 목록을 만들고 저장하는 기능을 사용해보았을 것이다.
이 플레이 목록은 m3u 또는 m3u8 확장자로 저장되는데 해당 파일을 열어보면 각 줄마다 재생할 영상의 위치를 저장하는 단순한 구조이다.
예를 들면 다음과 같이 저장된다.
#EXTM3U8
C:\Users\bluesky\Downloads\ForBiggerBlazes_write.mp4
C:\Users\bluesky\Downloads\Sample-Video-File-For-Testing.mp4
이 파일은 별다른 기능도 없고 단순히 재생할 목록만 줄 별로 저장을 하지만 사실 더 많은 설정을 할 수 있다.
m3u8은 이 m3u 포맷을 utf-8 encoding으로 저장하는 걸 의미한다.
m3u 포맷을 사용하면 더 많은 설정을 저장할 수 있다.
각 줄에 #로 시작하는 항목은 원래 주석이지만 #EXT로 시작하는 경우 지시어를 의미한다.
예를 들어 다음과 같은 m3u 파일이 있다면
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:2018589
#EXT-X-DISCONTINUITY-SEQUENCE:1058
#EXTINF:6,video;1;2022-03-02T13:11:55.864413708+00:00
streaming-master-m1-na3/segment-2018589.ts
#EXTINF:6,video;1;2022-03-02T13:12:01.809902058+00:00
streaming-master-m1-na3/segment-2018590.ts
#EXTINF:6,video;1;2022-03-02T13:12:07.869878839+00:00
streaming-master-m1-na3/segment-2018591.ts
이 파일에서 사용된 지시어는 다음과 같다.
지시어 | 역할 |
#EXTM3U | 가장 첫줄에 명시, m3u 포맷임을 알림 |
#EXT-X-VERSION | 미디어 및 해당 서버를 기반으로 하는 파일의 호환성 버전을 나타냄 |
#EXT-X-TARGETDURATION | 파일 목록에 나열된 각 파일의 최대 재생 시간 |
#EXT-X-MEDIA-SEQUENCE | 제일 먼저 재생되어야 하는 파일의 일련번호 위의 경우 segment-2018589.ts |
#EXT-X-DISCONTINUITY-SEQUENCE | 동일한 Variant Stream 또는 다른 Variant Streams의 다른 변환 간의 동기화를 허용 |
#EXTINF | 트랙 정보 및 기타 추가 속성 해당 정보 바로 아래 줄이 재생할 ts 파일 정보 |
좀 더 다양한 지시어에 대한 정보는 아래에서 참고하면 된다.
https://docs.fileformat.com/audio/m3u/
위 예제의 경우 6초짜리 ts 파일 segment가 3개가 주어졌다.
ts 파일이 재생되는 동안 다시 해당 m3u 파일을 호출하며 호출된 파일은 다음과 같이 변경된다
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:2018590
#EXT-X-DISCONTINUITY-SEQUENCE:1058
#EXTINF:6,video;1;2022-03-02T13:12:01.809902058+00:00
streaming-master-m1-na3/segment-2018590.ts
#EXTINF:6,video;1;2022-03-02T13:12:07.869878839+00:00
streaming-master-m1-na3/segment-2018591.ts
#EXTINF:6,video;1;2022-03-02T13:12:13.799640364+00:00
streaming-master-m1-na3/segment-2018592.ts
#EXT-X-DISCONTINUITY-SEQUENCE 지시어를 사용하면 주기적으로 m3u8 파일을 호출하고 호출된 m3u8엔 기존과 다른 갱신된 내용이 반환되어 실시간 라이브 스트리밍이 구현된다.
따라서 backend에서는 이 m3u8을 주기적으로 갱신된 정보로 제공하여 재생될 ts 파일을 지정하면 된다.
이렇게 m3u8 파일을 통해 재생할 목록을 전달하면서 추가적인 기능도 제공이 가능하다.
#EXT-X-KEY 설정을 통해 ts 파일이 암호화되었음을 알려주고 암복호화 처리를 한다거나 또는 #EXT-X-STREAM-INF를 통해 대역별 재생 파일을 지정하여 480p 720p 1024p 같은 해상도별 ts파일을 제공하는 것이 가능하다.
ts 파일
ts 파일은 MPEG-2 TS (Transport Stream) 파일이며 디지털 방송을 위한 데이터 전송 규격이다.
hls에서는 이 ts 파일을 계속 요청하여 재생한다고 생각하면 된다.
CCTV를 라이브 스트리밍 한다고 가정하면 cctv device에서 영상을 전송받아 ts 파일로 만들어 어딘가에 저장한 후 해당 저장된 정보를 m3u8 로 반환하여 응답하는 처리를 한다.
cctv device에서 영상을 전송받는 부분은 보통 RTSP protocol로 전달받게 된다.
전달받은 media를 여러 ts 파일로 나누는 작업을 진행해야 하는데
hls.js
이렇게 m3u8 파일을 주기적으로 호출하여 ts 파일을 계속 재생하도록 구현한 라이브러리이다.
https://github.com/video-dev/hls.js/
확인하지 못한 부분
cctv에서 실제 스트리밍 동영상을 가져와 ts 파일로 변환을 하는 과정에 대해서는 확인을 하지 못하였다.
특정 영상을 hls를 위해 m3u8 파일과 ts 파일로 변환하는 것은 도와주는 ffmpeg 라이브러리가 있다는 것은 확인했다.
FFmpeg는 stream audio, video를 record 및 convert 해주는 오픈소스 라이브러리이다.
stackoverflow에서 FFmpeg로 rtsp를 통해 cctv 영상을 호출하여 변환하는 게 가능하다는 답변을 보긴 했다.
https://stackoverflow.com/questions/1735933/streaming-via-rtsp-or-rtp-in-html5
다만 실제 사용해보고 확인을 하진 못하였다.
ffmpeg -v info -i rtsp://ip:port/h264.sdp -c:v copy -c:a copy -bufsize 1835k -pix_fmt yuv420p -flags -global_header -hls_time 10 -hls_list_size 6 -hls_wrap 10 -start_number 1 /var/www/html/test.m3u8
참고 자료
https://ko.wikipedia.org/wiki/HTTP_%EB%9D%BC%EC%9D%B4%EB%B8%8C_%EC%8A%A4%ED%8A%B8%EB%A6%AC%EB%B0%8D
https://d2.naver.com/helloworld/7122