Open-source project
jiji262/douyin-downloader avatar
jiji262/douyin-downloader

douyin-downloader: a batch downloader whose CLI is currently blocked by Douyin itself

A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音批量下载工具,去水印,支持视频、图集、合集、音乐(原声)。

12,012 stars1,848 forksPythonMIT

At a glance

What is it?
A 12,000-star MIT-licensed Python tool for videos, galleries, collections and profile batches, whose README spends as much space documenting a platform-level 403 gate as it does listing features, plus a desktop build that routes requests through a real page.
Who is it for?
The most useful thing in this repository is the limitations section. Douyin's edge returns HTTP 403 with the message `Blocked by ArgusSecurityPlugin Uifid Not Found` for non-browser requests to a growing list of endpoints, and no amount of retrying or cookie handling defeats it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 17 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Twelve thousand stars and a feature list that starts with a warning

The repository has 12,012 stars and 1,848 forks with 21 open issues, which makes it one of the more widely used open source tools around Chinese short-form video. It is MIT licensed, written in Python, and its last push was 2026-09-19. The version in `pyproject.toml` is 2.0.0, marked as Beta, and it requires Python 3.9 or newer.

What is unusual is the shape of the README. Before the feature table there is a bolded warning that Douyin's anti-bot gate blocks the CLI from likes, favourites and favourite collections since 2026-08, and single videos, notes, collections and music since 2026-09, with profile posts left dependent on the browser fallback. The warning points readers to a limitations section for the cause and directs anyone who still needs those downloads to the desktop application. A project that leads with its own breakage rather than burying it is unusual enough to notice.

The feature list underneath is long and specific, which suggests real use rather than aspiration. Single video and image-note URLs are given as `/video/{aweme_id}` and `/note/{note_id}`, with `/gallery/{note_id}` as an alternative form. Collections resolve from `/collection/{mix_id}` or `/mix/{mix_id}`. Music comes from `/music/{music_id}`, preferring direct audio and falling back to the first related video. Short links on the `v.douyin.com` and `v.iesdouyin.com` hosts are parsed, including bare hosts.

Profile batch mode takes a `/user/{sec_uid}` path plus a mode list covering posts, likes, mixes and music. Logged-in favourites collections go through `/user/self?showTab=favorite_collection` with collection and collection-mix modes. Watermark-free sources are preferred automatically, and the highest bitrate is picked from the video bit rate ladder including the live photo variant.

Beyond that there is live stream recording to FLV or HLS with partial data preserved when a stream ends, per-video comment collection saved as JSON with optional replies, hot board and keyword search dumped to JSONL, an optional REST API server mode, notification push through Bark, Telegram or a webhook, cover, music, avatar and JSON metadata alongside the video, and optional transcription through the OpenAI Transcriptions API.

What the Argus gate actually blocks, and what still works

The limitations section is specific enough to be useful to anyone hitting the same wall. Douyin's edge component named `ArgusSecurityPlugin` answers non-browser requests to a set of endpoints with HTTP 403 and the text `Blocked by ArgusSecurityPlugin Uifid Not Found`. The README states this happens with or without cookies and no matter how often you retry, which is the key point: this is not a login problem and not a rate limit problem.

The dates matter. Since 2026-08 the blocked set covers `aweme/favorite`, the `collects/*` family, `aweme/listcollection` and `mix/listcollection`, which together mean likes, favourites and favourite collections. Since 2026-09-10 it covers `mix/aweme`, the collection items endpoint. Since 2026-09-14 it covers `aweme/detail` for single videos and notes, `aweme/post` for profile posts, and `mix/detail`.

That progression is worth reading as a pattern. Douyin closed the endpoints in stages, starting with the ones that require a logged-in identity and working outward to the ones a plain link would hit. Any tool that automates this platform is therefore on a clock, and the honest conclusion is that the CLI portion of this project is mostly a document of what used to work.

