A reimplementation of the local audio server on Cloudflare
Workers + Rust.
HTTP interface stays identical to the original:
| Original (Python / Anki) | This project (Workers / Rust) |
|---|---|
| Local audio files on disk | R2 bucket (AUDIO binding) |
entries.db (SQLite) |
D1 database (DB binding) |
http.server on 127.0.0.1 |
Cloudflare Worker (axum router) |
default_config.json |
embedded in src/sources.rs |
GET /→Worker Audio Server v0.0.1(plain text)GET /?term=<term>&reading=<reading>&sources=<a,b>&user=<speaker>→ YomitanaudioSourceListJSONGET /{source_id}/{file}→ audio bytes (streamed from R2)GET /favicon.ico→ 400
Query parameters mirror demo/server.py::parse_query_components:
term(orexpression) — requiredreading— optional; normalized katakana→hiragana,null/undefined/empty treated as absentsources— comma-separated source ids; defaults to all configured sourcesuser— comma-separated speaker names (forvo)
All responses include Access-Control-Allow-Origin: *.
src/
├── lib.rs # axum router + all request handlers
├── sources.rs # source config (the embedded default_config.json)
├── query.rs # dynamic D1 SQL builder (port of execute_query)
├── jp.rs # katakana→hiragana (port of jp_util)
└── error.rs # worker::Error → axum IntoResponse bridge
schema.sql # D1 schema (identical to the Python entries table)
wrangler.toml # Worker + D1 + R2 bindings
wrangler d1 create audio-db
wrangler r2 bucket create audio-bucketPut the printed database_id into wrangler.toml.
wrangler d1 execute audio-db --remote --file=migrations/00_schema.sql
wrangler d1 execute audio-db --remote --file=migrations/01_entries.sqlwrangler dev # local (uses local D1 + R2 state under .wrangler)
wrangler deploy # productionSet the custom audio source URL to your worker, e.g.:
https://<worker>.<subdomain>.workers.dev/?term={term}&reading={reading}