An Emby server plugin that reads AudioBookShelf (ABS) local sidecar files — metadata.json and cover.jpg — and imports them as metadata and cover art for your audiobooks. No network requests; everything stays local.
- Fully local — no internet, no API keys, no remote lookups.
- Works with both library types — Books (
Bookentity) and Audio Books (MusicAlbum+Audioentity,CollectionType.AudioBooks). - Parses
metadata.json— handles ABS schema variants (string vs object-array authors/narrators/series, numeric vs string year/sequence). - Local cover art — serves any of
cover.jpg/cover.jpeg/cover.png/folder.jpg/folder.jpeg/folder.pngas the primary image. - Configurable — five settings toggles for fine-grained control.
- Lock-safe file reads — reads sidecars with
FileShare.ReadWriteso an in-progress ABS write won't crash a scan. - Read-only — never modifies your source files.
Emby auto-discovers the local providers at startup. During a library scan or metadata refresh:
- The provider resolves the item's containing folder from the path Emby passes.
- It looks for
metadata.json(thenmetadata.absif absent) in that folder via the cache-backedIDirectoryService. - The JSON is deserialised with version-tolerant converters and mapped onto the Emby entity.
- The image provider returns
cover.jpg(or candidates) asImageType.Primary; Emby copies it into its own image cache.
ABS metadata.json |
Books library (Book) | AudioBooks library (MusicAlbum / Audio) |
|---|---|---|
title |
Name (with series suffix when present); Album (raw title) |
Name (with series suffix when present); Album (raw title) |
subtitle |
Tagline |
Tagline |
description |
Overview |
Overview |
publishedYear |
ProductionYear |
ProductionYear |
publisher |
AddStudio(...) |
AddStudio(...) |
language |
PreferredMetadataLanguage |
PreferredMetadataLanguage |
genres[] |
AddGenre(...) for each |
AddGenre(...) for each |
tags[] |
AddTag(...) for each |
AddTag(...) for each |
isbn |
SetProviderId("ISBN", ...) |
SetProviderId("ISBN", ...) |
asin |
SetProviderId("ASIN", ...) |
SetProviderId("ASIN", ...) |
authors[] / authorName |
PersonInfo{ Type=Writer } |
Artists + AlbumArtists (when MapAuthorsAsAlbumArtists is on) |
narrators[] / narratorName |
PersonInfo{ Type=Actor, Role="Narrator" } |
Composers LinkedItemInfo[] (when MapNarratorsAsComposers is on; else "Narrator: X" tag) |
series[] / seriesName |
Appended to Name as " - name #seq" and IndexNumber set from sequence (both configurable — see note) |
Appended to Name as " - name #seq" and IndexNumber set from sequence (both configurable — see note) |
Note on name & series: When AppendSeriesToName is on (default), Name becomes {title} - {seriesName} #{sequence} (e.g. "The Hobbit - The Lord of the Rings #1"). Album always holds the raw title. When MapSeriesToIndexNumber is on (default), the series sequence is written to IndexNumber for Book and MusicAlbum items. Audio tracks do not receive IndexNumber — Emby derives track order from filenames and ID3 tags. Both toggles can be turned off in plugin settings.
| Emby Library Type | Entities Scanned | Plugin Uses |
|---|---|---|
| Books | Book |
AbsMetadataProvider + AbsImageProvider |
| Audio Books | MusicAlbum + Audio |
AbsAlbumMetadataProvider + AbsAudioMetadataProvider + AbsImageProvider |
└── 📁 Author Name/
└── 📁 Book Title (1994)/
├── metadata.json ← generated by AudioBookShelf
├── cover.jpg ← optional; used as primary art
├── audiobook.m4b ← single-file book
└── ... (or multiple tracks)
Example metadata.json:
{
"title": "The Fellowship of the Ring",
"subtitle": "Being the First Part of The Lord of the Rings",
"description": "A quiet evening in the Shire...",
"publishedYear": 1954,
"publisher": "George Allen & Unwin",
"language": "en",
"isbn": "9780547928210",
"authors": ["J.R.R. Tolkien"],
"narrators": ["Rob Inglis"],
"series": [{ "name": "The Lord of the Rings", "sequence": "1" }],
"genres": ["Fantasy", "Adventure"],
"tags": ["classic"]
}All settings default to true and can be tuned in the Emby dashboard (Plugins → ABS Import → Settings).
| Setting | Default | Effect |
|---|---|---|
EnableNfoFallback |
true |
Try .nfo, desc.txt, and reader.txt if no metadata.json is found. |
MapNarratorsAsComposers |
true |
Write narrators to the Composers field on AudioBooks library items. When off, narrators are added as "Narrator: Name" tags. |
MapAuthorsAsAlbumArtists |
true |
Write authors to MusicAlbum.AlbumArtists / .Artists and Audio.Artists (ABS artist=author convention). Disable to preserve artist data from ID3 tags. |
AppendSeriesToName |
true |
Append " - seriesName #seq" to item.Name when a series is present. Disable to keep only the raw title. |
MapSeriesToIndexNumber |
true |
Set item.IndexNumber from the series sequence for Book and MusicAlbum. Disable to leave index unset. |
Prerequisites: .NET SDK 8.0 or later.
git clone https://github.com/Jdiesel87/Abs2Emby.git
cd ABS_Import
dotnet build -c ReleaseThe compiled plugin DLL is placed at:
bin/Release/netstandard2.0/ABS_Import.dll
- Stop your Emby server.
- Copy
ABS_Import.dllinto your Emby plugins directory:- Windows:
%AppData%\Emby-Server\plugins - Linux / Docker:
/config/plugins
- Windows:
- Restart the server.
- Go to Dashboard → Plugins and confirm ABS Import appears.
- Edit your audiobook library: Library → Manage Library → (library) → Metadata / Images.
- Enable these providers:
AudioBookShelf Local Metadata(forBook)AudioBookShelf Local Metadata (Album)(forMusicAlbum)AudioBookShelf Local Metadata (Track)(forAudio)AudioBookShelf Local Cover
- Refresh metadata on the library or individual items.
- Built against Emby
MediaBrowser.Server.Core4.9.1.90 (netstandard2.0). - Should work cleanly with Emby 4.9.x and later.
MapAuthorsAsAlbumArtists(default on) writes authors toArtists/AlbumArtists;MapNarratorsAsComposers(default on) writes narrators toComposers. Both may override data Emby parsed from file ID3 tags. Turn them off to preserve tag-origin artist/composer data.
| Symptom | Likely Cause | Check |
|---|---|---|
| No metadata is applied | Provider not enabled or priority too low | Library → Manage Library → Metadata/Images |
| ABS metadata ignored | Sidecar has a different filename | metadata.json or metadata.abs in the item folder |
| Cover not showing | Cover file name not in the candidate list | Try cover.jpg, cover.png, or folder.jpg |
| Conflicting or missing data | Another provider (tag-based, online) runs first | Lower the order of other providers, or disable them |
| Errors in Emby log | Look for log entries with category AbsImport |
Dashboard → Logs |
- AudioBookShelf for the metadata sidecar format this plugin consumes.
- Emby Team for the server plugin SDK and community support.
This project is licensed under the MIT License — see the LICENSE file for details.