Communitygithub.com

starrandy123/reanimate-video

비디오의 애니메이션을 프레임 단위로 코드로 복사하여 재현합니다. 게임 영상, 모션 그래픽, 화면 녹화, GIF 등 모든 비디오를 지원하며, 복사 과정을 클립으로 보여줍니다.

reanimate-video란 무엇인가요?

이 스킬은 `reanimate` 라이브러리 (github.com/NiazMorshed2007/reanimate) 를 기반으로 비디오에서 애니메이션을 정밀하게 코드로 복제하는 도구입니다. 사용자는 게임 플레이 영상, 스톡 모션 그래픽, 화면 녹화, GIF 등 모든 비디오를 입력으로 사용할 수 있습니다. `reanimate` 자체는 라이브 페이지를 촬영하고 코드로 재현하는 방식이지만, 비디오를 참조로 사용할 때 여러 가지 함정(트랩)에 부딪힙니다. 본 스킬은 이러한 함정들을 해결하고(예: 10비트 비디오 프레임을 8비트로 변환, ES 모듈 로딩 문제 해결, 비교 성능 최적화), 비디오 픽셀에서 직접 모션을 측정하는 `measure/` 도구 모음을 제공합니다. 사용자는 `rv ref` 로 기준 프레임을 추출하고, `rv measure` 로 각 요소의 움직임을 측정한 후, `animation.js` 에서 순수 함수로 애니메이션을 재구성합니다. 여러 라운드에 걸쳐 `rv round` 명령어로 원본과 복제본을 비교하며 정확성을 높이고, 최종적으로 `rv film` 으로 전체 과정을 클립으로 제작합니다. Cursor 및 Claude Code와 같은 AI 에이전트 플랫폼에서 사용할 수 있습니다.

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

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

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

문서

reanimate-video은(는) 무엇을 하나요?

reanimate는 라이브 페이지를 촬영하고, 코드로 재구성한 후, 촬영된 복제본을 원본과 비교하여 수치가 일치할 때까지 반복합니다. 비디오 참조를 위한 자체 경로가 있지만, 첫 실제 실행(2026년 11월 6일, 무료 스톡 카운트다운)에서 각각 조용하거나 느린 일곱 가지 함정에 부딪혔습니다. 이 키트는 이러한 함정을 제거하고 비디오에 필요한 측정 기능을 추가합니다. 비디오에는 검사할 페이지가 없기 때문입니다.

reanimate 필요: npx skills add NiazMorshed2007/reanimate -g, 그 다음 bash <reanimate>/scripts/setup.sh. 이후 rv setup 한 번 실행(측정 도구의 numpy와 opencv를 키트 자체 Python에 설치: 대부분의 Mac이 가진 python3는 전역 pip 설치를 거부합니다). rv doctor로 확인. (rv는 이 스킬의 rv 파일입니다.)

함정과 키트가 하는 일

함정 (배포 상태의 reanimate, 비디오에서)키트
110비트 비디오(ProRes, 대부분의 스톡 영상)가 16비트 PNG가 되어 프레임당 10MBrv ref는 8비트 프레임을 씁니다
2시트가 모든 프레임을 한 페이지에 인라인으로 포함하고 1080p 프레임에서 타임아웃시트는 480px 복사본에서 가져옴
3file://로 열린 복사본이 ES 모듈을 로드할 수 없음: reanimate가 빈 페이지를 말없이 기록rv serve + rv round는 file://을 거부하고, 모든 녹화를 확인: BLANK 또는 FROZEN은 라운드를 중단
4복사본의 첫 프레임이 첫 애니메이션 프레임 전에 기록됨템플릿이 로드 시 그리기를 수행
51080p에서 300프레임 비교는 라운드당 몇 분 소요라운드는 절반 크기로 비교, 매 라운드 동일한 방식, 선명함과 4px 블러
6비디오에는 읽을 요소 트랙이나 키프레임이 없음measure/: 중심, 플로트, 회전, 호, 페이드, 크기, 세그먼트, 서체, 픽셀에서 추출
7가상 클록이 부동 소수점으로 틱을 합산하여 프레임의 마지막 틱을 건너뛸 수 있음: 해당 프레임이 페이지를 한 틱 일찍 표시(기본 60Hz에서 17ms)템플릿의 복사본은 정확히 t = k / fps에서 draw를 호출하여 기록됨; 다른 페이지는 240Hz 틱
8(키트 자체 도구) numpy와 opencv를 대부분의 Mac이 가진 python3에 pip 설치할 수 없음(Homebrew의 PEP 668)rv setup이 키트 자체 Python(.venv)을 생성; rv measure <tool>은 각 도구를 이 Python으로 실행

