Simple personal server to serve audiofiles files from folders. Intended primarily for audio books, but anything with decent folder structure will do.
Simple personal server to serve audiofiles files from folders. Intended primarily for audio books, but anything with decent folder structure will do.
[DEMO AVAILABLE - shared secret: mypass]
Simple personal server to serve audio files from directories. Intended primarily for audio books, but anything with decent directories structure will do. Focus here is on simplicity and minimalist design.
Server is written in Rust, new web PWA client (Typescript and Svelte) is focused on modern browsers and is using rather recent functionality (Service Worker), older, less demanding web client is still around - check Web client chapter for details. There is also old Android client, and simple API for custom clients.
For some (now bit outdated) background and video demo check this article(bit old but gives main motivation behind it) Audioserve Audiobooks Server - Stupidly Simple or Simply Stupid?
If you will install audioserve and make it available on Internet do not underestimate security.
Apple users need to add additional configuration - read this.
Like audioserve and want to start quickly and easily and securely? Try this simple guide to have audioserve up and running for free in no time.
Audioserve is intended to serve files from directories in exactly same structure (with support for .m4b and similar single file audiobooks, where chapters are presented as virtual files), audio tags are not used for browsing, only optionally they can be displayed. Recommended directory structure of collections is:
Author Last Name, First Name/Audio Book Name
Author Last Name, First Name/Series Name/Audio Book NameFiles should be named so they are in right order - ideally prefixed with padded number, recently audioserve supports (by default, can be switched off by no-natural-files-ordering argument) natural ordering so padding of numbers is not necessary:
001 - First Chapter Name.opus
002 - Second Chapter Name.opusBut this structure is not mandatory - you will just see whatever directories and files you have, so use anything that will suite you.
Audioserve assumes that file and folder names are in UTF-8 encoding (or compatible), for other encodings it may not work correctly.
The characters $$ and | are used for internal usage of audioserve, so you should not use them in file names.
In folders you can have additional metadata files - first available image (jpeg or png) is taken as a cover picture and first text file (html, txt, md) is taken as description of the folder.
Search is done for folder names only (not individual files, neither audio metadata tags).
You can have several collections/libraries - just use several collection directories as audioserve command arguments. In client you can switch between collections. Typical usage will be to have separate collections for different languages.
By default symbolic(soft) links are not followed in the collections directory (because if incorrectly used it can have quite negative impact on search and browse), but they can be enabled by --allow-symlinks program argument.
Initially I though that everything can be just served from the file system. However experience with the program and users feedback have revealed two major problems with this approach:
So I implemented caching of collection data into embedded key-value database (using sled). I'm quite happy with it now, it really makes audioserve superfast.
However it brings bit more complexity into the program. Here are main things to consider:
sigusr1 to the program.--tags, --tags-custom, tags-encoding, --ignore-chapters-meta, --no-dir-collaps, --allow-sym-link, -chapters-duration, --chapters-from-duration, read-playlist, --collapse-cd-folders, cd-folders-regexp, no-natural-files-ordering. If audioserve is restarted and some of these arguments is changed, it should start full collection cache reload.sigusr1 signal to program, or starting it with --force-cache-update argument, which enforces initial full cache reload.changes-debounce-interval, however too small value may lead to inefficient handling of changes ), before changes are visible in the program. For large collections you should increase the limit of inotify watchers in linux:cat /proc/sys/fs/inotify/max_user_watches
# use whatever higher number matches your requirement
echo fs.inotify.max_user_watches=1048576 | sudo tee -a /etc/sysctl.conf
sudo sysctl -pthese contiunous updates do require some resources, firstly above mentioned kernel watches and also 3 threads per collection. You can disable watching for changes by program argument dont-watch-for-changes. Then changes will be updated only if you browse the folder (and audioserve will notice modified mtime of the folder) or assure updates manually (as metioned above like sending sigusr1 signal to program after changes or in regular interval, this will force full cache reload/rescan). Changes not updated into cache will not be available for search.
cache is indeed bound with collection directory path (hash of absolute normalized path is used as an identification for related cache) - so if you change collection directory path cache will also change (and old cache will still hang there - so some manual clean up might be needed).
if you do not want to cache particular collection you can add :no-cache option after collection directory argument. However then position sharing and metadata tags will also not work for that collection and search will be slow.
audioserve also supports single file audiobooks like .m4b (one big file with chapters metadata) and similar (.mp3 can also contain chapters metadata). Such file is presented as a folder (with name of original file), which contains chapters as "virtual" files (chapters behaves like other audio files - can be transcoded to lower bitrates, seeked within etc.) (if you do not like this feature you can disable with --ignore-chapters-meta argument, I have seen some .mp3 files, which contained bad chapters metadata).
Also long audiofile without chapters metadata, can be split into equaly sized parts/chapters (this has a slight disadvantage as split can be in middle of word). To enable this use --chapters-from-duration to set a limit, from which it should be used, and chapters-duration to set a duration of a part. Also for large files, which do not have chapters metadata, you can easily supply them in a separate file, with same name as the audio file but with additional extension .chapters - so it looks like your_audiobook.mp3.chapters. This file is simple CSV file (with header), where first column is chapter title, second is chapter start time, third (and last) is the chapter end time. Time is either in seconds (like 23.836) or in HH:MM:SS.mmm format (like 02:35:23.386).
For MPEG-4 containers, .m4b files and similar, cover image and description can extracted directly from file (cover is MJPEG video stream with attached picture flag, description is metadata tag named "description").
If chaptered file is a single file in a directory (and there are no other subdirectories), then chapters are presented within this directory, as if they were files in this directory and cover and description can be overriden from this directory (remplaces embeded metadata). If you do not like this feature you can disable by --no-dir-collaps option.
Also note that web client will often load same part of chapter again if you're seeking within it (especially Firefox with m4b), so it's definitely not bandwidth optimal (similar issue appears when often seeking in transcoded file).
Sometimes (mainly for historical reasons) content of audiobook is divided in CD subfolders, reflecting how it was originally distributed on physical media. In audioserve you have option to collapse all these CD subfolders into main root folder and thus see whole audiobook at once. File names then will be prefixed with CD subfolder name.
This is an optional feature and could be enabled by argument --collapse-cd-folders (will require full reload of collection cache) and will collapse CD subfolders if:
Only folders matching regular expression r"^CD[ -_]?\s*\d+\s*$" (case insensitive) are collapsed into parent folder. Custom regular expression can be provided by argument --cd-folder-regexp.
audioserve is using directory structure for navigation and searching. This is one of key design decisions and it will not change. Main reason is because tags are just one big mess for audiobooks, everybody uses them in slightly different way, so they are not reliable. This was key reason why I started work on audioserve - to see my collec
No open issues yet, or sync has not completed.