# Reelcut

> ถอดสูตรคลิปสั้น/รีล/โฆษณาแนวตั้งแบบ forensic (teardown) แล้วเอาสูตรที่วัดได้ไปสร้างคลิปใหม่ — วัดจริงทุกค่า ไม่เดา — คัต, push-in, freeze/speed-ramp, กราฟิก, เกรดสี, LUFS/LRA/True-peak, สเตอริโอ, ช่องว่างลมหายใจ, ความเร็วพูด, แยกสเต็มหา BGM-vs-SFX, และการซิงก์เสียงกับภาพ. Trigger เมื่อผู้ใช้พิมพ์ /reelcut หรือขอ "วิเคราะห์คลิปนี้ / ถอดสูตรคลิป / ศึกษาองค์ประกอบคลิป / คลิปนี้ตัดต่อยังไง / ใส่เอฟเฟกต์อะไรบ้าง / เสียงทำยังไง / reverse engineer วิดีโอ / ทำคลิปแบบคลิปนี้ / อยากได้แบบรีลตัวนี้".

- Skill: `ksmaster03/reelcut` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add ksmaster03/reelcut`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ksmaster03/reelcut/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ksmaster03 (https://skillmd.com/u/ksmaster03)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/ksmaster03/reelcut

---


# /reelcut — ถอดสูตรคลิป แล้วทำตามสูตร

สองโหมด อ่านเจตนาจากประโยคผู้ใช้แล้วเลือกเอง:

- **A · TEARDOWN** — "คลิปนี้มีอะไรบ้าง / ตัดต่อยังไง / เสียงทำยังไง" → §1–§4
- **B · BUILD** — "อยากได้คลิปแบบนี้ / ทำตามสูตรนี้" → §5

ถ้าผู้ใช้ส่งคลิปมาเฉยๆ พร้อมคำว่า "ศึกษา/ดูให้หน่อย" → **TEARDOWN**
ถ้าจะทำ **BUILD** ให้ teardown คลิปอ้างอิงก่อนเสมอ อย่าเดาสูตรจากความจำ

สื่อสารสองภาษา: สรุปไทย + ศัพท์เทคนิคอังกฤษ ตามที่ผู้ใช้ชอบ

---

## หลักการเดียวที่ห้ามละเมิด

> **วัด อย่าเดา.** ทุกตัวเลขที่รายงานต้องมาจากคำสั่งที่รันจริง
> ถ้าวัดไม่ได้ ให้บอกว่าวัดไม่ได้ — ห้ามประมาณแล้วเขียนเหมือนเป็นค่าที่วัดมา

โดยเฉพาะเรื่อง **"มีเพลงประกอบไหม"** — หูคนฟังผิดประจำเพราะ SFX ท้ายยาวๆ ฟังเหมือนเพลง
ต้องแยกสเต็มแล้ววัด (§2 ข้อ 11) ถึงจะตอบได้

---

## 0. Environment (เครื่องนี้ — ยืนยันแล้ว 2026-07-28)

| ของ | สถานะ |
|---|---|
| `ffmpeg` / `ffprobe` | อยู่บน PATH แล้ว |
| `numpy` 2.4 / `scipy` 1.18 | มี |
| `demucs` 4.1.0 + `torch` 2.13 (CPU) | **มี** — แยกสเต็ม ~1 วิ CPU ต่อเสียง 1 วิ |
| `faster_whisper` | มี — `small` เร็ว, `medium` ต้องโหลดโมเดล ~1.5 GB (ครั้งแรกนานมาก) |
| `librosa` | **ไม่มี** — อย่าเรียก เขียน scipy เอา |

สคริปต์หลัก: `scripts/reelcut_analyze.py` (ในโฟลเดอร์สกิลนี้)

---

## 1. TEARDOWN — รันตัววิเคราะห์

```bash
python "~/.claude/skills/reelcut/scripts/reelcut_analyze.py" \
       "<path/to/clip.mp4>" --stems
```

- `--stems` **ใส่เสมอเมื่อเรื่องเสียงสำคัญ** (ซึ่งคือเกือบทุกครั้ง) — เป็นการทดสอบเดียวที่ชี้ขาดว่ามี BGM หรือไม่
- `--work DIR` เลือกที่เก็บไฟล์กลาง (default = `_reelcut/` ข้างไฟล์วิดีโอ) → **ให้ชี้ไป scratchpad** อย่าไปสร้างขยะในโฟลเดอร์ผู้ใช้
- `--no-frames` ข้ามการวิเคราะห์ภาพ (ใช้ตอนสนใจเฉพาะเสียง)

สคริปต์พิมพ์ออกมา 13 ส่วน:

| § | วัดอะไร |
|---|---|
| 1 | container + **ธงเตือน platform transcode** |
| 2 | คัตจริง (spike ที่โดดเหนือเพื่อนบ้าน ≠ ภาพเคลื่อนไหวเร็ว) |
| 3 | shot list + framing drift (proxy — ต้องเอาตาดูประกอบ) |
| 4 | freeze frame / speed ramp |
| 5 | ช่วง whip / กราฟิกวิ่งเร็ว |
| 6 | เกรดสี (crushed black %, tint เงา/ไฮไลต์, saturation) |
| 7 | ไทม์ไลน์กราฟิกบนจอ |
| 8 | **LUFS / LRA / True peak** |
| 9 | ความกว้างสเตอริโอ (corr + side-below-mid) |
| 10 | ช่องว่างเสียงพูด + ความเร็วพยางค์ |
| 11 | **BGM vs SFX — ตัวชี้ขาด** |
| 12 | รายการ SFX ทีละก้อน + สเปกตรัมย่าน |
| 13 | คัตตกลมหายใจไหม / SFX ตกที่คัตหรือที่กราฟิก |

---

## 2. TEARDOWN — ดูภาพด้วยตา (สคริปต์แทนไม่ได้)

ตัวเลขบอกว่า *เกิดอะไร* ตาบอกว่า *มันหน้าตายังไง* ต้องทำทั้งคู่

**contact sheet** — 2 fps ทั้งคลิป แล้ว `Read` ดู:
```bash
ffmpeg -hide_banner -v error -i CLIP -vf "fps=2,scale=200:-1,tile=7x4" -q:v 3 SHEET_%02d.jpg -y
```

**เฟรมความละเอียดสูงตรงจุดสำคัญ** — เอาเวลาจาก §2/§5/§12 มาใช้:
```bash
ffmpeg -hide_banner -v error -ss 2.60 -i CLIP -frames:v 1 -q:v 2 out.jpg -y
```

**สเปกโตรแกรม** (ดูรูปร่าง SFX/riser):
```bash
ffmpeg -hide_banner -v error -i CLIP -lavfi "showspectrumpic=s=1400x600:mode=combined:legend=1:scale=log" spec.png -y
```

จาก contact sheet ให้เก็บ: ข้อความบนจอทุกชิ้น + เวลา, ฟอนต์/stroke/เงา/ไล่สี, ชนิดเอฟเฟกต์ที่พาข้อความเข้า (mask wipe / explosion sprite / glitch), โลโก้อยู่ไหน, อะไรเป็น prop จริง อะไรเป็นกราฟิก

---

## 3. TEARDOWN — ถอดบท

```bash
python - <<'PY' > tx.txt 2>&1
from faster_whisper import WhisperModel
m = WhisperModel("small", device="cpu", compute_type="int8")
segs, info = m.transcribe(r"<a16.wav>", language="th", vad_filter=False)
for s in segs: print(f"[{s.start:6.2f} -> {s.end:6.2f}] {s.text}")
PY
```

- ใช้ `small` ก่อน — `medium` ดีกว่าแต่โหลดโมเดลครั้งแรกนานมาก ถ้าจะใช้ให้สั่ง background แล้วทำอย่างอื่นรอ
  **คุ้มที่จะรอ**: ในคลิปอ้างอิง `small` ได้ยิน "2.4.9" แต่ `medium` ได้ยิน "2.4 GHz" ถูกต้อง
  ซึ่งเป็นตัวชี้ขาดว่าข้อความบนจอพิมพ์ผิด ไม่ใช่คนพูดผิด
- คำทับศัพท์อังกฤษจะเพี้ยน → **เอาข้อความบนจอมาปะติดปะต่อ** จะได้บทที่ถูก
- เสียงจาก stem `vocals.wav` ให้ผลดีกว่าเสียงดิบเมื่อมี SFX หนัก
- **ขอบเขต segment ของ whisper = สัญญาณหาจุดคัตที่ดีกว่า silence detection**
  คัตที่ตกกลางประโยคแบบไม่มีช่องว่างเสียงเลย ยังตกที่ "รอยต่อวรรค" อยู่ดี — silence จับได้แค่ครึ่งเดียว
  ให้เทียบเวลาคัต (§2) กับทั้ง VO gaps (§10) **และ** ขอบ segment ของ whisper

---

## 4. TEARDOWN — เขียนรายงาน

โครงที่ผู้ใช้คนนี้ชอบ (ยืนยันแล้ว):

1. **สเปกไฟล์** + คำเตือน transcode ถ้ามี
2. **Beat sheet** ตาราง: เวลา / บท / ภาพ / กราฟิก
3. **การตัดต่อ** — shot list, cut-on-breath, push-in, whip, สิ่งที่*ไม่*มี (freeze, dissolve)
4. **กราฟิก & เอฟเฟกต์** — ตารางทุก overlay + ชนิดเอฟเฟกต์ที่พาเข้า
5. **เกรดสี**
6. **เสียงละเอียด** — มาสเตอร์ริ่ง / สเตอริโอ / VO / **มี-ไม่มี BGM พร้อมหลักฐาน** / ตาราง SFX / กฎการวาง SFX
7. **สูตรทำซ้ำ** เป็นข้อๆ ทำตามได้จริง
8. **จุดที่ควรแก้** — เอาไปลอกไม่ได้

กฎการเขียน:
- ทุกข้ออ้างต้องมีตัวเลขติดมา ("LRA 2.4 LU" ไม่ใช่ "บีบอัดหนัก")
- ทั้ง **สิ่งที่มี และ สิ่งที่จงใจไม่มี** — "ไม่มีเพลงเลย" มักเป็นข้อค้นพบที่ใหญ่ที่สุด
- ตารางเยอะๆ ผู้ใช้อ่านเร็ว
- ปิดท้ายด้วยข้อเสนอต่อยอด อย่ายัดเยียด

---

## 5. BUILD — ทำคลิปตามสูตร

ถ้าจะ**สร้าง**ไม่ใช่แค่วิเคราะห์ ให้ส่งต่อไปที่ toolchain เดิม แล้วใช้สูตรจาก teardown เป็น spec:

- ตัดฟุตเทจจริง → **[[vdocut]]** (มี Windows/Thai gotcha ครบ)
- รีลข่าว/แชร์ข้อมูล 9:16 มี VO+ภาพ gen → **[[reel-factory]]**
- explainer การ์ตูน → **[[vdostory]]**
- วางแผน hook/retention → **[[vidcraft]]**

**เช็กลิสต์ก่อนเรนเดอร์** (เทียบกับตัวเลขที่ teardown มา):

- [ ] ทุกช็อตมีการเคลื่อนไหว — ห้ามมีช็อตนิ่งสนิท
- [ ] Hard cut ล้วน ไม่มี dissolve เว้นแต่มีเหตุผล
- [ ] คัตตกในช่องว่างลมหายใจ 90–270 ms
- [ ] ความเงียบใน VO < 12% ของความยาว
- [ ] SFX 6–8 ก้อน วางที่ **กราฟิกเข้า** ไม่ใช่ที่คัต
- [ ] SFX หลักมี sub 60–80 Hz + noise sweep 2–8 kHz
- [ ] Master −14 LUFS, LRA 3–5 LU, **True peak ≤ −1.5 dBTP** (อย่าไป −0.7 แบบต้นฉบับ)
- [ ] ส่งโมโนได้ถ้ากลุ่มเป้าหมายดูบนมือถือ
- [ ] มีซับ — ต้นฉบับไม่มี และนั่นคือจุดอ่อนของมัน
- [ ] รันตัววิเคราะห์กับงานตัวเอง แล้วเทียบตัวเลขกับ reference

ค่าอ้างอิงที่วัดมาแล้วจากคลิปโฆษณาไทยที่ทำได้ดี อยู่ในความทรงจำ `ref-reel-ad-anatomy`

---

## 6. Gotchas ที่จ่ายค่าเรียนไปแล้ว

1. **`-v error` ฆ่า `showinfo`/`ebur128`** — filter พวกนี้ log ที่ระดับ info ถ้าจะอ่าน output ใช้ `-hide_banner` อย่างเดียว ห้ามใส่ `-v error`

2. **`metadata=print:file=...` ไม่ยอมเขียนไฟล์บนเครื่องนี้** — อย่าเสียเวลา ให้ dump raw frame แล้ววิเคราะห์ด้วย numpy แทน (เร็วกว่าและยืดหยุ่นกว่ามาก)

3. **อย่าไปป์ output ของ whisper ผ่าน `tail -N` ใน background task** — มันตัดหัวทิ้ง ได้บทมาแค่ท้ายคลิป **เขียนลงไฟล์แล้วค่อย grep**

4. **Bash tool รีเซ็ต cwd ทุกครั้ง** — ใช้ absolute path เสมอ อย่าพึ่ง `cd` ค้าง

5. **แยกคัตจริงจากภาพเคลื่อนไหวเร็ว** — threshold เฉยๆ ไม่พอ กราฟิกวิ่งเข้าให้ค่า frame-diff 12–18 ติดกันยาว ส่วนคัตจริงคือ spike โดดเดี่ยวที่สูงกว่าเพื่อนบ้าน ≥2 เท่า

6. **Framing-drift proxy หลอกได้** — มือ/ป้ายเข้า-ออกเฟรมทำให้ตัวเลขเหมือนซูม ต้องเปิด contact sheet ดูก่อนสรุป

7. **HE-AAC / bitrate ต่ำ = ไฟล์จากแพลตฟอร์ม ไม่ใช่มาสเตอร์** — ย่านสูง >10 kHz เป็น SBR สังเคราะห์ อย่าเคลมเรื่องคุณภาพย่านสูง

8. **BGM ที่ "ได้ยิน" มักไม่มีจริง** — ต้องดู 3 ค่าคู่กัน: ระดับ bed ย่าน 300 Hz–8 kHz, correlation กับ envelope ของ VO, และ beat autocorrelation ค่าเดียวตัดสินไม่ได้

9. **ห้าม `shell=True`** ในสคริปต์ที่รับ path จากผู้ใช้ — ใช้ argv list

10. **`librosa` ไม่มีบนเครื่องนี้** — scipy `welch`/`stft`/`hilbert`/`find_peaks` ทำได้หมด

