Communitygithub.com

dmtrKovalenko/fframes

코드로 비디오를 생성, 애니메이션, 검토 및 렌더링합니다 (Rust, SVG 장면, ffmpeg 인코딩, Skia GPU 렌더링). 사용자가 비디오, 애니메이션, 모션 그래픽, 설명 영상, 홍보 영상, 소셜 클립, 타이틀 카드, 팟캐스트 비주얼, 가사/자막 영상 또는 프로그래밍 방식으로 렌더링된 .mp4/.webm을 원하거나, fframes 비디오를 변경, 수정, 속도 조정 또는 확인하도록 요청할 때 사용하십시오. fframes 설치, 프로젝트 생성, 멋진 모션 디자인, 3D 샷(`fframes::three_d`, three.js 스타일 장면), 사운드(음악, 음성, SFX, 음량), 실시간 미리보기 창에서 시청, 프레임 및 접촉 시트 PNG, 자동 문제 감지, 음량 수치, 빠른 드래프트 및 범위 렌더링과 같은 결과를 시청하지 않고도 확인하는 방법을 다룹니다.

fframes란 무엇인가요?

fframes는 Rust 라이브러리로, 개발자가 코드를 사용하여 비디오를 만들고 애니메이션화하며 렌더링할 수 있게 해줍니다. 이 기술은 각 프레임에 대해 SVG 트리를 반환하는 `render_frame` 메서드가 있는 Rust 구조체 기반의 비디오로, `svgr!` 매크로를 사용하여 SVG 마크업에 Rust 표현식을 직접 임베딩합니다. 장면은 타임라인을 분할하고, `timeline!` 및 스프링 애니메이션 시스템으로 값을 애니메이션화하며, 오디오 맵으로 사운드를 배치하고, ffmpeg로 최종 결과를 인코딩합니다. 주요 사용 사례로는 마케팅 비디오, 소셜 미디어 클립, 타이틀 카드, 설명 영상 및 자막 비디오를 프로그래밍 방식으로 제작하는 것이 포함됩니다. 이 도구는 Claude Code, Cursor, Codex와 같은 AI 에이전트 플랫폼을 통해 접근하도록 설계되었으며, 명령줄 인터페이스와 실시간 미리보기 창을 제공합니다. AI 에이전트는 템플릿 기반 접근 방식보다는 독창적인 모션 디자인과 정밀한 동기화를 강조하는 신중한 계획 방법론을 따라야 합니다. GPU 가속 Skia 백엔드는 빠른 렌더링과 실시간 미리보기를 제공하며, `inspect`, `strip`, `frame`, `onion`과 같은 다양한 명령어로 문제 감지 및 세부 검토를 지원합니다. 이 기술은 사용자가 비디오 제작 요청을 할 때마다(예: "인트로 비디오 만들어 줘" 또는 "이 설명 영상 속도 높여 줘") 활성화됩니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/dmtrKovalenko/fframes/tree/HEAD/skills/fframes-video

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

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

문서

fframes로 비디오 만들기

fframes는 코드로 비디오를 렌더링하는 Rust 라이브러리입니다. 비디오는 render_frame(frame) -> Svgr 메서드를 가진 Rust 구조체입니다. 모든 프레임에 대해 SVG 트리를 반환하며, svgr! 매크로(SVG 마크업에 {rust 표현식} 포함)로 빌드됩니다. 장면(Scene)은 타임라인을 분할하고, timeline!과 스프링(Spring)이 값을 애니메이션화하며, 오디오 맵이 사운드를 배치하고, ffmpeg가 결과를 인코딩합니다.

각 프로젝트는 명령줄(fframes::cli에서 제공)을 얻습니다. 모든 작업에 이것을 사용하십시오: 비디오 렌더링, 실시간 미리보기 창 열기, 프레임, 접촉 시트 및 음량 수치를 읽을 수 있는 파일로 확인. 디자인하기 전에는 references/design.md를, 코드를 작성하는 동안에는 references/api.md를, 사운드는 references/audio.md, 3D 샷(fframes::three_d)은 references/3d.md를 읽으십시오.

제공된 비디오와 일치시킬 때는 먼저 references/design.md의 참조 분석 지침을 따르십시오. 해당 비디오의 컷, 페이싱 및 모션이 아래의 기본 설계보다 우선합니다. 빠른 편집과 의도적인 검은 프레임은 요청된 결과의 일부일 수 있습니다.

