npx skills add https://github.com/marswaveai/skills --skill explainer/speech 或 /podcast)/podcast)/image-gen)/speech)生成解说视频,将单一叙述者的旁白与 AI 生成的画面相结合。适用于产品介绍、概念解释和教程。支持纯文本脚本生成或完整的文本+视频输出。
shared/authentication.md 以了解 API 密钥和请求头信息广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
shared/common-patterns.mdshared/config-pattern.md 读取配置~/Downloads/ 或 .listenhub/ — 将生成物保存到当前工作目录,并使用基于主题的友好名称(参见 shared/config-pattern.md § 生成物命名)info(信息风格)或 story(故事风格)— 切勿使用 slides(请改用 /slides 技能)遵循 shared/config-pattern.md § API 密钥检查。如果密钥缺失,立即停止。
遵循 shared/config-pattern.md 步骤 0(零问题启动)。
如果文件不存在 — 静默创建默认配置并继续:
mkdir -p ".listenhub/explainer"
echo '{"outputMode":"inline","language":null,"defaultStyle":null,"defaultSpeakers":{}}' > ".listenhub/explainer/config.json"
CONFIG_PATH=".listenhub/explainer/config.json"
CONFIG=$(cat "$CONFIG_PATH")
请勿询问任何设置问题。 直接进入交互流程。
如果文件存在 — 静默读取配置并继续:
CONFIG_PATH=".listenhub/explainer/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/explainer/config.json"
CONFIG=$(cat "$CONFIG_PATH")
仅在用户明确要求重新配置时运行。显示当前设置:
当前配置 (explainer):
输出方式:{inline / download / both}
语言偏好:{zh / en / 未设置}
默认风格:{info / story / 未设置}
默认主播:{speakerName / 使用内置默认}
然后询问:
outputMode : 遵循 shared/output-mode.md § 设置流程问题。
Language (可选): "默认语言?"
nullStyle (可选): "默认风格?"
null收集答案后,立即保存:
NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
CONFIG=$(cat "$CONFIG_PATH")
自由文本输入。询问用户:
您想解释或介绍什么?
接受:主题描述、文本内容或要解释的概念。
如果 config.language 已设置,则在摘要中预填并显示 — 跳过此问题。否则询问:
Question: "What language?"
Options:
- "Chinese (zh)" — 内容为中文普通话
- "English (en)" — 内容为英文
如果 config.defaultStyle 已设置,则在摘要中预填并显示 — 跳过此问题。否则询问:
Question: "What style of explainer?"
Options:
- "Info" — 信息性、事实陈述风格
- "Story" — 叙事性、讲故事风格
遵循 shared/speaker-selection.md:
config.defaultSpeakers.{language} 已设置 → 静默使用已保存的主播shared/speaker-selection.md 中针对该语言的内置默认主播解说视频仅支持 1 位主播。
Question: "What output do you want?"
Options:
- "Text script only" — 仅生成旁白脚本,不生成视频
- "Text + Video" — 生成包含 AI 画面的完整解说视频
总结所有选择:
Ready to generate explainer:
Topic: {topic}
Language: {language}
Style: {info/story}
Speaker: {speaker name}
Output: {text only / text + video}
Proceed?
在调用任何 API 之前,等待明确的确认。
提交(前台) : POST /storybook/episodes 附带内容、主播、语言、模式 → 提取 episodeId
告知用户任务已提交
轮询(后台) : 使用 run_in_background: true 和 timeout: 600000 运行以下精确的 bash 命令。请勿使用 python3、awk 或任何其他 JSON 解析器 — 按所示使用 jq:
EPISODE_ID="<id-from-step-1>"
for i in $(seq 1 30); do
RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/storybook/episodes/$EPISODE_ID" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "X-Source: skills" 2>/dev/null)
STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.processStatus // "pending"')
case "$STATUS" in
success|completed) echo "$RESULT"; exit 0 ;;
failed|error) echo "FAILED: $RESULT" >&2; exit 1 ;;
*) sleep 10 ;;
esac
done
echo "TIMEOUT" >&2; exit 2
收到通知后,下载并呈现脚本:
从配置中读取 OUTPUT_MODE。遵循 shared/output-mode.md 中的行为说明。
inline 或 both:内联呈现脚本。
呈现:
解说脚本已生成!
「{title}」
在线查看:https://listenhub.ai/app/explainer/{episodeId}
download 或 both:同时保存脚本文件。按照 shared/config-pattern.md § 生成物命名规则生成主题 slug。
* 如果仅输出文本:保存为当前工作目录下的 `{slug}-explainer.md`(如果存在则去重)
* 如果输出文本+视频:创建 `{slug}-explainer/` 文件夹(如果存在则去重),并在其中写入 `script.md`
* 除了上述摘要外,同时呈现保存路径。
5. 如果请求了视频 : POST /storybook/episodes/{episodeId}/video(前台)→ 再次轮询(后台),使用以下精确的 bash 命令,附带 run_in_background: true 和 timeout: 600000。轮询 videoStatus,而非 processStatus:
EPISODE_ID="<id-from-step-1>"
for i in $(seq 1 30); do
RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/storybook/episodes/$EPISODE_ID" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "X-Source: skills" 2>/dev/null)
STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.videoStatus // "pending"')
case "$STATUS" in
success|completed) echo "$RESULT"; exit 0 ;;
failed|error) echo "FAILED: $RESULT" >&2; exit 1 ;;
*) sleep 10 ;;
esac
done
echo "TIMEOUT" >&2; exit 2
6. 收到通知后,下载并呈现结果:
呈现结果
从配置中读取 OUTPUT_MODE。遵循 shared/output-mode.md 中的行为说明。
inline 或 both:将视频 URL 和音频 URL 显示为可点击链接。
呈现:
解说视频已生成!
视频链接:{videoUrl}
音频链接:{audioUrl}
时长:{duration}s
消耗积分:{credits}
download 或 both:同时将音频文件下载到 {slug}-explainer/ 文件夹中。
curl -sS -o "{slug}-explainer/audio.mp3" "{audioUrl}"
呈现:
已保存到当前目录:
{slug}-explainer/
script.md
audio.mp3
使用本次会话所做的选择更新配置:
NEW_CONFIG=$(echo "$CONFIG" | jq \
--arg lang "{language}" \
--arg style "{info/story}" \
--arg speakerId "{speakerId}" \
'. + {"language": $lang, "defaultStyle": $style, "defaultSpeakers": (.defaultSpeakers + {($lang): [$speakerId]})}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
预计时间:
shared/api-speakers.mdshared/speaker-selection.mdshared/api-storybook.mdshared/common-patterns.md § 异步轮询shared/config-pattern.md/speech 进行旁白用户:"创建一个介绍 Claude Code 的解说视频"
代理工作流程:
curl -sS -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Source: skills" \
-d '{
"sources": [{"type": "text", "content": "Introduce Claude Code: what it is, key features, and how to get started"}],
"speakers": [{"speakerId": "cozy-man-english"}],
"language": "en",
"mode": "info"
}'
轮询直到文本就绪,然后如果请求了视频则生成视频。
每周安装数
379
仓库
GitHub 星标数
28
首次出现
12 天前
安全审计
安装于
codex375
gemini-cli373
cursor373
opencode373
cline372
github-copilot372
/speech or /podcast)/podcast)/image-gen)/speech)Generate explainer videos that combine a single narrator's voiceover with AI-generated visuals. Ideal for product introductions, concept explanations, and tutorials. Supports text-only script generation or full text + video output.
shared/authentication.md for API key and headersshared/common-patterns.md for polling, errors, and interaction patternsshared/config-pattern.md before any interaction~/Downloads/ or .listenhub/ — save artifacts to the current working directory with friendly topic-based names (see shared/config-pattern.md § Artifact Naming)info (for Info style) or story (for Story style) — never slides (use /slides skill instead)Follow shared/config-pattern.md § API Key Check. If the key is missing, stop immediately.
Follow shared/config-pattern.md Step 0 (Zero-Question Boot).
If file doesn't exist — silently create with defaults and proceed:
mkdir -p ".listenhub/explainer"
echo '{"outputMode":"inline","language":null,"defaultStyle":null,"defaultSpeakers":{}}' > ".listenhub/explainer/config.json"
CONFIG_PATH=".listenhub/explainer/config.json"
CONFIG=$(cat "$CONFIG_PATH")
Do NOT ask any setup questions. Proceed directly to the Interaction Flow.
If file exists — read config silently and proceed:
CONFIG_PATH=".listenhub/explainer/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/explainer/config.json"
CONFIG=$(cat "$CONFIG_PATH")
Only run when the user explicitly asks to reconfigure. Display current settings:
当前配置 (explainer):
输出方式:{inline / download / both}
语言偏好:{zh / en / 未设置}
默认风格:{info / story / 未设置}
默认主播:{speakerName / 使用内置默认}
Then ask:
outputMode : Follow shared/output-mode.md § Setup Flow Question.
Language (optional): "默认语言?"
nullStyle (optional): "默认风格?"
nullAfter collecting answers, save immediately:
NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
CONFIG=$(cat "$CONFIG_PATH")
Free text input. Ask the user:
What would you like to explain or introduce?
Accept: topic description, text content, or concept to explain.
If config.language is set, pre-fill and show in summary — skip this question. Otherwise ask:
Question: "What language?"
Options:
- "Chinese (zh)" — Content in Mandarin Chinese
- "English (en)" — Content in English
If config.defaultStyle is set, pre-fill and show in summary — skip this question. Otherwise ask:
Question: "What style of explainer?"
Options:
- "Info" — Informational, factual presentation style
- "Story" — Narrative, storytelling approach
Follow shared/speaker-selection.md:
config.defaultSpeakers.{language} is set → use saved speaker silentlyshared/speaker-selection.md for the languageOnly 1 speaker is supported for explainer videos.
Question: "What output do you want?"
Options:
- "Text script only" — Generate narration script, no video
- "Text + Video" — Generate full explainer video with AI visuals
Summarize all choices:
Ready to generate explainer:
Topic: {topic}
Language: {language}
Style: {info/story}
Speaker: {speaker name}
Output: {text only / text + video}
Proceed?
Wait for explicit confirmation before calling any API.
Submit (foreground) : POST /storybook/episodes with content, speaker, language, mode → extract episodeId
Tell the user the task is submitted
Poll (background) : Run the following exact bash command with run_in_background: true and timeout: 600000. Do NOT use python3, awk, or any other JSON parser — use jq as shown:
EPISODE_ID="<id-from-step-1>"
for i in $(seq 1 30); do
RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/storybook/episodes/$EPISODE_ID" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "X-Source: skills" 2>/dev/null)
STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.processStatus // "pending"')
case "$STATUS" in
success|completed) echo "$RESULT"; exit 0 ;;
failed|error) echo "FAILED: $RESULT" >&2; exit 1 ;;
*) sleep 10 ;;
esac
done
echo "TIMEOUT" >&2; exit 2
Read OUTPUT_MODE from config. Follow shared/output-mode.md for behavior.
inline or both: Present the script inline.
Present:
解说脚本已生成!
「{title}」
在线查看:https://listenhub.ai/app/explainer/{episodeId}
download or both: Also save the script file. Generate a topic slug following shared/config-pattern.md § Artifact Naming.
* If text-only output: save as `{slug}-explainer.md` in cwd (dedup if exists)
* If text+video output: create `{slug}-explainer/` folder (dedup if exists), write `script.md` inside
* Present the save path in addition to the above summary.
5. If video requested : POST /storybook/episodes/{episodeId}/video (foreground) → poll again (background) using the exact bash command below with run_in_background: true and timeout: 600000. Poll for videoStatus, not processStatus:
EPISODE_ID="<id-from-step-1>"
for i in $(seq 1 30); do
RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/storybook/episodes/$EPISODE_ID" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "X-Source: skills" 2>/dev/null)
STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.videoStatus // "pending"')
case "$STATUS" in
success|completed) echo "$RESULT"; exit 0 ;;
failed|error) echo "FAILED: $RESULT" >&2; exit 1 ;;
*) sleep 10 ;;
esac
done
echo "TIMEOUT" >&2; exit 2
6. When notified, download and present result :
Present result
Read OUTPUT_MODE from config. Follow shared/output-mode.md for behavior.
inline or both: Display video URL and audio URL as clickable links.
Present:
解说视频已生成!
视频链接:{videoUrl}
音频链接:{audioUrl}
时长:{duration}s
消耗积分:{credits}
download or both: Also download the audio file into the {slug}-explainer/ folder.
curl -sS -o "{slug}-explainer/audio.mp3" "{audioUrl}"
Present:
已保存到当前目录:
{slug}-explainer/
script.md
audio.mp3
Update config with the choices made this session:
NEW_CONFIG=$(echo "$CONFIG" | jq \
--arg lang "{language}" \
--arg style "{info/story}" \
--arg speakerId "{speakerId}" \
'. + {"language": $lang, "defaultStyle": $style, "defaultSpeakers": (.defaultSpeakers + {($lang): [$speakerId]})}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
Estimated times :
shared/api-speakers.mdshared/speaker-selection.mdshared/api-storybook.mdshared/common-patterns.md § Async Pollingshared/config-pattern.md/speech for voiceoverUser : "Create an explainer video introducing Claude Code"
Agent workflow :
curl -sS -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Source: skills" \
-d '{
"sources": [{"type": "text", "content": "Introduce Claude Code: what it is, key features, and how to get started"}],
"speakers": [{"speakerId": "cozy-man-english"}],
"language": "en",
"mode": "info"
}'
Poll until text is ready, then generate video if requested.
Weekly Installs
379
Repository
GitHub Stars
28
First Seen
12 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex375
gemini-cli373
cursor373
opencode373
cline372
github-copilot372
AI Elements:基于shadcn/ui的AI原生应用组件库,快速构建对话界面
54,900 周安装
When notified, download and present script :