본문 바로가기

개발기술/영상처리

HLS 프로토콜 튜닝

HLS (영상 프로토콜)

  • HLS는 내부적으로 **HTTP 요청/응답(GET)**을 이용해서 .m3u8 (playlist) 파일과 .ts (video segment) 파일을 순차적으로 다운로드해서 재생합니다.
  • HLS 같은 미디어 스트리밍 프로토콜은 "브라우저 자체"가 지원하지 않으면, JavaScript 라이브러리에 의존해야 합니다. 때문에 자신이 원하는 방식의 통신을 위한 프로토콜에 맞추어 설계하여야함

통신 순서

  • 1. 클라이언트 → HTTP GET → playlist.m3u8 요청
  • 2. 서버 → playlist.m3u8 응답 (.ts 목록이 들어 있음)
  • 3. 클라이언트 → HTTP GET → segment1.ts
  • 4. 클라이언트 → HTTP GET → segment2.ts

 

 

FFmpeg HLS 튜닝 플래그

  • -hls_time : 각 .ts 세그먼트의 길이(초),
    • -hls_time 4 → 4초 단위 분할
  • -hls_list_size : .m3u8에 유지할 세그먼트 개수
    • -hls_list_size 5 → 마지막 5개만 유지

 

Frame-based I-frame Spacing

  • -g 30 :  Setting maximum distance between I-frames. Setting GOP size (Group of Pictures). Insert a keyframe every 30 frames 
  • -keyint_min 30 : Sets the minimum number of frames before another keyframe can appear.

 

 

Time-based I-frame Spacing

  • -force_key_frames "expr:gte(t,n_forced*2)" : forces to insert a keyframe every 2 second, based on time t
    • expression interpretation : Is current time (t) ≥ number of keyframes inserted so far * 2 ?
    • 문제가 있던 rtsp 소스에서 keyframe이 25초에 1번씩 있었기때문에 2초당 1회로 강제로 keyframe을 생성해줌

 

Situation Use Why
🔴 Real-time HLS streaming (e.g., live camera monitoring) -force_key_frames (Time-based) Ensures fixed-length segments for predictable stream delivery
🟢 Video recording for later playback or storage -g (Frame-based) Keeps file size small, saves disk/network
🟡 Adaptive bitrate streaming (ABR) Both If each version(1080p, 720p, 480p) has keyframes in different places, the player can’t switch between them smoothly. It’ll freeze or stutter.
so insert Keyframes at the same timestamps 

 

  • -hls_flags delete_segments : 오래된 .ts 파일 자동 삭제. 
    • 프론트엔드는 자동적으로 가장 최신의 m3u8 파일의 리스트를 읽기때문에 delete segment를 해두면 최신화가 가능
  • -hls_segment_filename : 세그먼트 파일명 포맷 지정
  • . -c:v libx264 : Re-encodes video using H.264
  • -preset ultrafast : Minimize CPU load (real-time encoding)
  • -tune zerolatency : Removes buffering delay
  • -hls_flags +discont_start : 영상소스가 기존과 다르면 플레이어에게 알려주는 플래그를 삽
ffmpeg -i rtsp://192.168.0.6:554/instance \
-c:v libx264 -preset ultrafast -tune zerolatency \
-g 30 -keyint_min 30 -force_key_frames "expr:gte(t,n_forced*1)" \
-c:a aac -b:a 128k \
-hls_time 2 -hls_list_size 2 \
-hls_flags delete_segments+append_list \
-hls_allow_cache 0 -fflags nobuffer -strict experimental \
-avioflags direct -fflags discardcorrupt -flags low_delay \
-start_number 1 /home/data/hls/2/output.m3u8

 

 

주요 HLS 튜닝 요소

playlist.m3u8 구성요소

태그 역할
#EXTM3U M3U8 파일의 시작. HLS라는 것을 나타냅니다.
#EXT-X-VERSION:3 HLS 버전. 숫자가 높을수록 기능 많아짐 (1~7 정도 존재)
#EXT-X-TARGETDURATION:4 segment 하나의 최대 길이 (초 단위)
#EXT-X-MEDIA-SEQUENCE:105 이 재생목록의 첫 번째 segment의 시퀀스 번호
#EXTINF:4.000, 해당 segment의 재생 시간 (초 단위)
segmentX.ts 실제로 재생할 segment 파일 이름 (URL 가능)
#EXT-X-DISCONTINUITY 파일생성자가 영상 소스가 갑자기 변경되면 해당 플래그로 알림을 주고, 

 

HLS 규격에 맞춘 스트리밍 전략

 

목적에 따른 옵션변경

목적 조절 요소 관련 옵션
지연 시간 감소 세그먼트 시간 줄이기 -hls_time (ex: 2~4초)
저장 공간 절약 오래된 ts 삭제 -hls_list_size, -hls_flags delete_segments
브라우저 안정성 너무 짧은 세그먼트 피하기 일반적으로 4~6초 추천

비고

  • 세그먼트가 짧으면 → 지연은 줄지만 → 파일 수 많아지고 CPU 부하 증가
  • 너무 길면 → 지연 커지고 실시간성 저하됨

CCTV 분석 영상에서 추천하는 접근 전략

요소설정값  전략
segment 길이 (hls_time) 1~2초 이하
segment 개수 (hls_list_size) 3개 이하 (2~3개)
#EXT-X-MEDIA-SEQUENCE 정확하게 증가 관리해야 함
m3u8 요청 주기 1초 이하로 빠르게 polling
프론트 재생 전략 m3u8 재요청 시 항상 가장 마지막 세그먼트부터 재생

 

 

 

HLS 예외케이스 처리

 

브라우저문제

  • 새로운 HLS Player가 시작하였으나 브라우저 캐쉬가 된 Segment가 시작할때

통신/백엔드문제

  • Segment 번호가 갑자기 끊기거나 Jump 할때