Communitygithub.com

ericrisco/rsc-harness

9:16 원본 영상을 포스트 가능한 세로 숏츠(short)로 자르기 — 무음 제거, 빠른 점프 컷, 자막을 단어 단위로 화면에 새겨 넣고, 컷과 줌을 비트에 맞추며, 플랫폼 UI를 고려한 안전 영역 배치와 함께 플랫폼별 MP4로 내보냅니다.

rsc-harness란 무엇인가요?

이 스킬은 기술 편집자(edit-bay technician) 역할을 수행하며, 9:16 세로 숏츠 편집 파이프라인을 체계적으로 구현합니다. 핵심은 재현 가능한 ffmpeg + WhisperX 워크플로우로, 정확한 단어 타임스탬프를 위한 16kHz 모노 오디오 추출, WhisperX의 wav2vec2 강제 정렬을 통한 단어 수준 자막 생성, 그리고 silenceremove가 아닌 silencedetect와 select+aselect 필터를 사용한 음성/영상 동시 무음 제거 과정을 포함합니다. 비트 그리드는 librosa로 생성하며, 컷 포인트와 줌 키프레임을 가장 가까운 비트에 스냅하되 발화 경계를 우선시합니다. 자막은 수직 중간 밴드(아래쪽 15-20%가 아님)에 배치하여 TikTok, Instagram Reels, YouTube Shorts의 플랫폼 UI에 가려지지 않도록 합니다. 최종 출력은 H.264, 1080x1920, 30fps의 범용 마스터 파일로, `+faststart` 옵션을 포함하며 플랫폼별 비트레이트(2,000~15,000 kbps)를 지원합니다. CapCut(수동 단일 편집) 및 Remotion(React 컴포지션 재사용) 경로도 함께 제공하지만, 주력은 도구 독립적인 ffmpeg + WhisperX 파이프라인입니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ericrisco/rsc-harness/tree/HEAD/skills/shortform-editing

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

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

문서

숏폼 편집 — 영상을 포스트 가능한 숏츠로 자르기

당신은 편집실 기술자입니다. 누군가 실제 영상(토킹헤드 테이크, 화면 녹화, 나레이션, B-roll)을 건네주면, 당신은 그것을 포스트 가능한 세로 숏츠로 만듭니다: 무음 제거, 빠른 컷, 단어 단위로 화면에 새겨진 자막, 비트에 맞춘 모션, 명세에 맞춰 내보내기. 당신은 픽셀과 타이밍을 인코딩합니다. 단어를 쓰거나 훅을 고르지 않습니다.

핵심은 검증 가능한 파일입니다: ffprobe가 확인하는, 화면에 새겨진 자막이 있는 1080x1920 H.264 MP4와 중간 산출물(컷 리스트, .ass/.srt, 비트 그리드). 결과물을 ffprobe로 확인하여 명세를 충족하지 못하면 완료된 것이 아닙니다.

범위: 세 가지 스킬이 '세로 비디오'를 다룹니다 — 자신의 역할을 알아야 합니다

요청담당산출물
스크립트, 훅, 비트, 화면 자막 텍스트, 편집 결정 시트 작성../video-shorts/SKILL.md.md 스크립트
실제 영상 컷/자막/내보내기, 도구 무관여기편집된 .mp4 + 자막/컷 파일
Remotion React 컴포지션 프로젝트(<TransitionSeries>, 헤드리스 렌더) 빌드../remotion-video/SKILL.md.tsx 프로젝트

한 줄 라우터: 영상 입력 → 컷, 자막, 내보내기 → 이 스킬. 단어 또는 계획 → video-shorts. React 코드베이스 → remotion-video. 세 가지 중 유일하게 도구에 구애받지 않는 스킬입니다.

먼저 경로를 선택하세요

도구를 선택하기 전에 자르기를 시작하지 마세요. 선택은 누가 실행하고 재현 가능해야 하는지에 달려 있습니다.

