Communitygithub.com

Prateekiiitg56/ffmpeg-pipeline

프로덕션에 적합한 ffmpeg 파이프라인 - 프로빙, 회전 및 VFR 수정, HDR/HLG/Dolby Vision을 SDR로 톤 매핑, Apple Log, 구간별 추출, 무손실 연결, xfade 전환, 오버레이 타이밍, PNG/알파 오버레이, 자막 삽입, 속도 변경, 업스케일링, 인스타그램/틱톡/유튜브/마스터 내보내기 프리셋을 제공합니다. ffmpeg 또는 Python 빌드 스크립트로 편집을 렌더링할 때마다 사용하세요.

ffmpeg-pipeline란 무엇인가요?

이 스킬은 ffmpeg를 사용한 스크립트 기반 비디오 편집을 위한 완전한 파이프라인입니다. 전화기에서 흔히 발생하는 회전 플래그, 가변 프레임 레이트(VFR), HDR(HLG/PQ, Dolby Vision) 및 Apple Log와 같은 문제를 처리하기 위한 정규화 단계를 포함하며, 올바른 색 공간과 톤 매핑을 보장합니다. 빌드 스크립트의 아키텍처(소스 → 세그먼트 추출 → 연결 → 오버레이 → 최종 인코딩)를 제공하고 정확한 트림, 9:16 리필, xfade 전환, 다양한 유형의 오버레이(정적, 시간 제한, 애니메이션, Python 파이프) 및 여러 개의 속도 변경 방법을 다룹니다. 인스타그램, 틱톡, YouTube, 마스터 아카이브 및 미리보기용으로 사전 정의된 인코딩 프리셋이 포함되어 있어 올바른 포맷과 품질 설정을 보장합니다. 이 스킬은 ffmpeg 및 Python 스크립트를 사용하며, OpenAI Codex, Cursor 및 유사한 AI 코딩 어시스턴트와 호환됩니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Prateekiiitg56/video-editing-skills/tree/HEAD/skills/ffmpeg-pipeline

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

ffmpeg 파이프라인

도우미 스크립트는 이 파일과 같은 디렉토리의 scripts/에 있습니다. python <skill_dir>/scripts/<name>.py로 실행하세요.

  • probe.py IN... — 파일당 한 줄 요약 (크기, fps, 회전, HDR, 길이, 오디오).
  • export.py IN OUT --preset instagram|tiktok|shorts|youtube|master|preview — 올바른 설정으로 최종 인코딩.
  • frames.py IN OUTDIR --times 0.5,3,7.2 또는 --every 1 — 체크 프레임 캡처.

1. 먼저 프로빙 및 정규화

전화기 영상의 함정:

  • 회전: iPhone은 가로 픽셀을 저장하고 회전 플래그를 추가합니다. ffmpeg은 디코딩 시 자동 회전합니다(-noautorotate로 비활성화). OpenCV VideoCapture는 회전하지 않을 수 있습니다 — frame.shape를 확인하고 직접 회전하세요.
  • VFR: 전화기는 가변 프레임 레이트를 기록합니다. 추출 시 CFR로 변환: -vf fps=30 (또는 -r 30 출력)하여 프레임 계산이 정확하도록 합니다.
  • HDR: color_transfer=arib-std-b67 (HLG) 또는 smpte2084 (PQ). 그대로 두면 SDR에서 흐릿하게/회색으로 보입니다. 톤 매핑:
# HDR (HLG 또는 PQ) -> SDR Rec.709, CPU zscale 경로
-vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p"

hable = 필름릭; mobius는 채도를 더 유지합니다. zscale이 없으면 libplacebo를 사용하세요 (-vf libplacebo=tonemapping=bt.2390:colorspace=bt709:color_primaries=bt709:color_trc=bt709).

  • Apple Log / 카메라 로그: 먼저 제조사의 Log → Rec.709 LUT를 적용하고 (lut3d=AppleLog_to_Rec709.cube), 그레이딩하세요.
  • 10비트 소스: 많이 그레이딩할 때는 중간 파일을 10비트로 유지하고 (-pix_fmt yuv422p10le ProRes 또는 yuv420p10le x265), 소셜용 최종 내보내기 시에만 8비트 yuv420p로 변환하세요.

2. 빌드 스크립트의 아키텍처

sources/ (절대 수정하지 않음)
edit/
  build.py          # 소스 + 데이터 파일에서 모든 것을 재생성
  edl.json          # [{src, in, out, speed, grade, transition}]
  segments/         # EDL 항목당 하나의 그레이딩되고 정규화된 파일 (무손실에 가깝게)
  overlays/         # PNG / PNG 시퀀스 / ProRes 4444 / WebM 알파
  preview.mp4, final.mp4

규칙:

  1. 구간별 추출 모든 클립별 작업(트림, 속도, 스케일/크롭, 그레이드, fps)을 한 번에 수행 → -crf 10 (x264) 또는 ProRes 422 HQ 중간 파일.
  2. 전환이 필요 없을 때 연결 concat 디먹서와 -c copy 사용 (모든 세그먼트는 코덱, 해상도, fps, pix_fmt, 타임베이스가 동일해야 함).
  3. 오버레이 및 텍스트 연결된 비디오에 대해 한 번의 최종 패스에서 처리한 다음, 전달 사양에 따라 한 번 인코딩합니다.
  4. 오디오는 별도로 구성(음악 + SFX + 대화 → 하나의 WAV)한 다음 최종 패스에서 먹싱합니다.

정확한 트림

