콘텐츠로 이동

FFmpeg에서 넘어오기

FFmpeg 필터그래프로 영상을 만들어 왔다면, 이 페이지에서 같은 일을 alpha2로 하는 방법과 각 도구가 어디에 맞는지 볼 수 있습니다.

alpha2는 FFmpeg를 대체하지 않습니다. 네이티브 프로그램은 FFmpeg 8로 디코딩하고 인코딩합니다. 달라지는 것은 그 사이입니다. 필터그래프 문자열 대신 프로젝트 문서를 씁니다. 소스, 트랙, 클립으로 된 JSON 타임라인이며 GPU 엔진이 렌더링합니다. 같은 문서가 브라우저에서 프리뷰되고 서버에서 렌더링되며, 편집하고 diff하고 스키마로 검사할 수 있습니다.

FFmpeg alpha2
입력(-i) id가 붙은 sources. 파일은 export할 때 --asset <id>=<path>로 넘깁니다.
레이블 붙은 스트림의 필터그래프 하나의 타임라인 위 tracks의 clips. 뒤 트랙이 위에 그려집니다.
입력별 타임스탬프, -ss, -t, trim 클립의 timeline_range(재생 위치)와 source_range(소스의 재생 부분), 틱 단위
마지막 필터가 정하는 출력 크기 프로젝트의 settings.width와 height. 모든 소스가 그 안에 맞춰집니다.
픽셀 좌표(x=W-w-40) 정규화된 위치: 캔버스 가로세로 0~1
스트림에 거는 필터 클립의 컴포지션 그래프 안의 이펙트
sendcmd나 t에 대한 식을 쓴 -filter_complex 애니메이션 가능한 모든 값의 키프레임

사진 두 장 사이의 크로스페이드, 두 번째 사진의 색 보정, 한 줄의 텍스트를 담은 프로젝트와 그에 해당하는 FFmpeg 명령입니다.

터미널 창
ffmpeg -loop 1 -t 3 -i coast.jpg -loop 1 -t 3 -i forest.jpg -filter_complex "
[0:v]scale=1280:720,setsar=1[a];
[1:v]scale=1280:720,setsar=1,eq=contrast=1.2:saturation=1.3[b];
[a][b]xfade=transition=fade:duration=1:offset=2,
drawtext=fontfile=HankenGrotesk.ttf:text='Day two':fontsize=58:fontcolor=white:
x=w*0.05:y=h*0.92-th:enable='gte(t,3)'" -r 30 out.mp4
{
"schema_version": 1,
"id": "from-ffmpeg",
"name": "From FFmpeg",
"settings": {
"width": 1280,
"height": 720,
"frame_rate": {
"num": 30,
"den": 1
},
"sample_rate": 48000
},
"sources": [
{
"id": "coast",
"locator": "asset://coast",
"kind": "image"
},
{
"id": "forest",
"locator": "asset://forest",
"kind": "image"
},
{
"id": "caption",
"kind": "generated",
"generator": {
"type": "text",
"text": "Day two",
"style": {
"font_family": "Hanken Grotesk",
"font_size": 0.08,
"align": "start",
"position": {
"x": 0.05,
"y": 0.92
},
"anchor": {
"x": 0,
"y": 1
}
}
}
}
],
"compositions": [
{
"id": "graded",
"output": "eq",
"nodes": [
{
"id": "clip",
"op": {
"type": "clip"
}
},
{
"id": "eq",
"op": {
"type": "effect",
"input": "clip",
"effect": {
"id": "alpha2.effect.color-controls",
"version": 1,
"params": {
"contrast": {
"mode": "constant",
"value": {
"type": "float",
"value": 1.2
}
},
"saturation": {
"mode": "constant",
"value": {
"type": "float",
"value": 1.3
}
}
}
}
}
}
]
}
],
"timeline": {
"tracks": [
{
"id": "v1",
"name": "Picture",
"kind": "video",
"clips": [
{
"id": "a",
"source_id": "coast",
"timeline_range": {
"start": 0,
"end": 360000
},
"source_range": {
"start": 0,
"end": 360000
}
},
{
"id": "b",
"source_id": "forest",
"timeline_range": {
"start": 240000,
"end": 600000
},
"source_range": {
"start": 0,
"end": 360000
},
"composition": {
"id": "graded"
}
}
],
"transitions": [
{
"from_clip": "a",
"to_clip": "b",
"timeline_range": {
"start": 240000,
"end": 360000
},
"easing": {
"type": "linear"
},
"effect": {
"id": "alpha2.transition.fade",
"version": 1
}
}
]
},
{
"id": "text",
"name": "Text",
"kind": "video",
"clips": [
{
"id": "caption-clip",
"source_id": "caption",
"timeline_range": {
"start": 360000,
"end": 600000
},
"source_range": {
"start": 0,
"end": 240000
}
}
],
"transitions": []
}
]
}
}
터미널 창
alpha2-host export --project graded.json \
--asset coast=coast.jpg --asset forest=forest.jpg \
--font HankenGrotesk.ttf --out out.mp4
터미널 창
[a][b]xfade=transition=fade:duration=1:offset=2