다른 무엇보다 먼저 지켜야 할 두 가지 규칙

코드를 작성하기 전에 계획하십시오

템플릿을 열고 바로 애니메이션을 시작하지 마십시오. 먼저:

  1. 브리프를 확정하십시오: 누가 어디서 볼 것인지(플랫폼이 형식과 길이를 결정), 시청자가 기억해야 할 한 가지, 톤, 존재하는 에셋(로고, 제품 샷, 푸티지, 음악, 음성 해설). 누락되었거나 중요한 것이 있으면 사용자에게 물어보십시오. 제품 사실, 숫자 또는 인용구를 절대 만들어내지 마십시오.
  2. 비디오가 음악이나 음성에 맞춰 컷될 때는 먼저 사운드를 선택하십시오. 템포, 비트 및 프레이즈가 다른 모든 것의 타이밍을 결정합니다.
  3. 먼저 모션 디자인을 계획하고, 모션 디자인을 사운드 피크에 동기화하여 독특한 흐름을 만드십시오: 요소가 어디에서 나타날지, 어떻게 변형될지. 모든 장면에 대해 독특한 모션 디자인을 만들어 고급스럽고 세련되게 보이도록 노력하십시오. 비디오가 슬라이드 쇼처럼 보이면 안 됩니다.
  4. 최종 비디오를 시청하는 사람의 느낌에 대해 추론하고, 그에 따라 모든 디자인 요소(흐름, 템포, 비트, 모션, 색상)를 조정하십시오.

슬롭(Slop) 금지

슬롭은 기본 선택으로 만들어진 비디오입니다. 텍스트만 변경되고 다른 모든 것이 동일한 제품에 대해 만들어질 수 있으며, 시청자는 1초 안에 그것을 알아차립니다. 사용자가 요청하지 않는 한, 다음을 제공하지 마십시오:

  • 템플릿 잔재: 시작 레이아웃, 색상, 글꼴 또는 장식, 플레이스홀더 텍스트, 가짜 로고, 조작된 숫자.
  • 비트 스팸: 모든 비트마다 전체 프레임이 줌, 흔들림 또는 깜박임. 작은 것(획, 단어, 불꽃)을 비트에 동기화하고, 몇 번의 컷에서만 전체 프레임을 변경하십시오.
  • 모든 것에 하나의 모션: 모든 요소가 동일한 이징과 지속 시간으로 40px 위로 페이드 인.
  • 정적 장면: 하나의 요소가 나타나고, 멈추고, 페이드 아웃되는 동안 다른 것은 움직이지 않음.
  • 일반적인 카피: "소개", "발휘", "완벽", "차원이 다른", 세 단어 태그라인("빠름. 간단. 강력."). 사람이 말하는 방식으로 화면 텍스트를 작성하십시오.
  • 일반적인 텍스트: 텍스트 양은 제한적이고 정확해야 합니다.

대신, 모든 요소에 주제와 연결된 이유를 부여하고 이유가 없는 것은 제거하십시오. 단어보다는 디테일과 모션에 노력을 쏟으십시오: 2차 모션, 엇갈린 등장, 그려진 획, 서로 반응하는 객체, 컷을 넘어 이어지는 요소. 사용자에게 아무것도 보여주기 전에, 스트립을 보고 텍스트만 변경되었을 때 다른 제품에서도 같은 비디오가 작동할지 질문하십시오. 그렇다면 색상이 아니라 아이디어를 바꾸십시오.

1. 설치

https://rustup.rs에서 Rust를 설치한 다음, ffmpeg가 빌드될 시스템 라이브러리를 설치하십시오:

# macOS
brew install pkg-config ffmpeg x264 x265 opus nasm ninja
# Debian / Ubuntu
sudo apt-get install -y yasm nasm ffmpeg libx264-dev libx265-dev libopus-dev libclang-dev clang ninja-build libvpx-dev libasound2-dev
# Arch
sudo pacman -S ninja yasm nasm ffmpeg x264 x265 opus clang

Windows는 사전 빌드된 FFmpeg 9 공유 빌드를 대신 링크합니다(FFMPEG_DIR을 BtbN/FFmpeg-Builds의 압축 해제된 ffmpeg-n9.0-latest-win64-gpl-shared 빌드로 설정하고, bin을 PATH에 추가, winget install LLVM.LLVM으로 LLVM 설치, LIBCLANG_PATH 설정). 자세한 내용은 fframes README에 있습니다.

