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"
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.
Optional .env values:
DOUYIN_SESSION_DIR: session storage directory, default ~/.douyin-sessionsDOUYIN_HEADLESS: set true for headless mode, default falseDOUYIN_BROWSER_CHANNEL: Playwright browser channel, default chromiumDOUYIN_UPLOAD_TIMEOUT: upload timeout in milliseconds, default 600000DOUYIN_LOGIN_TIMEOUT: login timeout in milliseconds, default 300000Login 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
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.
~/.douyin-sessions//state.json .debug-output/ for troubleshooting.Use debug-output/publish-*/ checkpoints to locate the failure:
01-upload-page-loaded and 02-video-file-selected only: video entered the page, then processing or required metadata blocked.metadata-filled missing with an error like locator.click: Timeout ... waiting for locator('text=公开') and : do not click default public; keep public as the default and retry after verifying the script skips that click.cover-uploaded missing: rerun with an explicit --cover path. Missing cover can leave the page in a state where publish controls stay disabled or downstream clicks become unreliable.publish-button-enabled missing: inspect the screenshot for incomplete title, cover, originality/terms controls, or account prompts.publish-success present with Status: 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"
共 1 个版本