Uniformly wraps three types of download capabilities:
douyin-downloader: preferred for Douyin, supports additional resources such as cover, music, JSON, and comments (already integrated into.runtime/douyin-downloader)。wx_channels_download: for WeChat Channelsweixin.qq.com/sph/share links, parsed and downloaded via a local API, without operating the WeChat client.yt-dlp: for video downloads from sites supported by yt-dlp.
After any of the three backends successfully downloads a video, it generates next to the media file
<媒体文件名>.metadata.json. The sidecar records the obtainable title, author, platform, publish time,
duration, video ID, full original caption, topics, and public source page, for downstream skills such as Immich
to automatically generate a complete description. For the field contract, see references/metadata-handoff.md。
Configuration sources
Configuration files are looked up in the following fixed order:
- Project-level: the skill's parent directory's
agent_config.toml - Global directory:
~/.agents/agent_config.toml
Do not use any other directory-guessing strategy.
This skill's configuration section is [video-downloader]. The template file is located in the skill directory:
agent_config.example.toml
Scope of responsibility:
agent_config.tomlonly stores this skill's high-level configuration, such as backend, tool paths, and default output directory.douyin-downloader's native runtime configuration continues to be stored in its ownconfig.yml。- Do not stuff the Douyin Cookie or
douyin-downloader's complete configuration structure intoagent_config.toml。
Script paths
Relative to the skill directory:
scripts/video_downloader.py
Prefer using this script; do not manually assemble download commands.
What to do first
When the user requests a download, first check the environment:
python3 scripts/video_downloader.py doctor --json
Decision rules:
- Douyin URL: prefer using
douyinbackend。 - WeChat Channels SPH share URL: use
wx-channelsbackend。 - Other URLs: prefer using
yt-dlpbackend。
If the target backend is unavailable:
- Do not silently install.
- First ask the user whether they want you to install it, or have the user specify the invocation path in
agent_config.toml.
Only execute installation commands after the user explicitly agrees.
Download commands
Douyin video
Video only:
python3 scripts/video_downloader.py download "https://v.douyin.com/xxxx/" --backend douyin --video-only
Video + music + cover + JSON:
python3 scripts/video_downloader.py download "https://v.douyin.com/xxxx/" --backend douyin --with-assets
With comments:
python3 scripts/video_downloader.py download "https://v.douyin.com/xxxx/" --backend douyin --with-assets --comments
yt-dlp supported sites
python3 scripts/video_downloader.py download "https://example.com/video" --backend yt-dlp
yt-dlp uses the same author directory structure as the other backends:
{default_output_dir}/{作者名或账号名}/{标题} [{id}].{ext}
The author directory takes uploader、channel、creator、uploader_id、channel_idin order; when none are available, use unknown-author。yt_dlp_output_template only controls a relative path within the author directory; absolute paths or ..。
WeChat Channels SPH share link
On first use, install the skill dependencies and the dedicated Chromium first:
uv sync --project scripts
uv run --project scripts python scripts/video_downloader.py install-wx-channels-browser
Confirm the local wx_channels_download API has been started and download:
uv run --project scripts python scripts/video_downloader.py doctor --json
uv run --project scripts python scripts/video_downloader.py start-wx-channels
uv run --project scripts python scripts/video_downloader.py download \
"https://weixin.qq.com/sph/xxxx" --backend wx-channels
This flow calls /api/channels/parse_sph, does not install a proxy certificate, and does not log in to or control the WeChat client. When authentication is missing or expired, the download command automatically opens the skill's dedicated Chromium and enters Tencent Yuanbao; the user only completes login, captcha, or QR code scanning, and the skill then automatically executes:
- Only reads
hy_source、hy_user、hy_token。 - atomically updates the upstream
config.yaml'scloudflare.sphCookie。 - sets the configuration file permissions to
600(POSIX)。 - Restart the local API and retry the original download once.
The download directory is grouped by the video account nickname:
{default_output_dir}/{视频号名称}/{精简标题} [{sph_id}].mp4
The simplified title takes the first line of the original description and removes #话题, filesystem-illegal characters, and symbol characters; the title part retains at most 30 characters; Chinese and regular punctuation remain unchanged, andsph_id is always retained for deduplication. The command also outputs the unmodified Original description, for writing into the description when uploading to Immich (including the original hashtags).
The command also outputs Metadata file. When uploading to Immich, pass the media path first so that Immich
automatically reads the adjacent sidecar;Original description is only for manual verification or downstream systems that do not support sidecars.
This is consistent with the rule that douyin-downloader creates directories by author nickname by default, but within the video account directory, post or a single-work directory is no longer added. Videos with the same name that older versions saved directly in the download root directory will be automatically migrated to the corresponding video account directory when processed again.
To actively refresh, run:
uv run --project scripts python scripts/video_downloader.py refresh-wx-channels-cookie
The dedicated browser profile is saved by default in the skill's .runtime/ and persists the login state. Do not point it to the profile of a daily browser such as Chrome or Edge, do not display or log cookies, and do not fall back to the WeChat client proxy mode.
Non-interactive tasks must place --non-interactive before the subcommand; if authentication is missing, fail directly without opening a browser:
uv run --project scripts python scripts/video_downloader.py --non-interactive \
download "https://weixin.qq.com/sph/xxxx" --backend wx-channels
Automatically select the backend
python3 scripts/video_downloader.py download "URL" --backend auto
Combining with Immich
When the user requests downloading and uploading to Immich:
- Execute
doctor --json, selecting the backend by URL. - Download the video and confirm the
Downloaded filereturned by the command or the backend's final media path. - Confirm that
<媒体文件名>.metadata.json。 - exists next to the media. Pass the media path to
immich upload; no need to manually concatenate--description。 - . After a successful upload, return Immich's public link. Downloaded files are retained by default.
The metadata sidecar contains only public whitelist fields, and does not include cookies, request headers, API keys,
browser profiles, or platform media direct links.yt-dlp does not save the full info JSON.
Installation command
Run only after the user has explicitly agreed.
Install or update douyin-downloader(already integrated into .runtime/douyin-downloader, dependencies are installed automatically on first use):
python3 scripts/video_downloader.py install-douyin
Install or update yt-dlp:
python3 scripts/video_downloader.py install-yt-dlp
Update douyin-downloader
douyin-downloader is already integrated into .runtime/douyin-downloader, update method:
cd .runtime/douyin-downloader
git pull origin main
rm -rf .venv
uv sync --extra browser --extra dev
The above commands are executed from the skill directory. You can also directly run python3 scripts/video_downloader.py install-douyin to complete installation or update.
Current version:184155f (2026-07-01)
Refresh Cookie
When Douyin download reports that the Cookie is missing or invalid, use this command to start browser login:
python3 scripts/video_downloader.py refresh-cookies
This opens a browser window; after the user completes Douyin login, the Cookie is saved automatically.
Trending list
Get the Douyin trending list and save it as a JSONL file:
# 获取前 30 条热搜
python3 scripts/video_downloader.py hot-board --limit 30
# 获取全部热搜
python3 scripts/video_downloader.py hot-board --limit 0
# 指定输出目录
python3 scripts/video_downloader.py hot-board --limit 30 --output-dir ~/Downloads/hot-board
The output file is saved in the hot_board/ subdirectory, with the filename format {timestamp}.jsonl。
Search works
Search Douyin works and save them as a JSONL file:
# 搜索关键词,默认最多 50 条
python3 scripts/video_downloader.py search "美食"
# 指定最大条数
python3 scripts/video_downloader.py search "美食" --max 100
# 指定输出目录
python3 scripts/video_downloader.py search "美食" --max 50 --output-dir ~/Downloads/search
The output file is saved in the search/ subdirectory, with the filename format {keyword}_{timestamp}.jsonl。
Configuration fields
[video-downloader] supports these fields:
[video-downloader]
default_backend = "auto"
default_output_dir = "~/Downloads/video-downloads"
yt_dlp_path = ""
yt_dlp_output_template = "%(title)s [%(id)s].%(ext)s"
douyin_downloader_home = ""
douyin_config_path = ""
wx_channels_api_url = "http://127.0.0.1:2022"
wx_channels_timeout_seconds = 30
wx_channels_login_timeout_seconds = 300
wx_channels_binary_path = ""
wx_channels_config_path = ""
wx_channels_browser_profile_dir = ""
hot_board_output_dir = ""
search_output_dir = ""
Notes:
yt_dlp_path: explicitly specifyyt-dlpExecutable file path.yt_dlp_output_template: the relative output template used by yt-dlp within the author directory, default%(title)s [%(id)s].%(ext)s. The skill always adds the author/account directory; the template may contain deeper relative subdirectories, but cannot be an absolute path or contain..。douyin_downloader_home: explicitly specify thedouyin-downloaderrepository directory. When empty, use the one under the skill directory.runtime/douyin-downloader。douyin_config_path: explicitly specify thedouyin-downloadernativeconfig.ymlpath used. When empty, use.runtime/douyin-downloader/config.yml。wx_channels_api_url:wx_channels_downloadAPI service root address, defaulthttp://127.0.0.1:2022; the trailing/apiis automatically cleaned up.wx_channels_binary_path: optionalwx_video_downloadexecutable file path. When empty, search fromPATH.wx_channels_config_path: optional upstreamconfig.yamlpath, used only to start the service; when empty, check the same directory as the executable forconfig.yaml. Sensitive cookies are saved in this file and are not placed intoagent_config.toml。wx_channels_timeout_seconds: timeout for parsing requests and media downloads.wx_channels_login_timeout_seconds: the maximum time to wait for the user to complete Tencent Yuanbao login, default 300 seconds.wx_channels_browser_profile_dir: skill-specific browser profile path; when empty, use.runtime/wx-channels-browser-profile。hot_board_output_dir: trending list output directory. When empty, usedefault_output_dir/hot_board/。search_output_dir: search results output directory. When empty, usedefault_output_dir/search/。
All path fields support ~ and environment variables. Relative paths are uniformly based on the skill directory; there is no need to write machine-specific absolute paths in the configuration or documentation.
douyin configuration handling
When calling the Douyin backend, the script behavior is:
- Read
douyin_config_pathpointed to byconfig.yml。 - If this path is not configured, read
douyin_downloader_home/config.yml。 - If the default
config.ymldoes not exist, generate a safe default configuration. - Before running, generate a temporary request configuration that only overrides the fields needed for this download:
path、music、cover、avatar、json、comments、mode
Therefore:
- Long-term cookies, browser fallback, thread count, and other low-level settings are still placed in
douyin-downloader's ownconfig.yml。 - The skill only overrides download behavior at the single-request level.
Cookie handling
If Douyin download reports that cookies are missing or invalid, do not assume on your own that the login state is normal.
Cookies are saved in .runtime/douyin-downloader/config/cookies.json。
When login is needed, run:
python3 scripts/video_downloader.py refresh-cookies
This opens a browser window; after the user completes Douyin login, the cookies are saved automatically.
Output requirements
Keep replies to the user concise:
- Clearly state whether the download succeeded.
- Provide the output directory or key file paths.
- When Douyin lacks additional resources such as avatars, mention it only when relevant.
- If you cannot continue due to missing installation or configuration, clearly point out the missing backend and give the two options: "install" or "configure path".
Collaborating with upload-type skills
When the user requests downloading network resources and continuing to upload them to services such as Immich:
- First complete the download with this skill, and confirm that the download succeeded.
- Provide the subsequent skill with the accurate local media file path, and do not pass the original network URL.
- At the same time, keep the adjacent
<媒体文件名>.metadata.json; Immich will automatically read it and generate a detailed description. - After a subsequent upload succeeds, the downloaded files are still kept by default; delete them only when the user explicitly requests cleanup.
When the user has already provided a local file or attachment, do not call this skill; hand it directly to the corresponding upload skill.