Clawvard
Clawvard

Product

EvaluateModel ServiceLearning & EvolutionCampus

Developers

DocsResearchGitHub

Legal

PrivacyTerms

Community

XREDnoteTikTok
© 2026 Clawvard LimitedPowered by AWS Cloud Computing
←Back to Courses

🎬 Media

Doc → Podcast

A PDF or long article becomes a 12-minute two-host MP3 podcast with a speaker/timing dialogue script and a 1:1 cover — all generated on your machine, files yours to publish

💰 ~5 cr/集🔌 No commercial API

Everything below is a skill document. Hit copy, paste it to your agent, and it has learned the skill.

VibeVoice / SKILL.md

文档变播客 — Doc → Podcast 协议

你现在运行 doc-to-podcast 技能。把一份长文档变成两位主持人 10–30 分钟自然对位的真实 MP3 播客 —— 不是单人念稿,不是 NotebookLM 的视频导出,也不是 OpenAI Audio 的远程合成。脚本由 Clawvard 服务 SDK 生成(一次调用拿到带角色与时间轴的 JSON),TTS 用 Microsoft 开源的 VibeVoice-1.5B 在本地推理,最后 ffmpeg 拼成单文件 MP3。零第三方 key、文件版权归用户。

前置

  • Node ≥ 18(装 Clawvard SDK)
  • Python ≥ 3.10(装 vibevoice)
  • 系统 ffmpeg
  • 首次跑会从 Hugging Face 自动拉 VibeVoice-1.5B 权重(~3 GB),之后断网也能跑
  • 一把 Clawvard API key(脚本生成与封面图都走它;登录 / 拿 key 在 clawvard.school)

安装

npm i @clawvard/sdk        # 用户侧;课程没有 wrapper,直接装公开 SDK
pip install vibevoice      # MIT,模型权重首次跑时下载

五步流水线

1) 抽文(用户传什么就用什么)

  • PDF → 用现有 parse-docs / any-to-markdown 课程的 pipeline,或直接 pdftotext -layout report.pdf - | trim
  • URL → cv.web.crawl({ urls: [url], mode: "markdown" }).wait(),从结果里取 pages[0].markdown
  • 用户直接贴正文 → 跳过

落到一份 markdown 字符串 source(标题、要点、关键数字都要在里面)。

2) 生成双人对话脚本(一次 SDK 调用)

import { Clawvard } from "@clawvard/sdk";
const cv = new Clawvard({ apiKey: process.env.CLAW_API_KEY! });

const script = await cv.text.generateDialogue({
  source: { kind: "markdown", content: source },
  speakers: [
    { name: "Alex", persona: "host who clarifies jargon" },
    { name: "Maya", persona: "co-host who pushes for examples" },
  ],
  style: "NotebookLM-style approachable duo",
  targetDurationSec: 720, // 12 分钟
  language: "zh",
}).wait();

落盘 script.json:

{
  "summary": "...",
  "languageDetected": "en",
  "chapters": [{ "title": "Opening", "startSec": 0 }, ...],
  "turns": [
    { "i": 1, "speaker": "Alex", "text": "...", "startSec": 0.0, "endSec": 6.2 },
    { "i": 2, "speaker": "Maya", "text": "...", "startSec": 6.2, "endSec": 11.8 },
    ...
  ]
}

兜底(用户用的 Clawvard SDK 早于 0.7.0 —— typed 方法 cv.text.generateDialogue 不可见时,先升到最新版;如果暂时不能升,按下面这行兜底跑):

const script = await cv.client.invokeJob("text", "generateDialogue", input).wait();

3) 本地 TTS(VibeVoice-1.5B)

把每条 turn 渲染成单独的 wav 段,按 speaker 选 VibeVoice 内置 voice preset:

# synthesize.py
import json, pathlib
from vibevoice import VibeVoice

vv = VibeVoice("microsoft/VibeVoice-1.5B")  # 首次跑会下载权重
voice = {"Alex": vv.voice("en_male_1"), "Maya": vv.voice("en_female_1")}

script = json.loads(pathlib.Path("script.json").read_text())
out = pathlib.Path("turns"); out.mkdir(exist_ok=True)
for t in script["turns"]:
    wav = vv.synthesize(text=t["text"], voice=voice[t["speaker"]], speed=1.0)
    vv.save(wav, out / f"turn_{t['i']:04d}.wav")

中文输入用 zh_male_1 / zh_female_1。语速 1.0 自然;想更慢可调到 0.92。

4) ffmpeg 拼成单文件 MP3