2. 프로젝트 생성

curl -fsSL https://raw.githubusercontent.com/dmtrKovalenko/fframes/main/scripts/new-video.sh | bash -s -- my-video --yes
# 또는 생성기를 한 번 설치하고 직접 사용:
cargo install --locked cargo-fframes
cargo fframes new my-video --format landscape --fps 30 --yes

옵션: --template single-scene|multi-scene, --format landscape|portrait|square|uhd, --fps, --title, --backend, --dir. 프로젝트는 설치된 cargo-fframes와 일치하는 fframes 릴리스에 의존합니다. --git은 대신 저장소의 main 브랜치를 사용합니다. 항상 --yes를 전달하여 입력을 기다리지 않도록 하십시오.

템플릿:

  • single-scene (기본값): 하나의 장면. 모든 형식에 적응합니다. 단일 샷 클립, 타이틀 카드 및 세로 비디오는 여기서 시작하십시오.
  • multi-scene: 두 장면. 여러 장면이 있는 모든 것은 여기서 시작하십시오. landscape 및 uhd만 허용합니다.

템플릿 내용은 API를 보여주는 플레이스홀더 코드입니다. 사용자가 요청한 비디오를 위해 만들어진 디자인으로 레이아웃, 색상, 글꼴 및 장식을 교체하십시오.

Skia GPU 백엔드(기본값)를 사용하십시오. cargo fframes new는 macOS에서 Metal, Linux/Windows에서 Vulkan을 선택합니다. CPU 백엔드보다 약 10배 빠르게 렌더링하고 실시간 preview 창을 제공합니다. macOS와 Linux에서 첫 번째 빌드는 사전 빌드된 Skia와 ffmpeg를 다운로드하고 Rust 종속성만 컴파일합니다(약 1분; 다른 대상 또는 metal과 vulkan을 함께 사용하면 Skia를 소스에서 컴파일하여 약 20분). 즉시 시작하고 실행되는 동안 비디오를 작성하십시오:

cd my-video && cargo build --release        # 백그라운드에서 실행, 첫 번째 빌드가 느림

--backend cpu는 Skia가 필요하지 않지만 미리보기 창이 없습니다. GPU가 없을 때만 선택하십시오.

프로젝트는 생성된 대로 렌더링됩니다:

my-video/
  src/lib.rs        # 비디오 (템플릿에서)
  src/main.rs       # 명령줄
  media/            # 바이너리로 컴파일된 글꼴, 이미지 및 오디오 (시작 글꼴 하나)
  README.md         # 아래 명령어들

모든 아래 명령어는 cargo run --release -- <command>입니다. 짧은 셸 함수를 정의하십시오 (zsh(macOS 셸)에서는 변수(예: R="cargo run --release --")가 단어로 분할되지 않으므로):

R() { cargo run --release -- "$@"; }

3. 작업 루프

이 스킬을 사용할 때는 테스트를 전혀 작성하지 마십시오. 단위, 통합, 스냅샷 또는 시각적 회귀 테스트, 테스트 모듈 또는 테스트 하니스를 만들지 마십시오. inspect, 렌더링된 프레임, 접촉 시트, 오디오 검사 및 네이티브 미리보기로 비디오를 검증하십시오.

미리보기, 렌더링하지 마십시오. 비디오가 GPU 렌더 백엔드를 사용하고 이 머신에서 GPU를 사용할 수 있는 경우, 변경할 때마다 비디오를 다시 렌더링하는 대신 네이티브 미리보기를 실행하십시오(또는 사용자에게 명령어를 보여주십시오). 변경 사항을 검토할 준비가 되면:

  1. 실제 프로젝트 경로와 패키지 이름을 사용하여 복사 가능한 셸 코드 블록으로 완전한 명령어를 표시하십시오. 사용자가 $R 헬퍼를 정의하도록 요구하지 마십시오. 예: cd /absolute/path/to/fframes && cargo run --release -p my-video -- preview 0s.
  2. 해당 미리보기를 사용자에게 실행할 것을 명시적으로 제안하십시오. 사용자가 이미 미리보기 열기 또는 새로고침을 승인한 경우, 명령어를 표시하고 해당 승인 내에서 계속하십시오.

