-
-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: audiobookshelf server support #67
Comments
Hey, Thanks for sharing your idea! It sounds very feasible. For Linux: I could get the simulator working, although the network during sync mode is not working, so I still have to move to windows for testing. Don't try Eclipse studio though, Visual Studio Code with the plugin is much easier to get working! With regards to the actual implementation:
Currently, SubMusic does not have an auto-removal feature (e.g. remove the episode once listened). Of course such a feature would be a nice addition, however, AudioBookShelf might remove played episodes/books from the playlist already? If so, we could just sync the progress (the Scrobble), then request the playlist endpoint to retrieve the new playlist. Also something to take into account: podcasts and audiobooks typically have quite large files, so maybe it is nice to add some memory check before trying to download all files from the playlist. Hope this helps! |
yeah, that seems like a big issue. the mechanism for getting progress on individual episodes being either a giant json blob of progress of all episodes or having to hit an api call for every episode progress info is needed for both is a little problematic here too. Looking at my local setup with a podcast that has 500~ episodes produces around 2MB of json. I opened advplyr/audiobookshelf/issues/1504 - maybe we'll have some positive movement around that - it's hard to see a device handling larger libraries/playlists well without pagination
yeah basically, with this example json for an audiobook, you can see that you eventually drill down into a set of tracks that have a example json{
"id": "pl_qbwet64998s5ra6dcu",
"libraryId": "lib_c1u6t4p45c35rf0nzd",
"userId": "root",
"name": "Favorites",
"description": null,
"coverPath": null,
"items": [
{
"libraryItemId": "li_8gch9ve09orgn4fdz8",
"episodeId": null,
"libraryItem": {
"id": "li_8gch9ve09orgn4fdz8",
"ino": "649641337522215266",
"libraryId": "lib_c1u6t4p45c35rf0nzd",
"folderId": "fol_bev1zuxhb0j0s1wehr",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule",
"relPath": "Terry Goodkind/Sword of Truth/Wizards First Rule",
"isFile": false,
"mtimeMs": 1650621074299,
"ctimeMs": 1650621074299,
"birthtimeMs": 0,
"addedAt": 1650621073750,
"updatedAt": 1650621110769,
"lastScan": 1651830827825,
"scanVersion": "2.0.21",
"isMissing": false,
"isInvalid": false,
"mediaType": "book",
"media": {
"libraryItemId": "li_8gch9ve09orgn4fdz8",
"metadata": {
"title": "Wizards First Rule",
"titleIgnorePrefix": "Wizards First Rule",
"subtitle": null,
"authors": [
{
"id": "aut_z3leimgybl7uf3y4ab",
"name": "Terry Goodkind"
}
],
"narrators": [
"Sam Tsoutsouvas"
],
"series": [
{
"id": "ser_cabkj4jeu8be3rap4g",
"name": "Sword of Truth",
"sequence": "1"
}
],
"genres": [
"Fantasy"
],
"publishedYear": "2008",
"publishedDate": null,
"publisher": "Brilliance Audio",
"description": "The masterpiece that started Terry Goodkind's New York Times bestselling epic Sword of Truth In the aftermath of the brutal murder of his father, a mysterious woman, Kahlan Amnell, appears in Richard Cypher's forest sanctuary seeking help...and more. His world, his very beliefs, are shattered when ancient debts come due with thundering violence. In a dark age it takes courage to live, and more than mere courage to challenge those who hold dominion, Richard and Kahlan must take up that challenge or become the next victims. Beyond awaits a bewitching land where even the best of their hearts could betray them. Yet, Richard fears nothing so much as what secrets his sword might reveal about his own soul. Falling in love would destroy them - for reasons Richard can't imagine and Kahlan dare not say. In their darkest hour, hunted relentlessly, tormented by treachery and loss, Kahlan calls upon Richard to reach beyond his sword - to invoke within himself something more noble. Neither knows that the rules of battle have just changed...or that their time has run out. Wizard's First Rule is the beginning. One book. One Rule. Witness the birth of a legend.",
"isbn": null,
"asin": "B002V0QK4C",
"language": null,
"explicit": false,
"authorName": "Terry Goodkind",
"authorNameLF": "Goodkind, Terry",
"narratorName": "Sam Tsoutsouvas",
"seriesName": "Sword of Truth"
},
"coverPath": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/cover.jpg",
"tags": [
"Favorite"
],
"audioFiles": [
{
"index": 1,
"ino": "649644248522215260",
"metadata": {
"filename": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"ext": ".mp3",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"relPath": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"size": 48037888,
"mtimeMs": 1632223180278,
"ctimeMs": 1645978261001,
"birthtimeMs": 0
},
"addedAt": 1650621074131,
"updatedAt": 1651830828023,
"trackNumFromMeta": 1,
"discNumFromMeta": null,
"trackNumFromFilename": 1,
"discNumFromFilename": null,
"manuallyVerified": false,
"invalid": false,
"exclude": false,
"error": null,
"format": "MP2/3 (MPEG audio layer 2/3)",
"duration": 6004.6675,
"bitRate": 64000,
"language": null,
"codec": "mp3",
"timeBase": "1/14112000",
"channels": 2,
"channelLayout": "stereo",
"chapters": [],
"embeddedCoverArt": null,
"metaTags": {
"tagAlbum": "SOT Bk01",
"tagArtist": "Terry Goodkind",
"tagGenre": "Audiobook Fantasy",
"tagTitle": "Wizards First Rule 01",
"tagTrack": "01/20",
"tagAlbumArtist": "Terry Goodkind",
"tagComposer": "Terry Goodkind"
},
"mimeType": "audio/mpeg"
},
{
"index": 2,
"ino": "649644248522215261",
"metadata": {
"filename": "Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"ext": ".mp3",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"relPath": "Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"size": 47972352,
"mtimeMs": 1632223180281,
"ctimeMs": 1645978261001,
"birthtimeMs": 0
},
"addedAt": 1650621074130,
"updatedAt": 1651830828023,
"trackNumFromMeta": 2,
"discNumFromMeta": null,
"trackNumFromFilename": 1,
"discNumFromFilename": null,
"manuallyVerified": false,
"invalid": false,
"exclude": false,
"error": null,
"format": "MP2/3 (MPEG audio layer 2/3)",
"duration": 5996.2785,
"bitRate": 64000,
"language": null,
"codec": "mp3",
"timeBase": "1/14112000",
"channels": 2,
"channelLayout": "stereo",
"chapters": [],
"embeddedCoverArt": null,
"metaTags": {
"tagAlbum": "SOT Bk01",
"tagArtist": "Terry Goodkind",
"tagGenre": "Audiobook Fantasy",
"tagTitle": "Wizards First Rule 02",
"tagTrack": "02/20",
"tagAlbumArtist": "Terry Goodkind",
"tagComposer": "Terry Goodkind"
},
"mimeType": "audio/mpeg"
}
],
"chapters": [
{
"id": 0,
"start": 0,
"end": 6004.6675,
"title": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01"
},
{
"id": 1,
"start": 6004.6675,
"end": 12000.946,
"title": "Terry Goodkind - SOT Bk01 - Wizards First Rule 02"
}
],
"duration": 33854.905,
"size": 268824228,
"tracks": [
{
"index": 1,
"startOffset": 0,
"duration": 6004.6675,
"title": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"contentUrl": "/s/item/li_8gch9ve09orgn4fdz8/Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"mimeType": "audio/mpeg",
"metadata": {
"filename": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"ext": ".mp3",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"relPath": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"size": 48037888,
"mtimeMs": 1632223180278,
"ctimeMs": 1645978261001,
"birthtimeMs": 0
}
},
{
"index": 2,
"startOffset": 6004.6675,
"duration": 5996.2785,
"title": "Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"contentUrl": "/s/item/li_8gch9ve09orgn4fdz8/Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"mimeType": "audio/mpeg",
"metadata": {
"filename": "Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"ext": ".mp3",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"relPath": "Terry Goodkind - SOT Bk01 - Wizards First Rule 03.mp3",
"size": 47972352,
"mtimeMs": 1632223180281,
"ctimeMs": 1645978261001,
"birthtimeMs": 0
}
}
],
"missingParts": [],
"ebookFile": null
},
"libraryFiles": [
{
"ino": "649644248522215260",
"metadata": {
"filename": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"ext": ".mp3",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"relPath": "Terry Goodkind - SOT Bk01 - Wizards First Rule 01.mp3",
"size": 48037888,
"mtimeMs": 1632223180278,
"ctimeMs": 1645978261001,
"birthtimeMs": 0
},
"addedAt": 1650621052494,
"updatedAt": 1650621052494,
"fileType": "audio"
},
{
"ino": "649644248522215261",
"metadata": {
"filename": "Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"ext": ".mp3",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"relPath": "Terry Goodkind - SOT Bk01 - Wizards First Rule 02.mp3",
"size": 47972352,
"mtimeMs": 1632223180281,
"ctimeMs": 1645978261001,
"birthtimeMs": 0
},
"addedAt": 1650621052494,
"updatedAt": 1650621052494,
"fileType": "audio"
},
{
"ino": "649644248522215267",
"metadata": {
"filename": "cover.jpg",
"ext": ".jpg",
"path": "/audiobooks/Terry Goodkind/Sword of Truth/Wizards First Rule/cover.jpg",
"relPath": "cover.jpg",
"size": 325531,
"mtimeMs": 1638754803540,
"ctimeMs": 1645978261003,
"birthtimeMs": 0
},
"addedAt": 1650621052495,
"updatedAt": 1650621052495,
"fileType": "image"
}
],
"size": 268990279
}
}
],
"lastUpdate": 1669623431313,
"createdAt": 1669623431313
} I'm not 100% on how they handle transcoding, I know that's something that audiobookshelf does but it's not obvious from the API |
Transcoding is not a strict requirement, we could also filter available audio files based on content type. Based on the response in your referenced issue, the libraryItems can be retrieved by page. That may or may not be sufficient depending on what endpoint is used to obtain the playlists. Below the complete table of features that require implementation:
Not sure what series, playlists and collections mean in the AudioBookshelf api? |
Series, Playlists, and Collections are just ways that multiple books can be collected together.
See the following on Collection or playlists https://www.audiobookshelf.org/guides/collections/ One thing to keep in mind is Audio Book shelf works based on Libraries. There is frequently two libraries. One for Audio Books and one for Podcasts. |
Hey, I actually had ambitions of building this out myself but after an afternoon of trying and failing to get the garmin connect simulator functioning correctly on my linux machine... i give up. Hopefully just leaving this issue inspires someone else
Audiobookshelf github: https://github.com/advplyr/audiobookshelf is an audiobook/podcast focused server you can use to manage your audiobooks/podcasts. It's pretty good and getting better as it goes, having support in SubMusic for it as a backend would be fantastic. It's got the basic features (with some quirks)
They don't have a programmatically described API but it seems fairly stable and they have good documentation at least, functionally you need to login
and then you can get playlists
from there you can typically drill down into the podcast/audiobook chapters/episodes and get the files from them for downloading
so the quirks...
1, figuring out if a file has already been played is a bit weird, you can either call the progress api for every single library item which is not great for large playlists, or call the authorize API, which is what the webUI does. It contains a User object which contains the mediaProgress of every single piece of audio the signed in user has listened to, which can be manually cross referenced with library items
2, syncing media progress back to the server is a little weird, they want to you do create a local listening session, but I've not been able to figure out how. I think the mobile webapp does that, then you can sync the local listening session. The alternative is manually updating media progress which seems probably simpler
The text was updated successfully, but these errors were encountered: