Communitygithub.com

amrodwaire/phone-reel-edit

휴대폰 영상을 아랍어 자막이 포함된 세로형 릴, 쇼츠, 틱톡으로 편집하기 위한 가이드입니다. 소스 확인, 절단, 안정화, 슬로우 모션, 색보정, 아랍어 텍스트 삽입, 음악 편집, 마스터링 및 게시 전 확인 사항을 다룹니다.

phone-reel-edit란 무엇인가요?

이 스킬은 휴대폰으로 촬영한 영상을 아랍어 자막이 포함된 세로형 숏폼 콘텐츠(릴, 쇼츠, 틱톡)로 편집하기 위한 종합적인 워크플로우를 제공합니다. ffmpeg을 이용한 영상 절단, 안정화, 슬로우 모션, 색보정(LUT 또는 DaVinci Resolve), Remotion을 이용한 아랍어 텍스트 자동 배치, 음악 편집, 전화 스피커를 위한 음량 마스터링까지 모든 단계를 상세히 설명합니다. 각 단계별 실패 사례에서 얻은 교훈을 바탕으로 작성되었으며, 특히 아랍어 텍스트의 가독성, 색상 정확도, 모바일 기기에서의 최적 재생을 중요시합니다. Claude Code와 같은 AI 에이전트가 숏폼 영상 편집을 안내할 때 활용할 수 있으며, 명령어와 스크립트를 통해 반복적인 작업을 자동화할 수 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/amrodwaire/phone-reel-edit/tree/HEAD

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

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

문서

휴대폰 릴 편집

여기 있는 대부분의 규칙은 실제로 그 단계에서 실패한 릴에서 비롯되었습니다. references/research.md에는 이유와 출처가 있습니다. references/resolve-ui.md에는 DaVinci Resolve 컨트롤을 컴퓨터 사용으로 조작하기 위한 매핑이 있습니다.

일부 사례는 아직 게시된 릴로 검증되지 않았습니다: HDR 소스, 30fps 슬로우 모션, 카메라 앞에서 하는 말, TikTok 및 Shorts 안전 영역, 커버. 이에 대한 명령어는 테스트 클립에서만 실행되었습니다. references/other-cases.md에 해당 내용과 확인 방법이 있습니다. 편집이 이러한 사례 중 하나에 의존하는 경우 사용자에게 알리십시오.

파이프라인: 휴대폰 소스 → ffmpeg 절단 및 안정화 → 색보정(DaVinci Resolve 또는 전체 프레임 이동용 scripts/grade.py) → Remotion 텍스트 → ffmpeg 사운드 및 마스터링.

절단 전

  1. 클라이언트의 브랜드 규칙(금칙어, 연락처 줄, AI 표시, 게시 전 승인이 필요한 사항)이 있는 경우 먼저 읽습니다.
  2. 모든 소스 클립을 확인합니다: python -I scripts/probe_source.py clip.mp4. 회전, 프레임 속도 및 가변 여부, SDR 또는 HDR, 색상 태그 및 오디오를 보고한 후 클립에 필요한 추가 작업을 나열합니다. 일반적인 휴대폰 클립은 약 30 또는 60fps의 SDR bt709입니다. HDR, 가변 프레임 속도 및 30fps 소스는 각각 references/other-cases.md에 설명된 추가 단계가 필요합니다. 배경 대화가 있는 경우 원본 사운드는 음소거 상태를 유지합니다. 카메라에 있는 사람이 시청자에게 말을 거는 경우, 같은 파일의 '말하기' 섹션을 참조하십시오.
  3. 두 번째 AI 모델을 리뷰어로 사용하는 경우, 결정하기 전에 해당 모델과 아이디어를 논의하고, 그 이후에 모델이 말한 내용을 검증하십시오. references/research.md에는 리뷰어 모델이 저지른 실수 유형이 나열되어 있습니다.

속도

  • 릴 하나당 하나의 아이디어. 텍스트가 길이를 결정하며, 목표 숫자가 아닙니다. 테스트 릴은 클라이언트가 10.5초 또는 13.5초에 읽기를 마칠 수 없어 18.6초가 필요했습니다.
  • 한 줄이 나타나는 시점부터 초당 10개의 아랍어 문자를 기준으로 합니다. 의도적으로 느리게 설정되었습니다. 시청자는 휴대폰에서 영상도 함께 보고 있기 때문입니다.
  • 가능하면 샷당 두 번의 리빌(reveal)을 사용하고, 리빌 사이에 최소 1.5초 간격을 둡니다. 함께 나타나는 줄은 하나의 리빌로 계산합니다.
  • 원어민의 속도 판단이 어떤 모델의 판단보다 우선합니다.
  • 가장 강력한 비주얼과 후크 텍스트는 0프레임에 표시되며, 검은색에서 페이드 인하지 않습니다.
  • 갑작스러운 3배속을 피하십시오. 대신 좋지 않은 구간을 부드럽게 램프 업하십시오.

