Wjs Uploading Video — Wjs 上传视频
v3上传一个或多个视频到 YouTube。当用户想要“上传到 YouTube”、“发 YouTube”、“批量上传”、“upload to YouTube”、“post videos to YouTube”,或发布一个完成的 `final/` 目录的 MP4 文件时使用。从同级的 `UPLOAD_META.md` 文件中读取每个视频的元数据(标题/描述/标签),如果文件存在(用户的标准 markdown 格式),否则从命令行标志中读取。通过使用 `requests` 直接进行可恢复上传,支持在 SOCKS/HTTP 代理后运行(原始的 `google-api-python-client` MediaFileUpload 在此代理设置下会卡住)。
运行时依赖
安装命令
点击复制技能文档
wjs-uploading-video 将完成的视频上传到 YouTube。默认设置适用于此用户的工作流程(王建硕频道,中国网络使用本地代理,1080p 水平录制从 Riverside / 多摄像头编辑)。
何时使用: 用户有一个或多个完成的 .mp4 文件,并希望将其上传到 YouTube 用户指向一个 final/ 目录,其中包含多个段和一个 UPLOAD_META.md 用户希望指定隐私 / 播放列表 / 计划发布
不适用: 微信视频号上传(无公共 API;用户通过 Web 手动上传) 抖音 / 小红书 / B 站(不同的 API,尚未在此实现) YouTube Shorts 变体从水平源(先使用 wjs-reframing-video 生成 9:16 剪辑,然后通过此技能上传)
先决条件(每台机器一次): Google Cloud OAuth 客户端:~/.config/youtube/credentials.json 必须存在。请参阅 references/credentials-setup.md 获取 5 分钟设置说明(如果缺失)。 Python 依赖项:pip3 install google-auth-oauthlib google-api-python-client requests(仅 google-auth + requests 在上传时严格需要,但 OAuth-lib 会拉取它们)。
第一次上传将打开浏览器进行 Google 同意,并写入 ~/.config/youtube/token.json。后续运行将默默地重用它。
工作原理(以及为什么不是原生的 youtube-uploader) YouTube 的可恢复上传协议在元数据 POST 后发出 Location: URL,然后接受分块 PUT 请求的字节。原生的 google-api-python-client 在此用户的本地 SOCKS+HTTP 代理栈上运行此协议,会在后续的 PUT 请求中抛出 [Errno 65] 无路由到主机或 socket.timeout 并无限期阻塞。此技能绕过了 httplib2:它通过 google-auth 进行 OAuth,然后使用 requests 手动驱动可恢复上传,显式传递代理。8 MB 块(不是原生的 256 KB)- 通过代理的往返次数较少。socket.timeout / ConnectionError / 5xx 上的指数退避重试。如果您想“直接调用 YouTube API 客户端”,请不要这样做 - 它将在此环境中失败。
使用方法: 批量上传 final/ 目录 python3 ~/.claude/skills/wjs-uploading-video/scripts/upload_youtube.py \ --dir "/path/to/final" \ --meta "/path/to/final/UPLOAD_META.md" 脚本: 读取 UPLOAD_META.md 并将每个 ## NN · filename.mp4 块与 --dir 中的视频文件配对 跳过 --results-file(默认
/.youtube_upload_results.json)中已有的视频 - 安全地在失败后重新运行 顺序上传,每 8 MB 进度一次 将最终 URL 列表写入 --results-file 单个文件 python3 ~/.claude/skills/wjs-uploading-video/scripts/upload_youtube.py \ --video /path/to/clip.mp4 \ --title "My Title" \ --description "Body text" \ --tags "tag1,tag2,tag3"常见覆盖: 标志 默认 值 备注 --privacy unlisted 私有 / 不公开 / 公开 --category 28 28 = 科学与技术。27 = 教育。24 = 娱乐。 --made-for-kids false YouTube 需要此声明 --playlist 无 将每个上传的视频添加到播放列表中 --publish-at 无 计划发布(需要 --privacy 私有) --credentials ~/.config/youtube/credentials.json OAuth 客户端 JSON --token ~/.config/youtube/token.json 缓存的 OAuth 令牌 --chunk-mb 8 如果上传继续失败,请使用较小的块 --dry-run 关闭 解析元数据 + 列出将要上传的内容,不要触摸网络
UPLOAD_META.md 格式 解析器预计用户的标准结构:
01 · segment_01_no-bugs.mp4 短标题 代码没有错误,只有意图不一致 视频描述 AI 时代屎山的重新定义... —— 王建硕 × 任鑫《...》第 1 集 #王建硕 #AI编程 #ClaudeCode
--- 映射:NN · → 此块描述的视频
短标题(或 Title)块 → YouTube 标题,逐字。 视频描述(或 Description)块 → YouTube 描述,逐字,保留底部的 # 标签 视频描述中的所有 # 单词标记 → YouTube 标签(每个 # 被剥离;用户的频道名称 王建硕 根据全局指令自动添加) 标题中的文件名必须与 --dir 中的实际文件匹配。如果文件存在但没有元数据块,脚本会大声报错 - 传递 --allow-missing-meta 以使用 --title 和空描述上传它。此技能内置的合理默认值: 隐私 = 不公开:允许用户在公开之前进行审查;在 YouTube Studio 中准备好后切换(或传递 --privacy 公共) 类别 = 28(科学与技术):与 王建硕 频道的主要内容相符;使用 --category 覆盖每次上传 selfDeclaredMadeForKids = false:YouTube 需要;用户的内容针对成人 块大小 = 8 MB:通过此用户的本地代理验证的工作大小(256 KB 停滞) 跳过已上传:结果文件是事实的来源;删除它将强制重新上传 频道名称 CTA 规则 如果您在视频元数据中写入描述脚注、签名或“订阅我”的行,请使用 王建硕(用户的频道名称)。不要在那里放置客人的名字 - 像 任鑫 这样的客人属于描述内部。