상황경로이유
재현 가능 / 배치 / CI / '이걸 40개 클립에 적용'ffmpeg + WhisperX스크립트 가능, 결정론적, GUI 없음 — 같은 입력, 같은 출력
레포가 이미 Remotion 프로젝트임@remotion/captions기존 컴포지션 그래프 재사용; 셸 명령어 사용 안 함
사람이 하나의 비디오를 손으로 다듬는 중CapCut 클릭 경로자동 자막 + 자동 비트 마커로 단일 수동 패스에 가장 빠름

이 스킬의 나머지 부분은 ffmpeg + WhisperX 파이프라인(재현 가능한 경로)이며, Remotion 및 CapCut 경로는 차이점이 있는 부분에서 언급됩니다. 긴 명령 블록은 references/ffmpeg-pipeline.md에, 자막 세부 사항은 references/captions.md에 있습니다.

재현 가능한 파이프라인, 순서대로

이것이 핵심입니다. 위에서 아래로 실행하며 각 단계가 다음 단계에 입력을 제공합니다.

1. 전사를 위해 깨끗한 모노 16kHz 오디오 트랙을 추출합니다.

ffmpeg -i in.mp4 -vn -ac 1 -ar 16000 a.wav

왜 모노 16kHz인가: Whisper 모델이 기대하는 형식입니다; 스테레오 48kHz를 공급하면 시간만 낭비하고 정확도에는 변화가 없습니다.

2. 단어 수준 타임스탬프로 전사합니다. 세그먼트 타임스탬프만으로는 부족합니다 — 단어별 자막에는 단어별 타이밍이 필요합니다.

whisperx a.wav --model large-v3 --output_format json --highlight_words True

WhisperX(v3.8.5)는 faster-whisper에 wav2vec2 강제 정렬을 더하여 100ms 미만의 단어 타이밍 정확도를 제공합니다. 이는 가라오케 하이라이트의 기본 조건입니다. faster-whisper 단독으로도 word_timestamps=True를 사용하면 작동하지만(~10% 오버헤드), 단어 경계에서 더 많이 어긋납니다. 왜 강제 정렬인가: Whisper의 네이티브 워드 스탬프는 보간되어 지터가 있습니다; 강제 정렬은 각 단어를 오디오에 고정시킵니다. 설치 및 JSON 구조는 references/captions.md를 참조하세요.

3. 무음을 감지한 다음, 비디오와 오디오를 함께 자릅니다. 이 단계를 사람들이 자주 잘못합니다.

# Pass 1: 무음 구간 찾기(음성 임계값)
ffmpeg -i in.mp4 -af silencedetect=noise=-25dB:d=0.3 -f null - 2> silence.log

silenceremove 단독은 오디오 전용 필터로 비디오와 동기화가 깨집니다 — 절대 원샷으로 사용하지 마세요. silence.log에서 silence_start / silence_end 줄을 파싱하고, 이를 유지 구간으로 반전시킨 다음, 두 스트림에서 동일한 구간을 제거하는 select + aselect 필터(또는 trim+concat 그래프)를 빌드하세요. 임계값: 음성 noise=-25dB:d=0.3; 배경 음악 noise=-40dB:d=1. 필터 생성 스니펫은 references/ffmpeg-pipeline.md에 있습니다.

4. 비트 그리드를 구축합니다(음악에 맞춰 자르는 경우에만).

python -c "import librosa; y,sr=librosa.load('music.wav'); \
_,b=librosa.beat.beat_track(y=y,sr=sr,units='time'); print(*b,sep='\n')" > beats.txt

beats.txt는 초 단위 비트 시간 목록입니다. CapCut은 이러한 마커를 자동으로 웨이브폼에 추가합니다; librosa(또는 aubio)는 스크립트에서 동일한 그리드를 제공합니다.

5. 컷 포인트와 줌 키프레임을 가장 가까운 비트에 스냅합니다. 각 컷 시간을 beats.txt에서 가장 가까운 값으로 반올림합니다. 비트에 맞춘 줌 펀치는 에너지로 읽힙니다; 아래 '비트 동기화'에서 언제 하지 말아야 하는지 확인하세요.

6. 가라오케 .ass 자막을 화면에 새깁니다.

ffmpeg -i tightened.mp4 -vf "ass=captions.ass" -c:a copy captioned.mp4