60fps를 0.5배속으로 재생하면 실제 프레임이 30fps로 제공되므로 보간이 필요 없습니다. 30fps 소스에는 여분의 프레임이 없으므로, 슬로우 모션을 적용하기 전에 references/other-cases.md의 슬로우 모션 섹션을 읽으십시오. 60fps 중간 파일로 안정화한 후 타임 리매핑하십시오:

ffmpeg -ss S -t D -i raw.mp4 -vf "vidstabdetect=shakiness=6:accuracy=15:result=x.trf" -f null -
ffmpeg -ss S -t D -i raw.mp4 -vf "vidstabtransform=input=x.trf:smoothing=14:zoom=2:optzoom=0:interpol=bicubic,crop=W:H:X:Y,scale=1080:1920:flags=lanczos,fps=60" -an -c:v libx264 -preset veryfast -crf 10 -pix_fmt yuv420p im.mp4
python -I scripts/retime.py im.mp4 c1.mp4 --start 0.4 --frames 99 --keys 0:.5

scripts/ 경로는 이 스킬의 폴더에서 실행하십시오. ffmpeg에는 vidstab 필터가 필요합니다. 모든 클립은 시간 0에서 시작해야 합니다. 0이 아닌 시작 시간은 Resolve에서 클립 앞부분에 검은 프레임으로 표시되기 때문입니다. -ss를 시간 필터와 함께 사용할 때 setpts=PTS-STARTPTS를 추가하고, start_time을 ffprobe로 확인하십시오.

정지 샷의 마지막 몇 프레임으로 손이 밀려드는 경우, 이전 프레임을 유지하여 숨길 수 있습니다: trim=end_frame=N,setpts=PTS-STARTPTS,tpad=stop_mode=clone:stop_duration=0.6.

색상

여기서 색상은 보정을 의미합니다: 중립 흰색, 자연스러운 피부, 실제 제품 색상, 샷 간 일치. 크리에이티브 룩은 마지막에 미미하게 적용되며, 적용 후에도 제품 색상이 실제와 일치해야 합니다.

샷의 필요에 따라 경로를 선택하십시오:

  • 전체 프레임 이동만 필요한 경우 (색조, 노출, 대비, 채도): scripts/grade.py. 더 빠르고 반복 가능하며, 숫자는 재실행 가능한 명령어에 남습니다.
  • 프레임의 특정 부분만 수정이 필요한 경우 (다른 조명 아래의 피부, 특정 물체): 파워 윈도우를 사용할 수 있는 DaVinci Resolve.

두 경로 모두 동일한 측정, 조정, 측정 루프와 아래 동일한 목표 값을 사용합니다.

grade.py 사용

python -I scripts/grade.py still c1.mp4 1.5 before.png
python -I scripts/measure_grade.py before.png --patch counter:40,60,200,220 --skin 100,1450,1000,1920
python -I scripts/grade.py make c1.cube --frame before.png --neutral 40,60,200,220 --white 205 --contrast 1.06 --pivot 0.4 --lift -0.02
python -I scripts/grade.py still c1.mp4 1.5 check.png --lut c1.cube --compare
python -I scripts/grade.py apply c1.mp4 c1g.mp4 --lut c1.cube

--neutral은 회색 또는 흰색이어야 하는 패치입니다: 카운터, 벽, 종이, 흰색 뚜껑. make는 R, G, B를 균등하게 만들고, --white는 결과 레벨을 설정합니다. 조명이 고르고 날아가지 않은 패치를 선택하십시오. 적용 전에 --compare 프레임을 전체 크기로 보고 보정된 절반을 측정하십시오. 각 샷에는 자체 색조가 있으므로 샷당 하나의 LUT를 사용합니다.

게인이 하이라이트를 250 이상으로 밀어 올리는 경우 --knee 0.85를 추가하십시오. 눈에 띄게 노이즈가 있는 저조도 클립에만 --denoise light를 사용하고, --sharpen은 드물게 사용하십시오: 휴대폰은 이미 선명도를 적용하며, 추가로 적용하면 가장자리와 텍스트에 후광이 생깁니다.

Resolve에서 만든 그레이드는 LUT로 내보낼 수 있습니다: 컬러 페이지에서 클립의 썸네일을 마우스 오른쪽 버튼으로 클릭하고, LUT 생성, 33포인트 큐브를 선택합니다. grade.py apply --lut를 사용하면 모든 클립에 적용할 수 있습니다. LUT는 전체 프레임 이동만 포함하므로 윈도우 효과는 포함되지 않습니다.