요청된 변경 후에는 변경된 부분 직전 또는 직후의 특정 초에 명령어의 시작 시간을 설정하여 입장 또는 전환을 볼 수 있는 충분한 리드인 시간을 확보하십시오. 예를 들어, preview 8.5s는 사용자가 처음부터 다시 재생하지 않고 약 9초 주변의 변경 사항을 검토할 수 있게 합니다. 어떤 섹션을 볼 수 있는지 명시하십시오. 최종 내보내기가 요청되면 전체 비디오를 렌더링하십시오. 해당 요청이 이미 명시적인 경우 다른 확인을 요구하지 마십시오.

모든 변경 후:

  1. $R timeline은 장면을 프레임 및 초 범위와 함께 나열하고 모든 오디오 트랙을 표시합니다. 여기서 픽셀을 보기 전에 구조와 페이싱을 확인하십시오.
  2. $R inspect는 0.25초마다 한 프레임과 각 장면의 첫 번째 및 마지막 프레임을 확인합니다. 누락된 이미지, 글꼴 또는 글리프, 캔버스 가장자리로 잘린 텍스트, 잘못된 SVG(크기가 0인 직사각형, 잘못된 반경), 깨진 변환 및 패닉을 각각 시간과 장면과 함께 보고합니다. 오류 시 코드 2로 종료합니다. 보고된 모든 것을 수정하십시오. 장면의 첫 번째 프레임에만 나타나는 경고는 일반적으로 입구입니다. 스트립으로 확인하십시오.
  3. $R strip <scene or range> -n 12는 접촉 시트(strip.png)를 작성합니다: 하나의 레이블이 지정된 이미지에 균일하게 간격을 둔 프레임. 이미지 도구로 여십시오. 레이아웃, 리듬 및 모션을 판단하는 가장 빠른 방법입니다. $R strip 2s,5s,9s는 선택한 시간을 나란히 배치합니다.
  4. $R frame Intro@end,Outro@50%는 전체 크기 PNG를 frames/에 작성하여 세부 검사(타이포그래피, 정렬, 대비)를 수행하고 해당 프레임에서 발견된 문제를 출력합니다. 작은 세부 사항(요소 간 접촉, 가장자리, 작은 모양)은 축소된 프레임이 아닌 선명하게 확대된 크롭에서 판단하십시오: $R frame 3s --crop 1100,520,240,120 (비디오 픽셀, 약 960px 너비로 확대). --ids는 id가 있는 모든 요소의 윤곽과 이름을 표시하여 어떤 모양이 무엇인지 찾습니다.
  5. $R onion "[email protected]@1s" -n 6은 프레임을 하나의 이미지(onion.png)로 혼합하여 움직임의 경로와 간격(이징, 오버슈트, 엇갈림)을 보여줍니다.
  6. $R preview Intro은 사용자가 시청할 수 있는 사운드가 포함된 실시간 창을 엽니다(space 재생/일시정지, h/l 1초 탐색, j/k 1프레임 이동, q 종료). 닫힐 때까지 차단되므로 사용자를 위해 실행할 때 백그라운드에서 시작하십시오. 위에서 설명한 대로 명령어를 표시하고 실행을 제안하십시오. 편집 후에는 변경 사항 근처의 특정 초를 사용하십시오.

인코딩된 샘플이 필요할 때 $R render Intro --draft는 하나의 장면을 절반 해상도로 인코딩합니다. $R render는 요청된 최종 내보내기에 전체 비디오를 기록합니다.

완성된 비디오를 보여주기 전에 $R inspect --pops를 실행하십시오: 모든 프레임을 작게 렌더링하고 팝(여전히 정지된 프레임 사이에서 한 프레임에서 변경되는 그림의 일부, 예: 다른 요소 앞으로 이동하는 대신 나타나거나 사라지거나 점프하는 요소)에 대해 경고합니다. 각 경고는 해당 frame ... --crop ... 명령어를 제공합니다. 동일한 영역의 반복(카운터, 깜박이는 불빛)은 하나의 경고로 그룹화됩니다.

규칙:

  • 아무것도 괜찮다고 말하기 전에 PNG를 먼저 보십시오.
  • 여러 frame 호출보다는 strip을 선호하십시오. 구성만 필요한 경우 --scale 0.5를 추가하십시오.
  • 출력을 구문 분석할 때 --json을 추가하십시오: 결과는 stdout으로, 진행률은 stderr로 이동합니다.
  • --release를 유지하십시오: 디버그 빌드는 훨씬 느리게 렌더링합니다.

시간 지정

