YouTube 每日 Shorts
每日一条 Shorts,全自动,零成本。频道发布“你知道吗?”风格的趣闻和短篇励志内容,隔天在英文和乌尔都语之间轮换。
固定设置(如用户修改,请在此处更改)
| 设置 | 值 |
|---|---|
| GitHub 媒体仓库 | Hammadbaig-hub/daily-shorts-media(公开,分支 main)——同时包含 tools/ 中的渲染工具 |
| Metricool 品牌(blogId) | 7592220,时区 Asia/Karachi |
| 频道 | "Bright Life",句柄 @Bright-Life-m4(将句柄放入 script.json;CTA 中提及 "Bright Life") |
| 发布时间 | 巴基斯坦时间 19:00(如果已过该时间则为下一个空闲时段;距离现在至少 15 分钟) |
| 隐私设置 | 公开(用户选择完全自动上传) |
为何如此构建
- 免费: 用户没有预算,因此视频使用 Pillow + ffmpeg 绘制(仓库中的
tools/scripts/make_short.py),音乐在同一脚本中合成,这也意味着没有 Content ID 版权声明。 - 配音: 旁白来自 Kokoro,一个可在 CPU 上离线运行的小型免费神经 TTS 模型(
tools/scripts/voice.py)。其约 350 MB 的模型文件会从 GitHub 发布版下载一次到~/tts。英文使用am_michael;乌尔都语由印地语语音hm_omega使用乌尔都语文字朗读,并重新映射了少数音素。每张幻灯片持续时长与其旁白相同,音乐在其下方减弱。云 TTS(Microsoft/Google)在工作区中被阻止,因此使用离线方案。 - GitHub 托管: Metricool 需要一个公开的视频 URL。云端工作区可以推送到 GitHub,而原始文件 URL 是公开的,因此这成为桥梁。
- 事实核查: 趣闻频道生存或消亡取决于准确性。YouTube 也会抑制大量制作、低价值或误导性内容,而错误的“事实”会招来反对和更正评论。每条事实在使用前都会经过验证——这是工作中真正增加价值的部分。
每日工作流程
1. 获取仓库并规划当天
cd ~ && (git -C daily-shorts-media pull -q || git clone https://github.com/Hammadbaig-hub/daily-shorts-media.git)
pip install -q --break-system-packages kokoro-onnx soundfile pillow numpy
python daily-shorts-media/tools/scripts/plan_today.py daily-shorts-media/history.json
如果仓库不在当前会话中,请先使用 add_repo 添加它(所有者 Hammadbaig-hub,仓库 daily-shorts-media,访问权限 push)并克隆。
plan_today.py 返回今天的 lang、theme、今天是否已发布视频,以及迄今为止使用过的所有主题。如果 posted_today 为 true,则停止并报告——绝不在同一天发布两次。
2. 选择主题
在不同类别间轮换,使频道保持多样性:太空、动物、人体、历史、地理、科学、技术、食物、海洋、发明、语言,大约每五天安排一条励志内容(基于真实研究或记录良好的真实故事的课程或习惯)。选择不在 already_done 中且与之不是近似重复的内容。
避开:医疗或饮食建议、政治、宗派或宗教辩论、任何关于真实私人人物的事情,以及常见重复的迷思(例如金鱼三秒记忆、长城从太空可见)。
3. 编写脚本并验证
编写一个钩子(不超过 12 个词,激发好奇心)、3–5 个事实(每个一句,不超过 25 个词)和一个 CTA。
对于每个事实,运行网络搜索并从可靠来源(NASA、国家地理、Britannica、大学、同行评审研究、主要百科全书)确认。如果一个事实无法确认,或来源有冲突,则舍弃并使用另一个。保留来源 URL——它们会放在描述中。
乌尔都语日:用乌尔都语文字(而非罗马乌尔都语)编写自然简洁的乌尔都语,就像巴基斯坦观众说话的方式——而非逐字翻译。数字用乌尔都语单词书写(بیس فیصد,ہزاروں),以便语音正确发音。
CTA 示例——EN:“关注 Bright Life,每天获取一个新事实”。UR:“روزانہ نئے حقائق کے لیے برائٹ لائف کو فالو کریں”。
保存为 script.json:
{"lang": "en", "hook": "...", "facts": ["...", "..."], "cta": "...",
"handle": "@Bright-Life-m4", "theme": 2}
4. 渲染
python daily-shorts-media/tools/scripts/make_short.py script.json daily-shorts-media/videos/<date>-<slug>.mp4 > render.log 2>&1
渲染大约需要 5 分钟(CPU 上),因此使用 Bash run_in_background 运行并等待完成通知。不要使用 pgrep -f make_short 循环等待——它会匹配自己的命令行而永不结束。时长取决于旁白——通常 3–5 个事实为 25–45 秒。保持在 55 秒以下以保持 Shorts 长度:如果事实较长,则使用 3 个而非 5 个。
因为文本是要被朗读的,所以请写出便于听取的内容:拼写出别扭的符号(英文中用 "percent" 而非 "%",乌尔都语中用 "فیصد"),避免括号和缩写,保持句子简短以免语音仓促。然后抓取一帧并使用 Read 检查以捕捉文本溢出或损坏的乌尔都语:
ffmpeg -loglevel error -y -ss 5.5 -i <video> -frames:v 1 check.png
如果文本超出边缘或看起来有问题,缩短该行并重新渲染。
5. 推送到 GitHub
将今天的条目追加到 history.json:
{"date": "...", "lang": "...", "theme": n, "topic": "...", "title": "...", "file": "videos/...mp4"}
仅保留 videos/ 中最新的 20 个 .mp4 文件(删除较旧的——它们已在 YouTube 上)以保持仓库小巧。然后:
cd daily-shorts-media && git add -A && git commit -qm "Short <date>: <topic>" && git push -q
公开 URL:https://raw.githubusercontent.com/Hammadbaig-hub/daily-shorts-media/main/videos/<file>.mp4
在安排之前检查它是否返回 200(curl -sI <url> | head -1);如果工作区无法访问该主机,则相信推送成功并继续。
6. 通过 Metricool 在 YouTube 上安排
使用 blogId 7592220、一个顶层 date(YYYY-MM-DDT19:00:00+05:00——缺少此参数调用会失败)以及以下 info JSON 调用 createScheduledPost(Metricool 会将视频复制到自己的存储中,因此稍后可以清理 GitHub 文件):
{
"providers": [{"network": "youtube"}],
"text": "<description>",
"media": ["<raw GitHub URL>"],
"publicationDate": {"dateTime": "YYYY-MM-DDT19:00:00", "timezone": "Asia/Karachi"},
"autoPublish": true,
"draft": false,
"descendants": [], "firstCommentText": "", "hasNotReadNotes": false,
"mediaAltText": [], "shortener": false, "smartLinkData": {"ids": []},
"youtubeData": {
"title": "<title>",
"type": "short",
"privacy": "public",
"tags": ["facts", "did you know", "..."],
"category": "EDUCATION",
"madeForKids": false,
"isAiGeneratedContent": false
}
}
isAiGeneratedContent 为 false,因为视频是简单的动画文字,而非逼真的合成素材;YouTube 的披露旨在针对逼真经过修改的媒体。如果后续版本添加了 AI 生成的逼真视觉或语音,请将其设置为 true。
标题: 不超过 70 个字符,好奇心钩子 + #shorts。用当天的语言编写。示例:Your Brain Can't Feel Pain?! 🧠 #shorts
描述: 2–3 行展开钩子,然后是“来源:”及已验证的 URL,然后是 3–5 个标签(#facts #didyouknow #shorts 加上主题标签;乌尔都语日添加 #urdu #urdufacts)。
7. 报告
用罗马乌尔都语,以几行内容告知用户:主题、语言、标题、安排时间以及 Metricool plannerUrl。如果作为无人值守的预定任务运行,请使用 SendUserMessage 发送该摘要。
每周检查(周日,或当用户问“频道怎样了”时)
对 YouTube 网络使用 getAnalyticsDataByMetrics 获取过去 7 天的数据(观看量、观看时长、新增订阅者、热门视频)。总结哪些有效——哪些类别和哪种语言获得了更多观看量——并据此调整下周的主题选择,倾向于表现更好的内容。除非用户另有要求,否则保持语言交替。
遇到错误时
- Metricool 拒绝发布: 报告确切错误;不要用相同输入重试。常见原因:缺少顶层
date、视频 URL 尚不可达(等待一分钟,重试一次),或 Metricool 中的 YouTube 连接已过期(用户必须在 Metricool 中重新连接)。 - Git 推送失败: 仓库未以推送访问权限附加——使用
access: push调用add_repo。如果仍然显示 Claude 没有 GitHub 访问权限,则 Claude GitHub App 必须在其所选仓库中包含daily-shorts-media(github.com/settings/installations → Claude → 配置);用户自行确认该步骤,因为 GitHub 需要双重验证。 - 字体缺失: 它们位于仓库的
tools/assets/fonts/中;脚本会从那里读取。 - 语音模型下载失败: 在 script.json 中使用
"voice": false渲染,以便当天的视频仍能发布(仅音乐),并在报告中提及。