
Douyin
Download Douyin videos or fetch title, author, and stats via browser automation for research and repurposing pipelines.
Overview
Douyin is an agent skill most often used in Grow (also Idea discover) that downloads Douyin videos or returns video info using nodriver browser automation and a Python script.
Install
npx skills add https://github.com/xiaoyiv/douyin-skill --skill douyinWhat is this skill?
- Downloads Douyin videos from v.douyin.com short links and full URLs
- --info-only mode for metadata without file download
- One-time interactive login profile via nodriver-kit
- Python download script with optional output directory
- Browser automation–based flow, not a public official API wrapper
- Supports short links (v.douyin.com) and full video URLs
- CLI flags: --info-only and --output
Adoption & trust: 4.1k installs on skills.sh; 2 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need a Douyin clip or its stats for research but manual saving and scraping is slow and breaks on short links.
Who is it for?
Builders running content research, localization, or analysis workflows that legitimately need Douyin assets on disk.
Skip if: Users who cannot run Python/browser automation, or projects that require guaranteed API stability without login sessions.
When should I use this skill?
User wants to download Douyin videos or get video info (title, author, stats); supports short links and full URLs.
What do I get? / Deliverables
You get a local video file or structured info output from a supported Douyin URL after one-time browser login setup.
- Downloaded video file(s)
- Metadata snapshot in info-only mode
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Content growth is the primary shelf because the skill supports harvesting Douyin media and metadata for creator workflows. Short-video research, archiving, and competitive content study map directly to the content subphase rather than backend build.
Where it fits
Download a reference clip into ./videos before scripting a localized remake.
Pull --info-only stats on trending Douyin posts in a niche.
Archive competitor Douyin creatives for side-by-side format comparison.
How it compares
Browser-login download integration—not an official Douyin API SDK or a generative video editor.
Common Questions / FAQ
Who is douyin for?
Indie creators and agents-on-call who work with Douyin URLs and comfortable with Python plus nodriver-kit setup.
When should I use douyin?
In Grow for content archiving and stats; in Idea for competitor or trend discovery when the user asks to download Douyin videos or get video info.
Is douyin safe to install?
It uses local browser profiles and network access; review the Security Audits panel on this page and respect Douyin terms and copyright.
SKILL.md
READMESKILL.md - Douyin
# Douyin Skill Download videos from Douyin using browser automation. ## Setup (One-Time) ```bash python -m nodriver_kit.tools.login_interactive --url https://www.douyin.com --profile douyin ``` ## Download Video ```bash python scripts/download.py "https://v.douyin.com/xxx" python scripts/download.py "https://v.douyin.com/xxx" --info-only python scripts/download.py "https://v.douyin.com/xxx" --output ./videos ``` # Douyin Skill A Claude Code skill for downloading Douyin (抖音) videos. **Usage:** See [SKILL.md](./SKILL.md) ## Dependencies - [nodriver-kit](https://github.com/anthropics/nodriver-kit) AGPL-3.0 # Python __pycache__/ *.py[cod] *$py.class *.so .Python .venv/ venv/ ENV/ env/ # Data and cache data/ *.json *.db *.log # IDE .vscode/ .idea/ *.swp *.swo *~ # OS .DS_Store Thumbs.db # Temporary files *.tmp temp/ #!/usr/bin/env python3 """ Download Douyin videos. Usage: python download.py <url> [--output <dir>] [--info-only] Examples: python download.py https://v.douyin.com/xxx python download.py https://www.douyin.com/video/123456 --output ./videos python download.py https://v.douyin.com/xxx --info-only """ import argparse import asyncio import json import logging import re import sys from pathlib import Path from typing import Any, Dict, List, Optional import requests logger = logging.getLogger(__name__) DEFAULT_PROFILE = "douyin" async def parse_video(url: str, profile: str = DEFAULT_PROFILE, timeout: int = 30) -> Dict[str, Any]: """Parse video info from Douyin URL using CDP network monitoring.""" from nodriver_kit import cdp, connect_browser, browser_start, browser_stop browser = None api_responses: List[Dict] = [] own_browser = False started_port = None # Track port if we started browser try: # Try to connect to existing browser first try: browser = await connect_browser(port=9222) logger.info("Connected to existing browser on port 9222") except Exception: # Start new browser using nodriver-kit (handles session restore, etc.) logger.info(f"Starting browser with profile: {profile}") result = browser_start(profile=profile) if "error" in result: raise RuntimeError(result["error"]) started_port = result["port"] browser = await connect_browser(port=started_port) own_browser = True tab = browser.main_tab await tab.send(cdp.network.enable()) request_map: Dict[str, str] = {} def on_request(event: cdp.network.RequestWillBeSent): req_url = event.request.url if "aweme/v1/web/aweme/detail" in req_url: request_map[event.request_id.to_json()] = req_url async def on_response(event: cdp.network.ResponseReceived): req_id = event.request_id.to_json() if req_id in request_map: try: body_result = await tab.send(cdp.network.get_response_body(event.request_id)) api_responses.append(json.loads(body_result[0])) except Exception: pass tab.add_handler(cdp.network.RequestWillBeSent, on_request) tab.add_handler(cdp.network.ResponseReceived, on_response) logger.info(f"Navigating to: {url}") await tab.get(url) for _ in range(timeout): await asyncio.sleep(1) if api_responses: await asyncio.sleep(2) break current_url = tab.url logger.info(f"Page URL: {current_url}") # Extract video ID video_id = _extract_video_id(current_url) or _extract_video_id(url) # Parse API response video_url =