The browser fallback is the documented workaround for profile posts, launching a real browser when pagination is blocked and leaving a manual CAPTCHA step available. The desktop application takes a different route, described in the release notes as routing these requests through an in-app Douyin page channel so that they look like they come from a page rather than a script. The 0.11.6 desktop release is explicit that versions 0.11.5 and earlier failed entirely on single video, profile, collection and music downloads, and that those requests now go through the page channel.

A desktop app for three platforms, in closed beta

The Douzy desktop application is the more current half of the project. It shares the backend with the CLI and provides separate workspaces for Douyin, TikTok and YouTube. The described flow is to paste a link to start, sync account content, follow each task, and manage downloaded works in a local archive.

The Douyin workspace covers videos, galleries, profiles and collections. The TikTok workspace covers public videos, photo posts and profiles, described as working without signing in. The YouTube workbench covers videos, Shorts, channels and playlists, with configuration for video, MP3 or subtitle downloads. Account-level sync on the Douyin side covers the following list, favourites collections, collected series and likes.

The interface is organised around a multi-link queue, task status and retry controls, a local download archive with filters, and quick re-download. Screenshots are included in the repository under `img/desktop/`, and the README notes that the screenshots use demonstration data for privacy.

It is in closed beta, and the release notes describe the gating precisely: the standard single-link task entry point needs no invite code, while the batch queue and advanced UI flows still require beta qualification. Builds are published per platform, with macOS Apple Silicon and Intel disk images and a Windows installer. The releases are unsigned, so macOS Gatekeeper and Windows SmartScreen both intercept first launch, and the documented workaround on macOS is a right-click Open or clearing the quarantine attribute with xattr. Telegram notifications need your own API credentials, which are described as optional for other platforms.

The Chinese-language release notes for 0.11.6 also document a batch of honest fixes around failure reporting: modes within a profile task no longer fail together when one pagination request is rejected, a rejected collection is no longer reported as an empty success, retry buttons go through the page channel, and failure messages now distinguish a platform rejection where retrying is pointless from a channel error or a possible rate limit.

Engineering details that separate this from a script

The dependency list is short and explains a lot. `aiohttp` and `httpx` handle HTTP, `aiosqlite` the history database, `rich` the progress bars, `pyyaml` the configuration, `python-dateutil` the time filters and `gmssl` the cryptographic call signing Douyin requires. `imageio-ffmpeg` is pinned to an exact version because a bundled static FFmpeg binary is used to extract audio before uploading to the transcription endpoint, and the pin exists so CI builds are reproducible across machines. Optional extras cover Playwright for the browser fallback, openai-whisper for transcription, and fastapi with uvicorn and pydantic for the REST server mode.

`pyproject.toml` carries inline comments that read like a changelog. One notes that `httpx` is imported at runtime by the file manager and must stay in sync with `requirements.txt` or clean-room sidecar builds crash at boot. Another explains that 0.6.0 of the FFmpeg package is the first release with a native macOS arm64 wheel, so older versions only produced x86_64 macOS binaries. That is the kind of detail that usually disappears into a commit message.

The operational features are the ones that separate this from a quick script. Concurrent downloads default to 5. Retries use exponential backoff at one, two and five seconds. Rate limiting defaults to 2 requests per second. Downloads validate Content-Length and delete incomplete files automatically. Incremental behaviour is disk-based rather than database-based, which is a deliberate choice: the SQLite history records metadata for reference and explicitly does not decide what to skip, and skipping is decided by looking at what is already in the download directory. Time filters accept start and end times. Progress output has a quiet mode.

The repository ships a Dockerfile, and it is a plain one: a slim Python 3.12 base, a compiler installed for the packages that need it, dependencies copied and installed before the source so that layer stays cached, a `Downloaded` directory created, volumes for that directory and for the config file, and an entry point of `run.py` with `config.yml` as the argument.

Repository layout, and the housekeeping files inside it

