hive alpha¶
/usr/local/m2/setting.json 다음 영역에 대해 기술한다.
{
"functions": {
"contents": {
"hive": {
...
}
}
}
}
hive 는 videofly 서비스의 HLS 가공 컴포넌트다.
원본 미디어를 사전 변환 없이 요청 시점에( Just-in-time ) 세그먼트 단위로 트랜스코딩하여 서빙한다.
JIT Packaging (HLS) — 원본을
master.m3u8·playlist.m3u8와fMP4·MPEG2-TS세그먼트로 온디맨드 패키징한다. ( HLS = HTTP Live Streaming )JIT Transcoding — 세그먼트를 요청 시점에 트랜스코딩하며, 프로파일 기반 해상도 · 코덱 조합 래더를 제공한다.
Video On Demand — 프로파일 · 랜디션 단위 재생을 지원한다.
How to use¶
원본 URL 뒤에 키워드( 기본 vfly/v1/vod )와 VOD 명령어를 추가한다.
# 원본
https://example.com/video.mp4
# 원본 + 키워드(vfly/v1/vod) + 명령어
https://example.com/video.mp4/vfly/v1/vod/_default/master.m3u8
Note
클라이언트(플레이어)가 직접 구성하는 URL 은 master.m3u8 뿐이다.
랜디션 재생목록 · 세그먼트 URL 은 마스터가 발급하므로 그대로 따라가면 된다.
명령어 리스트¶
재생¶
# 빌트인 프로파일
https://example.com/video.mp4/vfly/v1/vod/_default/master.m3u8
# 고객향 프로파일
https://example.com/video.mp4/vfly/v1/vod/myprofile/master.m3u8
# 컨테이너 고정 — 프로파일 이름 뒤 .fmp4 또는 .m2ts
https://example.com/video.mp4/vfly/v1/vod/_default.fmp4/master.m3u8
https://example.com/video.mp4/vfly/v1/vod/_default.m2ts/master.m3u8
프로파일 · 컨테이너 · 구간을 조합해 요청한다.
요청 유형 |
경로 |
결과 |
|---|---|---|
프로파일 |
|
프로파일이 정의한 모든 컨테이너의 랜디션을 노출한다. |
컨테이너 고정 |
|
해당 컨테이너의 랜디션만 노출한다. |
구간 추출¶
# 0초 ~ 30초 구간만 재생
https://example.com/video.mp4/vfly/v1/vod/trim/0-30/_default/master.m3u8
# 10초부터 끝까지 (열린 구간)
https://example.com/video.mp4/vfly/v1/vod/trim/10-/_default/master.m3u8
# 처음부터 90.5초까지 (소수 허용)
https://example.com/video.mp4/vfly/v1/vod/trim/-90.5/_default/master.m3u8
명령어 |
파라미터 |
동작 |
|---|---|---|
|
|
|
캡처¶
# 10.5초 시점 프레임을 320x180 webp 이미지로
https://example.com/video.mp4/vfly/v1/vod/capture/10.5/320x180.webp
# avif · jpg 포맷
https://example.com/video.mp4/vfly/v1/vod/capture/10/320x180.avif
https://example.com/video.mp4/vfly/v1/vod/capture/10/320x180.jpg
명령어 |
파라미터 |
동작 |
|---|---|---|
|
|
|
meta¶
"meta": {
"enable": false,
"keyword": "vfly/v1/vod"
}
enable (기본: false)활성화
keyword (기본: vfly/v1/vod)VOD 명령을 인식하는 URL 키워드. 이 키워드 이후 경로가 VOD 명령으로 해석된다.
transcoder¶
HLS Segement 트랜스코더를 구성한다.
"transcoder": {
"type": "local",
"timeout": 60
}
type (기본: local)트랜스코더 타입.
local개발목적의 동시성 1의 트랜스코더로, GPU/CPU 모드를 자동으로 설정한다.hlseg-transcoder={name}사용할 hlseg-transcoder 의name을 연결한다."transcoder": { "type": "hlseg-transcoder=ondemand", "timeout": 60 }
videofly 가 비활성화되어 있거나 hlseg-transcoder 연결이 유효하지 않다면
503 Service Unavailable를 응답한다.
timeout (기본: 60)요청전송 후 완료 응답을 기다리는 최대 시간(초). 초과하면 응답 미수신으로 판단하여
503 Service Unavailable로 응답한다.
Note
hlseg-transcoder 는 전송·취합(aggregation) 담당이며, 응답 대기·대응 정책은 본 가상호스트 설정이 소유한다.
로그¶
hlseg-transcoder 트랜잭션은 전역로그인 log 에 기록된다.
access.log 의
x-ctx-id와 log 의x-ctx-id는 동일하다.
장애시 응답¶
HLS 서비스 중 장애는 다음과 같이 처리된다.
분류 |
장애응답 |
주요 원인 |
|---|---|---|
|
|
원본 미디어 인식불가 |
|
|
트랜스코더 장애 |
Note
정상 HLS 서비스가 어려운 경우 빠른 실패 후 클라이언트/플레이어에서 재생가능한 수단으로 fallback 처리할 것을 권장한다.
profiles¶
프로파일은 HLS 패키징과 세그먼트 비디오 형식을 정의하며, 고객 환경에 맞추어 자유롭게 정의 가능하다.
재생 URL 의 {profile} 자리에 프로파일 이름을 넣어 선택한다.
Note
자주 사용되는 프로파일은 아래와 같이 _ 로 시작하는 built-in 프로파일로 자유롭게 사용 가능하다.
# 빌트인 프로파일 재생
https://example.com/video.mp4/vfly/v1/vod/_premium/master.m3u8
name |
video |
audio |
max fps |
renditions |
용도 |
|---|---|---|---|---|---|
|
AV1 / H.264 |
AAC |
원본 |
1080p · 720p · 360p · 144p |
기본값. 보편적인 코덱과 해상도 지원. |
|
AV1 / H.264 |
AAC |
30 |
1080p · 720p · 480p · 360p |
가성비 범용 (general purpose) |
|
AV1 / H.264 |
AAC |
30 |
720p · 480p · 360p |
용량 절감 우선 (aggressive compression) |
|
AV1 / H.264 |
AAC |
30 |
2160p · 1440p · 1080p · 720p |
고품질 VOD / OTT, 4K 대응 |
|
원본 유지 |
원본 유지 |
원본 |
original (무변환) |
원본 코덱 호환성만 보장 |
|
AV1 / H.264 |
AAC |
30 |
1440p ~ 144p 7단 |
YouTube 스타일 MBR |
|
AV1 / H.264 |
AAC |
60 |
|
고프레임(HFR) 콘텐츠 |
각 프로파일은 공통 HLS 패키징 정책( hls )과 개별 스트림 목록( renditions )을 포함한다.
"profiles": [
{
"schema_version": "v1",
"name": "example",
"description": "설명을 넣는다."
"hls": {
"transcode": {
"policy": "if_spec_mismatch",
"upscale": false
},
"version": 7,
"path": "abs",
"split": "loose",
"segment_duration": 2
},
"renditions": [ ... ]
}
]
Note
각 프로파일의 상세 규격은 런타임 스키마 검증기( ajv )가 전담하므로, 배포 시 필드 타입 · enum 위반은 거부된다.
schema_version프로파일 스키마 버전 (
v1)name프로파일을 식별하는 고유 이름. 재생 URL 의
{profile}값이다.^[A-Za-z0-9_][A-Za-z0-9_-]*$패턴을 따른다.description프로파일 설명 (기능하지 않는다.)
hlsHLS Packetizing을 정의한다.
transcode.policy트랜스코딩 여부 기준.
정책명
Codec
Resolution
Bitrate
alwaysif_bitrate_exceeds일치
일치
같거나 낮음
if_spec_mismatch일치
일치
if_codec_mismatch일치
조건이 모두 만족하면 트랜스코딩하지 않는다.
transcode.upscale원본보다 큰 해상도로 트랜스코딩할지 여부
versionHLS playlist 의
EXT-X-VERSION값 (1 이상)pathplaylist 안의 segment 경로 표현 방식.
abs절대경로 (항상/로 시작)rel상대경로
split목표 segment 길이 기준 분할 정책.
설정
설명
loose원본 키프레임을 위배하지 않는다.
balancesegment_duration기준 +-1 초 가능한 적게 분할한다.strict정확히
segment_duration단위로 분할한다.segment_duration목표 HLS segment 길이 (초, 0 초과). 길수록 한번에 트랜스코딩하는 크기가 커져 반응성이 저하된다.
renditions¶
프로파일이 제공하는 멀티 스트림(해상도 · 코덱 조합)을 정의한다.
정의된 순서대로 master.m3u8 에 노출된다.
"renditions": [
{
"name": "fmp4_144p",
"container": "fmp4",
"video": { ... },
"audio": { ... }
}
]
namerendition 고유 이름.
{container}_{name}규칙을 따른다 (예:fmp4_1080p,m2ts_720p).^(fmp4|m2ts)_[a-z0-9][a-z0-9_.-]*$패턴.containerHLS 패키징 컨테이너 (
fmp4·m2ts중 택1)
video¶
"video": {
"enable": true,
"codec": "av1",
"gpu": { "preset": "p3", "quality": 35 },
"cpu": { "preset": "9", "quality": 35 },
"codec_options": { "profile": "main", "level": "4.1" },
"bit_rate": 2000000,
"frame_rate": 30,
"max_frame_rate": 60,
"resolution": "256x144",
"sizing_policy": "fit_to_orientation_no_upscale",
"padding_policy": "no_pad"
}
enable이 rendition 에 비디오 포함 여부
codec논리적 비디오 코덱 (
h264·av1). 실제 인코더 이름은 구현 정책에서 결정한다.gpuGPU 인코더 설정.
preset속도/품질 preset (^p[1-7]$, 즉p1~p7)quality품질 튜닝 값 (1~63, 낮을수록 고품질,cq에 대응). 필수
cpuCPU 인코더 설정 (GPU 사용 불가 시).
preset속도/품질 preset. 허용 범위는 구현 인코더 정책에서 결정한다.quality품질 튜닝 값 (1~63, 낮을수록 고품질,crf에 대응). 필수
codec_options코덱 세부 옵션.
profile코덱 프로파일 (예:baseline·main·high)level코덱 레벨 (예:4.0·4.1)max_bitrate/min_bitrate최대/최소 비디오 비트레이트 (bps)chroma_subsamplingyuv420p·yuv422p·yuv444p·nv12·autointerlace_modeauto·progressive·top_field_first·bottom_field_first
bit_rate목표 비디오 비트레이트 (bps)
frame_rate요청 출력 프레임레이트 (fps)
max_frame_rate최대 출력 프레임레이트 (fps). 인코더가 이 값을 초과하지 않도록 한다.
resolution{가로}x{세로}형식의 목표 해상도 (^\d+x\d+$, 예:1280x720)sizing_policy (기본: fit_to_orientation_no_upscale)원본을 목표 해상도에 맞추는 방식 (
fit·fit_to_orientation·fill·stretch·center_crop·fit_no_upscale·fill_no_upscale·fit_to_orientation_no_upscale)padding_policysizing_policy처리 후 남는 영역의 패딩 여부.no_pad패딩을 추가하지 않는다(운영 기본 동작).pad목표 해상도까지 레터박스 패딩을 추가한다.
Note
프로파일은 전역 스코프인 functions.contents.hive.profiles 설정만 지원한다. 가상호스트 단위 profile 정의는 지원하지 않는다.
audio¶
"audio": {
"enable": true,
"codec": "aac",
"codec_options": { "profile": "aac_low" },
"sample_rate": 48000,
"bit_rate": 128000,
"channels": 2
}
enable이 rendition 에 오디오 포함 여부
codec오디오 코덱 (
aac·ac3·eac3·opus). 값이 없으면 원본 유지 또는 구현 기본 정책을 따른다.codec_options.profile오디오 코덱 프로파일 (
aac_low·aac_he·aac_he_v2·auto). AAC 기준aac_low는 AAC-LC 에 대응한다.sample_rate샘플레이트 (Hz)
bit_rate목표 오디오 비트레이트 (bps)
channels오디오 채널 수 (1~8)
encrypt¶
EXT-X-KEY 암호화를 구성한다.
"encrypt": {
"enable": false,
"key_file_name": "enc.key",
"token": "",
"token_type": "raw",
"iv": null
}
enable (기본: false)HLS 암호화 활성화
key_file_nameplaylist 에 기록할 키 파일명
token암호화 토큰 또는 키 재료.
Note
공유 프로파일 파일에는 운영용 비밀값을 저장하지 않는 것을 권장한다.
token_typetoken표현 방식.rawtoken을 그대로 사용enc암호화된token을 사용 전 복호화
iv (기본: null)선택적 AES-128 Initial Vector.
0x로 시작하는 16바이트 16진수 문자열(^0x[0-9a-fA-F]{32}$)로 지정한다.
built-in 프로파일¶
별도 설정 없이 바로 동작하는 프로파일을 지원한다. 빌트인 프로파일은 _ 로 시작하는 규칙을 가진다.
대부분의 서비스는 빌트인만으로 충분하며, 세밀한 제어가 필요할 때만 profiles 을 정의한다.
# 빌트인 프로파일 재생
https://example.com/video.mp4/vfly/v1/vod/_premium/master.m3u8
name |
video |
audio |
max fps |
renditions |
용도 |
|---|---|---|---|---|---|
|
AV1 / H.264 |
AAC |
원본 |
1080p · 720p · 360p · 144p |
기본값. 보편적인 코덱과 해상도 지원. |
|
AV1 / H.264 |
AAC |
30 |
1080p · 720p · 480p · 360p |
가성비 범용 (general purpose) |
|
AV1 / H.264 |
AAC |
30 |
720p · 480p · 360p |
용량 절감 우선 (aggressive compression) |
|
AV1 / H.264 |
AAC |
30 |
2160p · 1440p · 1080p · 720p |
고품질 VOD / OTT, 4K 대응 |
|
원본 유지 |
원본 유지 |
원본 |
original (무변환) |
원본 코덱 호환성만 보장 |
|
AV1 / H.264 |
AAC |
30 |
1440p ~ 144p 7단 |
YouTube 스타일 MBR |
|
AV1 / H.264 |
AAC |
60 |
|
고프레임(HFR) 콘텐츠 |
Note
video 코덱은 컨테이너를 따른다 — fMP4 랜디션은
AV1, MPEG2-TS 랜디션은H.264._youtube계열의 MPEG2-TS 는 1440p · 240p 랜디션을 제외한다.
컨테이너 선택은 두 가지 방법이 있다.
URL 접미 (권장) — 프로파일 이름 뒤에
.fmp4·.m2ts를 붙이면 해당 컨테이너 랜디션만 노출한다 (예:_premium.fmp4). 접미가 없으면 프로파일이 제공하는 모든 컨테이너를 노출한다.전용 프로파일 — 컨테이너를 고정한 빌트인을 직접 지정한다:
_{tier}_fmp4·_{tier}_m2ts(예:_balance_fmp4,_default_m2ts).
Warning
프로파일은 빌트인과 구분하기 위해 _ 로 시작할 수 없다.
빌트인 프로파일의 정의는 다음과 같다. _{tier}_fmp4 · _{tier}_m2ts 는 아래 정의에서
해당 컨테이너의 rendition 만 남긴 것이다.
{
"schema_version": "v1",
"name": "_default",
"description": "기본 VideoFly profile. fMP4는 AV1, MPEG2-TS는 H.264 rendition을 제공한다.",
"hls": {
"transcode": {
"policy": "if_spec_mismatch",
"upscale": false
},
"version": 7,
"path": "abs",
"split": "loose",
"segment_duration": 2
},
"renditions": [
{
"name": "fmp4_1080p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 32
},
"codec_options": {
"profile": "main"
},
"resolution": "1920x1080"
}
},
{
"name": "fmp4_720p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 33
},
"codec_options": {
"profile": "main"
},
"resolution": "1280x720"
}
},
{
"name": "fmp4_360p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 38
},
"cpu": {
"preset": "9",
"quality": 35
},
"codec_options": {
"profile": "main"
},
"resolution": "640x360"
}
},
{
"name": "fmp4_144p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 35
},
"cpu": {
"preset": "9",
"quality": 35
},
"codec_options": {
"profile": "main"
},
"resolution": "256x144"
}
},
{
"name": "m2ts_1080p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"preset": "fast",
"quality": 25
},
"codec_options": {
"profile": "high",
"level": "4.2"
},
"resolution": "1920x1080"
}
},
{
"name": "m2ts_720p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"preset": "fast",
"quality": 23
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720"
}
},
{
"name": "m2ts_360p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 33
},
"cpu": {
"preset": "fast",
"quality": 23
},
"codec_options": {
"profile": "baseline",
"level": "3.0"
},
"resolution": "640x360"
}
},
{
"name": "m2ts_144p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 30
},
"cpu": {
"preset": "fast",
"quality": 23
},
"codec_options": {
"profile": "baseline",
"level": "2.0"
},
"resolution": "256x144"
}
}
]
}
{
"schema_version": "v1",
"name": "_balance",
"description": "가성비 범용 profile (general purpose). 1080p ~ 360p 4단 래더.",
"renditions": [
{
"name": "fmp4_1080p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 36
},
"codec_options": {
"profile": "main"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "fmp4_720p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 37
},
"codec_options": {
"profile": "main"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "fmp4_480p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 42
},
"cpu": {
"preset": "9",
"quality": 38
},
"codec_options": {
"profile": "main"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "fmp4_360p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 42
},
"cpu": {
"preset": "9",
"quality": 40
},
"codec_options": {
"profile": "main"
},
"resolution": "640x360",
"max_frame_rate": 30
}
},
{
"name": "m2ts_1080p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"preset": "fast",
"quality": 28
},
"codec_options": {
"profile": "high",
"level": "4.2"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "m2ts_720p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"preset": "fast",
"quality": 28
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "m2ts_480p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"preset": "fast",
"quality": 28
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "m2ts_360p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 33
},
"cpu": {
"preset": "fast",
"quality": 28
},
"codec_options": {
"profile": "baseline",
"level": "3.0"
},
"resolution": "640x360",
"max_frame_rate": 30
}
}
]
}
{
"schema_version": "v1",
"name": "_compact",
"description": "용량 중심 profile (aggressive compression). 720p AV1 only + 480p/360p 저용량 래더.",
"renditions": [
{
"name": "fmp4_720p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 48
},
"cpu": {
"preset": "9",
"quality": 38
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "fmp4_480p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 48
},
"cpu": {
"preset": "9",
"quality": 40
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "fmp4_360p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 48
},
"cpu": {
"preset": "9",
"quality": 40
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "640x360",
"max_frame_rate": 30
}
},
{
"name": "m2ts_720p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"preset": "fast",
"quality": 28
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "m2ts_480p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"preset": "fast",
"quality": 28
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "m2ts_360p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 33
},
"cpu": {
"preset": "fast",
"quality": 28
},
"codec_options": {
"profile": "baseline",
"level": "3.0"
},
"resolution": "640x360",
"max_frame_rate": 30
}
}
]
}
{
"schema_version": "v1",
"name": "_premium",
"description": "고해상도 프리미엄 profile. 고품질 VOD/OTT 대응. 2160p(4K) ~ 720p 래더.",
"renditions": [
{
"name": "fmp4_2160p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 28
},
"cpu": {
"preset": "9",
"quality": 20
},
"codec_options": {
"profile": "main",
"level": "5.1",
"chroma_subsampling": "yuv420p"
},
"resolution": "3840x2160",
"max_frame_rate": 30
}
},
{
"name": "fmp4_1440p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 30
},
"cpu": {
"preset": "9",
"quality": 22
},
"codec_options": {
"profile": "main",
"level": "5.0",
"chroma_subsampling": "yuv420p"
},
"resolution": "2560x1440",
"max_frame_rate": 30
}
},
{
"name": "fmp4_1080p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 32
},
"cpu": {
"preset": "9",
"quality": 24
},
"codec_options": {
"profile": "main",
"level": "4.0",
"chroma_subsampling": "yuv420p"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "fmp4_720p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 34
},
"cpu": {
"preset": "9",
"quality": 26
},
"codec_options": {
"profile": "main",
"level": "3.1",
"chroma_subsampling": "yuv420p"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "m2ts_2160p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 20
},
"cpu": {
"quality": 14
},
"codec_options": {
"profile": "high",
"level": "5.1",
"chroma_subsampling": "yuv420p"
},
"resolution": "3840x2160",
"max_frame_rate": 30
}
},
{
"name": "m2ts_1440p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 22
},
"cpu": {
"quality": 16
},
"codec_options": {
"profile": "high",
"level": "5.0",
"chroma_subsampling": "yuv420p"
},
"resolution": "2560x1440",
"max_frame_rate": 30
}
},
{
"name": "m2ts_1080p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 25
},
"cpu": {
"quality": 18
},
"codec_options": {
"profile": "high",
"level": "4.0",
"chroma_subsampling": "yuv420p"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "m2ts_720p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 27
},
"cpu": {
"quality": 20
},
"codec_options": {
"profile": "high",
"level": "3.1",
"chroma_subsampling": "yuv420p"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
}
]
}
{
"schema_version": "v1",
"name": "_source",
"description": "무변환 profile. 트랜스코딩 없이 원본 코덱 호환성만 보장하여 재생 가능하게 한다.",
"renditions": [
{
"name": "fmp4_original",
"container": "fmp4",
"audio": {
"enable": true
},
"video": {
"enable": true
}
},
{
"name": "m2ts_original",
"container": "m2ts",
"audio": {
"enable": true
},
"video": {
"enable": true
}
}
]
}
{
"schema_version": "v1",
"name": "_youtube",
"description": "YouTube 스타일 MBR profile. 최대 30fps. 1440p ~ 144p 래더.",
"renditions": [
{
"name": "fmp4_1440p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 35
},
"cpu": {
"preset": "9",
"quality": 26
},
"codec_options": {
"profile": "main",
"level": "5.0"
},
"resolution": "2560x1440",
"max_frame_rate": 30
}
},
{
"name": "fmp4_1080p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 38
},
"cpu": {
"preset": "9",
"quality": 28
},
"codec_options": {
"profile": "main",
"level": "4.0"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "fmp4_720p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 38
},
"cpu": {
"preset": "9",
"quality": 30
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "fmp4_480p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 32
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "fmp4_360p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 33
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "640x360",
"max_frame_rate": 30
}
},
{
"name": "fmp4_240p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 35
},
"codec_options": {
"profile": "main",
"level": "2.1"
},
"resolution": "426x240",
"max_frame_rate": 30
}
},
{
"name": "fmp4_144p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 38
},
"cpu": {
"preset": "9",
"quality": 37
},
"codec_options": {
"profile": "main",
"level": "2.0"
},
"resolution": "256x144",
"max_frame_rate": 30
}
},
{
"name": "m2ts_1080p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "high",
"level": "4.0"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "m2ts_720p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "m2ts_480p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "m2ts_360p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 33
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "baseline",
"level": "3.0"
},
"resolution": "640x360",
"max_frame_rate": 30
}
},
{
"name": "m2ts_144p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 30
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "baseline",
"level": "2.0"
},
"resolution": "256x144",
"max_frame_rate": 30
}
}
]
}
{
"schema_version": "v1",
"name": "_youtube_hfr",
"description": "YouTube HFR 스타일 profile. youtube 래더에 720p60 · 1080p60 rendition 추가. 고프레임 콘텐츠 대응.",
"renditions": [
{
"name": "fmp4_1440p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 35
},
"cpu": {
"preset": "9",
"quality": 26
},
"codec_options": {
"profile": "main",
"level": "5.0"
},
"resolution": "2560x1440",
"max_frame_rate": 30
}
},
{
"name": "fmp4_1080p60",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p4",
"quality": 35
},
"cpu": {
"preset": "8",
"quality": 26
},
"codec_options": {
"profile": "main",
"level": "4.2"
},
"resolution": "1920x1080",
"max_frame_rate": 60
}
},
{
"name": "fmp4_1080p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 38
},
"cpu": {
"preset": "9",
"quality": 28
},
"codec_options": {
"profile": "main",
"level": "4.0"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "fmp4_720p60",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p4",
"quality": 36
},
"cpu": {
"preset": "8",
"quality": 28
},
"codec_options": {
"profile": "main",
"level": "3.2"
},
"resolution": "1280x720",
"max_frame_rate": 60
}
},
{
"name": "fmp4_720p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 38
},
"cpu": {
"preset": "9",
"quality": 30
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "fmp4_480p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 32
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "fmp4_360p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 33
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "640x360",
"max_frame_rate": 30
}
},
{
"name": "fmp4_240p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 40
},
"cpu": {
"preset": "9",
"quality": 35
},
"codec_options": {
"profile": "main",
"level": "2.1"
},
"resolution": "426x240",
"max_frame_rate": 30
}
},
{
"name": "fmp4_144p",
"container": "fmp4",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "av1",
"gpu": {
"preset": "p3",
"quality": 38
},
"cpu": {
"preset": "9",
"quality": 37
},
"codec_options": {
"profile": "main",
"level": "2.0"
},
"resolution": "256x144",
"max_frame_rate": 30
}
},
{
"name": "m2ts_1080p60",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 28
},
"cpu": {
"quality": 20
},
"codec_options": {
"profile": "high",
"level": "4.2"
},
"resolution": "1920x1080",
"max_frame_rate": 60
}
},
{
"name": "m2ts_1080p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "high",
"level": "4.0"
},
"resolution": "1920x1080",
"max_frame_rate": 30
}
},
{
"name": "m2ts_720p60",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 28
},
"cpu": {
"quality": 20
},
"codec_options": {
"profile": "high",
"level": "3.2"
},
"resolution": "1280x720",
"max_frame_rate": 60
}
},
{
"name": "m2ts_720p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "main",
"level": "3.1"
},
"resolution": "1280x720",
"max_frame_rate": 30
}
},
{
"name": "m2ts_480p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 35
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "main",
"level": "3.0"
},
"resolution": "854x480",
"max_frame_rate": 30
}
},
{
"name": "m2ts_360p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 33
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "baseline",
"level": "3.0"
},
"resolution": "640x360",
"max_frame_rate": 30
}
},
{
"name": "m2ts_144p",
"container": "m2ts",
"audio": {
"codec": "aac",
"codec_options": {
"profile": "aac_low"
},
"channels": 2
},
"video": {
"codec": "h264",
"gpu": {
"quality": 30
},
"cpu": {
"quality": 23
},
"codec_options": {
"profile": "baseline",
"level": "2.0"
},
"resolution": "256x144",
"max_frame_rate": 30
}
}
]
}
kvcache¶
"kvcache" : {
"url_to_videoid": "5min",
"mezzanine": { }
}
url_to_videoid (기본: 5min)클라이언트 요청 URL에 매칭되는 video-id 캐싱시간
mezzanine¶
다음 세그먼트 요청에 대비해 원본 데이터(=mezzanine)를 가용상태로 유지한다.
"mezzanine": {
"keepalive": "5min",
"onIdle": { ... }
}
keepalive (기본: 5min)지정된 시간동안 mezzanine을 유지한다. 타임아웃은 접근될 때마다 초기화된다.
onIdle유휴 상태로 전환될 때의 정규화 위임. 지정하지 않으면 폐기한다.
onIdle¶
keepalive 가 만료되어 mezzanine 이 캐시에서 내려가는 시점에 canon draft 정규화를 위임한다.
캐시에서 내려갈 뿐 원본이 삭제되는 것이 아니다.
구조는 canon 작업 생성 의 본문과 같다.
대상 원본( origin )은 mezzanine 의 원본 URL 이 자동으로 지정되므로 적지 않는다.
# 정규화하여 원본 스토리지의 원본 경로에 적재한다. (덮어쓰기)
"onIdle": {
"profile": "my_standard_profile",
"dest": [ "originstorage" ]
}
# 다른 저장소 두 곳에 적재하고 원본을 삭제한다.
"onIdle": {
"profile": "my_standard_profile",
"dest": [ "canonarchive", "canonbackup" ],
"delete": [ "originstorage" ]
}
storage¶
원본 조회( src ) 및 산출물 저장( dest )에 사용할 오브젝트 스토리지(S3) 목록을 정의한다.
"storage": {
"list": [
{
"name": "vfly-src",
"scope": "src",
"bucket": "vfly-src-bucket",
"region": "ap-northeast-2",
"enableRead": true,
"enableWrite": false
},
{
"name": "vfly-dst",
"scope": "dest",
"bucket": "vfly-asset-bucket",
"region": "ap-northeast-2",
"enableRead": true,
"enableWrite": true,
"touch": {
"enable": false,
"age": "300d"
}
}
]
}
name스토리지 식별 이름
scope스토리지 용도. 세 값만 허용하며, 그 외 값은 배포가 거부된다.
설정
설명
src원본 미디어 조회
dest가공 산출물 저장
both조회 · 저장 겸용
enableRead읽기 활성화.
read접근 시 이 플래그가true인 항목만 선택된다.enableWrite쓰기 활성화.
write접근 시 이 플래그가true인 항목만 선택된다.bucket버킷 이름
region버킷 리전 (예:
ap-northeast-2)basepath객체 키 접두. 미지정 시 meta 의
basepath→ 빈 문자열 순으로 폴백한다.domain엔드포인트 도메인 (S3 호환 스토리지 지정 시)
accessKey/secretKey접속 자격 증명
touch객체 접근 시각 갱신 정책.
enable활성화 여부age갱신 최소 간격
See also
transcoder — 트랜스코딩 시스템 권장사항 및 프리셋.
profiles — 프로파일 기반 HLS 구성 개념.
HLS JIT Packaging — 원본 세그먼트 확보에 사용한다.
canon draft — JIT 재생에 부적합한 원본을 정규화해 입력 원본으로 대체한다.