# -ss를 -i 앞에 두면 빠르고 프레임 정확함 (ffmpeg >= 2.1, 재인코딩 시)
ffmpeg -ss 12.40 -i IN.mov -t 2.333 -vf "fps=30,scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920" \
  -c:v libx264 -crf 10 -preset medium -pix_fmt yuv420p -an seg_003.mp4

프레임 정확해야 하는 트림에는 -c copy를 절대 사용하지 마세요 (키프레임에 스냅됩니다).

16:9를 9:16으로 채우기

  • 크롭 (커버): scale=-2:1920,crop=1080:1920:(iw-1080)*X:0 (X는 0..1로 피사체 위치 선택, 피사체가 움직이면 추적).
  • 흐린 배경 (컨테인): split[a][b];[a]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,boxblur=40:2[bg];[b]scale=1080:-2[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2

연결

# list.txt:  file 'segments/seg_001.mp4'  (한 줄에 하나)
ffmpeg -f concat -safe 0 -i list.txt -c copy joined.mp4

xfade로 전환

ffmpeg -i a.mp4 -i b.mp4 -filter_complex \
 "[0:v][1:v]xfade=transition=fade:duration=0.5:offset=4.5,format=yuv420p[v]; \
  [0:a][1:a]acrossfade=d=0.5[a]" -map "[v]" -map "[a]" out.mp4

offset = 첫 번째 클립 길이 − 전환 길이. 유형: fade, fadeblack, fadewhite, wipeleft, slideup, smoothleft, circleopen, radial, zoomin, hblur, pixelize, dissolve… 여러 클립에 대해 누적 오프셋 체인 (각 xfade는 길이만큼 총 길이를 줄입니다).

오버레이

# 전체 비디오에 대한 정적 PNG (전체 프레임, 투명) — -loop 불필요
[0:v][1:v]overlay=0:0:format=auto
# 시간 제한
overlay=0:0:enable='between(t,2.0,5.5)'
# 출력에서 T 시간에 시작하는 애니메이션 오버레이 클립
[1:v]setpts=PTS-STARTPTS+T/TB[ov];[0:v][ov]overlay=0:0:eof_action=pass

알파 오버레이: PNG 시퀀스 (-framerate 30 -i ov/%04d.png), ProRes 4444 (-c:v prores_ks -profile:v 4444 -pix_fmt yuva444p10le), 또는 VP9 WebM (-c:v libvpx-vp9 -pix_fmt yuva420p). 긴 비디오의 경우 4K RGBA PNG를 -loop 1로 사용하지 마세요. RAM을 많이 소모합니다. 단일 이미지 입력은 overlay에서 자동으로 반복됩니다.

Python(PIL/OpenCV 합성)에서 ffmpeg로 원시 프레임 파이핑:

p = subprocess.Popen(["ffmpeg","-y","-f","rawvideo","-pix_fmt","rgb24","-s",f"{W}x{H}","-r","30","-i","-",
                      "-c:v","libx264","-crf","12","-pix_fmt","yuv420p","out.mp4"], stdin=subprocess.PIPE)
p.stdin.write(frame.tobytes())   # numpy uint8 HxWx3, 프레임당

같은 방식으로 소스 프레임 읽기 (-f rawvideo -pix_fmt rgb24 -), OpenCV 회전 및 코덱 문제 방지.

속도

  • 일정: setpts=PTS/2 (2배) + atempo=2.0 (atempo 범위 0.5-100; 더 체인).
  • 30fps에서 부드러운 슬로모: minterpolate=fps=60:mi_mode=mci:mc_mode=aobmc:vsbmc=1, 그런 다음 setpts=2*PTS. 가장자리/손에서 왜곡 확인.
  • 가변 속도 램프: 시간 맵에서 프레임별로 렌더링 (beat-sync 참조), 여러 setpts 표현식 쌓지 말 것.

자막 (마지막)

-vf "subtitles=captions.ass:fontsdir=fonts"     # ASS는 완전한 스타일 제어 제공

3. 내보내기 프리셋

대상비디오오디오비고
인스타그램 릴스 / 틱톡 / 쇼츠1080x1920 (또는 2160x3840) H.264 High, 30 fps, CRF 16-18, -maxrate 25M -bufsize 50M, yuv420pAAC 48 kHz 256-320k-movflags +faststart; 플랫폼이 재인코딩하므로 고품질 파일 제공
YouTube 16:93840x2160 또는 1920x1080, H.264 CRF 16 또는 HEVC CRF 18, 소스 fpsAAC 48 kHz 320k1080p 콘텐츠라도 4K로 업로드하여 더 나은 VP9/AV1 인코딩 획득
마스터ProRes 422 HQ 또는 x264 CRF 10 / x265 CRF 14 -tag:v hvc1PCM 24-bit 48 kHz보관용
미리보기720p, CRF 28, -preset veryfastAAC 128k빠른 반복

소셜용으로 항상 -pix_fmt yuv420p 추가 (10비트 또는 4:2:2는 업로드 후 실패하거나 잘못 보일 수 있음) 및 SDR을 올바르게 태그하기 위해 -color_primaries bt709 -color_trc bt709 -colorspace bt709 추가.

4. 확인

ffprobe -v error -show_entries stream=codec_name,width,height,r_frame_rate,pix_fmt -show_entries format=duration -of compact out.mp4
ffmpeg -i out.mp4 -af ebur128=peak=true -f null - 2>&1 | tail -12
ffmpeg -i out.mp4 -vf "select='gt(scene,0.3)',showinfo" -f null - 2>&1 | grep pts_time   # 실제 컷 위치

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

관련 스킬