tests/run.sh는 배포 상태의 reanimate에서 모든 함정을 재현(RED)한 후 키트 방식으로 실행(GREEN); tests/e2e.sh는 작은 사례(참조 자체인 복사본은 0% 읽음; 의도적으로 잘못된 색상은 더 나쁨)에서 전체 경로를 실행합니다. 키트 변경 후 두 가지를 모두 실행하세요.

시작 전: 이 비디오를 복사해도 되나요?

사용자가 복사해도 되는 비디오의 외형(LOOK) 만 복사하세요: 자신의 비디오, 또는 변경을 허용하는 무료 라이선스(Videezy 표준 라이선스: "Videezy.com" 크레딧과 함께 개인 및 상업용 무료; Mixkit 무료 라이선스; Pexels 및 Pixabay 라이선스). 라이선스, 출처 링크, 날짜를 <work>/LICENSE.md에 기록하고, 비디오가 표시되는 곳 어디든(<work>/film.json "credit") 화면에 크레딧을 표시하세요. 게임 영상은 모션(MOTION) 만 복사됩니다(reanimate의 기본값): 외형(단어, 글꼴, 색상, 아트)은 사용자 자신의 것입니다.

단계

  1. rv doctor
  2. rv ref <video> <work> (일부분은 --start/--end, 한 요소는 --crop x,y,w,h 추가). <work>/ref/sheets의 모든 시트와 <work>/ref/sheets_full_rate의 전체 속도 시트를 읽으세요. 무엇이 움직이고 언제 움직이는지 측정 전에 기록하세요.
  3. 각 움직이는 요소를 해당 종류의 모션에 맞는 도구로 측정하세요(measure/README.md; 각각 rv measure <tool> ...로 실행), <work>/ref/frames에서. 각 도구를 요소에 대해 신뢰하기 전에 증명하세요(--sheet 또는 일치해야 하는 두 번째 프레임 사용).
  4. <work>/spec.md: 요소별, 속성별로 한 행: 시작, 지속 시간, 시작값 -> 끝값, 이징 또는 측정된 테이블, 숫자가 나온 파일. "?"가 있는 행은 완료되지 않음.
  5. 빌드: template/을 프로젝트로 복사하세요. animation.js는 draw(ctx, t) (시간의 순수 함수)와 DURATION을 내보냅니다; 모든 측정된 숫자를 숫자가 나온 파일과 함께 모듈에 넣으세요. 캔버스는 참조의 크기입니다(<work>/run.json).
  6. rv serve <copy dir> 그 다음 rv round 1 <work> --url http://127.0.0.1:8765/index.html. <work>/compare-1/report.md와 해당 시트(compare-1/sheets)를 읽으세요: 숫자는 얼마나 차이가 나는지, 시트는 무엇이 차이인지 알려줍니다. 가장 큰 차이만 수정한 후 rv round 2 ...를 실행하세요. 5라운드에서 중단; 여전히 실패하는 것은 숫자와 이유와 함께 보고됩니다.
  7. rv rounds <work> (테이블) 및 rv film <work> (프로세스 클립, 1080x1920: 비디오, 프레임, 각 라운드의 차이점(빨간색)과 숫자, 숫자가 줄어드는 모습, 최종 동기화).
  8. 보고: 무엇이 어떤 정밀도로 복사되었는지, 파일, 라운드 테이블, 일치하지 않은 부분과 그 이유.

비디오에서 복사되는 것과 그렇지 않은 것

측정으로 잘 복사됨: 도형, 텍스트, 회전하는 링과 호, 켜지는 틱과 세그먼트, 페이드와 플래시, 성장과 슬라이드, 모든 것의 순서와 타이밍. measure/로 측정하고 도형으로 재구성하세요.