The tree shows a codebase organised into clear responsibility folders: `auth/`, `cli/`, `config/`, `control/`, `core/`, `server/`, `storage/`, `tools/` and `utils/`, plus `tests/` and `docs/`. The entry point is `run.py` at the root, configuration is a YAML file with `config.example.yml` shipped as the template, and a `Dockerfile` and `.dockerignore` cover container use. GitHub Actions are configured for testing and linting, and the dev extra includes pytest, pytest-asyncio and ruff, with a comment in the dependency block referring to property-based tests.

Two files stand out as signals about how the project is worked on. `AGENTS.md` and `CLAUDE.md` both sit at the root, which means the repository carries written instructions for automated coding assistants, including the project conventions and the failure modes that earlier work uncovered. `PROJECT_SUMMARY.md` is present as well, suggesting a maintained summary of the codebase's state.

The README itself ships in two languages, with `README.zh-CN.md` as the Chinese version linked from the English one. That matters for the audience question. The user base for a Douyin downloader is predominantly Chinese, and the release notes and desktop release names are Chinese-language, while the main README and the release notes for the download builds are English. If you are reading only one language, the Chinese documentation is the more current one.

The licensing situation is the one uncomplicated thing here: MIT, stated in the repository metadata and in the `pyproject.toml` licence field, with the classifier list including the MIT licence classifier.

Editorial conclusion

The most useful thing in this repository is the limitations section. Douyin's edge returns HTTP 403 with the message `Blocked by ArgusSecurityPlugin Uifid Not Found` for non-browser requests to a growing list of endpoints, and no amount of retrying or cookie handling defeats it. A maintainer who had quietly removed the broken feature table would have kept the star count and lost the reader. This one puts a warning above the feature list, dates each regression, and explains that only the desktop build survives because it sends requests through an actual in-app Douyin page channel. The trade-offs are equally clear. The CLI path that most people will try first is the part that is broken for single items and profiles, closed beta gating sits in front of the desktop app's batch queue, release builds are unsigned, and the project is scoped to a platform whose API access can change again without notice. If you are here for the Douyin side, read the limitations first. If you want TikTok or YouTube, the same backend handles both and that is currently the smoother path.

Frequently asked questions

Does the douyin-downloader CLI still work for single videos?

Not as of 2026-09-14, according to the README. Douyin's edge answers non-browser requests to the `aweme/detail` endpoint for single videos and notes with HTTP 403 and a message about ArgusSecurityPlugin, regardless of cookies or retries. The README directs users who need these downloads to the Douzy desktop application, which routes the requests through an in-app page channel.

Why does the tool return 403 Blocked by ArgusSecurityPlugin Uifid Not Found?

That response comes from Douyin's edge security component when a request does not come from a real browser page. The README states it happens with or without cookies and no matter how often you retry, so it is not a login or rate limit problem. The documented workarounds are the browser fallback for profile posts and the desktop application's page channel for the rest.

Can I download TikTok and YouTube videos with this project?

The Douzy desktop application includes dedicated TikTok and YouTube workspaces on the same backend. TikTok covers public videos, photo posts and profiles without signing in, and YouTube covers videos, Shorts, channels and playlists with video, MP3 or subtitle download options. These are described as separate workspaces rather than as part of the command line interface.

Is the Douzy desktop application available to everyone?

No, it is in closed beta. Builds are published on the releases page for macOS Apple Silicon, macOS Intel and Windows, and the single-link task entry point needs no invite code, but the batch queue and advanced interface flows still require beta qualification. The builds are also unsigned, so macOS and Windows will both warn on first launch.

What licence is douyin-downloader released under?

MIT. The repository metadata reports it, and `pyproject.toml` declares the same licence text and includes the MIT classifier alongside Beta status and Python 3.9 through 3.12 support markers.

How does the tool decide which videos to skip on a repeat run?

Skipping is disk-based rather than database-based. The SQLite history records download metadata for reference but does not decide incremental skips. Instead, the `increase.post`, `increase.like`, `increase.mix` and `increase.music` settings check what is already present in the download directory and skip or re-download accordingly.

Official sources

  1. Issues
  2. jiji262/douyin-downloader on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jiji262-douyin-downloader.svg)](https://hysenlabs.com/projects/jiji262-douyin-downloader)