Seedance không clone được khuôn mặt bạn: Pipeline biến bài viết thành video ngắn thật sự
Muốn video ngắn dùng mặt thật + giọng thật? Seedance/Veo vô dụng — bạn cần lip-sync engine. Pipeline 6 bước: Supabase → ElevenLabs → HeyGen → Remotion, ~$0.40/video, chạy tự động sau mỗi lần publish.
Nếu bạn muốn video ngắn dùng khuôn mặt thật và giọng thật của mình, đừng dùng Seedance, Veo hay Runway. Chúng không làm được. Những mô hình đó sinh video từ prompt — kết quả sẽ là một người giông giống bạn, khẩu hình lệch, và mỗi lần render lại một khác. Với brand cá nhân, như vậy là không dùng được. Thứ bạn cần là talking-head lip-sync engine chạy trên giọng đã clone.
Dưới đây là pipeline backend đầy đủ mà tôi sẽ dựng để biến mọi bài blog vừa publish thành một video dọc 35 giây, tự động, không cần chạm tay sau khi đăng.
Tại sao Seedance hay Veo không tạo được video mặt thật của tôi?
Vì chúng giải bài toán khác. Seedance và Veo là mô hình video generative: đưa text hoặc ảnh vào, nhận footage mới hoàn toàn. Chúng không có cơ chế giữ nguyên danh tính một con người cụ thể qua từng frame, và cũng không có cơ chế khớp khẩu hình với một file audio cụ thể.
Avatar lip-sync engine hoạt động ngược lại: bạn đưa bản ghi hình thật của chính bạn cộng một file audio, và nó làm khuôn mặt thật của bạn cử động theo audio đó. Danh tính được giữ nguyên vì ngay từ đầu nó không hề được "sinh ra".
Vậy nên lớp "sinh video motion" trong pipeline AI video thông thường phải được thay thế:
- Pipeline thông thường: script → TTS → Seedance/Veo → render
- Pipeline brand cá nhân: script → voice clone → avatar lip-sync → render
Mọi thứ còn lại giữ nguyên.
Pipeline hoàn chỉnh trông như thế nào?
Sáu bước, kích hoạt bởi một sự kiện database duy nhất:
[1] Bảng posts trên Supabase
| trigger: status -> published
v
[2] Hook Extractor -> cắt lead paragraph, nối CTA
v
[3] ElevenLabs TTS -> giọng clone của bạn
| /with-timestamps -> audio.mp3 + alignment JSON
v
[4] Avatar Lip-sync -> HeyGen API (nhận audio, KHÔNG dùng TTS của họ)
| -> avatar.mp4 (async, poll hoặc webhook)
v
[5] Remotion -> khung 9:16, sub từng chữ, logo, endcard CTA
v
[6] Render + Upload -> Supabase Storage / đăng social
Chi tiết then chốt nằm ở điểm bàn giao giữa bước 3 và 4. ElevenLabs sinh audio trước; HeyGen chỉ lip-sync theo audio đó. Nếu bạn để HeyGen tự đọc text bằng TTS của nó, bạn mất giọng thật — mà đó chính là toàn bộ lý do làm việc này.
Chọn tool nào cho từng bước?
| Bước | Khuyến nghị | Lý do / lựa chọn thay thế |
|---|---|---|
| Voice | ElevenLabs Professional Voice Clone + eleven_multilingual_v2 |
Một voice ID đọc được cả tiếng Việt lẫn tiếng Anh. Clone một lần, dùng cho cả hai phiên bản ngôn ngữ của mọi bài |
| Timestamps | /v1/text-to-speech/{voice_id}/with-timestamps |
Trả về alignment cấp ký tự ngay trong cùng response. Không cần Whisper — bớt một bước, và chính xác hơn việc transcribe lại audio của chính mình |
| Avatar | HeyGen API (Instant Avatar từ 2–5 phút quay thật) | Độ khớp khẩu hình tốt nhất hiện nay, API ổn định, nhận input audio. Rẻ hơn: D-ID Clips. Open-source: LatentSync (tự host GPU, chất lượng kém hơn thấy rõ) |
| Ghép dựng | Remotion | Bạn cần sub động, khung brand, endcard. Làm bằng FFmpeg thuần rất cực. Remotion cho bạn video có version control — sửa component, render lại y hệt |
| Render | Remotion Lambda | Serverless, ~30 giây mỗi video, không phải nuôi máy |
| Orchestration | Bảng video_jobs + GitHub Actions cron |
Bước 4 chạy async mất 1–3 phút. Đừng viết script chạy thẳng một mạch rồi block ở đó |
Kịch bản video nên nói gì?
Lấy một ví dụ thật — bài Wizy của tôi về dùng Reddit cho AEO. Đoạn lead của nó dài 75 từ, đọc khoảng 28 giây. Cộng thêm CTA cố định là ra ~35 giây: vừa đúng chuẩn Shorts, Reels và TikTok.
Bạn có để ý điều này gần đây không? Khách hàng giờ không chỉ tìm trên Google nữa. Nhiều người hỏi thẳng ChatGPT hoặc Gemini — "Tiệm nail nào ở Mississauga tốt vậy?" — và AI trả lời ngay lập tức, kể tên vài tiệm.
Vậy câu hỏi triệu đô là: làm sao để tiệm của bạn có mặt trong danh sách đó?
Câu trả lời ngắn gọn: hãy để tên tiệm bạn được nhắc tới trên Reddit.
Nhưng làm thế nào mới là phần cụ thể — tôi đã viết hết toàn bộ cách làm trong bài. Link ở dưới.
Câu in đậm cuối là template cố định, dùng lại cho mọi video. Chỉ ba khối đầu là lấy từ bài viết.
Quy tắc cắt tự động: lấy paragraph đầu tiên của content_vi, strip Markdown, cắt ở câu hoàn chỉnh cuối cùng trước 130 từ, rồi nối template CTA. Nếu paragraph đầu dưới 40 từ thì lấy thêm paragraph thứ hai.
Logic này cố ý "ngu" — và đó chính là điểm mấu chốt. Một đoạn hook tốt vốn đã là một kịch bản video tốt: bạn viết nó để chặn ngón tay người đang lướt. Đừng đưa qua LLM để "cải thiện"; bạn sẽ nhận về giọng văn AI chung chung và mất đúng cái thứ đã làm nó hiệu quả.
Code cụ thể
Bước 3 — ElevenLabs kèm timestamps:
const res = await fetch(
`https://api.elevenlabs.io/v1/text-to-speech/${VOICE_ID}/with-timestamps`,
{
method: 'POST',
headers: { 'xi-api-key': KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
text: script,
model_id: 'eleven_multilingual_v2',
voice_settings: { stability: 0.5, similarity_boost: 0.85 },
}),
}
);
const { audio_base64, normalized_alignment } = await res.json();
// normalized_alignment -> dựng caption cấp từ cho Remotion
Bước 4 — HeyGen nhận audio, không phải text:
const job = await fetch('https://api.heygen.com/v2/video/generate', {
method: 'POST',
headers: { 'X-Api-Key': HEYGEN_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
video_inputs: [{
character: { type: 'avatar', avatar_id: MY_AVATAR_ID },
voice: { type: 'audio', audio_url: publicAudioUrl }, // <- giọng ElevenLabs
}],
dimension: { width: 1080, height: 1920 },
}),
}).then(r => r.json());
// sau đó poll /v1/video_status.get cho tới khi status === 'completed'
Bước 5 — Remotion composition:
export const ShortVideo = ({ avatarUrl, captions, articleTitle }) => (
<AbsoluteFill style={{ background: '#0B0B0F' }}>
<OffthreadVideo src={avatarUrl} />
<CaptionTrack captions={captions} /> {/* highlight từng chữ */}
<BrandFrame title={articleTitle} /> {/* logo + tiêu đề bài */}
<Sequence from={durationInFrames - 90}>
<EndCard cta="Đọc bài viết đầy đủ ->" url="wizy.ca/blog/..." />
</Sequence>
</AbsoluteFill>
);
Kích hoạt tự động bằng cách nào?
Cách đơn giản nhất, không cần dựng hạ tầng mới:
- Thêm bảng
video_jobstrong Supabase:post_id,lang,status,audio_url,avatar_url,final_url. - Supabase Database Webhook kích hoạt khi
posts.statuschuyển sangpublished, insert hai job — một tiếng Việt, một tiếng Anh. - GitHub Actions cron chạy mỗi 5 phút, quét job
pending, và đẩy mỗi job tiến đúng một state mỗi lần chạy. Vì bước 4 là async, worker không bao giờ bị block — nó chỉ kiểm tra HeyGen xong chưa rồi đi tiếp.
Mỗi bài viết publish giờ tự sinh ra hai video ngắn, không cần thao tác tay nào.
Chi phí mỗi video là bao nhiêu?
Cho một clip ~35 giây:
| Hạng mục | Ước tính |
|---|---|
| ElevenLabs | ~$0.05–0.15 |
| HeyGen | ~$0.30–1.00 |
| Remotion Lambda | ~$0.01–0.05 |
| Tổng | ~$0.40–1.20 / video |
Đây là con số ballpark theo các gói phổ thông — bạn nên tự kiểm tra bảng giá hiện hành, đặc biệt là HeyGen vì họ tính theo credit và thay đổi khá thường xuyên.
Nên triển khai theo thứ tự nào?
- Tuần 1 — làm tay một lần. Clone giọng trên ElevenLabs, quay 3 phút video để tạo HeyGen Instant Avatar, rồi dựng thủ công đúng một video. Mục tiêu chỉ là trả lời một câu hỏi: avatar và giọng có đủ tốt để bạn dám đăng lên profile cá nhân của mình không?
- Tuần 2 — script hóa bước 2 đến 4. Hook extractor, ElevenLabs, HeyGen. Xuất ra file MP4 thô.
- Tuần 3 — Remotion. Sub, khung brand, endcard.
- Tuần 4 — tự động hóa. Bảng
video_jobs, webhook, cron.
Đừng đảo thứ tự này. Rủi ro lớn nhất của cả dự án không phải kỹ thuật — mà là avatar trông không đủ giống bạn để dám đăng. Đó là rủi ro về chất lượng, và bạn trả lời được nó trong một buổi chiều. Hãy trả lời trước khi viết dòng code pipeline nào.
Sai lầm cần tránh
Các team làm việc này thường bị hút vào lớp generation và mất hàng tuần so sánh các mô hình video. Nhưng trong pipeline talking-head, việc chọn mô hình gần như không liên quan — avatar engine mới là thứ làm toàn bộ công việc, và thực tế chỉ có hai ba lựa chọn thật sự.
Đòn bẩy nằm ở những phần nhàm chán: cắt hook một cách xác định, sub chính xác từng chữ từ timestamps bạn vốn đã có sẵn, và một renderer tạo ra đúng y video đó sau khi sửa kịch bản. Làm đúng ba thứ này, bạn có một cỗ máy content. Làm sai, bạn có một máy sinh video ngẫu nhiên đắt tiền.
Bài viết tham khảo dùng trong ví dụ: Reddit for AEO: How to Get Your Shop Recommended When Customers Ask ChatGPT & Google AI
FAQ
Seedance hay Veo có tạo được video mặt thật của tôi đang nói không? Không. Chúng là mô hình generative, không có cơ chế giữ danh tính và không lip-sync theo audio. Hãy dùng talking-head engine như HeyGen hoặc D-ID.
Làm sao giữ giọng ElevenLabs thật khi dùng HeyGen?
Truyền voice: { type: 'audio', audio_url: ... } trong request HeyGen thay vì type: 'text'. HeyGen khi đó chỉ lip-sync theo audio bạn upload và không hề gọi TTS của nó.
Có cần Whisper để làm phụ đề không?
Không. Endpoint /with-timestamps của ElevenLabs trả về alignment cấp ký tự kèm luôn audio — chính xác hơn và bớt được một bước so với transcribe lại.
Remotion hay FFmpeg cho khâu render cuối? Remotion nếu bạn muốn sub động, khung brand và video có version control dạng React component. FFmpeg nếu bạn cần tốc độ thô, ít phụ thuộc và chấp nhận overlay tĩnh.
Video nên dài bao nhiêu? Nhắm 30–40 giây. Một đoạn lead 75 từ đọc khoảng 28 giây; thêm câu CTA cố định là ra tầm 35 — điểm ngọt cho Shorts, Reels và TikTok.
#AIVideo #ElevenLabs #HeyGen #Remotion #Supabase #ContentAutomation #VoiceClone #ShortForm #AIAgents #DevTools
✍️ Tác giả: Do Ngoc Hoan Founder of CookConnects.ca & Wizy.ca. Kết nối khoảng cách giữa thuật toán tiên tiến và thực thi kinh doanh. Tôi viết cho những founder kỹ thuật muốn mở rộng tầm ảnh hưởng bằng AI và kỹ thuật vững chắc.