Douyin Publisher
Automate publishing videos to the Douyin creator platform (creator.douyin.com) with Playwright browser automation.
发布前检查
发布前必须先确认这些条件,避免上传到一半才失败:
- 确认视频文件存在,并用双引号包住完整路径。
- 确认
--title已提供,标题不超过 55 个字符。 - 正式发布必须带
--cover。优先使用同一exports/目录下最新的*cover*.png、*cover*.jpg、*封面*文件;没有封面时先生成封面再发布。 - 先运行
pnpm run douyin:status,只有Live check: Logged in才继续发布。 - 默认公开发布时不要额外依赖点击“公开”。脚本应把
public当成默认状态;只有private或friends才需要主动切换可见性。
如果需要从视频生成临时封面:
ffmpeg -y -ss 00:00:01 -i "/path/to/video.mp4" -frames:v 1 "/path/to/cover.png"
Install
From the skill root, install dependencies and the Chromium browser:
pnpm install
pnpm exec playwright install chromium
Create a local environment file when overriding defaults. If .env is missing, create it directly:
if [ ! -f .env ]; then
cat > .env <<'EOF'
# Douyin session storage directory (cookies, localStorage)
DOUYIN_SESSION_DIR=~/.douyin-sessions
# Default session name
DOUYIN_DEFAULT_SESSION=default
# Browser options
DOUYIN_HEADLESS=false
DOUYIN_BROWSER_CHANNEL=chromium
# Upload defaults
DOUYIN_DEFAULT_VISIBILITY=public
# Timeout settings (milliseconds)
DOUYIN_UPLOAD_TIMEOUT=600000
DOUYIN_LOGIN_TIMEOUT=300000
EOF
fi
When this skill is vendored inside a project that already has dependencies installed, the project can call scripts/douyin-publish.ts directly. For SkillHub distribution, keep package.json and all runtime code inside this skill directory.
Environment
Optional .env values:
DOUYIN_SESSION_DIR: session storage directory, default~/.douyin-sessionsDOUYIN_HEADLESS: settruefor headless mode, defaultfalseDOUYIN_BROWSER_CHANNEL: Playwright browser channel, defaultchromiumDOUYIN_UPLOAD_TIMEOUT: upload timeout in milliseconds, default600000DOUYIN_LOGIN_TIMEOUT: login timeout in milliseconds, default300000
Commands
Login is required before publishing:
pnpm run douyin:login
pnpm run douyin:login -- --method sms --phone 13800138000
pnpm run douyin:login -- --session account1
Publish a video:
pnpm run douyin:publish ./video.mp4 --title "My first video" --cover ./cover.jpg
pnpm run douyin:publish ./video.mp4 \
--title "My video title" \
--description "Video description" \
--tags travel food \
--cover ./cover.jpg \
--session account1
Schedule a video:
pnpm run douyin:publish ./video.mp4 \
--title "Scheduled video" \
--cover ./cover.jpg \
--schedule "2026-06-01T10:00:00+08:00"
For native datetime-local controls, the script fills YYYY-MM-DDTHH:mm from the provided schedule value.
Do not add an extra -- after pnpm run douyin:publish in this package. In the observed pnpm setup, the extra separator was forwarded as a literal video argument and caused --title to be missed.
Check session status:
pnpm run douyin:status
pnpm run douyin:status -- --session account1
Utility Script
The executable entrypoint lives inside this skill:
pnpm exec tsx scripts/douyin-publish.ts --help
Runtime modules live under scripts/douyin/. Keep helper scripts for this workflow under scripts/ in this skill directory so the skill remains self-contained when published.
How It Works
- Uses Playwright with a stealth plugin to simulate a real browser.
- Stores named browser sessions in
~/.douyin-sessions/<name>/state.json. - Opens a browser for manual QR scan or SMS verification when logging in.
- Automates the creator upload page, metadata entry, optional cover upload, scheduling, and publish confirmation.
- Writes upload screenshots to
debug-output/for troubleshooting.
Troubleshooting
Use debug-output/publish-*/ checkpoints to locate the failure:
01-upload-page-loadedand02-video-file-selectedonly: video entered the page, then processing or required metadata blocked.metadata-filledmissing with an error likelocator.click: Timeout ... waiting for locator('text=公开')and<label ...> intercepts pointer events: do not click defaultpublic; keep public as the default and retry after verifying the script skips that click.cover-uploadedmissing: rerun with an explicit--coverpath. Missing cover can leave the page in a state where publish controls stay disabled or downstream clicks become unreliable.publish-button-enabledmissing: inspect the screenshot for incomplete title, cover, originality/terms controls, or account prompts.publish-successpresent withStatus: reviewing: the publish request succeeded and Douyin is reviewing the video.
Recommended retry command after a cover-related failure:
pnpm run douyin:publish "/path/to/video.mp4" \
--title "视频标题" \
--cover "/path/to/cover.png"
Limitations
- First login requires manual QR scan or SMS code entry.
- Captcha challenges require manual intervention.
- Douyin UI selectors may change and require script updates.
- Video processing and review happen server-side after submission.
微信扫一扫