videofly alpha¶
/usr/local/m2/setting.json 다음 영역에 대해 기술한다.
{
"functions": {
"services": {
"videofly": {
...
}
}
}
}
How to use¶
명령어 리스트¶
# _default 프로파일로 재생
https://example.com/video.mp4/vfly/v1/profile/_default/master.m3u8
# review 프로파일로 재생
https://example.com/video.mp4/vfly/v1/profile/review/master.m3u8
# review 프로파일로 재생 후 세부옵션 조정
https://example.com/video.mp4/vfly/v1/profile/review/options/duration=10/master.m3u8
# review 프로파일로 재생 후 세부옵션 조정
https://example.com/video.mp4/vfly/v1/profile/review/options/duration=10;split=balance/master.m3u8
# 30초 구간 추출 후 재생
https://example.com/video.mp4/vfly/v1/trim/0-30/profile/_default/master.m3u8
# mpeg2-ts포맷 (h264 코덱)의 720p 스트림만 제공한다.
https://example.com/sample.mp4/vfly/v1/profile/_default.m2ts.720p/playlist.m3u8
# fmp4포맷 (av1 코덱)의 360p 스트림만 제공한다.
https://example.com/sample.mp4/vfly/v1/profile/_default.fmp4.360p/playlist.m3u8
# 원본미디어 파일로부터 HLS 라이브 재생을 제공한다.
https://example.com/video.mp4/vfly/v1/profile/_default/live/start=20250729100000/master.m3u8
https://example.com/video.mp4/vfly/v1/profile/_default/live/start=20250730143050;buffer=60/master.m3u8
https://example.com/sample.mp4/vfly/v1/profile/_default.fmp4.360p/live/start=20250729100000;end=20250729110000/playlist.m3u8
fallback 옵션¶
정상재생이 불가능한 경우(=fallback 상황) 차선책을 통한 재생을 지원한다.
Note
클라이언트가 아래와 같이 master.m3u8 로 진입하는 상황에서만 동작한다.
https://example.com/video.mp4/vfly/v1/profile/{profile}/master.m3u8
기존 URL뒤에 아래와 같이 fallback 명령을 추가하여 사용가능하다.
# 최저 해상도만 playlist로 제공(=트랜스코딩)한다.
.../fallback/lowest;reason=throttling
# 원본을 HLS로만 포맷변환한다. 트랜스코딩하지 않는다.
.../fallback/onlyhls;reason=manifest
# 원본을 MP4로만 포맷변경한다. 트랜스코딩하지 않는다.
.../fallback/remux;reason=manifest
# 원본을 전송한다.
.../fallback/origin;reason=throttling
/fallback/onlyhls는 [원본 해상도] 무변환 과 동일하다.reason은 fallback된 원인을 추적하는 태그일 뿐 동작에 영향을 주지 않는다.
See also
-위 URL은 fallback 정책으로 Redirect시 Location 헤더의 값으로 사용된다.
정상재생 실패시 MP4 스트리밍 전환¶
미디어 서비스 처리 과정에는 다양한 예외가 발생할 수 있다.
원본이 비디오가 아닌 경우
원본 미디어 파일의 일부가 오염된 경우
원본 미디어 파일의 코덱을 인식할 수 없는 경우
서버의 CPU가 과부하 상태로 트랜스코딩이 불가능한 경우 ( throttling 참조)
정상재생 시나리오 는 아래 조건을 모두 만족해야 한다.
master.m3u8정상 서비스(선택된 해상도의)
playlist.m3u8정상 서비스(선택된 해상도로 트랜스코딩된) 첫 번째 세그먼트 정상 서비스
HLS 재생실패가 인지되었다면, MP4 스트리밍이 차선이 될 수 있다.
# MP4 스트리밍
https://example.com/video.mp4/vfly/v1/profile/{profile}/fallback/remux
# 원본 스트리밍
https://example.com/video.mp4/vfly/v1/profile/{profile}/fallback/origin
Warning
Remux 및 원본 스트리밍은 트랜스코딩하지 않기 때문에 브라우저 재생을 담보할수 없다. 하지만 정상시나리오에서 실패했기 때문에 트랜스코딩을 다시 시도한다고 하여도 성공을 기대하기 어렵다.
싱글/멀티비트레이트¶
기본 _default 프로파일의 master.m3u8 는 다음과 같이 멀티 비트레이트 스트림을 모두 제공한다.
클라이언트 네트워크 상태에 맞추어 최적의 스트림을 선택하여 재생한다.¶
Note
HLS 스펙에서 코덱과 포맷은 다소 모호하게 정의되어 있기 때문에 아래와 같이 쌍으로 제공하도록 기본 구성된다.
fMP4는av1코덱만 지원MPEG2-TS는h264코덱만 지원
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-STREAM-INF:BANDWIDTH=12000000,RESOLUTION=1920x1080,CODECS="av01.0.08M.08,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.fmp4.1080p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=6000000,RESOLUTION=1280x720,CODECS="av01.0.05M.08,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.fmp4.720p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=854x480,CODECS="av01.0.04M.08,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.fmp4.480p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1600000,RESOLUTION=640x360,CODECS="av01.0.04M.08,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.fmp4.360p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=426x240,CODECS="av01.0.00M.08,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.fmp4.240p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=250000,RESOLUTION=256x144,CODECS="av01.0.00M.08,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.fmp4.144p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=16000000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.m2ts.1080p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=8000000,RESOLUTION=1280x720,CODECS="avc1.4D001F,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.m2ts.720p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4000000,RESOLUTION=854x480,CODECS="avc1.4D001E,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.m2ts.480p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2200000,RESOLUTION=640x360,CODECS="avc1.42001E,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.m2ts.360p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=426x240,CODECS="avc1.420014,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.m2ts.240p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=256x144,CODECS="avc1.420014,mp4a.40.2"
/sample.mp4/vfly/v1/profile/_default.m2ts.144p/playlist.m3u8
특정 스트림을 선택하는 문법은 다음과 같다.
# 프로파일의 마스터
.../vfly/v1/profile/{프로파일명}/master.m3u8
# 프로파일의 개별스트림
.../vfly/v1/profile/{프로파일명}.{포맷}.{해상도 or 프리셋}/playlist.m3u8
{프로파일명}profiles 에 정의된 프로파일 이름.
_default프리셋이 지원된다.{포맷}미디어 세그먼트 포맷.
fmp4,m2ts중 택1{해상도 or 프리셋}
싱글 스트림만 제공하고 싶은 경우에는 2가지 방법이 가능하지만, 특별한 경우가 아니라면 1안을 권장한다.
master.m3u8는 멀티로 제공하고 노출영역에 맞추어 특정 스트림만 제공한다.# mpeg2-ts포맷 (h264 코덱)의 720p 스트림만 제공한다. https://example.com/sample.mp4/vfly/v1/profile/_default.m2ts.720p/playlist.m3u8 # fmp4포맷 (av1 코덱)의 360p 스트림만 제공한다. https://example.com/sample.mp4/vfly/v1/profile/_default.fmp4.360p/playlist.m3u8
단일 스트림만 제공하도록 profiles 를 구성한다.
meta¶
"meta" : {
"enable" : false,
"keyword": "vfly",
"urlScheme": null
}
enable (기본: false)활성화
keyword (기본: vfly)키워드
urlScheme (기본: null)플레이리스트 및 세그먼트 URL을 설정에 맞추어 생성한다
owaspOWASP 룰셋에 위배되지 않도록 URL을 생성한다.
fallback¶
fallback 상황의 정책의 기본동작을 정의한다.
Warning
이미 재생에 진입한 플레이리스트과 개별 세그먼트 요청은 통제대상이 아니다.
진입점인
master.m3u8에 대한 요청에 대해서만 통제대상이다.
상황발생시 대응설정인 action 의 의미는 다음과 같다. (우선순위별)
값 |
트랜스코딩 |
설명 |
|---|---|---|
|
O |
설정된 |
|
X |
[원본 해상도] 무변환 만 제공하는 URL로 Redirect한다. |
|
X |
|
|
X |
원본을 제공한다. |
|
X |
|
Warning
Redirect를 통한 CDN 충돌방지
일반적으로 비디오 서비스는 CDN(Contents Delivery Network)을 이용한다.
서버 상태에 따라 콘텐츠가 달라질 경우 CDN 캐싱 무결성에 문제가 발생할 수 있다.
HTTP Redirect 메커니즘을 이용하여 CDN이 다른 키로 인식할 수 있도록 운영한다.
manifest¶
master.m3u8 생성실패시 정책을 수립한다.
"manifest": {
"enable": false,
"action": [ "redirect_to_mp4ps" , "redirect_to_origin" ]
}
enable (기본: false)master.m3u8생성실패시 fallback 활성화action (기본: "redirect_to_mp4ps" , "redirect_to_origin")master.m3u8생성실패시 재생가능한 단계를 순차적으로 진행한다..../master.m3u8생성실패시.../fallback/remux로 redirect된다..../fallback/remux실패시.../fallback/origin으로 redirect된다..../fallback/origin실패시 에러처리된다.
어느 단계라도 클라이언트에게 정상적인 콘텐츠를 제공할 수 있다면 더 이상 redirect되지 않는다.
# master.m3u8 생성싪패시 MP4 Pseudo-Streaming URL로 Redirect한다. # MP4 Pseudo-Streaming 실패시 원본을 전달한다. "action": [ "redirect_to_mp4ps" , "redirect_to_origin" ] # master.m3u8 생성싪패시 MP4 Pseudo-Streaming URL로 Redirect한다. # MP4 Pseudo-Streaming 실패시 redirect_to_origin가 생략되어 있어 에러로 응답한다. "action": [ "redirect_to_mp4ps" ] # master.m3u8 생성싪패시 503으로 응답한다. redirect하지 않는다. "action": [ "error" ]
Note
Redirect시 원인 추적을 위해
reason이 추가된다.원본을 획득할 수 없는 경우는
404 Not Found등 원본 응답코드가 송신된다.
throttling¶
CPU 과부하시 정책을 수립한다.
"throttling": {
"enable": false,
"usage": 80,
"action": [ "redirect_to_onlyhls" , "redirect_to_mp4ps" , "redirect_to_origin" ]
}
enable (기본: false)CPU 과부하 상태 fallback 활성화
usage (기본: 80, 최대: 100)CPU 과부하 상태 판단 임계치 (평균 cpu 사용량 기준). 값이
100인 경우 사실상 과부하 판단을 하지 않는 것과 동일하다.Note
이미 재생중인 플레이리스트는 지속적으로 유입되어 트랜스코딩될 수 있음을 인지하고 설정해야 한다.
action (기본: redirect_to_onlyhls , redirect_to_mp4ps , redirect_to_origin)CPU 과부하 상태시 재생가능한 단계를 순차적으로 진행한다.
CPU 과부하시
.../fallback/onlyhls로 redirect된다..../fallback/onlyhls실패시.../fallback/remux으로 redirect된다..../fallback/remux실패시.../fallback/origin으로 redirect된다..../fallback/origin실패시 에러처리된다.
어느 단계라도 클라이언트에게 정상적인 콘텐츠를 제공할 수 있다면 더 이상 redirect되지 않는다.
# CPU 과부하시 트랜스코딩 없이 원본을 HLS로만 변환하여 전송한다. # 원본을 HLS로만 변환 싪패시 MP4 Pseudo-Streaming URL로 Redirect한다. # MP4 Pseudo-Streaming 실패시 원본을 전달한다. "action": [ "redirect_to_onlyhls" , "redirect_to_mp4ps" , "redirect_to_origin" ] # CPU 과부하시 저화질만 제공한다. # 저화질 제공 실패시 503으로 응답한다. redirect하지 않는다. "action": [ "redirect_to_lowest" , "error" ]
Note
Redirect시 원인 추적을 위해
reason이 추가된다.
profiles¶
HLS 상세한 구성은 프로파일로 정의한다. 다음은 빌트인 프로파일이다.
name |
playlist |
비디오 코덱 |
해상도 |
|---|---|---|---|
|
|
|
1080p, 720p, 480p, 360p, 144p |
|
|
|
1080p, 720p, 480p, 360p, 144p |
|
|
|
1080p, 720p, 480p, 360p, 144p |
"profiles" : [
{
"enable": true,
"name": "review",
"ver": 7,
"path": "abs",
"split": "loose",
"duration": 3,
"transcode": { ... },
"playlist:" { ... },
"event": { ... },
"live": { ... },
"encrypt": { ... }
},
{
"name": "ads"
}
]
enable (기본: true)프로파일 활성화
name프로파일 이름
ver (기본: 7)HLS 버전
path (기본: "abs")경로구성 정책
abs (기본)절대경로 (항상/로 시작)rel상대경로
split (기본: loose)세그먼트 분할 방법. 키 프레임이
duration보다 너무 긴 경우 반응성을 개선하기 위함이다. 원본 키프레임이 1초 간격이라면 병합하여duration을 맞출 수 있어 차이가 미비하다.설정
설명
loose원본 키프레임을 위배하지 않는다.
balanceduration기준 +-1 초 가능한 적게 분할한다.strict정확히
duration단위로 분할한다.Note
balance모드를 사용한다면duration은 2초를 궈장한다.strict는 반응성은 빠르지만, 세그먼트가 너무 많아져(=키프레임이 많아져) 전체 용량이 증가한다.
duration (기본: 3)비디오 분할 시간. 길수록 한번에 트랜스코딩하는 크기가 커져 반응성이 저하된다.
transcodetranscode 참조
playlistplaylist 참조
eventevent 이벤트를 발동시킨다.
transcode¶
트랜스코딩 정책과 해상도를 구성한다.
"transcode": {
"enable": true,
"policy": "IF_SPEC_MISMATCH",
"resolution": [ "1080p", "720p", "480p", "360p", "144p" ],
"upscale": false
}
enable (기본: true)트랜스코딩 활성화.
Note
[원본 해상도] 무변환 경우에만 비활성화한다.
policy (기본: IF_SPEC_MISMATCH)개별 스트림 제공시 트랜스코딩 정책. 조건이 모두 만족할 경우에는 트랜스코딩하지 않는다.
정책명
Codec
Resolution
Bitrate
IF_BITRATE_EXCEEDS일치
일치
같거나 낮음
IF_SPEC_MISMATCH일치
일치
IF_CODEC_MISMATCH일치
ALWAYSresolution (기본: null)스트림 해상도
가로로 촬영된 비디오는 세로 기준, 세로로 촬영된 비디오는 가로 기준으로 해상도 결정
4:3 비율의 원본 비디오가 입력될 경우, 높이에 맞춰 가로 해상도 결정
이름
해상도
2160p3840 x 2160
1440p2560 x 1440
1080p1920 x 1080
720p1280 x 720
480p854 x 480
360p640 x 360
240p426 x 240
144p256 x 144
upscale (기본: true)원본 비디오의 해상도가 출력 해상도보다 낮을 경우 업스케일링 여부.
false인 경우 원본 해상도보다 높은 스트림은 생성하지 않는다.
playlist¶
플레이리스트를 구성한다.
멀티비트레이트 스트림을 지원한다.
fMP4와MPEG2-TS멀티 미디어 세그먼트를 지원한다.
Note
클라이언트 호환성을 100% 담보할 수 없는 경우
fMP4와MPEG2-TS를 같이 구성fMP4는av1코덱만 지원MPEG2-TS는h264코덱만 지원플레이어가 코덱을 통해 재생할 미디어 세그먼트를 선택
fmp4¶
fMP4(Fragmented MP4) 세그먼트를 구성한다.
"fmp4": {
"enable": true,
"vcodec": "av1",
"acodec": "aac",
"presets": null
}
enable (기본: true)활성화
vcodec (기본: av1)비디오 코덱 (
av1,h264중 택1)acodec (기본: aac)오디오 코덱 (
aac는 AAC-LC를 의미한다.)presets (기본: null)resolution외에 추가될 제공할 트랜스코딩 presets 리스트
m2ts¶
MPEG2-TS(Transport Stream) 세그먼트를 구성한다.
"m2ts": {
"enable": true,
"vcodec": "h264",
"acodec": "aac",
"presets": null
}
enable (기본: true)활성화
vcodec (기본: h264)비디오 코덱 (
h264단일지원)acodec (기본: aac)오디오 코덱 (
aac는 AAC-LC를 의미한다.)presets (기본: null)resolution외에 추가될 제공할 트랜스코딩 presets 리스트
live¶
원본파일을 라이브 스트리밍으로 제공한다.
라이브 스트림은 URL의 start 시간부터 재생시간 동안만 유효하다.¶
명령어 |
필수 |
예제 |
설명 |
|---|---|---|---|
|
O |
start=20250729100000 |
라이브 시작시간 (형식: YYYYMMDDhhmmss) |
|
X |
end=20250729110000 |
라이브 종료시간 (형식: YYYYMMDDhhmmss) |
|
X |
buffer=30 |
버퍼링 시간 (초) |
"live" : {
"buffer": 30,
"denialCode": 403
}
buffer (기본: 30초)버퍼링 시간
denialCode (기본: 403)라이브 시간이 아닐 경우의 응답코드
Note
멀티 포맷/멀티 해상도 스트림이 아닌 원본 그대로의 라이브 구성이 필요하다면 [원본 해상도] 무변환 를 참고한다.
설정 변경¶
라이브 방송의 특성상 일부 헤더 설정이 필요하다.
m3u8파일이 캐싱되지 않도록 bypass 설정으로instant2를 설정한다.# functions.network.http.frontEnd.bypass "matchingList": [ { "pattern": "$URL[/*/mp4hls/live/*/*.m3u8]", "action": "instant2" } ]
instant모드로 설정할 경우 원본 비디오까지instant모드로 동작하기 떄문에 매 요청마다 원본 비디오를 다운로드 받게 된다.인덱스 파일이 갱신 메커니즘(
304 Not Modified)을 수행하지 않도록 modify 설정으로 클라이언트 응답헤더를 제거한다.# functions.network.http.frontEnd.headers.modify "matchingList": [ { "pattern": "$URL[/*/mp4hls/live/*/*.m3u8]", "header": "$RES[Last-Modified]", "mode": "unset" }, { "pattern": "$URL[/*/mp4hls/live/*/*.m3u8]", "header": "$RES[ETag]", "mode": "unset" }, { "pattern": "$URL[/*/mp4hls/live/*/*.m3u8]", "header": "$RES[Cache-Control: no-cache, no-store, must-revalidate]", "mode": "set" } ]
Note
엔터프라이즈 서비스에서 CDN 사용시 주의사항
CDN TTL 정책
/*/mp4hls/live/*/*.m3u8은 1~5초를 설정하여 매번 갱신되도록 한다./*/mp4hls/live/*/*.ts는 1~5분으로 설정하여, 적당한 유효재생시간 동안 캐싱되도록 한다.
CDN 응답시
Last-Modified나ETag헤더를 제거하기에304 Not Modified는 발생하지 않는다.CDN (또는 브라우저)에게 좀 더 명시적인 동작을 강제하기 위해
Cache-Control: no-cache, no-store, must-revalidate헤더를 추가한다.
원본 다운로드를 최소화하거나 트래픽 시점은 분산시키고 싶다면 limitMaxRange 를 설정한다.
# functions.network.http.backEnd.headers "limitMaxRange": { "enable": true, "size": 4 }
비디오 해상도에 따라
4MB면 아래와 같이 추정할 수 있다.해상도
재생시간
비트레이트
1080p
약 5~8초
4~6 Mbps
720p
약 10~16초
2~3 Mbps
480p
약 21~32초
1~1.5 Mbps
360p
약 32~46초
0.7~1 Mbps
encrypt¶
EXT-X-KEY 암호화를 지원한다.
"encrypt": {
"enable": false,
"keyFileName": "enc.key",
"token": "",
"tokenType": null,
"iv": null
}
enable (기본: false)암호화 활성화
keyFileName (기본: "enc.key)인덱스 파일에 표기될 키 파일명
#EXTM3U ... #EXT-X-KEY:METHOD=AES-128,URI="/sample.mp4/vfly/v1/profile/_default.m2ts.720p/enc.key" #EXTINF:10.677, ...
token암호화 토큰
tokenType (기본: null)암호화 토큰 타입
null설정된token이 암호화 키로 사용한다.enc설정된token이 encryptpassword 로 암호화되어 있다. 사용시 복호화하여 사용한다.
iv (기본: null)Initial Vector.
0x로 시작하는 16진수로 설정한다.#EXTM3U ... #EXT-X-KEY:METHOD=AES-128,URI="/sample.mp4/vfly/v1/profile/_default.m2ts.720p/enc.key",IV=0x0123456789abcdef0123456789abcdef #EXTINF:10.677, ...
fallback¶
See also
별도로 정의하지 않는 경우 fallback 정책을 승계받는다.
각 profile별로 실패동작을 세분화하여 정의할 수 있다.
event¶
원본비디오가 서비스될 때 발생시킬 이벤트를 정의한다.
"event": {
"normalize": "to_h264_aac"
}
normalize비디오 포맷 표준화를 위헤해 스케쥴링한다.
Note
storgate beta 의 스케쥴링과 연동
2차 고도화시 스펙정의
설정 예제¶
다음은 멀티 스트림을 지원하는 최소 구성이다.
"profiles" : [
{
"name": "example",
"transcode": {
"policy": "IF_SPEC_MISMATCH",
"resolution": [ "1080p", "720p", "480p", "360p", "144p" ]
}
}
]
그 밖의 예외적인 설정예제를 제공한다.
[원본 해상도] 무변환¶
트랜스코딩 없이 원본 해상도 그대로 HLS로 전송하는 구성이다.
"profiles" : [
{
"name": "example",
"transcode": {
"enable": false
}
}
]
[원본 해상도] 코덱호환성 보장¶
[원본 해상도] 무변환 상황과 같으나, 코덱 옵션이 다를 경우에만 트랜스코딩을 수행한다.
"profiles" : [
{
"name": "example",
"transcode": {
"enable": true,
"policy": "IF_CODEC_MISMATCH"
}
}
]
[원본 해상도] h264 기반 fmp4¶
[원본 해상도] 코덱호환성 보장 상황과 유사하나 h264 코덱으로 fmp4 포맷만 제공하는 구성이다.
{
"name": "example",
"transcode": {
"enable": true,
"policy": "IF_CODEC_MISMATCH"
},
"playlist": {
"fmp4": {
"vcodec": "h264"
},
"m2ts": {
"enable": false
}
}
}