.ass는 2단계의 단어 타임스탬프와 안전 영역 여백을 기반으로 구축된 단어별 \k 타이밍을 포함합니다. 생성 세부 사항 및 템플릿은 아래 '가라오케 자막'에 있습니다.

7. 플랫폼 마스터를 내보냅니다(내보내기 명세 참조).

가라오케 자막

단어별 자막이 시그니처 룩입니다. 세그먼트 타임스탬프가 아닌 단어 타임스탬프로 구축하세요.

  • 타이밍. 각 단어의 화면 하이라이트는 강제 정렬 시작/종료에서 비롯됩니다. .ass에서 \k<센티초> 태그는 단어별로 가라오케 채움을 진행합니다. 세그먼트 타이밍의 단어별 자막은 지터가 발생하여 하이라이트가 잘못된 단어에 표시됩니다 — 항상 2단계의 단어별 스탬프를 사용하세요.
  • 소리 없을 때의 가독성. 크고 굵은 산세리프체, 두꺼운 외곽선/획, 선택적 그림자. 사람들은 음소거로 시청합니다: 한눈에 읽을 수 없으면 실패입니다. 한 번에 ≤ 2줄 / ~6단어로 유지하세요.
  • 안전 영역 — 덜 obvious한 것. 자막을 하단이 아닌 수직 중간 밴드에 배치하세요. 플랫폼 UI(오른쪽 레일 아이콘, 하단 캡션/CTA/프로필)는 하단 약 15-20%와 오른쪽 가장자리를 덮습니다. 자막과 핵심 텍스트를 1080x1920 프레임의 중앙 약 80% 내에 유지하세요. 하단에 새겨진 자막은 TikTok 버튼 뒤에 가려집니다 — 이것이 '내 자막이 깨졌다'는 불만의 #1 원인입니다.

최소 .ass 스타일 블록(전체 템플릿은 references/captions.md에):

[V4+ Styles]
Style: Karaoke,Montserrat,64,&H00FFFFFF,&H0000FFFF,&H00000000,&H64000000,-1,0,0,0,100,100,0,0,1,5,2,5,80,80,640,1

MarginV(끝의 640)가 줄을 중간 밴드로 들어 올립니다. 두꺼운 Outline(5)은 어떤 배경에서도 읽을 수 있게 합니다.

Remotion 경로: Remotion 프로젝트 내부에 있다면 @remotion/captions을 사용하세요 — createTikTokStyleCaptions({ captions, combineTokensWithinMilliseconds })가 토큰을 페이지로 나눕니다. 낮은 값(200–500ms) = 단어별 팝; 높은 값(1200–2000ms) = 구문 페이지. durationMs 페이지는 v4.0.261에서 추가되었습니다. CapCut 경로: 텍스트 → 자동 자막 → 생성 후 스타일 재지정.

비트 동기화

비트 그리드(4단계)는 초 단위 목록입니다. 컷 포인트와 줌 키프레임을 가장 가까운 비트에 스냅하여 모션이 음악에 맞게 떨어지도록 하세요.

  • 나쁨 → 좋음. 단어 중간에 끊어 비트에 정확히 컷을 맞추는 것은 실수로 읽힙니다 → 음성 경계도 존중하는 가장 가까운 비트로 컷을 조정하세요. 비트보다 단어를 먼저 존중하세요.
  • 비트 컷을 하지 말아야 할 때. 단어가 가치를 전달하는 토킹헤드 설명: 명확성이 리듬보다 우선합니다. 중간 문장에서 사람을 비트 컷하면 전달력을 망칩니다. 비트 동기화는 B-roll 몽타주, 전환, 음악 주도 세그먼트에만 예약하세요.
  • 전환은 저렴하고 빠르게 유지. 하드 컷이 기본입니다. 비트에만 휩팬(whip-pan) 또는 줌 펀치를 사용하세요. 30초 숏츠에서 1초 크로스페이드는 페이스를 죽입니다; 숏츠는 빠른 하드 컷으로 살아납니다.

내보내기 명세

세 플랫폼 모두에서 깨끗하게 재생되는 범용 세로 마스터 — 하나의 파일:

ffmpeg -i captioned.mp4 \
  -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,setsar=1" \
  -c:v libx264 -profile:v high -pix_fmt yuv420p -r 30 \
  -c:a aac -b:a 192k -ar 48000 -ac 2 \
  -movflags +faststart out.mp4

yuv420p(광범위한 재생), +faststart(웹 스트리밍이 전체 다운로드 전에 시작됨), AAC-LC 48kHz. 30fps 사용; 고모션 숏츠의 경우 60fps로 올리세요.

플랫폼비디오 비트레이트참고
TikTok~2,000–4,000 kbps세 개 중 가장 가벼움
Instagram Reels~3,500–4,500 kbps
YouTube Shorts (1080p)~8,000–15,000 kbps4K/60의 경우 최대 ~53,000

단일 1080x1920 H.264 MP4 @30fps ~250 MB 미만은 어디서나 안전합니다. 배송 전에 확인하세요:

ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height,codec_name,avg_frame_rate out.mp4

width=1080 height=1920 codec_name=h264가 예상됩니다. 전체 플랫폼별 인코딩 플래그와 ffprobe 어설션은 references/ffmpeg-pipeline.md에 있습니다.

안티패턴

나쁨왜 깨지는가좋음
silenceremove를 원샷 필터로 사용오디오 전용이며 비디오는 계속 재생 → 오디오/비디오 불일치silencedetect → 구간 반전 → select+aselect로 두 스트림 자르기
세그먼트 타임스탬프로 단어 자막 생성하이라이트가 지터나서 잘못된 단어에 표시됨강제 정렬 단어별 스탬프(WhisperX / word_timestamps)
자막을 하단 15-20%에 새김플랫폼 UI(버튼, CTA, 프로필)가 가림수직 중간 밴드, 중앙 약 80%에 배치
하나의 내보내기를 모든 플랫폼에 재사용어딘가에서 비트레이트 목표를 초과/미달함플랫폼별 비트레이트 또는 안전한 범용 마스터
30초 숏츠에서 1초 크로스페이드페이스를 죽이고 느리게 읽힘하드 컷; 비트에만 휩/줌 사용
토킹헤드를 문장 중간에 비트 컷전달력을 망치고 명확성 상실B-roll/몽타주만 비트 동기화; 음성 경계 존중
'명세 확인'을 위해 인코딩 다시 실행시간 낭비; 파일이 이미 존재함ffprobe로 출력 확인; 재렌더링하지 말고 검증
여기서 자막 카피나 훅 작성그것은 스크립트지 컷이 아님../video-shorts/SKILL.md로 라우팅; 당신은 새겨 넣기만 함
ffmpeg가 원본 파일을 덮어씀잘못된 플래그 하나면 원본이 사라짐항상 새 파일에 쓰고 in.mp4는 건드리지 않음

확인 및 참조

  • bash scripts/verify.sh <output.mp4> — ffprobe를 실행하여 width=1080, height=1920(9:16), 비디오 코덱 h264, 오디오 코덱 aac, fps가 {30, 60} 중 하나인지, 그리고 동일한 디렉토리에 .srt/.ass 자막 파일이 존재하고 비어 있지 않은지 어설션합니다. ffprobe가 없으면 경로/확장자 확인으로 대체됩니다. 읽기 전용이며 빈/깨끗한 대상에 대해 0으로 종료되어 거짓 실패를 하지 않습니다. '비트에 맞는 느낌' 판단은 기계적이지 않으며, 이는 역량 평가에 속합니다.
  • references/ffmpeg-pipeline.md — 무음 감지 → 유지 구간 반전 → 비디오+오디오를 함께 자르는 select/aselect 필터 생성 전체, concat/trim 접근법, 플랫폼별 인코딩 플래그, ffprobe 어설션, 및 동기화/오디오 드리프트/faststart 문제 해결.
  • references/captions.md — WhisperX 설치 및 실행, 단어 타임스탬프 JSON 구조, 안전 영역 여백이 포함된 전체 .ass 가라오케 템플릿, combineTokensWithinMilliseconds 가이드가 포함된 Remotion createTikTokStyleCaptions() 스니펫, 및 faster-whisper 대 WhisperX 트레이드오프.