120 (프레임), 3.2s, 500ms, 1:05.5, 50%, start, end; 구조체 이름으로 장면, Intro (IntroScene도 일치, 대소문자 구분 안 함), #3 (장면 인덱스), Intro[1] (해당 유형의 두 번째 장면); 장면 내부 [email protected], Intro@12, Intro@50%, Intro@end. 범위: a..b (끝 제외), a.., ..b, all, 또는 전체 장면의 장면 이름. 여러 시간을 쉼표로 구분하십시오.

모든 명령어

명령어용도
timeline장면, 지속 시간, 오디오 트랙 및 믹스 설정 보기
inspect [RANGE] [--every 0.1s | --all-frames] [--fail-on warning] [--pops]픽셀을 렌더링하지 않고 문제 찾기; --pops는 안팎으로 팝되는 요소도 찾음
strip [RANGE | TIMES] -n N [--columns 4] [--width 480] [--crop x,y,w,h]하나의 이미지에서 흐름과 모션 검토
frame TIMES [-o dir] [--svg] [--crop x,y,w,h] [--zoom N] [--ids]선택한 프레임의 전체 크기 PNG(및 레이아웃된 SVG), 선명한 크롭, 레이블이 지정된 요소
onion RANGE -n N움직임의 궤적과 이징 보기
svg TIME프레임의 최종 SVG를 텍스트로 읽기(위치, 텍스트, 색상)
preview [TIME] [--paused] [--mute]사용자를 위한 사운드가 포함된 실시간 창
render [RANGE] [-o out.mp4] [--draft]비디오 또는 일부 인코딩(오디오가 일치하도록 잘림)
audio analyze [RANGE] [--waveform w.png]음량(LUFS), 최고 피크, 클리핑, 무음, 장면별
audio at TIMES특정 순간에 재생되는 사운드, 파일 내 위치 및 음량
audio render [RANGE] -o a.wavWAV 파일로 믹스

브라우저 편집기

fframes는 타임라인과 스크러빙이 있는 웹 편집기도 제공하며, 사용자가 대화식으로 비디오를 조정하려는 경우 유용합니다. WebAssembly로 컴파일된 비디오를 실행하며 Node.js와 wasm-pack이 필요합니다. 설정은 fframes 저장소(https://github.com/dmtrKovalenko/fframes/tree/main/examples/hello-world)의 hello-world 예제에 있는 editor/ 폴더입니다. 사용자가 GUI 편집기를 요청할 때 언급하십시오. 시청에는 preview를, 자신의 검토에는 CLI를 사용하십시오.

4. 비디오 작성

impl Video for MyVideo<'_> {
    const FPS: usize = 30; const WIDTH: usize = 1920; const HEIGHT: usize = 1080;
    fn duration(&self) -> Duration<'_> { Duration::Auto }            // 장면의 합
    fn audio(&self) -> AudioMap<'_> { AudioMap::none() }              // references/audio.md 참조
    fn define_scenes(&self) -> Scenes<'_> { Scenes::from(vec![&self.intro as &dyn Scene, &self.main]) }
    fn render_frame<'a>(&'a self, frame: Frame, ctx: &FFramesContext<'a, '_>) -> Svgr<'a> {
        fframes::svgr!(<svg xmlns="http://www.w3.org/2000/svg" width={Self::WIDTH} height={Self::HEIGHT}>
            <rect width={Self::WIDTH} height={Self::HEIGHT} fill={BACKGROUND} />
            {ctx.render_scenes(&frame)}
        </svg>)
    }
}
  • 아이디어당 하나의 장면, 각각 2-6초. 장면 내에서 frame.seconds()는 장면 시작부터 계산됩니다.
  • 고정 값이 있는 모션의 경우 svgr! 속성에서 직접 frame.animate(fframes::timeline!(...))을 기본값으로 사용하십시오. svgr!는 이러한 애니메이션을 캐시된 정적 변수로 끌어올립니다. 타임라인에 이징을 인라인으로 정의하십시오. 여기에는 Easing::Spring { mass: 1.0, stiffness: 180.0, damping: 20.0 }이 포함됩니다. 명명된 이징 상수는 선택 사항입니다. 스프링의 끝 시간을 생략하여 ...

(이 문서는 fframes를 사용한 비디오 생성, 애니메이션 및 렌더링의 기본 개념과 명령어를 설명합니다. 자세한 내용은 fframes 저장소 및 첨부된 참조 문서를 참조하십시오.)

관련 스킬