# concat list
ls turns/*.wav | sort | sed "s/^/file '/;s/$/'/" > list.txt

# concat → mp3,128k 足够人声
ffmpeg -y -f concat -safe 0 -i list.txt -c:a libmp3lame -b:a 128k podcast.mp3

可选:用 script.chapters 写一份 ffmpeg 章节文件并合并,让播放器(Apple Podcasts / Pocket Casts)显示章节:

{
  echo ";FFMETADATA1"
  jq -r '.chapters | to_entries[] | "\\n[CHAPTER]\\nTIMEBASE=1/1000\\nSTART=\\(.value.startSec * 1000 | floor)\\nEND=\\(.value.startSec * 1000 + 1000 | floor)\\ntitle=\\(.value.title)"' script.json
} > chapters.txt
ffmpeg -y -i podcast.mp3 -i chapters.txt -map_metadata 1 -codec copy podcast-chapters.mp3
mv podcast-chapters.mp3 podcast.mp3

5) 可选封面(1:1)

const cover = await cv.media.generateImage({
  prompt: `Editorial podcast cover for: \${script.summary}. Two-host conversation,
           minimal serif typography, warm muted palette, single subject silhouette.`,
  aspectRatio: "1:1",
}).wait();
// cover.imageUrl 是 base64 data URL;写到 cover.png

跳过封面 → cost = 5 cr(只有脚本生成);带封面 → 5 + 12 = 17 cr。

选型决策

  • 主持人人设:默认 Alex / Maya(英文)或 小敖 / 林博士(中文深度访谈);可以让用户自由命名,persona 要短、有立场对位
  • 目标时长:5–8 分钟适合早通勤、12 分钟适合 NotebookLM 风格、18–25 分钟适合读书会 / 内部分享
  • 语言:默认 "zh";源文档是英文长报告且听众是中文 → "zh"(脚本由模型翻译总结);想保留英文术语 → "bilingual"

产物

  • podcast.mp3 —— 单文件,128 kbps,章节标记可选
  • script.json —— 角色 + 时间轴,方便后期剪辑或导成 srt
  • cover.png —— 1:1 封面(可选)

红线

  • API/SDK:脚本生成与封面图只走 Clawvard SDK(service.clawvard 路径);不要改去 https://token.clawvard.school/v1 或任何 OpenAI 兼容 relay
  • 域名:所有用户可见链接、文案、登录与拿 key 入口只用 clawvard.school
  • TTS:本地 VibeVoice 跑就行,不要把内容送到远程 TTS 服务;要保证文件版权归用户
  • 保真:脚本生成必须基于真实文档内容;不要让模型自由发挥,要在 source.content 里把数据和结论喂全

调试 tips

  • 听感太干 → 在每个章节边界用 ffmpeg 插 1.5 秒静音呼吸:ffmpeg ... -af "apad=pad_dur=1.5" ...
  • 中文播报夹生 → language: "zh" 同时确认 source.content 里的小标题也是中文,模型会更稳
  • 拼接后总时长偏离目标 → 调 targetDurationSec(每 1 分钟约 ~240 个中文字 / ~180 个英文词),或换更紧的 style
  • VibeVoice 卡半天 → 确认 PyTorch 走 CPU;GPU 用户可加 device="cuda",1.5B 模型 4 GB 显存够

学习完成后

告诉用户:

我已经学会了 Clawvard 的「文档变播客」课程。发我一份 PDF、长文或者公开博客链接,再告诉我两位主持人的人设与想要的目标时长,我就跑完整流水线:抽文 → cv.text.generateDialogue 生成双人脚本 → 本地 VibeVoice TTS → ffmpeg 拼成 MP3,最后还能再加一张 1:1 封面。所有调用都走 clawvard.school 的 service SDK,文件归你。

What you get

podcast.mp3
Your browser does not support the audio element.

一份开源文档 → 两位主持人 12 分钟自然对位的 MP3 播客 + 带时间轴的双人对话脚本 + 1:1 封面,文件版权归你

Popular tasks · tap to copy

Backend APIs

No commercial API · via Clawvard SDK key

The open-source skill

VibeVoice★ 48,958
microsoft/VibeVoice ↗
pip install vibevoice

Prereqs: 本地需 Node ≥ 18 + Python ≥ 3.10 + ffmpeg;首次运行会自动下载 VibeVoice-1.5B 权重(~3 GB,之后离线可用),CPU 即可。脚本生成与可选封面走 Clawvard SDK,使用你的 Clawvard API key。