DaVinci Resolve Free에서

Resolve가 볼 수 있는 일반 폴더에 클립을 복사합니다(일부 앱 데이터 폴더는 열 수 없으며 "경로가 존재하지 않습니다"라고 표시됨). 새 타임라인에 배치하고 Parade 스코프를 엽니다.

각 단계는 이전 단계에 의존하므로 다음 순서로 작업하십시오:

  1. 밸런스 노드. 게인은 흰색 레벨, 템프는 색조용. 양수 템프는 따뜻하게 만듭니다. 두 샷의 동일한 표면은 일치해야 합니다.
  2. 대비 노드. 대비 및 피벗, 깊은 검은색을 위한 리프트, 5 이하의 작은 채도 조정.
  3. 주제 노드, 전체 이동이 다른 부분에 해를 끼칠 때만. 부드러운 파워 윈도우를 사용합니다. 테스트 릴에서는 윈도우가 손의 피부를 보정하고 제품 색상은 그대로 두었습니다.
  4. 렌더링, 측정, 조정, 반복. 두 번이면 충분했습니다.
python -I scripts/measure_grade.py frame.png --patch counter:40,60,200,220 --skin 100,1450,1000,1920

목표 수치

  • 중립 표면: R, G, B가 약 35 이내. 흰색은 밝은 룩을 위해 195215 정도.
  • 피부 색조는 123도 근처. 벡터스코프 선은 참조용이지 목표가 아니므로 자연스럽게 유지하십시오.
  • 피부 밝기: 가이드에 따르면 피부와 장면에 따라 40%에서 70% 사이. 실수를 잡기 위한 범위로 사용하고, 정확히 맞춰야 할 숫자로 사용하지 마십시오.
  • 하이라이트: 250 이상인 픽셀이 전체의 약 2% 미만.
  • 채도: 전후의 chroma 라인을 비교하십시오. 보정은 p95를 원래와 가깝게 유지해야 합니다. 큰 변화는 그레이드가 장면에 없는 색상을 추가하고 있음을 의미합니다.
  • 제품을 판매하는 비디오인 경우 제품 색상은 실제와 일치해야 합니다.
  • 동일한 표면의 두 샷은 동일하게 측정되어야 합니다.

무엇이 무엇을 움직이는가:

  • 틴트는 붉은 손바닥을 거의 움직이지 못했습니다. 채널별 감마가 해결했습니다: G 증가, R과 B 약간 감소.
  • 템프 +300은 파란색 색조를 과도하게 보정했으며, +130이 적절했습니다. 작게 시작하십시오.

Remotion의 아랍어 텍스트

assets/reelTemplate.tsx는 작동하는 템플릿입니다. 각 텍스트 블록을 데이터로 유지하고 텍스트 확인을 위한 프로브 컴포지션이 있습니다. references/remotion-setup.md는 프로젝트를 처음부터 시작하고 컴포지션을 등록하는 방법을 다룹니다.

규칙:

  • 굵은 아랍체(템플릿은 Alexandria 800 사용), 흰색과 하나의 악센트 색상, 박스 없음, 부드러운 그림자.
  • 1080x1920 프레임에서 62~124px 크기. 휴대폰에서는 그 정도 크기가 필요합니다.
  • 아랍어의 경우 줄 간격 1.5. 1.22에서는 글자 꼬리가 다음 줄에 닿습니다.
  • 모든 글자는 x 110-950, y 220-1475 내에 있어야 Instagram의 오른쪽 레일과 하단 바가 아무것도 가리지 않도록 합니다.
  • whiteSpace: nowrap을 사용하여 줄이 예기치 않게 넘어가지 않도록 합니다.
  • 후크는 0프레임에 표시됩니다. 이후 줄은 약 1초 간격으로, 6프레임의 상승 및 페이드가 있습니다.
  • 텍스트 뒤의 부드러운 어두운 밴드는 텍스트 아래의 피사체가 계속 보이도록 합니다.
  • 고객 인용문은 그대로 유지하며, 고객이 동의하지 않은 한 이름이나 사진을 포함하지 않습니다.
  • 시청자가 보고 있는 것을 설명하십시오. 레이블이 그것이 유일한 옵션임을 암시하지 않도록 하십시오.

텍스트를 변경한 후 프로브 프레임을 렌더링하고 확인하십시오:

npx remotion still ReelProbe out/p0.png --frame=0
python -I scripts/check_text.py out/p0.png out/p1.png out/p2.png out/p3.png

두 줄의 잉크가 14px 이내로 오거나 글자가 안전 영역을 벗어나면 실패합니다. 한 블록은 최대 7줄을 담을 수 있습니다.