두 클립이 한 트랙에서 2초부터 3초까지 겹치고, 트랙의 transitions에 든 트랜지션이 그 구간에서 둘을 잇습니다. effect.id는 내장 트랜지션 122개 중 하나(alpha2.transition.fade, directional-wipe, circle-open 등)이고, easing이 진행의 모양을 정합니다. offset과 달리 구간이 타임라인에 명시되며, 두 클립은 각자의 시간을 유지합니다.

터미널 창
eq=contrast=1.2:saturation=1.3

graded 컴포지션은 두 번째 클립을 contrast 1.2, saturation 1.3인 alpha2.effect.color-controls에 통과시킵니다. exposure, temperature, tint도 있습니다. 계산식은 엔진 고유의 것이라, 같은 숫자를 넣으면 eq와 비슷한 느낌이 나지만 픽셀까지 같지는 않습니다. FFmpeg의 나머지 색 필터는 levels, lift-gamma-gain, hue-saturation, lut-3d(.cube 파일)가 맡습니다.

터미널 창
drawtext=fontfile=HankenGrotesk.ttf:text='Day two':fontsize=58:x=w*0.05:y=h*0.92-th:enable='gte(t,3)'

텍스트는 text 제너레이터를 쓰는 생성 소스이고, 3초부터 5초까지의 클립이 보여 줍니다. 이것이 enable을 대신합니다. font_size는 그림 짧은 변에 대한 비율입니다(0.08 × 720 ≈ 58픽셀). position은 텍스트의 anchor 점을 놓을 위치입니다. 앵커 (0, 1)은 텍스트의 왼쪽 아래 모서리이므로 x=w*0.05:y=h*0.92-th에 해당합니다. 줄은 텍스트의 줄바꿈 너비인 max_width(기본값은 캔버스 너비의 0.9) 안에서 정렬되므로, align: "start"로 왼쪽에 붙입니다. 폰트는 fontfile처럼 --font로 넘깁니다. 텍스트에 맞춰 크기가 정해지는 상자가 필요하면 레이아웃 제너레이터를 쓰십시오.

터미널 창
[1:v]scale=iw*0.32:-1[pip];[0:v][pip]overlay=W-w-50:H-h-50

위 트랙의 클립이 아래 트랙 위에 그려집니다. visual.scale은 맞춰진 크기에서 배율을 정하고, position은 anchor 점의 위치를 정합니다. 화면 속 화면 레시피에 전체 프로젝트가 있으며, FFmpeg에서는 필터 여러 개가 필요한 둥근 모서리와 그림자까지 들어 있습니다.

scale, pad, crop → 캔버스에 맞추기

