Tuần trước mình mất gần 3 tiếng để xem và ghi chú một playlist YouTube gồm 15 video về AI. Nhìn lại đống note lộn xộn đó, mình tự hỏi: tại sao không viết một script Python làm chuyện này tự động? Sau hai buổi tối, mình có một hệ thống tự transcribe video, tóm tắt nội dung, thậm chí viết thành bài blog hoàn chỉnh.
Bài này mình chia sẻ lại đúng những gì đã làm — từ cài đặt đến chạy được kết quả đầu tiên.
Chạy được trong 5 phút — làm ngay
Bạn cần Python 3.9+ và một API key của Anthropic. Thử chạy thật trước, hiểu sau.
Bước 1: Cài thư viện
pip install openai-whisper yt-dlp anthropic
- openai-whisper: model speech-to-text của OpenAI, chạy hoàn toàn local, miễn phí
- yt-dlp: tool tải audio từ YouTube (fork đang được maintain tích cực của youtube-dl)
- anthropic: SDK Python để gọi Claude API
Bước 2: Script hoàn chỉnh để chạy thử
import subprocess
import whisper
import anthropic
import sys
def download_audio(url: str, output: str = "audio") -> str:
subprocess.run([
"yt-dlp", "-x", "--audio-format", "mp3",
"-o", f"{output}.%(ext)s", url
], check=True)
return f"{output}.mp3"
def transcribe(audio_path: str) -> str:
model = whisper.load_model("base") # base: nhanh; small/medium: chính xác hơn
result = model.transcribe(audio_path)
return result["text"]
def summarize_to_article(transcript: str, topic: str) -> str:
client = anthropic.Anthropic() # đọc ANTHROPIC_API_KEY từ env
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
messages=[{
"role": "user",
"content": f"""Dựa vào transcript từ video YouTube về chủ đề "{topic}",
hãy viết một bài blog tiếng Việt hoàn chỉnh, rõ ràng, có cấu trúc H2/H3,
kèm ví dụ code nếu có. Vào thẳng nội dung, không cần intro dài dòng.
TRANSCRIPT:
{transcript[:8000]}"""
}]
)
return message.content[0].text
if __name__ == "__main__":
url = sys.argv[1]
topic = sys.argv[2] if len(sys.argv) > 2 else "công nghệ"
print("Đang tải audio...")
audio = download_audio(url)
print("Đang transcribe (1-2 phút với video 10-15 phút)...")
transcript = transcribe(audio)
print("Đang viết bài với Claude...")
article = summarize_to_article(transcript, topic)
with open("output.md", "w") as f:
f.write(article)
print("Xong! Bài viết lưu tại output.md")
Chạy thử
export ANTHROPIC_API_KEY="sk-ant-..."
python main.py "https://youtube.com/watch?v=VIDEO_ID" "Docker container"
Nếu thấy file output.md xuất hiện với nội dung bài blog, bạn đã qua bước đầu rồi.
Giải thích chi tiết — tại sao lại dùng Whisper thay vì subtitle YouTube?
Câu hỏi này mình hay gặp. Subtitle tự động của YouTube thường sai chính tả, thiếu dấu câu, và nhiều video kỹ thuật không có subtitle tiếng Việt. Whisper xử lý trực tiếp từ audio nên chính xác hơn đáng kể, đặc biệt với accent Việt Nam và thuật ngữ chuyên ngành IT.
Chọn model Whisper phù hợp
Whisper có 5 size. Mình hay dùng small cho video dưới 30 phút:
tiny: ~39M params — nhanh nhất, ít chính xácbase: ~74M params — cân bằng tốt cho demo và testsmall: ~244M params — điểm ngọt nhất (mình dùng hàng ngày)medium: ~769M params — chính xác cao, cần GPU ổnlarge: ~1.5B params — tốt nhất nhưng chậm trên CPU
Máy có GPU NVIDIA thì Whisper tự detect CUDA và chạy nhanh gấp 5-10 lần. Không có GPU vẫn chạy được trên CPU, chỉ lâu hơn.
Vấn đề context limit khi video dài
Video 1 tiếng có thể ra 15,000-20,000 từ transcript. Claude Sonnet chấp nhận đến 200K token, nhưng để tiết kiệm chi phí mình thường chunk transcript thành các đoạn 6,000 từ, tóm tắt từng đoạn trước rồi mới tổng hợp thành bài.
Nâng cao — xử lý video dài và cả playlist
Chunk transcript thông minh
def chunk_transcript(text: str, chunk_size: int = 6000) -> list[str]:
words = text.split()
return [" ".join(words[i:i + chunk_size]) for i in range(0, len(words), chunk_size)]
def summarize_long_video(transcript: str, topic: str) -> str:
client = anthropic.Anthropic()
chunks = chunk_transcript(transcript)
summaries = []
for i, chunk in enumerate(chunks):
print(f"Tóm tắt phần {i+1}/{len(chunks)}...")
# Dùng Haiku cho bước trung gian — rẻ hơn 10 lần Sonnet
resp = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=1024,
messages=[{"role": "user", "content": f"Tóm tắt ngắn gọn phần này (100-200 từ):\n\n{chunk}"}]
)
summaries.append(resp.content[0].text)
# Tổng hợp thành bài hoàn chỉnh bằng Sonnet
combined = "\n\n".join(summaries)
final = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=3000,
messages=[{"role": "user", "content": f"Viết bài blog tiếng Việt hoàn chỉnh từ các tóm tắt về '{topic}':\n\n{combined}"}]
)
return final.content[0].text
Xử lý cả playlist
# Lấy toàn bộ URL từ playlist
yt-dlp --flat-playlist --print url "https://youtube.com/playlist?list=PLAYLIST_ID" > urls.txt
with open("urls.txt") as f:
urls = f.read().splitlines()
for url in urls:
print(f"\nXử lý: {url}")
audio = download_audio(url, output=f"audio_{abs(hash(url))}")
transcript = transcribe(audio)
article = summarize_to_article(transcript, "AI và Machine Learning")
with open(f"article_{abs(hash(url))}.md", "w") as f:
f.write(article)
Tips thực tế từ mình dùng hàng ngày
Trong quá trình làm việc thực tế, mình nhận thấy đây là một trong những kỹ năng quan trọng cần nắm — không phải vì nó nghe hay, mà vì nó tiết kiệm thật sự vài tiếng mỗi tuần khi cần nghiên cứu nhiều tài liệu video.
1. Cache transcript để không transcribe lại
Whisper chạy khá lâu với video dài. Lưu transcript ra file để tái sử dụng:
import os
def get_or_transcribe(audio_path: str) -> str:
cache_file = audio_path.replace(".mp3", "_transcript.txt")
if os.path.exists(cache_file):
with open(cache_file) as f:
return f.read()
transcript = transcribe(audio_path)
with open(cache_file, "w") as f:
f.write(transcript)
return transcript
2. Tiết kiệm chi phí API
Dùng Haiku cho bước tóm tắt trung gian, chỉ dùng Sonnet cho bước viết bài cuối. Chi phí giảm khoảng 60-70% mà chất lượng bài cuối hầu như không ảnh hưởng. Với 50-100 video mỗi tháng, khoản này không nhỏ.
3. Force ngôn ngữ khi cần
result = model.transcribe(audio_path, language="vi") # Force tiếng Việt
result = model.transcribe(audio_path, language="ja") # Force tiếng Nhật
4. Prompt theo use case cụ thể
PROMPTS = {
"blog": "Viết bài blog kỹ thuật hoàn chỉnh với H2/H3, code example thực tế...",
"notes": "Tóm tắt thành bullet points, nhấn mạnh điểm chính và action items...",
"linkedin": "Viết post LinkedIn 200-300 từ, chuyên nghiệp, có insight thực tế...",
"quiz": "Tạo 5 câu hỏi trắc nghiệm kiểm tra hiểu biết về nội dung video này...",
}
5. Lưu ý về pháp lý
Hệ thống này phù hợp cho nội dung bạn có quyền sử dụng: video của chính bạn, conference talks có Creative Commons license, hoặc khóa học bạn đã mua. Không dùng để sao chép nội dung thương mại — hầu hết nền tảng có ToS quy định rõ về tự động hóa tải nội dung.
Hệ thống này không thay thế việc đọc bài gốc — nó cho bạn bản thảo 80% hoàn thiện, còn lại bạn vẫn cần chỉnh sửa trước khi publish. Nhưng thay vì bắt đầu từ trang trắng mỗi lần, bạn có điểm khởi đầu rõ ràng. Với mình, đó là sự khác biệt giữa “viết được 3-4 bài/tuần” và “không bao giờ có thời gian viết bài”.

