sentriz / gonic

music streaming server / free-software subsonic server API implementation
ircs://irc.libera.chat/#gonic
GNU General Public License v3.0
1.55k stars 111 forks source link

Support multiple libraries #50

Closed tjiho closed 2 years ago

tjiho commented 4 years ago

Thanks for this great project !

But a major feature of Airsonic is missing, be able to have multiple libraries.

sentriz commented 4 years ago

hey thank you :)

what I've been doing is making a gonic_music_dir, pointing gonic at that, then symlinking all your multiple libraries into it

sampleslaya commented 4 years ago

Hi, Sentriz.

Amazing project.

It would be nice assign libraries to user, and isolate the mp3 tree structure for each user.

Thanks!

djl commented 3 years ago

:+1:

My use case is having folders/libraries for different types of audio (e.g. audiobooks, podcasts and music). Lumping these together, especially if your library is large, makes browsing specific types rather awkward.

I think this is the only feature I still miss from *sonic. I'd be willing to chip in on a bug/feature bounty if anyone wants to set it up :)

cascooscuro commented 3 years ago

Thanks for this project Sentriz!!

I would love to see this implemented too.

jef commented 3 years ago

hey thank you :)

what I've been doing is making a gonic_music_dir, pointing gonic at that, then symlinking all your multiple libraries into it

I don't really see a problem with this approach.

Can someone explain why they wouldn't want to do this? I think an implementation would have the similar effect, so I'm not unaware of the (potential) benefits.

It would be nice assign libraries to user, and isolate the mp3 tree structure for each user.

I think this would be the only benefit. Are there others?

djl commented 3 years ago

I think this would be the only benefit. Are there others?

What I said above:

My use case is having folders/libraries for different types of audio (e.g. audiobooks, podcasts and music). Lumping these together, especially if your library is large, makes browsing specific types rather awkward.

I said "awkward" previously but in reality it's near impossible.

jef commented 3 years ago

This is because you're envisioning these multiple folders getting read in would be in different views?

djl commented 3 years ago

Yeah that's what I was imagining. The *sonic let the user choose which folders/libraries to view. Here's a screenshot from my Madsonic instance:

screenshot-2021-05-11-202739

jef commented 3 years ago

Ahh, right. Gotcha. Okay, seems interesting enough. Thanks for all the information.

sentriz commented 3 years ago

thanks too @djl this makes sense to me after seeing that screenshot

I've never even seen the ability to change music folders in the subsonic clients I use but that seems handy

cascooscuro commented 3 years ago

My use case is similar to @djl but with genres.

For example, in Play:sub iphone client you can select the folder. I have my library organized by genre and I usually start a random playlist within that genre:

Trying to do the same but using the genre tags becomes quite a challenge. I have something like a thousand different tags...

jstaro commented 2 years ago

There is also the issue of accessing symlinked paths on the host when you run gonic in docker. You can work around it by also mounting the paths that the symlinks point to, but it sort of defeats the point of symlinks, having to manage potentially many folders.

Whilst I don't divide my collection up in genre folders, I do have different folders like "new" (albums I just bought, but haven't listened a lot to yet), and albums then get moved to "unsorted" (the ones I liked and deemed were worth keeping), then I spend some time prettying up the folders/files/cover art/info and ultimately move them to "archive". Occasionally I may want to filter on that in my player.

sentriz commented 2 years ago

hi all, I added some experimental support for this. if anyone is familiar with building from source and would like to test it, checkout the mockfs-scanner branch

go install go.senan.xyz/gonic/cmd/gonic@mockfs-scanner

then multiple paths can be added by repeating the flag. eg

$ gonic \
      -music-path /example/path/a \
      -music-path /example/path/b \
      -music-path /example/path/c

or if you're using env vars, try GONIC_MUSIC_PATH=/example/a,example/b

if you want to speed up the gonic scan after adding multiple folders for the first time, provide your original (non extra) music dir as the first argument. this completely optional but can speed this up a bit if you like

cascooscuro commented 2 years ago

Just did a quick check with play:Sub, iSub and DSub mobile apps.

Play:Sub and DSub looks ok, but with iSub there is an issue.

I added three paths and, in the case of iSub, although all the albums are available, when you are in the "folders" view, you can only select one of the three paths:

Not sure if this an issue on iSub side or the way gonic is doing the response for getMusicFolders

In any case, thanks for adding this feature!!

sentriz commented 2 years ago

@cascooscuro thanks for trying it out :)

could you post the logs around the time of the iSub request to getMusicFolders? just interested in the query params that it's sending

also if you can, post the response from the request it is making? just a simple curl of the url it's requesting or put the url in your browser

cascooscuro commented 2 years ago

this is the tcpdump for iSub (/rest/getMusicFolders.view?c=iSub&p=REDACTED&u=user&v=1.0.0):

GET /rest/getMusicFolders.view?v=1.0.0&c=iSub&u=user&p=password HTTP/1.1
Host: 192.168.1.2:4747
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: iSub/413 CFNetwork/1240.0.4 Darwin/20.6.0
Accept-Language: en-us
Cache-Control: no-cache
Connection: keep-alive

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *
Content-Type: application/xml
Date: Mon, 08 Nov 2021 16:11:23 GMT
Content-Length: 419

<subsonic-response status="ok" version="1.15.0" xmlns="http://subsonic.org/restapi" type="gonic">
    <musicFolders>
        <musicFolder id="/genre/folk" name="folk"></musicFolder>
        <musicFolder id="/genre/blues" name="blues"></musicFolder>
        <musicFolder id="/genre/opera" name="opera"></musicFolder>
    </musicFolders>
</subsonic-response>

In this case iSub is only displaying "opera". It looks that it only sees the last musicfolder...

These are the logs for play:Sub app (/rest/getMusicFolders.view). In this case the app shows the three paths correctly:

POST /rest/getMusicFolders.view HTTP/1.1
Host: 192.168.1.2:4747
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Accept: */*
User-Agent: playSub/2021.2 (iPhone; iOS 14.8.1; Scale/2.00)
Accept-Language: en-US;q=1, es-ES;q=0.9
Accept-Encoding: gzip, deflate
Content-Length: 114

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Mon, 08 Nov 2021 16:19:49 GMT
Content-Length: 276

{"subsonic-response":{"status":"ok","version":"1.15.0","type":"gonic","musicFolders":{"musicFolder":[{"id":"/genre/folk","name":"folk"},{"id":"/genre/blues","name":"blues"},{"id":"/genre/opera","name":"opera"}]}}}

And finally for DSub (/rest/getMusicFolders.view?u=user&s=xxxxxxxxxxxxxxxxxxx&t=xxxxxxxxxxxxxxxxxxxxx&v=1.2.0&c=DSub). In this case the app shows the three paths correctly:

GET /rest/getMusicFolders.view?u=user&s=xxxxxxxxxxxxxxxxxxxxxxxxx&t=xxxxxxxxxxxxxxxxxx&v=1.2.0&c=DSub HTTP/1.1
Accept-Encoding: gzip
User-Agent: DSub
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxx==
Host: 192.168.1.2:4747
Connection: Keep-Alive

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *
Content-Type: application/xml
Date: Mon, 08 Nov 2021 16:40:52 GMT
Content-Length: 419

<subsonic-response status="ok" version="1.15.0" xmlns="http://subsonic.org/restapi" type="gonic">
    <musicFolders>
        <musicFolder id="/genre/folk" name="folk"></musicFolder>
        <musicFolder id="/genre/blues" name="blues"></musicFolder>
        <musicFolder id="/genre/opera" name="opera"></musicFolder>
    </musicFolders>
</subsonic-response>
sentriz commented 2 years ago

@cascooscuro thank you kindly. very detailed :) I think the issue is that iSub expects the music_folder ID to be an int (true to the spec) where as other clients allow strings. let me see if I can make them ints

sentriz commented 2 years ago

@cascooscuro how does the music-folder-id-ints branch work for you? I did a bit of testing but I think most of the subsonic clients I use don't support musicFolders

cascooscuro commented 2 years ago

It works!!! iSub now correctly displays all the music folders. Play:Sub and DSub keep working too.

Thanks for fixing it so quickly!

sentriz commented 2 years ago

great to hear :) gonna merge that branch to master then. though not gonna release for a while because i still think it's a bit experimental. thanks for your help and let me know if something weird happens :+1: