Douyin Dub — Playbook (input = 1 link Douyin)
Biến 1 clip Douyin (tiếng Trung) thành clip lồng giọng AI tiếng Việt khớp giây, giữ nguyên
hình + tiếng nền (nhai/ồn quán "thở" ở khoảng lặng). Máy lo phần cơ học (tải, bóc lời, TTS, ráp,
tự chấm độ khớp); BẠN (Claude) lo phần đầu: dịch thời thượng + phân giọng + vá câu lệch.
link ──dl.py──▶ video.mp4
video ──dub.py transcribe──▶ segs.json {start,end,zh,spk,vi:""} (Whisper large-v3, zh)
segs.json ──[CLAUDE điền tay]──▶ segs_vi.json (vi thời thượng + spk đúng) ◀── KHÂU QUAN TRỌNG NHẤT
segs_vi.json ──dub.py render --no-voice──▶ pre-duck.mp4 + 3 SRT (gộp/.A/.B) + "📊 KHỚP %"
pre-duck.mp4 ──caption.py──▶ *_cap.mp4 (hộp vàng lời Việt + CHE phụ đề Trung)
*_cap.mp4 ──ffmpeg che-góc (5b)──▶ final.mp4 (che nốt cột chữ Trung góc phải) ◀── OUTPUT MẶC ĐỊNH
GIAO: final.mp4 (KHÔNG giọng AI) + 3 SRT → user tự lồng giọng AI trong CapCut
MẶC ĐỊNH: LUÔN ra final.mp4 (caption che, KHÔNG giọng) + 3 SRT. Giọng AI để user làm ở CapCut. Đừng tự lồng edge-tts trừ khi user yêu cầu.
Đường dẫn (cố định)
- Code skill:
~/.claude/skills/douyin-dub/ (dub.py, dl.py, caption.py, setup.sh)
- Runtime (dùng chung với douyin-reup):
~/DouyinReup/
engine/douyin-downloader/ + cookies.json — do douyin-reup/install.sh dựng. Cookie hết hạn → gõ "refresh cookies" trong Claude Desktop, hoặc engine/.venv/bin/python -m tools.cookie_fetcher --output ~/DouyinReup/cookies.json.
.dubvenv/ — venv dub (tạo bằng setup.sh). Ký hiệu PY=~/DouyinReup/.dubvenv/bin/python.
dub/<id>/ — thư mục làm việc mỗi clip.
Setup (1 lần)
bash ~/.claude/skills/douyin-dub/setup.sh
Cài dub venv: faster-whisper, edge-tts, pydub, audioop-lts, yt-dlp + easyocr (cho caption — kéo theo torch ~2GB).
Cần sẵn ~/DouyinReup/engine + cookies.json (chạy douyin-reup/install.sh nếu chưa có).
Model Whisper large-v3 (~3GB) tải ở lần transcribe đầu; model easyocr (~100MB) tải ở lần caption đầu (cache lại sau).
Quy trình (mỗi link) — dùng PY và SK=~/.claude/skills/douyin-dub
- Tải:
ID=$(basename <link> | grep -oE '[0-9]{6,}' | head -1) (hoặc tự đặt); D=~/DouyinReup/dub/$ID
"$PY" "$SK/dl.py" "<link>" "$D" → $D/video.mp4.
- Bóc lời:
"$PY" "$SK/dub.py" transcribe "$D/video.mp4" → $D/segs.json (mặc định --model large-v3).
- DỊCH + PHÂN GIỌNG (BẠN làm tay): đọc
segs.json, viết file patch điền vi (thời thượng) + sửa spk, xuất $D/segs_vi.json.
→ SOI KHUNG HÌNH TRƯỚC (ffmpeg -ss T -frames:v 1) tại các câu hội thoại để biết ai nói với ai (nam/nữ, già/trẻ) → chọn xưng hô + phân giọng cho đúng. Xem mục XƯNG HÔ + 2 mục dưới.
- Render pre-duck + 3 SRT (MẶC ĐỊNH — KHÔNG lồng giọng):
"$PY" "$SK/dub.py" render "$D/video.mp4" --segs "$D/segs_vi.json" --sidechain --fit-cap 1.5 --no-voice --out dubbed.mp4
→ video pre-duck (tiếng gốc tự nhỏ lúc có lời, to lại lúc im — KHÔNG trộn edge-tts) + 3 SRT: dubbed.srt (gộp) + dubbed.A.srt (nhân vật chính) + dubbed.B.srt (phụ).
In 📊 KHỚP % — câu nào chồng giọng (over_next>0.15) thì rút gọn câu đó trong segs_vi.json → render lại (TTS cache nên nhanh). Lặp tới ~95%+.
- BURN CAPTION + CHE chữ Trung (MẶC ĐỊNH):
"$PY" "$SK/caption.py" "$D/dubbed.mp4" "$D/segs_vi.json" "$D/final_cap.mp4" (→ bước 5b che góc ra final.mp4)
→ burn hộp vàng lời Việt đè + che chữ Trung gốc (mosaic bám từng khung). Chạy TRÊN video pre-duck (bước 4) → clip cuối vừa che vừa có caption. Xem mục CAPTION.
⚠️ Render mosaic-từng-vùng CHẬM ~40–50 phút/clip 6 phút — đúng look user CHỐT; ĐỪNG đổi sang mask/blur-mạnh/pixelate-toàn-khung (user đã chê "xấu"). Track OCR cache ở <out>.track.json.
- TÁI DÙNG CACHE OCR khi render lại: chỉ sửa chữ (vd xưng hô) →
cp <out_cũ>.track.json <out_mới>.track.json rồi chạy caption.py với out mới → bỏ qua OCR ~40 phút, chỉ burn lại (~5–10 phút). Pixel video giống nhau nên cache còn đúng.
5b. CHE cột disclaimer chữ Trung dọc GÓC PHẢI (kênh này LUÔN có dòng dọc 视频内食物均已吃完拒绝浪费… ở góc phải trên — cố định, safety-net canh-giữa không phủ). Chạy 1 pass mosaic-góc SAU caption:
ffmpeg -i final_cap.mp4 -filter_complex "[0:v]crop=170:560:910:0,scale=iw/16:ih/16,scale=170:560:flags=neighbor[m];[0:v][m]overlay=910:0[v]" -map "[v]" -map 0:a -c:v libx264 -crf 18 -preset veryfast -pix_fmt yuv420p -c:a copy final.mp4
- GIAO (MẶC ĐỊNH): copy ra
~/Downloads/: final.mp4 (caption che + pre-duck, KHÔNG giọng AI) + 3 SRT. → User tự lên CapCut lồng giọng AI (TTS: track chính = .A.srt, track phụ = .B.srt; hoặc 1 giọng = bản gộp).
- (Hiếm khi) Muốn dub sẵn edge-tts: bước 4 bỏ
--no-voice → dubbed.mp4 có giọng (máy hơn CapCut).
CAPTION — burn hộp vàng + che chữ Trung (caption.py)
Kênh này phụ đề Trung nhảy vị trí lung tung (y 0.4→0.95, có câu ở giữa khung) → không thể đặt cố định. Giải pháp 2 LỚP (đã chốt với user):
- Lớp CHE (mosaic) bám từng khung = lưới an toàn: OCR (easyocr) dò vị trí chữ Trung mỗi ~0.33s → mosaic bám theo, che mọi lúc (kể cả lúc chuyển câu / caption đặt hụt → không bao giờ lòi chữ Trung).
- Lớp CAPTION (hộp vàng chữ đen bo góc) đè lên, đặt ở median vị trí chữ Trung.
- Lọc để chỉ nhận phụ đề: canh giữa (cx 0.36–0.64) + dẹt ngang (w/h≥1.15) + đúng vùng → loại chữ trên đồ ăn/tường/menu.
- Timing: kéo dài tới khi chữ Trung biến mất thật (bám tracking), cắt trước câu kế → hết sót đuôi.
- CHẠY XONG PHẢI TỰ SOI: chụp vài khung (
ffmpeg -ss T -i out.mp4 -frames:v 1 shot.jpg) rồi Read đánh giá — user yêu cầu bước này.
- Chỉnh style trong
caption.py: YELLOW, FS (font size), PADX/PADY/RAD (đệm/bo). Hộp ôm sát chữ Việt (đừng phình theo chữ Trung — user ghét hộp to).
- Giới hạn còn lại (đã báo user, chấp nhận): cột disclaimer góc phải → xử bằng pass che-góc (bước 5b); sticker/caption ĐỘNG giữa khung (vd "您说", "已傻眼") + chữ trên màn LED/bảng trong bối cảnh quán (vd "可以啊") vẫn lòi — safety-net đáy+góc không phủ, báo user, đừng tự che (che vùng động rất nặng); nặng+chậm (easyocr full clip ~10–15 phút).
- Dịch theo nghĩa + cảm xúc, giọng đời/trend TikTok VN. Giữ năng lượng nhân vật (hype, cảm thán).
- ⚠️ ĐỪNG DỊCH "AN TOÀN"/SÁCH VỞ (user chốt): teen Việt xài luôn từ mượn/lóng → phải TRENDY, không dịch phẳng.
- 帥哥 = "soái ca" (KHÔNG dịch "đẹp trai"/"anh đẹp trai" — mất chất). Teen Việt dùng "soái ca" thật.
不爽 (khó chịu/nhìn ghét) = "ngứa mắt" (không dịch "khó ưa" cho lành).
炫/炫饭 (ăn ngấu nghiến kiểu mukbang) = "quất / đớp / chiến".
牛(giỏi/đỉnh) = "đỉnh nóc / đỉnh nóc kịch trần"; 年糕殺手 = "chiến thần bánh gạo".
- Cảm thán phải ĐA DẠNG, đừng lặp 1 từ: luân phiên "Oáa / U là trời / Ối dồi ôi / Trời đất ơi / Mèn ơi / Xỉu". Đừng để "u là trời" xuất hiện 6 lần.
- GIỮ CÂU VỤN (cảm thán "Oáa", "Trời ơi", "Măm") cho tự nhiên — đừng bỏ hết (đã test: giữ vụn nghe đời hơn). Chỉ bỏ nếu user yêu cầu bản "thưa".
- Câu quá dài so với khe thời gian → viết ngắn/punchy (eval sẽ báo câu nào cần rút).
- Từ lóng chuẩn (clone từ kênh reup đối thủ — nên xài):
đớp = ăn · thánh đớp / chiến thần = thánh ăn · phê = ngon/đã · chốt món/chốt đơn
biến thứ 2 = màn/lượt 2 · xỉu ngang, xỉu up xỉu down · cháy túi = tốn tiền
dữ thần / dữ dội / xịn sò, tẹt ga, nức nở, u là trời, chuẩn bài
soái ca, ngứa mắt, quất, đỉnh nóc, ngon nhức nách, ăn là ghiền, cuốn, flex nhẹ
- ⚠️ Dùng vừa tay — nhồi slang quá đà thành cringe. Ưu tiên tự nhiên, punchy, đúng cảm xúc.
- KHÔNG bịa số liệu/nội dung. Whisper large-v3 vẫn nhoè vài câu ở audio ồn → đoán theo NGỮ CẢNH + hình, và nói rõ với user chỗ nào mình suy đoán.
XƯNG HÔ (anh/chị/em) — SOI KHUNG trước khi dịch (user CHỐT)
Đại từ xưng hô phải đúng vai, đừng dịch phẳng "tôi/anh". Trước khi điền vi, TRÍCH KHUNG HÌNH (ffmpeg -ss T -frames:v 1) tại các câu hội thoại để nhìn mặt người đối diện (nam/nữ, già/trẻ so với nhân vật chính) rồi mới chọn:
- Nói với KHÁN GIẢ (cả nhà ơi / các bạn / anh em / 兄弟们/家人们) → nhân vật chính TỰ XƯNG "tui" (hoặc "mình"), KHÔNG dùng "anh". (vd 家人们…我千古罪 → "Không thì tui mang tội thiên cổ mất!"). Gọi khán giả: "anh em / cả nhà / các sếp (爸爸们)".
- Nói với MỘT NGƯỜI cụ thể trong khung → theo tuổi+giới: nhỏ tuổi hơn → "em"; lớn hơn nam → "anh", nữ → "chị"; tự xưng ngược lại. (vd a Phong→nhân viên nữ trẻ: "Anh đưa em 2000 tệ"; cô lớn tuổi→a Phong: "Cái gì vậy em?").
- Nhân viên phục vụ → khách (nhân vật chính): "anh/chị" + "dạ/ạ" lễ phép.
- Không chắc giới/tuổi người đối diện → soi thêm khung; nữ trưởng thành mà lưỡng lự → "chị" an toàn hơn "em".
- Clip độc thoại mukbang (như clip anh gym): gần như chỉ 1 giọng A nói với khán giả → dùng "tui" xuyên suốt, 1 file SRT là đủ. Đừng bịa nhân vật phụ.
- Gen lại bản đã giao → TẠO FILE MỚI (segs_vi2/make_vi2/final_v2…), đừng ghi đè bản cũ trừ khi user bảo không cần giữ.
PHÂN GIỌNG (spk) — nhân vật chính phải NHẤT QUÁN
VOICE_MAP trong dub.py (VN edge-tts chỉ 2 giọng → phân biệt thêm bằng pitch):
| spk |
ai |
giọng |
| A |
nhân vật chính (vd a Phong) — CỐ ĐỊNH |
NamMinh, +8%, +3Hz (nam, năng lượng cao) |
| B |
nữ (nhân viên/khách nữ) |
HoaiMy +5% |
| C |
nam khác |
NamMinh pitch thấp -8Hz |
| D |
nữ khác |
HoaiMy -6Hz |
- Tự phân giọng theo NỘI DUNG hội thoại, đừng tin diarize tự động (audio quán ồn → hay gộp sai). Nhân vật chính = A xuyên suốt; câu của nhân viên/khách = B/C/D.
- Muốn đổi tông nhân vật chính → sửa dòng
"A" trong VOICE_MAP (dub.py). User đã chốt: giọng nhanh (+8%) nghe hay hơn.
- ⚠️ ĐỪNG pitch-hack edge-tts mạnh (đẩy/hạ pitch ±40Hz+ để đổi tông/giả giọng khác) → nghe méo, dở tệ. edge-tts chỉ hay khi để giọng tự nhiên. Muốn chất giọng "xịn" như kênh reup VN (nữ sáng ~180Hz) → dùng CapCut TTS (
--no-voice route) hoặc tích hợp FPT.AI Ban Mai / Vbee (cần API key). Kênh đối thủ dùng 2 giọng NỮ (chính ~180Hz + phụ ~235Hz), không phải giọng nam.
Cơ chế KHỚP (đã tinh chỉnh — đừng phá)
- Neo mỗi câu đúng
start gốc. Câu tràn sang câu kế → ép nhanh GIỮ NGUYÊN cao độ (atempo) tối đa --fit-cap (mặc định 1.5; atempo nên KHÔNG chipmunk như đổi frame-rate). Tràn xa quá → rút chữ.
_trim: cắt IM đầu/cuối mỗi clip TTS (edge-tts hay chèn 0.3–0.6s → câu 2 chữ mà dài 1.4s). Đây là đòn tăng khớp mạnh nhất (50%→93%).
--sidechain (duck ĐỘNG): lúc có giọng Việt → nén tiếng gốc; lúc IM → tiếng gốc tự nổi lên (nhai/ồn quán thở). Tự nhiên hơn hẳn duck cố định 12%.
- Eval:
over_next = phần tràn sang câu kế (>0.15s = chồng giọng, LỖI thật). over_act (tràn khỏi khe cảnh gốc) phần lớn là nhiễu — bỏ qua nếu không chồng câu kế.
- Cache TTS:
~/DouyinReup/dub/<id>/.tts_cache/ (md5 theo text+giọng). Sửa 1 câu → render lại chỉ đọc lại câu đó.
Bài học nhịp (từ phân tích kênh đối thủ reup cùng nhân vật)
- Đối thủ chỉ nói ~45% thời lượng, im 55% (để tiếng ăn/ồn quán thở). Đừng dub dày đặc — sidechain + giữ khoảng lặng làm việc này.
- Clip mukbang dài (6 phút) full-dub kiểu gì cũng dày → nếu user muốn "thưa" có thể (a) bỏ câu vụn, (b) cắt ngắn còn ~3 phút.
Che chữ Trung / watermark
- Phụ đề Trung cháy hình: dùng
caption.py (mục CAPTION ở trên) — vừa che vừa burn lời Việt.
- Watermark/@ID Douyin (nếu có): dùng MCP douyin-reup (
remove_watermark). Clip a Phong đa số KHÔNG có watermark, chỉ có phụ đề.
Thành thật (nói với user)
- Reup + dub khó kiếm tiền bền trên FB/TikTok (nền tảng phạt nội dung tái sử dụng; RPM VN thấp) — làm để TEST là chính.
- Whisper sai vài câu ở audio ồn → mình làm mượt theo ngữ cảnh (báo user).
- Xám pháp lý (bản quyền + ToS) là rủi ro của người vận hành.
Lệnh nhanh (copy-paste)
PY=~/DouyinReup/.dubvenv/bin/python ; SK=~/.claude/skills/douyin-dub
D=~/DouyinReup/dub/CLIP1 ; mkdir -p "$D"
"$PY" "$SK/dl.py" "<LINK_DOUYIN>" "$D" # -> $D/video.mp4
"$PY" "$SK/dub.py" transcribe "$D/video.mp4" # -> $D/segs.json (Claude điền -> segs_vi.json)
"$PY" "$SK/dub.py" render "$D/video.mp4" --segs "$D/segs_vi.json" --sidechain --fit-cap 1.5 --out dubbed.mp4
# HOẶC cho CapCut (giọng đẹp hơn): thêm --no-voice -> ra dubbed.srt + video pre-duck (chồng TTS CapCut lên)
"$PY" "$SK/dub.py" render "$D/video.mp4" --segs "$D/segs_vi.json" --sidechain --fit-cap 1.5 --no-voice --out capcut.mp4
1---2name: douyin-dub3description: Reup video Douyin sang tiếng Việt bằng giọng AI, KHỚP GIÂY (dub-over), giữ giọng nhân vật nhất quán + phân biệt nhiều giọng. Dùng khi user dán LINK DOUYIN và muốn "dub / lồng tiếng Việt / reup lên Facebook/TikTok" (đặc biệt kênh ăn uống kiểu a Phong 邓炫疯疯). Input = 1 link Douyin.4---56# Douyin Dub — Playbook (input = 1 link Douyin)78Biến 1 clip Douyin (tiếng Trung) thành clip **lồng giọng AI tiếng Việt khớp giây**, giữ nguyên9hình + tiếng nền (nhai/ồn quán "thở" ở khoảng lặng). Máy lo phần cơ học (tải, bóc lời, TTS, ráp,10**tự chấm độ khớp**); **BẠN (Claude) lo phần đầu**: dịch thời thượng + phân giọng + vá câu lệch.1112```13link ──dl.py──▶ video.mp414video ──dub.py transcribe──▶ segs.json {start,end,zh,spk,vi:""} (Whisper large-v3, zh)15segs.json ──[CLAUDE điền tay]──▶ segs_vi.json (vi thời thượng + spk đúng) ◀── KHÂU QUAN TRỌNG NHẤT16segs_vi.json ──dub.py render --no-voice──▶ pre-duck.mp4 + 3 SRT (gộp/.A/.B) + "📊 KHỚP %"17pre-duck.mp4 ──caption.py──▶ *_cap.mp4 (hộp vàng lời Việt + CHE phụ đề Trung)18*_cap.mp4 ──ffmpeg che-góc (5b)──▶ final.mp4 (che nốt cột chữ Trung góc phải) ◀── OUTPUT MẶC ĐỊNH19GIAO: final.mp4 (KHÔNG giọng AI) + 3 SRT → user tự lồng giọng AI trong CapCut20```21**MẶC ĐỊNH: LUÔN ra `final.mp4` (caption che, KHÔNG giọng) + 3 SRT.** Giọng AI để user làm ở CapCut. Đừng tự lồng edge-tts trừ khi user yêu cầu.2223## Đường dẫn (cố định)24- Code skill: `~/.claude/skills/douyin-dub/` (`dub.py`, `dl.py`, `caption.py`, `setup.sh`)25- Runtime (dùng chung với douyin-reup): `~/DouyinReup/`26 - `engine/douyin-downloader/` + `cookies.json` — **do douyin-reup/install.sh dựng**. Cookie hết hạn → gõ "refresh cookies" trong Claude Desktop, hoặc `engine/.venv/bin/python -m tools.cookie_fetcher --output ~/DouyinReup/cookies.json`.27 - `.dubvenv/` — venv dub (tạo bằng `setup.sh`). Ký hiệu **PY=`~/DouyinReup/.dubvenv/bin/python`**.28 - `dub/<id>/` — thư mục làm việc mỗi clip.2930## Setup (1 lần)31```bash32bash ~/.claude/skills/douyin-dub/setup.sh33```34Cài dub venv: faster-whisper, edge-tts, pydub, audioop-lts, yt-dlp + **easyocr (cho caption — kéo theo torch ~2GB)**.35Cần sẵn `~/DouyinReup/engine` + `cookies.json` (chạy `douyin-reup/install.sh` nếu chưa có).36**Model Whisper large-v3 (~3GB) tải ở lần transcribe đầu**; **model easyocr (~100MB) tải ở lần caption đầu** (cache lại sau).3738## Quy trình (mỗi link) — dùng PY và SK=`~/.claude/skills/douyin-dub`391. **Tải:** `ID=$(basename <link> | grep -oE '[0-9]{6,}' | head -1)` (hoặc tự đặt); `D=~/DouyinReup/dub/$ID`40 `"$PY" "$SK/dl.py" "<link>" "$D"` → `$D/video.mp4`.412. **Bóc lời:** `"$PY" "$SK/dub.py" transcribe "$D/video.mp4"` → `$D/segs.json` (mặc định `--model large-v3`).423. **DỊCH + PHÂN GIỌNG (BẠN làm tay):** đọc `segs.json`, viết file patch điền `vi` (thời thượng) + sửa `spk`, xuất `$D/segs_vi.json`.43 → **SOI KHUNG HÌNH TRƯỚC** (`ffmpeg -ss T -frames:v 1`) tại các câu hội thoại để biết ai nói với ai (nam/nữ, già/trẻ) → chọn xưng hô + phân giọng cho đúng. Xem mục **XƯNG HÔ** + 2 mục dưới.444. **Render pre-duck + 3 SRT (MẶC ĐỊNH — KHÔNG lồng giọng):**45 `"$PY" "$SK/dub.py" render "$D/video.mp4" --segs "$D/segs_vi.json" --sidechain --fit-cap 1.5 --no-voice --out dubbed.mp4`46 → **video pre-duck** (tiếng gốc tự nhỏ lúc có lời, to lại lúc im — KHÔNG trộn edge-tts) + **3 SRT**: `dubbed.srt` (gộp) + `dubbed.A.srt` (nhân vật chính) + `dubbed.B.srt` (phụ).47 In `📊 KHỚP %` — câu nào chồng giọng (`over_next>0.15`) thì **rút gọn câu đó** trong segs_vi.json → render lại (TTS cache nên nhanh). Lặp tới ~95%+.485. **BURN CAPTION + CHE chữ Trung (MẶC ĐỊNH):** `"$PY" "$SK/caption.py" "$D/dubbed.mp4" "$D/segs_vi.json" "$D/final_cap.mp4"` (→ bước 5b che góc ra `final.mp4`)49 → burn **hộp vàng lời Việt** đè + **che chữ Trung gốc** (mosaic bám từng khung). Chạy TRÊN video pre-duck (bước 4) → clip cuối vừa che vừa có caption. Xem mục CAPTION.50 ⚠️ Render mosaic-từng-vùng **CHẬM ~40–50 phút/clip 6 phút** — đúng look user CHỐT; **ĐỪNG đổi sang mask/blur-mạnh/pixelate-toàn-khung** (user đã chê "xấu"). Track OCR cache ở `<out>.track.json`.51 - **TÁI DÙNG CACHE OCR khi render lại:** chỉ sửa chữ (vd xưng hô) → `cp <out_cũ>.track.json <out_mới>.track.json` rồi chạy caption.py với out mới → **bỏ qua OCR ~40 phút**, chỉ burn lại (~5–10 phút). Pixel video giống nhau nên cache còn đúng.525b. **CHE cột disclaimer chữ Trung dọc GÓC PHẢI** (kênh này LUÔN có dòng dọc `视频内食物均已吃完拒绝浪费…` ở góc phải trên — cố định, safety-net canh-giữa không phủ). Chạy 1 pass mosaic-góc SAU caption:53 ```54 ffmpeg -i final_cap.mp4 -filter_complex "[0:v]crop=170:560:910:0,scale=iw/16:ih/16,scale=170:560:flags=neighbor[m];[0:v][m]overlay=910:0[v]" -map "[v]" -map 0:a -c:v libx264 -crf 18 -preset veryfast -pix_fmt yuv420p -c:a copy final.mp455 ```566. **GIAO (MẶC ĐỊNH):** copy ra `~/Downloads/`: **`final.mp4`** (caption che + pre-duck, **KHÔNG giọng AI**) + **3 SRT**. → User tự lên **CapCut lồng giọng AI** (TTS: track chính = `.A.srt`, track phụ = `.B.srt`; hoặc 1 giọng = bản gộp).57 - *(Hiếm khi)* Muốn dub sẵn edge-tts: bước 4 bỏ `--no-voice` → `dubbed.mp4` có giọng (máy hơn CapCut).5859## CAPTION — burn hộp vàng + che chữ Trung (caption.py)60Kênh này **phụ đề Trung nhảy vị trí lung tung** (y 0.4→0.95, có câu ở giữa khung) → không thể đặt cố định. Giải pháp **2 LỚP** (đã chốt với user):61- **Lớp CHE (mosaic) bám từng khung** = *lưới an toàn*: OCR (easyocr) dò vị trí chữ Trung mỗi ~0.33s → mosaic bám theo, che **mọi lúc** (kể cả lúc chuyển câu / caption đặt hụt → **không bao giờ lòi chữ Trung**).62- **Lớp CAPTION (hộp vàng chữ đen bo góc)** đè lên, đặt ở **median** vị trí chữ Trung.63- Lọc để chỉ nhận phụ đề: **canh giữa** (cx 0.36–0.64) + **dẹt ngang** (w/h≥1.15) + đúng vùng → loại chữ trên đồ ăn/tường/menu.64- Timing: kéo dài tới khi chữ Trung **biến mất thật** (bám tracking), cắt trước câu kế → hết sót đuôi.65- **CHẠY XONG PHẢI TỰ SOI:** chụp vài khung (`ffmpeg -ss T -i out.mp4 -frames:v 1 shot.jpg`) rồi Read đánh giá — user yêu cầu bước này.66- Chỉnh style trong `caption.py`: `YELLOW`, `FS` (font size), `PADX/PADY/RAD` (đệm/bo). Hộp **ôm sát chữ Việt** (đừng phình theo chữ Trung — user ghét hộp to).67- Giới hạn còn lại (đã báo user, chấp nhận): cột disclaimer góc phải → xử bằng pass che-góc (bước 5b); **sticker/caption ĐỘNG giữa khung** (vd "您说", "已傻眼") + **chữ trên màn LED/bảng trong bối cảnh quán** (vd "可以啊") vẫn lòi — safety-net đáy+góc không phủ, **báo user, đừng tự che** (che vùng động rất nặng); nặng+chậm (easyocr full clip ~10–15 phút).68- Dịch theo **nghĩa + cảm xúc**, giọng đời/trend TikTok VN. Giữ **năng lượng** nhân vật (hype, cảm thán).69- ⚠️ **ĐỪNG DỊCH "AN TOÀN"/SÁCH VỞ** (user chốt): teen Việt xài luôn từ mượn/lóng → phải TRENDY, không dịch phẳng.70 - **帥哥 = "soái ca"** (KHÔNG dịch "đẹp trai"/"anh đẹp trai" — mất chất). Teen Việt dùng "soái ca" thật.71 - `不爽` (khó chịu/nhìn ghét) = **"ngứa mắt"** (không dịch "khó ưa" cho lành).72 - `炫`/`炫饭` (ăn ngấu nghiến kiểu mukbang) = **"quất / đớp / chiến"**.73 - `牛`(giỏi/đỉnh) = **"đỉnh nóc / đỉnh nóc kịch trần"**; `年糕殺手` = **"chiến thần bánh gạo"**.74- **Cảm thán phải ĐA DẠNG, đừng lặp 1 từ:** luân phiên "Oáa / U là trời / Ối dồi ôi / Trời đất ơi / Mèn ơi / Xỉu". Đừng để "u là trời" xuất hiện 6 lần.75- **GIỮ CÂU VỤN** (cảm thán "Oáa", "Trời ơi", "Măm") cho tự nhiên — đừng bỏ hết (đã test: giữ vụn nghe đời hơn). Chỉ bỏ nếu user yêu cầu bản "thưa".76- Câu quá dài so với khe thời gian → viết **ngắn/punchy** (eval sẽ báo câu nào cần rút).77- **Từ lóng chuẩn (clone từ kênh reup đối thủ — nên xài):**78 - `đớp` = ăn · `thánh đớp / chiến thần` = thánh ăn · `phê` = ngon/đã · `chốt món/chốt đơn`79 - `biến thứ 2` = màn/lượt 2 · `xỉu ngang`, `xỉu up xỉu down` · `cháy túi` = tốn tiền80 - `dữ thần / dữ dội / xịn sò`, `tẹt ga`, `nức nở`, `u là trời`, `chuẩn bài`81 - `soái ca`, `ngứa mắt`, `quất`, `đỉnh nóc`, `ngon nhức nách`, `ăn là ghiền`, `cuốn`, `flex nhẹ`82 - ⚠️ Dùng vừa tay — nhồi slang quá đà thành **cringe**. Ưu tiên tự nhiên, punchy, đúng cảm xúc.83- **KHÔNG bịa số liệu/nội dung.** Whisper large-v3 vẫn nhoè vài câu ở audio ồn → đoán theo NGỮ CẢNH + hình, và nói rõ với user chỗ nào mình suy đoán.8485## XƯNG HÔ (anh/chị/em) — SOI KHUNG trước khi dịch (user CHỐT)86Đại từ xưng hô phải đúng vai, đừng dịch phẳng "tôi/anh". **Trước khi điền `vi`, TRÍCH KHUNG HÌNH** (`ffmpeg -ss T -frames:v 1`) tại các câu hội thoại để nhìn mặt người đối diện (nam/nữ, già/trẻ so với nhân vật chính) rồi mới chọn:87- **Nói với KHÁN GIẢ** (cả nhà ơi / các bạn / anh em / 兄弟们/家人们) → nhân vật chính TỰ XƯNG **"tui"** (hoặc "mình"), **KHÔNG dùng "anh"**. (vd 家人们…我千古罪 → "Không thì **tui** mang tội thiên cổ mất!"). Gọi khán giả: "anh em / cả nhà / các sếp (爸爸们)".88- **Nói với MỘT NGƯỜI cụ thể trong khung** → theo tuổi+giới: nhỏ tuổi hơn → **"em"**; lớn hơn nam → **"anh"**, nữ → **"chị"**; tự xưng ngược lại. (vd a Phong→nhân viên nữ trẻ: "Anh đưa **em** 2000 tệ"; cô lớn tuổi→a Phong: "Cái gì vậy **em**?").89- **Nhân viên phục vụ → khách** (nhân vật chính): "anh/chị" + "dạ/ạ" lễ phép.90- Không chắc giới/tuổi người đối diện → soi thêm khung; nữ trưởng thành mà lưỡng lự → "chị" an toàn hơn "em".91- **Clip độc thoại mukbang** (như clip anh gym): gần như chỉ 1 giọng A nói với khán giả → dùng "tui" xuyên suốt, 1 file SRT là đủ. Đừng bịa nhân vật phụ.92- **Gen lại bản đã giao** → TẠO FILE MỚI (segs_vi2/make_vi2/final_v2…), đừng ghi đè bản cũ trừ khi user bảo không cần giữ.9394## PHÂN GIỌNG (spk) — nhân vật chính phải NHẤT QUÁN95`VOICE_MAP` trong dub.py (VN edge-tts chỉ 2 giọng → phân biệt thêm bằng pitch):96| spk | ai | giọng |97|---|---|---|98| **A** | **nhân vật chính (vd a Phong) — CỐ ĐỊNH** | NamMinh, `+8%`, `+3Hz` (nam, năng lượng cao) |99| B | nữ (nhân viên/khách nữ) | HoaiMy `+5%` |100| C | nam khác | NamMinh pitch thấp `-8Hz` |101| D | nữ khác | HoaiMy `-6Hz` |102- **Tự phân giọng theo NỘI DUNG hội thoại**, đừng tin diarize tự động (audio quán ồn → hay gộp sai). Nhân vật chính = A xuyên suốt; câu của nhân viên/khách = B/C/D.103- Muốn đổi tông nhân vật chính → sửa dòng `"A"` trong `VOICE_MAP` (dub.py). User đã chốt: **giọng nhanh (`+8%`) nghe hay hơn**.104- ⚠️ **ĐỪNG pitch-hack edge-tts mạnh** (đẩy/hạ pitch ±40Hz+ để đổi tông/giả giọng khác) → nghe **méo, dở tệ**. edge-tts chỉ hay khi để giọng tự nhiên. Muốn chất giọng "xịn" như kênh reup VN (nữ sáng ~180Hz) → dùng **CapCut TTS** (`--no-voice` route) hoặc tích hợp **FPT.AI Ban Mai / Vbee** (cần API key). Kênh đối thủ dùng **2 giọng NỮ** (chính ~180Hz + phụ ~235Hz), không phải giọng nam.105106## Cơ chế KHỚP (đã tinh chỉnh — đừng phá)107- **Neo mỗi câu đúng `start` gốc.** Câu tràn sang câu kế → **ép nhanh GIỮ NGUYÊN cao độ (atempo)** tối đa `--fit-cap` (mặc định **1.5**; atempo nên KHÔNG chipmunk như đổi frame-rate). Tràn xa quá → rút chữ.108- **`_trim`:** cắt IM đầu/cuối mỗi clip TTS (edge-tts hay chèn 0.3–0.6s → câu 2 chữ mà dài 1.4s). **Đây là đòn tăng khớp mạnh nhất** (50%→93%).109- **`--sidechain` (duck ĐỘNG):** lúc có giọng Việt → nén tiếng gốc; lúc IM → **tiếng gốc tự nổi lên** (nhai/ồn quán thở). Tự nhiên hơn hẳn duck cố định 12%.110- **Eval:** `over_next` = phần tràn sang câu kế (>0.15s = chồng giọng, LỖI thật). `over_act` (tràn khỏi khe cảnh gốc) phần lớn là nhiễu — bỏ qua nếu không chồng câu kế.111- Cache TTS: `~/DouyinReup/dub/<id>/.tts_cache/` (md5 theo text+giọng). Sửa 1 câu → render lại chỉ đọc lại câu đó.112113## Bài học nhịp (từ phân tích kênh đối thủ reup cùng nhân vật)114- Đối thủ chỉ **nói ~45% thời lượng**, im 55% (để tiếng ăn/ồn quán thở). **Đừng dub dày đặc** — sidechain + giữ khoảng lặng làm việc này.115- Clip mukbang dài (6 phút) full-dub kiểu gì cũng dày → nếu user muốn "thưa" có thể (a) bỏ câu vụn, (b) cắt ngắn còn ~3 phút.116117## Che chữ Trung / watermark118- **Phụ đề Trung cháy hình:** dùng `caption.py` (mục CAPTION ở trên) — vừa che vừa burn lời Việt.119- **Watermark/@ID Douyin** (nếu có): dùng MCP **douyin-reup** (`remove_watermark`). Clip a Phong đa số KHÔNG có watermark, chỉ có phụ đề.120121## Thành thật (nói với user)122- Reup + dub **khó kiếm tiền bền** trên FB/TikTok (nền tảng phạt nội dung tái sử dụng; RPM VN thấp) — làm để TEST là chính.123- Whisper sai vài câu ở audio ồn → mình làm mượt theo ngữ cảnh (báo user).124- Xám pháp lý (bản quyền + ToS) là rủi ro của người vận hành.125126## Lệnh nhanh (copy-paste)127```bash128PY=~/DouyinReup/.dubvenv/bin/python ; SK=~/.claude/skills/douyin-dub129D=~/DouyinReup/dub/CLIP1 ; mkdir -p "$D"130"$PY" "$SK/dl.py" "<LINK_DOUYIN>" "$D" # -> $D/video.mp4131"$PY" "$SK/dub.py" transcribe "$D/video.mp4" # -> $D/segs.json (Claude điền -> segs_vi.json)132"$PY" "$SK/dub.py" render "$D/video.mp4" --segs "$D/segs_vi.json" --sidechain --fit-cap 1.5 --out dubbed.mp4133# HOẶC cho CapCut (giọng đẹp hơn): thêm --no-voice -> ra dubbed.srt + video pre-duck (chồng TTS CapCut lên)134"$PY" "$SK/dub.py" render "$D/video.mp4" --segs "$D/segs_vi.json" --sidechain --fit-cap 1.5 --no-voice --out capcut.mp4135```