An asynchronous, terminal-based downloader for ASMR.ONE. Downloads are persistent, resumable, bandwidth-throttled, and organized into a local SQLite library. Works from an interactive menu or entirely from the command line.
| β¨ Features | π¦ Requirements | π Installation |
| π₯οΈ Interactive Menu | π§ CLI Flags | |
| βοΈ Configuration | π Project Structure | π Troubleshooting |
- Async concurrent downloads via
asyncio+aiohttp. Configurable concurrency (default: 3 parallel files). - Resume support β downloads use HTTP
Rangeheaders. A.tmpfile is kept between sessions and extended on restart. No re-downloading from the beginning. - 3-attempt retry loop per file. After exhausting retries, the failure is recorded with its reason (HTTP status, exception type, or directory error) and displayed in the Session Report.
- Token-bucket bandwidth limiter β set
bandwidth_limit_mbpsin config to cap download speed globally.0means unlimited. - Mirror speed test on startup β all configured API mirrors are pinged in parallel and the fastest is selected automatically.
- SQLite library (
history.db) tracks every completed download: Work code (RJ/VJ), title, local path, file size, date. - Duplicate detection β before anything is queued, the app checks the library. Already-owned works are skipped with a notice.
- Persistent queue β the download queue lives in the database, not in memory. Interrupted sessions survive a restart. Use
--resumeto continue. - Format priority deduplication β when a work includes both WAV and MP3 versions of the same track, only the preferred format (per your
format_prioritylist) is downloaded.
--listβ print the full folder/file tree of any work code (RJ/VJ) without downloading.--dry-runβ simulate a download interactively: shows which files would be fetched and total size, writes nothing to disk.--allβ skip the file-selection prompt and download everything.--batchβ load a.txtfile of work codes (RJ/VJ) and queue them all.- Session Report β after each job: success/fail/skipped counts, elapsed time, average speed, and a per-file failure details table when errors occurred.
- Retry prompt β at the end of a batch, any failed work codes are collected and you are offered a single-key retry.
- Windows completion beep β a system notification sound plays when the full queue finishes.
- Audio tagging (
mutagen) β title, artist, album, and cover art are written to MP3, FLAC, and OGG files after download. - Flexible folder naming β configurable
dir_templateusing{rj_id},{title},{circle},{year}. - Optional file sorting β enable
sort_filesto separate downloads intoAudio/,Images/,Text/subdirectories.
- Python 3.10 or higher β download from python.org
- A terminal with ANSI color support:
- Windows: Windows Terminal (recommended), VS Code terminal, or PowerShell 7+
- macOS/Linux: any modern terminal emulator
- Git (for cloning) β download from git-scm.com
Python packages (installed automatically by setup.bat or pip install -r requirements.txt):
| Package | Purpose |
|---|---|
aiohttp |
Async HTTP client for downloads and API calls |
aiofiles |
Async file I/O for writing download chunks |
aiodns |
Custom DNS resolver (bypasses ISP-level blocking) |
rich |
Terminal UI β progress bars, tables, panels, color |
mutagen |
Audio metadata tagging (MP3, FLAC, OGG) |
pydantic |
Config validation and schema enforcement |
requests |
Used for synchronous GitHub update check |
packaging |
Version string parsing for update comparison |
git clone https://github.com/takoyune/asmr.one-downloader.git
cd asmr.one-downloaderOr download the ZIP directly from GitHub:
- Click the green Code button on the repository page
- Select Download ZIP
- Extract the ZIP to a folder of your choice
- Open a terminal in that folder
Option A: Automated (Windows)
Run the provided setup script. It creates a virtual environment and installs all dependencies into it:
setup.batAfter it finishes, all future launches via ./asmr will use the virtual environment automatically.
Option B: Manual (Windows / Linux / macOS)
If you prefer to manage your own environment:
# (Optional but recommended) Create a virtual environment
python -m venv venv
# Activate it
# Windows (PowerShell):
.\venv\Scripts\Activate.ps1
# Windows (CMD):
venv\Scripts\activate.bat
# macOS / Linux:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txtpython main.py --versionYou should see the current version printed. If you see a ModuleNotFoundError, re-run the install step or check that the correct virtual environment is active.
./asmr # Open interactive menu
./asmr RJ123456 # Download directly
./asmr --help # All available flagsCMD users:
asmr.batworks the same way β just typeasmr RJ123456
An asmr shell launcher is already included in the repo. Just make it executable once after cloning:
chmod +x asmrThen use it the exact same way as Windows:
./asmr # Open interactive menu
./asmr RJ123456 # Download directly
./asmr --list RJ123456 # Preview file tree without downloading
./asmr --dry-run RJ123456 # Simulate a download
./asmr --help # All available flagsLaunch ./asmr with no arguments:
ββββββββββββββββββββββββββββββββββββββββββ
β ASMR.ONE DOWNLOADER β
β by Takoyune β
ββββββββββββββββββββ π Library: 3 works ββ
[1] Download (Work Codes)
[2] Batch Download from File
[3] Library Browser
[4] Queue Manager
[5] Settings
[6] Statistics Dashboard
[7] System Utilities
[X] Exit
Enter one or more work codes separated by spaces (e.g. RJ123456 VJ01002074). The app fetches metadata, presents the full file tree, and lets you select specific files by number or range (e.g. 1 3-5 7). Leave the selection blank to download everything.
Enter the path to a .txt file with one work code (RJ or VJ) per line. All codes are validated, checked against your library, and added to the queue. The queue then processes them in order.
# Example batch file (my_list.txt)
RJ01234567
VJ01002074
RJ00112233
Search your local download history by title or circle name (partial matches supported). Shows the local folder path and file size for each result.
View all items currently in the queue (pending / active / error status). Add new codes, change download priority, or remove items before they start.
Edit all configuration options interactively without touching config.json manually. Includes a format_priority list editor where you can add, remove, and reorder your preferred formats.
Overview of your library: total works, total size on disk, queue length, and average work size.
- Cache Cleaner β Scans for
.tmpand.asmr_selection.jsonfiles. Shows a summary with sizes before asking for confirmation. - Network Diagnostics β Tests all configured API mirrors and shows latency for each.
- Mirror Selector β Re-run the speed test and update the active mirror in config.
Full reference:
usage: ./asmr [-h] [-b FILE] [-a] [--list] [--export FILE] [--test]
[--dry-run] [--resume] [--no-update-check] [--verbose] [-v]
[rj_codes ...]
| Flag | Short | Description |
|---|---|---|
work_codes |
β | One or more work codes (RJ or VJ) to queue and download immediately |
--batch FILE |
-b |
Path to a .txt file containing work codes (RJ/VJ), one per line |
--all |
-a |
Skip the file-selection prompt; download all tracks |
--list |
β | Print the full track tree for each work code and exit (no download) |
--export FILE |
β | Export the library to a CSV or JSON file (e.g., library.csv) |
--test |
β | Test all API mirrors and display detailed latency and error information |
--dry-run |
β | Show which files would be downloaded and total size; write nothing to disk |
--resume |
β | Skip mirror test and update check; process existing queue immediately |
--no-update-check |
β | Skip the GitHub update check this session |
--verbose |
β | Write DEBUG-level logs to singularity.log |
--version |
-v |
Print version and exit |
--help |
-h |
Show usage summary |
# Download a single work interactively (RJ or VJ)
./asmr RJ01234567
./asmr VJ01002074
# Download multiple works, skip file selection (get everything)
./asmr --all RJ01234567 VJ01002074
# Check what you'd download before committing
./asmr --dry-run VJ01002074
# Preview the file tree without downloading
./asmr --list VJ01002074
# Run a batch of codes from a file
./asmr --batch my_list.txt
# Batch download everything in the file without prompts
./asmr --batch my_list.txt --all
# Resume a previous session that was interrupted
./asmr --resume
# Quiet session, skip update check
./asmr --no-update-check RJ01234567
# Debug a failed download
./asmr --verbose RJ01234567
# Then check singularity.log for full HTTP logsconfig.json is created automatically on first launch in the project root. You can edit it directly or change values through Settings in the interactive menu.
{
"output_dir": "Downloads",
"max_concurrent": 3,
"proxy": null,
"mirror": "https://api.asmr.one",
"tag_audio": true,
"sort_files": false,
"dir_template": "{rj_id} {title}",
"timeout": 60,
"dns": "1.1.1.1",
"bandwidth_limit_mbps": 0.0,
"format_priority": ["flac", "wav", "mp3", "m4a", "ogg"],
"last_update_check": 0.0
}| Key | Default | Description |
|---|---|---|
π output_dir |
"Downloads" |
Where downloaded works are saved |
β‘ max_concurrent |
3 |
Parallel file downloads (1β20) |
π proxy |
null |
HTTP or SOCKS5 proxy URL |
π mirror |
auto | API mirror URL β set automatically on startup |
π΅ tag_audio |
true |
Write metadata tags to MP3 / FLAC / OGG |
π sort_files |
false |
Organize into Audio/, Images/, Text/ subfolders |
π·οΈ dir_template |
"RJ{rj_id} {title}" |
Folder name template β supports {rj_id}, {title}, {circle}, {year} |
β±οΈ timeout |
60 |
HTTP request timeout in seconds |
π‘οΈ dns |
"1.1.1.1" |
DNS server β use 1.1.1.1 or 8.8.8.8 to bypass ISP blocks |
πΆ bandwidth_limit_mbps |
0.0 |
Speed cap in MB/s β 0 = unlimited |
ποΈ format_priority |
["flac","wav","mp3",β¦] |
Preferred format when a track has multiple versions |
π last_update_check |
0.0 |
Auto-managed β skips GitHub check if run within 24 h |
| Template | Result folder name |
|---|---|
"RJ{rj_id} {title}" |
RJ01234567 Some Work Title |
"{circle} - {title}" |
SomeCircle - Some Work Title |
"{year}/{circle}/{title}" |
2024/SomeCircle/Some Work Title |
asmr.one-downloader/
β
βββ main.py # Entry point β CLI flags, preflight check, update check
βββ asmr # Linux / macOS launcher (run: chmod +x asmr)
βββ asmr.bat # Windows CMD launcher
βββ asmr.ps1 # Windows PowerShell launcher
βββ setup.bat # First-time setup (creates venv + installs deps)
βββ requirements.txt # Python dependencies
βββ config.json # Your settings (auto-created on first run)
βββ history.db # SQLite β library and download queue
βββ singularity.log # Rotating log file
β
βββ main/
βββ app.py # UI, menus, job execution
βββ orchestrator.py # Download logic, retry, stats
βββ network.py # HTTP client, mirror management
βββ db.py # All database operations
βββ config.py # Config loading and validation
βββ models.py # Data types (WorkMetadata, TrackItem, etc.)
βββ audio.py # Audio metadata tagging
βββ constants.py # Mirrors, log setup, shared constants
ASMR.ONE is actively region-blocked outside of East Asia (Japan, China, etc.). If the startup mirror test fails or you cannot connect, your connection is likely being blocked. We highly recommend using Cloudflare WARP to bypass this:
- Download and install Cloudflare WARP from https://one.one.one.one/
- Open the WARP app settings (click the gear icon).
- Make sure to choose Traffic and DNS (UDP) (do not just choose the 1.1.1.1 DNS option).
- Turn on the connection switch and restart the downloader.
Alternatively, if you have your own proxy, you can set the proxy field in config.json (e.g. "http://user:pass@ip:port").
- Increase
timeoutinconfig.json(e.g.120) - Reduce
max_concurrentto1or2to reduce connection pressure - Try a different DNS or enable a proxy
This is a known visual issue. The bar is initialized from file size on disk, not the database state. The download is still resuming correctly from the correct byte offset β the visual will correct itself as data flows in.
By default, only INFO, WARNING, and ERROR messages are logged. The --verbose flag adds DEBUG output (every HTTP request, byte offsets, retry attempts). Only use --verbose when actively debugging.
Check singularity.log for the full traceback. The log file is in the project root directory.
Ensure tag_audio is true in config.json. Tagging only applies to MP3, FLAC, and OGG files. WAV files are not tagged (the WAV format has no standard metadata container).
MIT License β see LICENSE for details.
Created by Takoyune