그런 다음 실제 이미지에 대해 텍스트를 확인하십시오. 각 샷의 마지막 프레임(모든 줄이 화면에 표시될 때)을 렌더링하고 동일한 순서로 해당 프레임을 전달하십시오:

npx remotion still Reel out/r0.png --frame=119
python -I scripts/check_text.py out/p0.png out/p1.png --real out/r0.png out/r1.png

각 줄은 글자 주변 이미지의 가장 밝은 부분에 대한 대비 수치를 얻으며, 3.0 미만이면 실패합니다. 테스트 릴에서 악센트 색상 줄은 3.2에서 4.6, 흰색 줄은 5 이상을 기록했습니다. 낮은 점수는 텍스트 뒤의 밴드를 더 강하게 하거나 블록을 이동해야 함을 의미합니다.

기본 박스는 Instagram용입니다. TikTok 또는 Shorts에도 게시되는 릴의 경우 --platform all을 추가하십시오. 이 두 박스는 타사 가이드에서 가져온 것이므로 각 앱에서 업로드를 미리 보십시오.

그런 다음 각 샷의 끝에서 전체 크기 프레임을 살펴보십시오. 썸네일 시트는 충돌을 숨기고, 텍스트 뒤에서 움직이는 것은 전체 크기에서만 보입니다. 테스트 릴에서 숟가락이 줄과 교차했습니다. 모서리 원점으로 약간 확대하면 숟가락이 비켜나가고 잘못된 손가락도 잘라냈습니다.

렌더링 및 사운드

npx remotion render Reel out/reel.mp4 --codec=h264 --crf=15 --muted --color-space=bt709
python -I scripts/beat_offset.py music.ogg --cuts 3.3,6.5,10.3 --length 13.5 --from 0 --to 40

--color-space=bt709는 중요합니다. 이를 생략하면 Remotion이 알 수 없는 프라이머리를 가진 전체 범위 bt470bg를 씁니다.

최적의 오프셋에서 음악을 자르고, 마지막 1.2초를 페이드 아웃한 후 -c:v copy로 결합하고 마스터링하십시오:

sh scripts/master.sh in.mov out.mp4 -14 0.4 0.75

마지막 숫자는 리미터 천장입니다. AAC는 그 위에 오버슈트를 추가하며, 그 양은 트랙에 따라 다르므로 스크립트는 작성된 파일을 측정하고 음량과 실제 피크를 출력합니다. TOO HOT(실제 피크가 -1 dBTP 초과)이 출력되면 0.7로 다시 실행하십시오.

휴대폰 스피커는 300Hz 이하의 대부분의 소리를 잃으므로 해당 대역을 확인하십시오:

ffmpeg -hide_banner -nostats -i out.mp4 -vn -af "highpass=f=300:poles=2,highpass=f=300:poles=2,lowpass=f=12000,ebur128" -f null - 2>&1 | tail -12

-14 LUFS 마스터에서 해당 대역이 -20 LUFS 이상이 되도록 목표로 하십시오. 저음이 강한 트랙은 -23.9로 측정되어 휴대폰에서 소리가 탁하게 들렸습니다. 파형과 스펙트럼도 그리십시오. 리뷰어 모델의 타임스탬프가 항상 일치하는 것은 아니기 때문입니다.

AI 생성 음악 또는 음성에는 플랫폼의 AI 표시가 필요합니다. 릴보다 약간 긴 음악을 생성하십시오. 너무 짧게 자른 트랙은 깔끔하게 늘일 수 없기 때문입니다.

완료 전 확인 사항

  • ffprobe에 yuv420p, tv, bt709, bt709, bt709와 올바른 길이 및 프레임 수가 표시되어야 합니다.
  • check_text.py가 --real 프레임을 포함하여 PASS를 출력해야 합니다.
  • master.sh가 -1 dBTP 이하의 실제 피크를 출력해야 합니다.
  • 릴이 프로필 그리드에 표시되는 경우 커버 프레임이 존재해야 합니다(references/other-cases.md 참조).
  • 전체 크기 프레임을 직접 살펴보십시오. 첫 번째 프레임, 마지막 프레임 및 각 컷 직전 프레임을 포함합니다.
  • 리뷰어 모델이 최종 mp4를 시청하는 경우, 이미 내린 결정을 알려주어 다시 논의하지 않도록 하십시오.
  • 확인되지 않은 사항을 명시하십시오. 에이전트는 오디오를 듣거나 휴대폰에서 파일을 볼 수 없습니다.
  • 이미 업로드된 파일을 교체한 후 다시 업로드하고, 공개 링크에서 확인하고, 이전 파일을 가리키는 예약된 항목을 업데이트하십시오.

게시에는 클라이언트의 승인이 필요합니다.

관련 스킬