측정으로 복사되지 않음: 3D 렌더링 장면, 영상, 무작위로 배치된 파티클, 조각이 번쩍이고 변하는 배경. measure/spin.py가 AGREEMENT로 이를 알려줍니다(약 0.3 미만에서는 밴드가 회전 이상을 수행). 2026년 11월 6일 카운트다운의 터널은 0.16-0.6을 읽었습니다: 복사본의 세 라운드는 번짐을 남겼고(76% -> 48% 픽셀 차이) HUD는 일치했습니다. 그런 경우: 앞쪽 요소를 복사하고, 배경은 사용자 자신의 장면(게임, 페이지)으로 제공하며, 요소가 있는 곳만 비교하거나 배경이 단색인 참조를 선택하세요. 이러한 복사본을 픽셀 완벽이라고 절대 부르지 마세요.

통과 기준 (reanimate 자체 기준, 비디오용으로 해석)

  • 타이밍: 모든 이벤트(요소의 10/50/90% 상승 및 하강, measure/curve.py)가 참조의 0.08초 이내.
  • 이징: 복사본의 측정된 곡선이 참조의 이동 거리(평균 절대 차이)의 5% 이내.
  • 픽셀: 평균 불일치가 픽셀 충실 복사본의 경우 최대 2% (사용자가 외형을 복사해도 되는 참조에만, 그리고 배경이 복사된 부분의 일부인 경우에만); 선명한 숫자와 블러 처리된 숫자를 함께 보고.
  • 모든 라운드의 녹화가 가드 통과 (빈 프레임 또는 프레임 고정 없음).

배운 함정

  • 전체 디자인에 대한 하나의 부동 소수점은 가설입니다: 무엇이든 안정화(stabilize.py)하기 전에 원본 프레임에서 각 링의 중심을 맞추세요(polar.py fit). 2026년 11월 6일(Videezy 40314) 첫 번째 피팅은 가장 밝은 링(흰색 링, 8.5px 표류)에 고정되었고, 319 위치의 링은 0.1px 움직였습니다. 세 라운드는 전체 HUD를 부동시키고 잘못된 레이어로 안정화된 프레임에서 측정했습니다. 라운드 4에서 흰색 링만 부동시키고 고정된 중심 주변에서 모든 것을 다시 측정했을 때 12.6% -> 9.3%로 개선되었습니다.

  • 라운드를 소비하기 전에 몇 프레임에서 변경을 시도하세요: rv still <work> --url ... --frames 0,60,150을 실행하고 compare.ts로 해당 프레임을 마지막 라운드 코드와 비교하세요. 11월 6일 세 가지 후보 변경 중 두 가지가 도움이 되었고(10.0 -> 9.5 -> 8.9%) 하나는 더 악화시켰습니다(13.3%): 이는 라운드가 되지 않았습니다.

  • measure/radial_diff.py는 어디서 라운드 디자인이 잘못되었는지 반지름별로 보여줍니다; 정적 부분만 읽습니다 - 부동 링은 중간값에서 번짐이 발생하므로, compare.ts와 불일치할 때는 compare.ts를 기준으로 판단하세요.

  • 정적 링은 모든 각도에서 밝습니다: 각도에 대한 30번째 백분위수는 정적 링을 유지하고 움직이는 부분을 제거합니다 - 링의 실제 반지름과 너비를 읽는 방법입니다.

  • rv film은 주제에 맞게 자릅니다(film.json "crop"): 쇼케이스는 주제를 크게 보여줍니다.

  • "가장 선명한 링"에서 찾은 중심은 가운데 큰 흰색 도형이 있을 때 흔들립니다: 여러 프레임에서 작고 밝은 랜드마크를 사용하고, 프레임들이 일치할 때만 신뢰하세요(measure/polar.py landmark).

  • 글로우는 모든 가장자리를 두껍게 만듭니다: 서체는 눈이 아닌 측정(measure/fontmatch.py)으로 선택하세요.

  • 측정된 줌이나 회전은 두 번째 뷰가 동의할 때까지 가설입니다: 11월 6일 로그-극 좌표 상관관계가 존재하지 않는 3%/s 줌을 보고했고, 복사본은 한 라운드 동안 터널을 그만큼 줄였습니다.

  • 면적은 크기의 제곱으로 증가합니다: 숫자의 크기는 그 앞 프레임 위의 흰색 면적의 제곱근, 또는 해당 박스입니다.

  • 무료 스톡 영상은 종종 4K ProRes, 클립당 1-2GB입니다: 1920 너비로 읽고(rv ref가 수행), 기록용으로 원본을 보관하며, 디스크 공간에 주의하세요.

관련 스킬