transcoder¶
/usr/local/m2/setting.json 다음 영역에 대해 기술한다.
{
"functions": {
"contents": {
"transcoder": {
...
}
}
}
}
Important
트랜스코딩 시스템 권장사항은 다음과 같다.
용도 |
Core |
메모리(GiB) |
비고 |
|---|---|---|---|
test |
4 |
4 |
동작을 위해 트랜스코딩 성능 제약 |
stage |
4 |
8 |
다른 함수와 동시 구동이 가능 |
production (SMB) |
8 |
16 |
gif2video 서비스 가능 |
production (enterprise) |
16 |
32 |
권장 |
How to use¶
명령어 리스트¶
# 비디오 분석정보를 JSON으로 제공한다.
https://example.com/video.mp4/xcdr/analyze/src
https://example.com/video.mp4/xcdr/analyze/srcd
# 원본-변환된 비디오 간 SSIM 값을 측정한다.
https://example.com/video.mp4/xcdr/preset/_720p/analyze/ssim
# /video.mp4를 사전 정의한 low 프리셋으로 트랜스코딩
https://example.com/video.mp4/xcdr/preset/low
# /video.mp4를 _1080p 프리셋 (built-in) 로 트랜스코딩
https://example.com/video.mp4/xcdr/preset/_1080p
# /video.mp4를 _1080p 프리셋 기반, 세부옵션만 조정하여 트랜스코딩
https://example.com/video.mp4/xcdr/preset/_1080p/options/audio.channels=1;video.frameRate=10
# /video.mp4를 구간/다구간 추출
https://example.com/video.mp4/xcdr/trim/01:20-01:30
https://example.com/video.mp4/xcdr/trim/01:20-01:30,03:57-04:28
https://example.com/video.mp4/xcdr/trim/45-50,11-13,36-43/faststart/true
# /video.mp4를 헤더만 앞으로 옮겨 전달
https://example.com/video.mp4/xcdr/faststart/true
# 화면을 캡쳐한다.
https://example.com/video.mp4/xcdr/capture/ts=10.3
# 화면을 캡쳐하여 avif로 추출한다.
https://example.com/video.mp4/xcdr/capture/ts=10.3;format=avif
# 화면을 캡쳐하여 animated 이미지로 제공한다.
https://example.com/video.mp4/xcdr/capture/ts=1,2,3,4,5
# 화면을 캡쳐하여 1s간격의 mp4 비디오로 제공한다.
https://example.com/video.mp4/xcdr/capture/ts=1,2,3,4,5;format=mp4
# 비디오 오리엔테이션을 세로 방향에 최적화한다.
https://example.com/video.mp4/xcdr/portrait/shorts
# 비디오와 이미지를 오버레이 합성한다.
https://example.com/video.mp4/xcdr/overlay/bg
# 변환된 비디오 용량이 원본보다 크면 예외처리되어, exception 명령처리한다. 미지정시 변환된 비디오를 응답한다.
https://example.com/video.mp4/xcdr/preset/_720p/throw/oversourcesize
# 다수의 예외처리 명령시 세미콜론을 사용한다.
https://example.com/video.mp4/xcdr/preset/_720p/throw/oversourcesize;missframe
여러 명령어를 결합하거나 다른 함수와 연계되면 보다 확장성있는 서비스를 구현할 수 있다.
# /video.mp4의 10초~20초 구간추출하여 low 프리셋으로 트랜스코딩
https://example.com/video.mp4/xcdr/trim/00:00:10-00:00:20/preset/low
https://example.com/video.mp4/xcdr/trim/10-20/preset/low
# /video.mp4의 1시간 15분 30초 이후 구간추출하여 low 프리셋으로 트랜스코딩 후 헤더를 앞으로 이동
https://example.com/video.mp4/xcdr/trim/1:15:30-/preset/low/faststart/true
# /video.mp4를 시작부터 1분 30초 구간만 추출하여 low 프리셋으로 트랜스코딩 후 헤더를 앞으로 이동
https://example.com/video.mp4/xcdr/trim/-01:30/preset/low/faststart/true
# mp4hls 연계 - /video.mp4를 _1080p 프리셋으로 트랜스코딩한 다음 해당영상을 HLS로 전송
https://example.com/video.mp4/xcdr/preset/_1080p/mp4hls/index.m3u8
# mp4hls 연계 - /video.mp4 원본을 HLS로 분할한 뒤 전송과정에서 _1080p 프리셋으로 트랜스코딩
https://example.com/video.mp4/mp4hls/index.m3u8/xcdr/preset/_1080p
# mp4hls 연계 - /video.mp4 원본을 구간추출한 뒤 _1080p 프리셋으로 트랜스코딩, 이후 HLS로 전송
https://example.com/video.mp4/xcdr/trim/00:01:40-00:03:00/preset/_1080p/mp4hls/index.m3u8
# dims 연계 - /video.mp4 원본의 10.3초 구간을 이미지로 추출하여 800x600으로 리사이즈한다.
https://example.com/video.mp4/xcdr/capture/ts=10.3/dims/resize/800x600
명령어 |
파라미터 |
동작 |
|---|---|---|
|
|
비디오 분석정보를 |
|
|
고~급스럽게 영국식 명령어를 제공한다. |
|
|
원본-변환된 비디오 간 SSIM 값을 측정한다. |
|
{이름} |
트랜스코딩할 프리셋을 지정한다. |
|
|
|
|
|
동영상 trim 구간을 지정한다. |
|
|
동영상 헤더정보를 파일의 앞으로 이동시킨다. |
|
|
프리셋 기반 트랜스코딩 처리 중 예외상황/오류가 발생시 예외처리 방법을 지정한다. |
|
|
화면을 캡쳐 지점. 단일 또는 콤마로 구분된 연속 |
|
{이름} |
동영상을 Portrait 오리엔테이션으로 출력한다. |
|
{이름} |
동영상과 이미지를 오버레이한다. |
|
|
동영상 변환 결과 크기가 원본보다 크다면 예외처리하여 |
|
|
동영상 원본이 비정상 프레임을 가진 경우 예외처리하여 |
Note
- 명령어 우선순위
이 함수는 priorityCommand: [“capture”, “trim”] 설정으로 명령어 우선순위를 처리한다.
명령어별 시스템 부하량이 상이하므로
capture,trim,preset순서로 우선순위가 책정된다.
trim명령어 원리와 옵션동영상 트리밍 기능은 필요한 구간을 keyframe 단위로 추출하므로 용량 변화가 없을 수 있다.
이때 경량화를 위해 인코딩을 강제하려면
!옵션을 사용한다. 예)trim/!3-5
비디오 분석정보¶
/analyze/src 명령어는 비디오 분석정보를 간략히 제공한다.
{
"enable": true,
"url": "/video.mp4",
"result": {
"source": {
"size": 6238713,
"format": "mp4",
"duration": 15.062,
"video": {
"codec_name": "h264",
"width": 1920,
"height": 1080
},
"audio": {
"codec_name": "aac"
}
},
"elapsed": {
"init": 2,
"complete": 14
},
"function": {
"keyword": "xcdr"
}
}
}
enable트랜스코더 모듈에 적재/처리 가능하다면
true, 불가하다면falseurl원본 URL
result분석결과
source미디어 정보
size (단위: bytes)용량
format포맷 -
flac,flv,fmp4,gif,mp2,mp3,mp4,mpg,mxf,oga,ogg,ts,wav,webmduration (단위: 초)재생시간 (소수점 3째자리까지 표시)
video비디오 정보. 비디오가 없다면
null이다.codec_name비디오 코덱
width (단위: px)가로길이
height (단위: px)세로길이
audio오디오 정보. 오디오가 없다면
null이다.codec_name비디오 코덱
elapsed경과시간
init (단위: ms)호출시점 ~ 원본이미지 초기화
complete (단위: ms)호출시점 ~ 완료
function트랜스코더 설정
keyword호출 키워드
/analyze/srcd 명령어는 보다 상세한 분석정보를 제공한다.
{
"enable": true,
"url": "/video.mp4",
"result": {
"source": {
"streams": [
{
"index": 0,
"codec_name": "aac",
"codec_long_name": "AAC (Advanced Audio Coding)",
"profile": "LC",
"codec_type": "audio",
"codec_time_base": "1/48000",
"codec_tag_string": "mp4a",
"codec_tag": "0x6134706d",
"sample_fmt": "fltp",
"sample_rate": "48000",
"channels": 2,
"channel_layout": "stereo",
"bits_per_sample": 0,
"r_frame_rate": "0/0",
"avg_frame_rate": "0/0",
"time_base": "1/48000",
"start_pts": -2048,
"start_time": "-0.042667",
"duration_ts": 722944,
"duration": "15.061333",
"bit_rate": "160002",
"max_bit_rate": "160002",
"nb_frames": "706",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0
},
"tags": {
"language": "kor",
"handler_name": "SoundHandler"
}
},
{
"index": 1,
"codec_name": "h264",
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
"profile": "High",
"codec_type": "video",
"codec_time_base": "1/60",
"codec_tag_string": "avc1",
"codec_tag": "0x31637661",
"width": 1920,
"height": 1080,
"coded_width": 1920,
"coded_height": 1088,
"has_b_frames": 2,
"sample_aspect_ratio": "1:1",
"display_aspect_ratio": "16:9",
"pix_fmt": "yuv420p",
"level": 41,
"color_range": "tv",
"color_space": "bt709",
"color_transfer": "bt709",
"color_primaries": "bt709",
"chroma_location": "left",
"refs": 4,
"is_avc": "1",
"nal_length_size": "4",
"r_frame_rate": "30/1",
"avg_frame_rate": "30/1",
"time_base": "1/15360",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 230400,
"duration": "15.000000",
"bit_rate": "3157810",
"bits_per_raw_sample": "8",
"nb_frames": "450",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0
},
"tags": {
"language": "und",
"handler_name": "VideoHandler"
}
}
],
"format": {
"filename": "http://rproxy.video.m2/http://127.0.0.1/mmv/media/monopoly.mp4",
"nb_streams": 2,
"nb_programs": 0,
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"format_long_name": "QuickTime / MOV",
"start_time": "-0.042667",
"duration": "15.062000",
"size": "6238713",
"bit_rate": "3313617",
"probe_score": 100,
"tags": {
"major_brand": "isom",
"minor_version": "512",
"compatible_brands": "isomiso2avc1mp41",
"encoder": "Lavf57.71.100"
}
}
},
"elapsed": {
"init": 2,
"complete": 14
},
"function": {
"keyword": "xcdr"
}
}
}
유사성 비교¶
/analyze/ssim 명령어는 원본과 변환된 비디오의 유사성을 SSIM(Structural Similarity Index Measure) 방식으로 비교한다.
{
"enable": true,
"url": "/example.mp4",
"result": {
"ssim": "0.971172",
"elapsed": {
"init": 5217,
"complete": 9559
}
}
}
enableSSIM 비교가 정상처리되었다. 실패라면
false로 응답하다.url원본 URL
result분석결과
ssim (범위: 0~1)원본과 변환된 비디오의 유사성으로 완전히 동일하다면
1이다.
Portrait 오리엔테이션 변경¶
portrait 명령어로 Shorts 영상과 같은 세로 방향 비디오를 생성한다.
# 사전 정의된 "shorts" 설정으로 오리엔테이션 반영
https://example.com/video.mp4/xcdr/portrait/shorts
오버레이 합성¶
overlay 명령어로 비디오를 합성한다.
# 사전 정의된 "bg" 설정으로 오버레이 합성
# overlay: [{name:bg, url:bg.png, fit:fill}]
https://example.com/video.mp4/xcdr/overlay/bg
# 동영상 하단 20% 영역에 subtitle.png 배치
# overlay: [{name:subtitle, url:title.png, gravity:s, size:100%x20%}]
https://example.com/video.mp4/xcdr/overlay/subtitle
# 다수의 오버레이 합성
https://example.com/video.mp4/xcdr/overlay/bg,subtitle
예외처리¶
프리셋 기반 트랜스코딩 처리 중 예외상황/오류가 발생했을 때 정책을 지정한다.
Note
기본정책은 오류 발생시
510응답한다.- 트랜스코딩 명령어
preset과 함께 동작한다. faststartoptions명령어와 함께 사용할 수 있다.trimcapturemp4hlsanalyze와 같이 원본 대체불가 명령과 함께 사용시510응답한다.
- 트랜스코딩 명령어
# 오류 발생시 510 Not Extended를 응답한다. 이 때 Body는 디버깅을 위한 분석정보가 노출된다. (기본)
https://example.com/sample.mp4/xcdr/preset/_gif2avif/exception/debug
# 오류 발생시 원본으로 리디렉션한다.
https://example.com/sample.mp4/xcdr/preset/_gif2avif/exception/redirect
# 오류 발생시 원본을 전달한다.
https://example.com/sample.mp4/xcdr/preset/_gif2avif/exception/origin
# debug 응답
{
# 원본이 200 OK라면 분석 정보를 제공한다.
"origin": {
...
},
# error - 표준 에러리스트 정보
"error": {
"code": 30500012,
"x-sc-chain": "failpresetformat",
"vhost": "cdn.example.com",
"url": "/sample.mp4",
"x-ctx-id": "454ecfb6-13d8-496d-b137-8b0d411caa21",
"command": "/preset/_gif2avif",
"content-length": 6686799,
"reason": "not gif format"
}
}
meta¶
"meta" : {
"enable" : false,
"keyword": "xcdr",
"tempdir": "xcdrtmp",
"mountdir": null,
"maxDuration": "3:00",
"capacityPerCore": 52428800,
"sliceMinSize": 5242880,
"sliceMinDuration": 4
}
enable (기본: false)트랜스코딩 활성화
keyword (기본: xcdr)트랜스코딩 키워드
tempdir (기본: xcdrtmp)임시파일 I/O 디렉토리 경로 (상대경로인 경우 설치경로 하위에 생성된다.)
mountdir (기본: null)원본 비디오를 파일시스템에서 참조한다.
# meta:{mountdir: /mnt/video} 설정 후 아래 요청시 http://example.com/group/sample.mp4/xcdr/preset/_mp42webm # 파일시스템의 다음 경로를 참조한다. /mnt/video/group/sample.mp4
Warning
이 설정시 가상호스트의 모든
xcdr요청에 대해 파일시스템에서 원본을 참조하므로, 시스템의 File I/O 병목을 유의해야한다.참고) transcoder 기본 동시성은 2개이며, 다음 설정을 참조한다.
env.properties > {process.transcoder.concurrent: 2}
maxDuration (기본: 3:00)트랜스코딩 가능한 소스 최대 시간으로
hh:mm:ss표기를 사용한다. 소스가trim되었다면trim된 시간을 기준으로 한다.Warning
이 값은 지나치게 무거운 워크로드로 인해 의도치 않은 서비스 지연을 방지하는 안전장치이다.
설정을 조정할 경우 서비스 흐름상에서 클라이언트가 응답에 대해 충분히 대기하여 처리 가능한지 검증되어야 한다.
capacityPerCore (기본: 50MB)코어당 트랜스코딩 대기 가능한 최대 용량. 8코어 머신이라면 400MB까지 큐잉이 가능하다.
Note
단, 현재 트랜스코딩되는 크기는 포함되지 않는다. 최대 큐잉크기를 넘어선다면
503 Service Unavailable을 응답한다.sliceMinSize (기본: 5MB)트랜스코딩시 원본 비디오를 슬라이싱해서 병렬 처리하기 위한 최소 용량. 이 값보다 작은 비디오는 병렬 처리 하지 않는다.
0 이면 병렬처리 하지 않는다.
sliceMinDuration (기본: 4초)트랜스코딩 병렬 처리 시 최소 구간 길이. 구간을 나눌 때 해당 값만큼 최소 길이를 보장한다.
Note
트랜스코딩 병렬 처리는 CPU 자원을 효율적으로 활용하기 위한 기능이다.
단, 구간이 너무 짧거나 용량이 작다면 오히려 성능이 저하될 수 있다.
최대 병렬 처리 수는 env.properties > {process.transcoder.concurrent} 설정을 따른다.
presets¶
AWS Elastic Transcoder 와 동일한 인터페이스와 기능을 제공한다.
"presets" : {
"optimize": {
"enable": true,
"priority": "size"
},
"passthrough": "none",
"list": [
{
"name": "low",
"video":{
"bitRate":"900",
"maxWidth":"640",
"maxHeight":"480"
},
"watermarks":[
{
"maxWidth": "20%",
"maxHeight": "20%",
"sizingPolicy": "ShrinkToFit",
"horizontalAlign": "Right",
"horizontalOffset": "10px",
"verticalAlign": "Bottom",
"verticalOffset": "10px",
"opacity": "55.5",
"target": "Content"
}
]
}
]
}
optimize동영상 인코딩 최적화 수준을 정의한다.
enable (기본: true)최적화 동작 활성화
priority최적화 우선순위
size (기본값)보통 품질로 최적화하여 용량을 절감한다.quality우수한 품질을 유지하며 용량을 소폭 절감한다.
Note
비디오 포맷 및 해상도에 따라 적절한 CRF 채택을 통해 품질을 조절한다.
코덱 / 컨테이너
720p (size / quality)
1080p (size / quality)
AV1 / WEBM, MP4
37 / 35
35 / 33
VP9 / WEBM
34 / 32
32 / 30
H.264 / MP4
25 / 23
23 / 21
passthrough (기본: none)트랜스코딩 효과가 낮은 경우 동작을 정의한다. 원본 비디오와 프리셋의 포맷/코덱, 해상도가 같은 경우 해당한다.
none트랜스코딩한다.redirect원본으로 리디렉션한다.origin원본을 응답한다.
Note
preset 명령어 단독 사용시 동작한다.
- 프리셋 해상도가
auto아닌 값으로 명시된 경우 동작한다. 예)
_1080p,_720p,_480p,_360p
- 프리셋 해상도가
# 원본 예) MP4 / H.264 / 1280x720 http://example.com/720p.mp4 # passthrough 동작 http://example.com/720p.mp4/xcdr/preset/_720p # passthrough 미동작 http://example.com/720p.mp4/xcdr/preset/_720p/options/video.maxWidth=720 http://example.com/720p.mp4/xcdr/preset/_720p/options/video.bitRate=1000 http://example.com/720p.mp4/xcdr/preset/_720p/faststart/true
list프리셋 정의
preset 세부옵션¶
설정옵션 |
값 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
출력 파일의 오디오 비트 전송률(KB/초) |
|
|
|
|
|
|
|
|
|
|
|
|
|
최대 참조 프레임 수 |
|
최대 비트 전송률 |
|
최소 비트 전송률 |
|
|
|
|
|
|
|
|
|
|
|
키 프레임 사이의 최대 프레임 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
최소 |
|
최소 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
built-in¶
별도 설정없이도 동작하는 프리셋을 지원한다.
빌트인 프리셋은 _ 로 시작하는 규칙을 가진다.
name |
container |
source formats |
video |
audio |
width |
height |
bitrate |
|---|---|---|---|---|---|---|---|
|
mp4 |
|
H.264 |
AAC |
1920 |
1080 |
5400 kbps |
|
mp4 |
|
H.264 |
AAC |
1280 |
720 |
2400 kbps |
|
mp4 |
|
H.264 |
AAC |
854 |
480 |
1200 kbps |
|
mp4 |
|
H.264 |
AAC |
640 |
360 |
720 kbps |
|
mp4 |
|
AV1 |
AAC |
|
|
|
|
webp |
|
webp |
|
|
|
360 kbps |
|
avif |
|
AV1 |
|
|
|
360 kbps |
|
webm |
|
AV1 |
opus |
|
|
|
|
mp4 |
|
H.264 |
|
|
|
3000 kbps |
|
webp |
|
webp |
|
|
|
360 kbps |
|
avif |
|
AV1 |
|
|
|
360 kbps |
|
webm |
|
vp9 |
opus |
|
|
|
Warning
요청한 원본 동영상이 프리셋의 원본 포맷과 (
source formats) 다르다면, 원본으로 리디렉션한다.presets.list[].name이름을_1080p로 build-in과 동일하게 지정하여 오버라이딩 가능하다. 하지만 혼란스러움을 감당할만큼 가치있는 일이 아니다.
{
"list": [
{
"name":"_1080p",
"container":"mp4",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio":{
"enable": true,
"codec":"AAC",
"codecOptions":{
"profile":"AAC-LC",
"bitDepth":"8"
},
"sampleRate":"44100",
"bitRate":"128",
"channels":"2"
},
"video":{
"enable": true,
"codec":"H.264",
"speed": "medium",
"codecOptions":{
"profile":"high",
"level":"4",
"maxReferenceFrames": "3",
"interlacedMode":"progressive",
"colorSpaceConversionMode":"none",
"chromaSubsampling":"yuv420p"
},
"keyframesMaxDist": "24",
"fixedGOP": false,
"bitRate": "5400",
"frameRate":"23.97",
"maxFrameRate":"30",
"maxWidth":"1920",
"maxHeight":"1080",
"sizingPolicy":"ShrinkToFit",
"paddingPolicy":"NoPad",
"displayAspectRatio":"auto"
}
},
{
"name":"_720p",
"container":"mp4",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio":{
"enable": true,
"codec":"AAC",
"codecOptions":{
"profile":"AAC-LC",
"bitDepth":"8"
},
"sampleRate":"44100",
"bitRate":"128",
"channels":"2"
},
"video":{
"enable": true,
"codec":"H.264",
"speed": "medium",
"codecOptions":{
"profile":"high",
"level":"3.1",
"maxReferenceFrames": "3",
"interlacedMode":"progressive",
"colorSpaceConversionMode":"none",
"chromaSubsampling":"yuv420p"
},
"keyframesMaxDist": "24",
"fixedGOP": false,
"bitRate": "2400",
"frameRate":"23.97",
"maxFrameRate":"30",
"maxWidth":"1280",
"maxHeight":"720",
"sizingPolicy":"ShrinkToFit",
"paddingPolicy":"NoPad",
"displayAspectRatio":"auto"
}
},
{
"name":"_480p",
"container":"mp4",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio":{
"enable": true,
"codec":"AAC",
"codecOptions":{
"profile":"AAC-LC",
"bitDepth":"8"
},
"sampleRate":"44100",
"bitRate":"128",
"channels":"2"
},
"video":{
"enable": true,
"codec":"H.264",
"speed": "medium",
"codecOptions":{
"profile":"main",
"level":"3",
"maxReferenceFrames": "3",
"interlacedMode":"progressive",
"colorSpaceConversionMode":"none",
"chromaSubsampling":"yuv420p"
},
"keyframesMaxDist": "24",
"fixedGOP": false,
"bitRate": "1200",
"frameRate":"23.97",
"maxFrameRate":"30",
"maxWidth":"854",
"maxHeight":"480",
"sizingPolicy":"ShrinkToFit",
"paddingPolicy":"NoPad",
"displayAspectRatio":"auto"
}
},
{
"name":"_360p",
"container":"mp4",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio":{
"enable": true,
"codec":"AAC",
"codecOptions":{
"profile":"AAC-LC",
"bitDepth":"8"
},
"sampleRate":"44100",
"bitRate":"128",
"channels":"2"
},
"video":{
"enable": true,
"codec":"H.264",
"speed": "medium",
"codecOptions":{
"profile":"Baseline",
"level":"3",
"maxReferenceFrames": "1",
"interlacedMode":"progressive",
"colorSpaceConversionMode":"none",
"chromaSubsampling":"yuv420p"
},
"keyframesMaxDist": "24",
"fixedGOP": false,
"bitRate": "720",
"frameRate":"23.97",
"maxFrameRate":"30",
"maxWidth":"640",
"maxHeight":"360",
"sizingPolicy":"ShrinkToFit",
"paddingPolicy":"NoPad",
"displayAspectRatio":"auto"
}
},
{
"name":"_mp42av1",
"container":"mp4",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio":{
"enable": true,
"codec":"AAC",
"codecOptions":{
"profile":"AAC-LC",
"bitDepth":"8"
},
"sampleRate":"44100",
"bitRate":"128",
"channels":"2"
},
"video":{
"enable": true,
"codec": "AV1",
"speed": "medium",
"codecOptions":{
"profile": "main",
"chromaSubsampling": "yuva420p"
},
"bitRateForce": true,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
},
{
"name": "_mp42webp",
"container": "webp",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio": {
"enable": false
},
"video": {
"enable": true,
"codec": "webp",
"codecOptions": {
"profile": "main",
"chromaSubsampling": "yuv420p"
},
"fixedGOP": false,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
},
{
"name": "_mp42avif",
"container": "avif",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio": {
"enable": false
},
"video": {
"enable": true,
"codec": "AV1",
"codecOptions": {
"profile": "main",
"chromaSubsampling": "yuv420p"
},
"fixedGOP": false,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
},
{
"name": "_mp42webm",
"container": "webm",
"source": {
"formats": ["mp4","avi","mov"]
},
"audio": {
"enable": true,
"codec": "opus",
"bitRateForce": false
},
"video": {
"enable": true,
"codec": "SVT_AV1",
"codecOptions": {
"profile": "main",
"chromaSubsampling": "yuva420p"
},
"bitRateForce": true,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
},
{
"name": "_gif2mp4",
"container": "mp4",
"source": {
"formats": ["gif"]
},
"audio": {
"enable": false
},
"video": {
"enable": true,
"codec": "H.264",
"codecOptions": {
"profile": "main",
"chromaSubsampling": "yuv420p"
},
"fixedGOP": false,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
},
{
"name": "_gif2webp",
"container": "webp",
"source": {
"formats": ["gif"]
},
"audio": {
"enable": false
},
"video": {
"enable": true,
"codec": "webp",
"codecOptions": {
"profile": "main",
"chromaSubsampling": "yuv420p"
},
"fixedGOP": false,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
},
{
"name": "_gif2avif",
"container": "avif",
"source": {
"formats": ["gif"]
},
"audio": {
"enable": false
},
"video": {
"enable": true,
"codec": "AV1",
"codecOptions": {
"profile": "main",
"chromaSubsampling": "yuv420p"
},
"fixedGOP": false,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
},
{
"name": "_gif2webm",
"container": "webm",
"source": {
"formats": ["gif"]
},
"audio": {
"enable": true,
"codec": "opus",
"bitRateForce": false
},
"video": {
"enable": true,
"codec": "vp9",
"codecOptions": {
"profile": "main",
"chromaSubsampling": "yuva420p"
},
"bitRateForce": true,
"sizingPolicy": "ShrinkToFit",
"paddingPolicy": "NoPad"
}
}
]
}
capture¶
capture 명령어로 추출되는 이미지 출력형태를 설정한다.
"capture" : {
"format" : "webp",
"interval" : "1s"
}
format (기본: webp)출력 포맷
webp,jpg,png,gif,avif,mp4를 지원한다.Note
jpg,png와 같이 animated를 지원하지 않는 포맷에서 다구간을 추출하는 경우라면 첫 장만 추출된다.interval (기본: 1s)다구간 animated 이미지 추출시 화면전환 간격
Warning
비디오 가로, 세로 길이가 고정되면 비율을 유지하지 않는다. 추출된 이미지에 대한 가공은 hyperdims 를 연계하는 것을 권장한다.
/video.mp4/xcdr/capture/ts=10/hdims/resize/640
portrait¶
portrait 명령어로 세로 방향 비디오로 크기를 조정한다.
"portrait" : [{
"name" : "shorts"
"fill" : 70,
"margin" : "0"
}]
name사전 정의된 프리셋 이름
size출력 비디오 해상도. 미지정시 원본 비디오 해상도에 따라 자동 선택된다.
1080x1920원본 해상도 FHD 이상720x1280원본 해상도 HD 이상480x640원본 해상도 VGA 이상240x320원본 해상도 VGA 미만
fill (기본: 70)캔버스 높이의 70% 이상을 채운다. 캔버스 밖으로 확대되는 영역은 노출되지 않는다.
margin (기본: 0)비디오의 상하좌우 마진을 구성한다. 웹 서비스의 비디오 위에 배치된 버튼 UI를 위해 사용한다.
10%상하좌우 마진 10%0+10%좌우 마진 10%
gravity (기본: c)캔버스 내 비디오 위치 지정
n캔버스 상단c캔버스 중앙s캔버스 하단
offset비디오 위치 지정. gravity로 결정된 위치의 상대위치를 조정한다.
+10-20x축 +10픽셀, y축 -20픽셀 이동+10%-20%x축 비디오 크기의 +10% 이동, y축 -20% 이동
color (기본: black)배경 색상 지정
색상명 또는 색상코드 (예:
0xFFFF00)
overlay¶
overlay 명령어로 비디오에 오버레이 미디어를 출력한다.
"overlay" : [{
"name" : "bg"
"url" : "http://example.com/bg.png",
"fit" : "fill",
"dissolve" : 50
}]
name사전 정의된 프리셋 이름
url미디어 리소스 위치. 원격 및 파일시스템을 지원한다.
Note
url: bg.png와 같이 상대경로 설정시 M2 설치 위치를 기준으로 한다.
fit (기본: none)
fill비디오 영역에 가득 채운다.
contain오버레이 표현이 모두 노출되도록, 가로세로비를 유지하며 확대/축소한다.
cover오버레이 표현이 일부 잘리더라도, 가로세로비를 유지하며 비디오 영역을 채우도록 확대/축소한다.
none크기를 조절하지 않는다.
size오버레이 크기 지정
20x0폭 20픽셀 고정, 높이 비율 조정20x-1폭 20픽셀 고정, 높이 조정 없음50%x100%폭 50%, 높이 100% 지정 (fit결과물 기준 비율)
gravity (기본: nw)캔버스 내 비디오 위치 지정
nw,n,ne,w,c,e,sw,s,se
offset (기본: +0+0)오버레이 위치 지정. gravity로 결정된 위치의 상대위치를 조정한다.
+10-20x축 +10픽셀, y축 -20픽셀 이동+10%-20%x축 비디오 크기의 +10% 이동, y축 -20% 이동
dissolve (기본: 0)투명도 지정 (0 ~ 100)