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 할때
'개발기술 > 영상처리' 카테고리의 다른 글
적응형 비트레이트 스트리밍(Adaptive Bitrate Streaming) 설계 (0) | 2025.04.02 |
---|---|
Encoding, Decoding, Frames 개념 (0) | 2025.03.30 |
영상 스트리밍 처리과정 (0) | 2025.03.26 |
영상처리 인터페이스 및 프로토콜 개략 (0) | 2025.03.13 |