kithara-server · 0.1, early

Your books, your server.

One binary, no database, nothing to sign up for. Point it at a folder of audiobooks and every device you own can stream or download from it, with your listening position and bookmarks following you between them. MIT licensed, source on GitHub.

Install

Three ways in. All of them need ffmpeg on the machine: ffprobe reads durations, tags and chapters, and ffmpeg pulls embedded cover art out of files that have it.

Linux or Mac binary

  1. Download the build for your machine from the latest release (linux/amd64, linux/arm64 for a Raspberry Pi or ARM NAS, or macOS), make it executable, and put it somewhere on your path such as /usr/local/bin.
  2. Install ffmpeg: sudo apt install ffmpeg on Debian and Ubuntu, brew install ffmpeg on a Mac.
  3. Create a user. It asks for a password of eight characters or more:
    kithara-server user add phil
  4. Serve the folder:
    kithara-server serve --library ~/Audiobooks --data ~/.kithara-server --name "Phil's shelf"

That is the whole server. kithara-server scan --library ~/Audiobooks prints what it sees without serving, which is the quickest way to check that a folder reads the way you expect. To keep it running after a reboot, the README has a systemd unit; the environment variables KITHARA_LIBRARY, KITHARA_DATA, KITHARA_ADDR and KITHARA_NAME take the place of the flags.

Docker

The image is multi-arch, so the same line works on a PC and on a Raspberry Pi:

docker run -d --name kithara \
  -v /srv/audiobooks:/library:ro -v kithara-data:/data -p 8080:8080 \
  ghcr.io/philcharitou/kithara-server
docker exec -it kithara kithara-server user add phil

Change /srv/audiobooks to your folder. ffmpeg is inside the image. The :ro keeps the library read-only, which means book ids live in the data volume rather than in small sidecar files beside each book; drop it if you would rather have the sidecars (they let a book keep its id when you rename its folder).

Windows

  1. Download kithara-server.exe from the latest release into a folder of its own.
  2. Get ffmpeg from ffmpeg.org (a Windows build such as the gyan.dev release), unzip it, and either put its bin folder on your PATH or copy ffmpeg.exe and ffprobe.exe next to kithara-server.exe.
  3. In a terminal in that folder:
    kithara-server.exe user add phil
    kithara-server.exe serve --library "D:\Audiobooks" --data "%LOCALAPPDATA%\kithara-server" --name "Home"

Allow it through Windows Firewall when asked, or your phone will not be able to reach port 8080.

Then, in Kithara

  1. Open Library. On a fresh install, pick a server from the empty screen; otherwise open the menu, Manage libraries, Add a library.
  2. Choose Kithara sync server.
  3. Server address: http://your-machine:8080, using the machine's name or its IP on your network. User name and password: the ones you created. Give the library a name if you like, then Connect.

The app checks /api/health, signs in, and syncs. Your books appear as a tab; tap a cover to stream, tap the cloud badge to download. From then on your position and bookmarks travel with you: pause on the phone, pick up on the tablet, and a stretch of offline listening never gets rewound by a stale copy elsewhere. Server libraries are free; nothing here needs Pro.

Away from home

Plain http:// is fine on your own Wi-Fi. To listen anywhere else you need one of two things, and you should not open port 8080 on your router without either. The token in every request is a bearer credential, so treat the connection like a password.

Tailscale (recommended, no configuration)

Tailscale puts your phone and the server on a private network wherever you are. Install it on both, and the server keeps its plain http:// address, just with the machine's Tailscale name instead of the LAN one. Nothing is exposed to the internet, so there is no certificate to manage and no port to forward.

A reverse proxy with TLS

If you want a public address, bind the server to 127.0.0.1 (KITHARA_ADDR=127.0.0.1:8080) and put a proxy in front. Caddy gets a certificate on its own; the whole configuration is:

audiobooks.example.com {
    reverse_proxy 127.0.0.1:8080
}

Point the domain at your public IP and forward ports 80 and 443 to the proxy. nginx with certbot works too. Either way the proxy must pass Range requests through untouched (they all do by default) and should not buffer large responses; in nginx, proxy_buffering off; keeps seeking snappy.

How the folder is read

  • A folder with audio files in it is a book. The files are its parts, in natural order, so part 10 comes after part 2.
  • A folder holding only CD 1, CD 2, Disc 3, Part 4 subfolders is one book, the discs joined in order.
  • A single audio file beside book folders, or at the top level, is a book of its own.
  • Anything above that is just organisation. Author/Series/Book/ works.
  • Formats: m4b, m4a, mp4, aac, mp3, ogg, opus, flac, wav, wma, mka.
  • Metadata comes from tags first. Title from album (or title for a single file), else the folder or file name; author from artist or album_artist; narrator from composer; series from series or grouping; description from description or comment.
  • Chapters are read from the files (m4b chapter atoms, mp3 chapter frames) and laid onto one combined timeline across the parts. Files without embedded chapters become one chapter each, named from their title tag or file name. No chapters at all? Add them in ten minutes.
  • Cover: cover.jpg, cover.png or folder.jpg in the folder, else the artwork embedded in the first file.
  • Ids survive renames. Each book folder gets a tiny .kithara-id file, so moving or renaming the folder keeps your listening position attached. On a read-only library the id is kept in the data folder instead, keyed by path.

New and changed books are picked up every ten minutes by default, at start, and on demand from a signed-in client. Probing is cached by file size and modification time, so a rescan of a large unchanged library costs almost nothing.

What it keeps

A handful of JSON files in the data folder: users and their password hashes, device tokens, each user's progress and bookmarks, the probe cache, and extracted covers. Back up the users/ folder; everything else is rebuilt from the library. Removing a user signs their devices out and sets their listening state aside rather than deleting it.

Requirements

  • Linux (amd64, arm64 or arm, so a Raspberry Pi or an ARM NAS is fine), macOS, or Windows. Any architecture Go builds for, if you build it yourself; the standard library is the only dependency.
  • ffmpeg and ffprobe on the PATH, or inside the Docker image.
  • Kithara 1.2 or later on the phone. Server libraries are free.

Writing your own client or server

kithara-server is the reference implementation of version 1 of the Kithara sync protocol: a few JSON routes and range-served audio, small enough to implement in an afternoon in whatever you already run. The protocol page is the contract; the README lists the server's few extras, such as an ETag on the library and a 409 when a stale position arrives.

It is early

This is version 0.1. It runs well on a home network for one household, and the format of the data folder will stay readable, but expect rough edges and read the release notes when you upgrade. Issues on GitHub are the place for bugs; the contact form works too.