Individual skills in this repo

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

ericrisco/rsc-harness

Use when writing the words on a single conversion page — the hero headline and subhead, the offer, the proof and testimonials, and one primary CTA — or diagnosing a page that gets traffic and does not convert, as a copy problem rather than a layout one. NOT the paid ad that drives the click (that is `ads`), NOT the visual layout the words sit in (that is `design`), NOT the experiment that picks the winning variant (that is `ab-testing`).

ericrisco/rsc-harness

Use when you need to render an actual video file with Remotion — React compositions, the Composition/Sequence/TransitionSeries graph, transitions, burned-in word-by-word captions from a transcript, automatic silence removal, b-roll overlays, headless CI renders, and a final MP4 or MOV. NOT writing the script, hook, beats or caption text (that is `video-shorts`), NOT mastering audio to LUFS or building an RSS feed (that is `podcast`), NOT structuring the narrative arc (that is `course-storytelling`).

ericrisco/rsc-harness

Use when a Reels/TikTok/Shorts account needs its next video ideas scored into a ranked backlog, grounded in its own performance log plus dated trending sounds, each bet logged so its outcome feeds the next batch. NOT scripting a chosen idea (that is `video-shorts`), NOT pillars or cadence (that is `shortform-strategy`), NOT packaging a finished cut (that is `shortform-packaging`).

ericrisco/rsc-harness

Use when a vertical short is shot or scripted and you need the upload-form copy and cover that win the feed — the hook line, the first-frame on-screen text, the search-led caption, a tight hashtag set, and the cover frame; it learns from what performed via the 02-DOCS log. NOT inventing the idea (that is `shortform-ideation`), NOT scripting or directing the cuts (that is `video-shorts`), NOT executing the edit (that is `shortform-editing`), NOT scheduling the post (that is `social-publisher`).

ericrisco/rsc-harness

Use when the unit of work is a TikTok/Reels account, not one clip: positioning, sustainable cadence and format mix, ride-or-skip on a trend or sound, recurring series, diagnosing a flat account, and the dated learning loop. NOT the single script or hook variants (that is `video-shorts`), NOT the idea backlog (that is `shortform-ideation`).

ericrisco/rsc-harness

Use when planning a posting schedule, building a multi-platform content calendar, or reshaping one source asset into channel-native posts across X, LinkedIn, Instagram, Threads, Bluesky, TikTok, Facebook or YouTube — cadence, best-time slots, per-platform format limits, API publish caps, and a dated CSV or JSON calendar a scheduler can import. NOT the brand voice the posts speak in (that is `brand-voice`), NOT the editorial strategy of what to make (that is `content-engine`).

ericrisco/rsc-harness

Use when connecting a real TikTok account to code via the Content Posting, Display and Business Account APIs — OAuth, chunked video publish with status polling, and pulling views, watch time and impression sources, then logging that performance into the wiki as a dated feedback record. Covers short-lived tokens breaking a cron, unverified pull-from-URL ownership, and rate limits. NOT what to post or how to package it (that is `shortform-strategy` and `shortform-packaging`).

ericrisco/rsc-harness

Use when scripting or directing the edit of a single vertical short that has to hold attention from the first frame — turning a topic, a clip or a long video into a shot-by-shot script and an edit decision sheet, fixing a hook that dies in second three, generating hook variants to test, and planning cuts and on-screen text. NOT scheduling or cross-platform cadence (that is `social-publisher`), NOT running the editorial calendar (that is `content-engine`), NOT defining the durable brand tone (that is `brand-voice`).

ericrisco/rsc-harness

Use to judge whether a short-form clip is worth publishing — scores a reel, short or podcast excerpt 0-100 on ten weighted criteria with automatic penalties, then ranks a batch and says where the cut-off falls. Run it on transcript candidates before rendering. NOT writing the hook or caption (that is `shortform-packaging`), NOT inventing the idea (that is `shortform-ideation`), NOT executing the edit (that is `shortform-editing`).

관련 스킬