섹션 제목: “scale, pad, crop → 캔버스에 맞추기”

모든 소스는 먼저 화면비를 유지한 채 캔버스 안 가운데에 맞춰집니다. scale=...:force_original_aspect_ratio=decrease,pad=...와 같습니다. 남는 부분은 프로젝트의 settings.background 색(기본값 검정)입니다. 화면을 채우려면(force_original_aspect_ratio=increase,crop=...) 클립을 키우고 position으로 옮기십시오. 세로 영상을 참고하십시오.

alpha2.effect.crop은 프레임 크기를 바꾸지 않고 가장자리를 잘라 냅니다. top_left와 bottom_right는 각 변에서 잘라 낼 비율이며, feather로 경계를 부드럽게 합니다. 클립의 masks로는 원하는 모양으로 자를 수 있습니다.

FFmpeg alpha2
concat 한 트랙에 차례로 놓인 클립
fade=in, fade=out 클립의 opacity 키프레임, 또는 트랜지션
setpts, atempo timeline_range보다 길거나 짧은 source_range: 클립이 빠르거나 느리게 재생되고, 소리는 타임 스트레치되거나 리샘플링됩니다
reverse "time_map": { "type": "reverse" }
boxblur, gblur alpha2.effect.gaussian-blur
unsharp alpha2.effect.unsharp-mask, alpha2.effect.sharpen
vignette alpha2.effect.vignette
chromakey, colorkey alpha2.effect.chroma-key
lut3d .cube 이펙트 리소스를 쓰는 alpha2.effect.lut-3d
amix, volume, pan 오디오 트랙, 클립의 audio.gain과 audio.pan
afade 클립의 audio.fade_in과 audio.fade_out
loudnorm export의 --loudness-target <LUFS>(EBU R128)
subtitles 자막 트랙: SRT 파일로 자막 만들기 참고
FFmpeg alpha2-host export
-ss, -to --start-ticks, --end-ticks
-r 30 --frame-rate 30/1
-c:v libx264, -c:v libvpx-vp9 --video-codec h264, --video-codec vp9
-crf, -b:v --video-quality high(단계) 또는 --video-quality 8000000(초당 비트)
-c:a, -b:a --audio-codec aac, --audio-quality
-an --no-audio
-f mp4 --container mp4, 또는 출력 파일 확장자
-y --overwrite

모든 플래그는 CLI 레퍼런스에 있습니다.

릴리스 아카이브에는 파일 하나를 다루는 두 번째 프로그램 alpha2가 있습니다. 편집 앱이 프로젝트 주변에서 늘 하는 ffprobe·ffmpeg 작업을 맡습니다.

작업 FFmpeg alpha2
파일 검사 ffprobe clip.mp4 alpha2 probe clip.mp4
특정 시점의 포스터 프레임 ffmpeg -ss 2 -i clip.mp4 -frames:v 1 poster.png alpha2 thumbnail clip.mp4 poster.png --at 2
대표 프레임 ffmpeg -i clip.mp4 -vf thumbnail -frames:v 1 poster.png alpha2 thumbnail clip.mp4 poster.png
편집용 프록시 ffmpeg -i clip.mp4 -vf scale=iw/2:-2 proxy.mp4 alpha2 transcode clip.mp4 proxy.mp4 --proxy half
오디오를 WAV로 ffmpeg -i clip.mp4 -ar 48000 audio.wav alpha2 export-audio clip.mp4 audio.wav
파형 데이터 ffmpeg ... astats alpha2 waveform clip.mp4(JSON)

--at이 없으면 thumbnail은 영상 전체에 고르게 퍼진 아홉 프레임 중 검거나 희지 않은 가장 선명한 프레임을 고릅니다. 디코딩하는 명령은 --decode-policy tolerant를 받아, 손상된 입력에서 실패하는 대신 건너뜁니다. CLI 레퍼런스를 참고하십시오.