Video Publish (Bilibili / YouTube / Douyin / Kuaishou / Xiaohongshu)
Hard Rules
- Before each publication, list the platform, account, file, cover, title, description, tags, category, and publishing method in a table for the user. Only execute when the user explicitly says "publish". The user can approve multiple items at once (e.g., "publish EP2–EP4 all"), but this only covers those specific items and content; any content changes require re-confirmation.
- Only the user can log in (terminal QR code scan). Do not enter account names, passwords, phone numbers, or verification codes for the user. Do not read or print cookie content.
- Uploads to Douyin, Kuaishou, and Xiaohongshu are based on
patchright(a browser that conceals automation traces). The user decides to use it, but the user runs the upload commands in their own terminal: Claude is responsible for preparing the complete command and submission information, but does not execute login/upload for these platforms, nor does it handle slider CAPTCHAs for the user.
Preparation
- Before publishing, review the compliance checklist in
references/plotome-lessons.mdoftech-explainer-video: check "Contains AI-generated content" (even if the narration is AI also check), include music licensing and attribution in the description, and do not use real faces or trademarks. - Write
out/upload_meta.mdaccording toreferences/upload-meta-template.md. The description should only contain content actually covered in the video. Prepend it with "Personal study notes." (user preference). - Cover: 1920×1080, no subtitles; generated by the
cover-epKcomposition oftech-explainer-video. - Send to the user for review (SendUserFile), and ask clearly about: cover, whether a code link (GitHub/Gist) is needed, and collection name.
Bilibili
Tool: dreammis/social-auto-upload (installed at ~/tools/social-auto-upload), which uses the biliup it downloads automatically for actual submissions.
First-time installation (first inform the user of the source, content, and size; wait for user consent before installing):
git clone --depth 1 https://github.com/dreammis/social-auto-upload.git ~/tools/social-auto-upload
cd ~/tools/social-auto-upload && uv venv --python 3.12 && uv pip install -e . && uv pip install playwright
cp conf.example.py conf.py
Login (have the user run this in their own terminal, select "QR code login" from the menu, and scan with the Bilibili app; if the QR code is not fully displayed, open qrcode.png):
cd ~/tools/social-auto-upload && .venv/bin/sau bilibili login --account <account_name>
Do not select SMS login: it will require passing a slider CAPTCHA and manually copying the challenge, which can easily expire and fail.
Check login: .venv/bin/sau bilibili check --account <account_name>, output should be valid.
Upload:
- First test the upload line:
tools/probe_lines.sh. Pick the fastest line (usuallytxorbda2). Do not let biliup auto-detect speed, as it may get stuck when going through a proxy. - Submit each video one by one:
The script converts the paths to absolute paths (it internally~/.claude/skills/video-publish/tools/bili_upload.sh <account_name> out/ep1.mp4 out/covers/ep1.jpg tx 231 "<title>" "<description>" "<tags,comma-separated>"cds tosocial-auto-upload). You can use relative paths from the video project directory. On success it printsSubmission successful BVxxxx link. On failure it prints the end of the log. Transmit episodes one by one in order, and tell the user the BV number after each episode. - After all are uploaded, remind the user to create a collection in the Creator Center "Collection Management" and add episodes in order; they will be public only after review.
Network troubleshooting:
- Very slow uploads,
error sending request,connection reset, server 500: usually caused by proxy TUN routing traffic through overseas nodes. Have the user addDOMAIN-SUFFIX,bilibili.com,DIRECTandDOMAIN-SUFFIX,bilivideo.com,DIRECTearly in the proxy rules, then reload the configuration. Runprobe_lines.shagain; only upload when speed reaches hundreds of KB/s or higher. - Monitor progress:
nettop -p <biliup pid> -L 1 -x -J bytes_out. biliup logs produce very little output until the upload completes, so do not assume it is stuck due to lack of output. - macOS does not have a
timeoutcommand. - If the first run of sau fails to download biliup (slow GitHub Release access): manually download using
https://gh-proxy.com/orhttps://gh-proxy.org/prepended to the release URL. - Before retransmitting, first verify that the previous submission did not succeed (check logs for a bvid) to avoid duplicate submissions.
Bilibili: Upload Limit and Multi-Parts
- New submissions are limited to approximately 7 per day. Exceeding this returns
21566 Submission too frequent. You must wait until the next day. Package one chapter into a single multi-part submission (biliupuploaduploads multiple files at once; the filenames become the part titles. Use hard linksout/parts/P<k> <episode_title>.mp4for naming to avoid extra disk space). - To append parts to an existing submission, use
biliup append --vid BV…. This does not consume the new submission quota. - Tags: maximum 12; truncate if exceeded. Test the line first with
probe_lines.sh;bldsahas had certificate expiration issues – if it fails, switch totx/bda2. - Queue script example:
tools/examples/upload_chapters.sh(retries on 21566 error every hour, up to 24 times; on success, writes- Result: BV… P<k>back toupload_meta.md).
Bilibili: Append to Existing Submission (Series Collection, tested with knowledge base from October to November 2026)
- One series uses a single multi-part submission. Each subsequent article appends using
biliup append --vid BV…. Do not create a new submission (especially not when the user explicitly says not to). - Queue script example:
tools/examples/upload_append.sh: one line per article:app <name> <BV> <project_directory>. Appendsout/parts/*.mp4in order.- Idempotent: on success, writes
<name> append <BV> <date>toresults.log; re-running automatically skips ("Already appended"). To add a new batch, simply add new lines at the end and rerun the whole script. - Line rotation:
alia→tx→bda2. If all three fail, sleep for 30 minutes and retry, up to 48 rounds. Success is determined by seeingManuscript modification successfulin output. - Launch with
nohup <script> > upload_kbN.log 2>&1 & disown; log files are labeled by batch number. Run a separate backgrounduntilloop waiting for the log to contain "Queue complete". - Common failure
client error (Connect): line fluctuation; the script will retry automatically – do not manually retransmit (this would duplicate parts).
- Idempotent: on success, writes
- Part titles are the filenames:
out/parts/P<k> <hook>: <topic>.mp4(hard link toout/epK.mp4, no extra space). appendcannot modify the description: for each batch, write a "Description supplement" paragraph inupload_meta.md, then append a note to a notes board for the author to manually paste it at the end of the original manuscript description in the Creator Center.- Different language versions (e.g., English dubbing) should not be appended to the Chinese manuscript; let the user decide where to publish them.
YouTube
- Tool: same sau (
sau youtube login/upload-video, must use--headed; headless mode prevents Google from allowing Studio access). The sau built-in YouTube uploader has two bugs. The fix is intools/examples/sau-youtube-fixes.patch: login check waits only 3 seconds and uses headless (false positive invalid); playlist selector clicks incorrectly (playlist never gets added, and the exception is swallowed). After installing sau on a new machine, apply this patch first. - Playlists must be created in Studio first (otherwise
--playlisthas no effect); after upload, randomly check one episode to verify it is in the playlist – if not, manually add it from the Studio video edit page. - There is a daily upload limit: if "Publish button not found" appears, or videos remain in draft status, it is likely the limit has been reached. Do not retransmit (this would leave duplicate drafts). In Studio, complete the drafts and publish them; upload the remaining ones the next day.
- Queue script example:
tools/examples/youtube_queue.sh(for long queues, usenohup … & disown; background tasks from a session will be recycled). - API approach (no browser):
youtubeuploader(brew install youtubeuploader) +tools/examples/youtube_api_upload.sh. Prerequisites: Google Cloud project with YouTube Data API v3 enabled, OAuth consent screen (external, add test users), Web application credentials (callbackhttp://localhost:8080/oauth2callback). For projects not approved, videos uploaded via API will always be locked to private; the approval form at https://support.google.com/youtube/contact/yt_api_form requires a public homepage, privacy policy, terms of service (can use GitHub Pages, example cassieliang6709/video-uploader), screenshots of the homepage/privacy page, OAuth flow, architecture diagram, user flow diagram, and the complete upload script. Continue using browser automation until approval.
Douyin / Kuaishou / Xiaohongshu
Tools: same social-auto-upload's sau douyin|kuaishou|xiaohongshu, browser automation (patchright).
The user must run the commands in their own terminal (see Hard Rules). Claude only prepares the commands and checks the results.
Videos: These three platforms primarily use portrait orientation. The recommended resolution is 1080×1920, or cut to about 1 minute of highlights; if needed, return to tech-explainer-video to render a portrait version.
Landscape videos can also be uploaded, but they will have black bars.
First-time browser installation (user runs):
cd ~/tools/social-auto-upload && PLAYWRIGHT_DOWNLOAD_HOST="https://npmmirror.com/mirrors/playwright" .venv/bin/patchright install chromium
Login & check (user runs; <platform> is douyin, kuaishou, or xiaohongshu):
cd ~/tools/social-auto-upload && .venv/bin/sau <platform> login --account <account_name> --headed
.venv/bin/sau <platform> check --account <account_name>
Upload (Claude fills in the complete command based on upload_meta.md and sends it to the user; the user confirms the content and runs it themselves):
cd ~/tools/social-auto-upload && .venv/bin/sau <platform> upload-video --account <account_name> \
--file <absolute_path_to_mp4> --title "<title>" --desc "<body>" --tags <tags,comma-separated> \
[--thumbnail <cover>] [--schedule "YYYY-MM-DD HH:MM"] [--collection <existing_collection_name>]
- Douyin:
--thumbnailshould be 3:4 portrait orientation; there is also--thumbnail-landscape(4:3); title cannot exceed 30 characters. - Kuaishou:
--thumbnailcan be any aspect ratio; the script only fills in the first 3 tags, so put the most important ones first. - Xiaohongshu: title cannot exceed 20 characters; does not support
--collection. - After the user runs it, paste the terminal output back for Claude to determine success or failure and write the link back to
upload_meta.md. If a slider CAPTCHA appears, the user handles it themselves. - For Douyin, publishing one chapter as a complete chapter collection (concatenate all episodes into
out/chapter.mp4, with a 4:3 landscape cover) is easier to manage than publishing episodes one by one. Queue script example:tools/examples/douyin_upload_all.sh(user runs in their own terminal; login check uses headed mode withDOUYIN_COOKIE_AUTH_HEADLESS=false).
Alternative (when you don't want to use scripts): Open the platform's creator page in the user's already-logged-in Chrome, help the user select the file, fill in the title and body, take a screenshot just before pressing the publish button, and let the user click "Publish" themselves.
Batch Pipeline (only with explicit user authorization)
The user can grant long-term authorization for a series: "After rendering a batch → directly upload → delete finished video files" (e.g., nudgecode algorithm illustration, authorized 2026-10-24). This authorization only covers the specific series mentioned by the user. Changing the series or platform requires asking again. Within the scope of authorization:
- After each chapter in this batch is rendered, write its title, description, and tags according to the existing
upload_meta.mdformat of that series (the description still starts with "Personal study notes." and only includes content present in the video). No longer need to show each item to the user; still runsau bilibili checkto confirm login andprobe_lines.shto select the best line. - Upload in chapter order, episode order. After each chapter, list the "Episode / Title / Link" in the conversation, and write the BV number back to
upload_meta.md. - Only delete an episode after obtaining its BV number:
out/epK.mp4,out/*.raw.mp4,out/check/,out/bundle/(and the project's ownnode_modules; shared symlinks are not touched). Keep source code, dubbing audio, srt subtitles, cover, andupload_meta.mdfor potential re-rendering. Never delete episodes that failed to upload. - If the delete command is blocked by permissions, give the command to the user to run themselves; do not try alternative methods to bypass it.
Cleanup
- Only delete a finished video after all target platforms have provided links. Deletion is often blocked by permissions; write a script for the user to run. Example:
tools/examples/cleanup_uploaded.sh(only deletes episodes that have results inupload_meta.md; can be run repeatedly).
Record
After publishing, write each episode's BV number back into the "Result" column of out/upload_meta.md, and list a table of "Episode / Title / Link" in the conversation.