Skip to content
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

More detailed instruction #2

Open
mxdalchau opened this issue Jan 24, 2023 · 68 comments
Open

More detailed instruction #2

mxdalchau opened this issue Jan 24, 2023 · 68 comments

Comments

@mxdalchau
Copy link

Hey,

could you write a more detailed instruction please?

thanks :)

@jmt-gh
Copy link
Owner

jmt-gh commented Jan 25, 2023

Could you be a bit more specific in what you're looking for? The "how to use" section is step by step on how to get things running. I'm more than happy to add additional information, but I'm not sure what exactly you're looking for

@prolife86
Copy link

prolife86 commented Jan 25, 2023

He might mean weather you are going to publish it on DockerHub?
This might make it easier for people to implement.
Just guessing here, and following this project with great interest!

@mxdalchau
Copy link
Author

Hey, sorry my english is no t so good...

If i use docker-compose with docker file.. which file i should edit?

@mxdalchau
Copy link
Author

mxdalchau commented Jan 25, 2023

so the docker-compose is running http://xxx.xxx.xxx.xxx:3333/wsdl

there is only a white site

could i see a log ... to analyze whats the problem

@mreitschuster
Copy link

I think a more detailed how-to might help. I am struggling with quite a few point:

  1. where can the file "soap-server.js" be found? it is described and when running without docker it seems to be the mian file ("run node soap-server.js") but I cannot find that file not found in this repo

Since I couldnt find it I tried via docker-compose

  1. docker-compose refers to node-docker but that cannot be found or installed.
audiobookshelf-sonos Error  
Error response from daemon: pull access denied for node-docker, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
  1. The "ABS_TOKEN=" likely stands for the audiobookshelf user token, that can be found when logging in as root and clicking on settings -> users -> specific username

  2. ABS_LIBRARY_ID= is not clear. Does it expect a ID (likely numeric) or the name of the library?

  3. are the modifications of config.js and sonos.wsdl also necessary when running via docker compose? if yes how does docker compose know which files to take - the only volumne defined there is sonos.wsdl?

@jt196
Copy link

jt196 commented Apr 5, 2023

I've spent a bit of time looking at this and have a few answers to the above.

  1. The file is server.js, I think it's been renamed but the docs haven't been updated.
  2. The docker image isn't hosted anywhere, so you need to build it. If you cd into the cloned directory, and run the command docker build -t node-docker:latest, the command will run and it should work.
  3. Pretty sure this is correct.
  4. This is a bit confusing, if you've got just one library, I belive the id is just "main". If you have a second library, you can see the id in the URL, "lib_xxxx".
  5. I think you need to add the environment variables in the Docker compose, and modify the sonos.wsdl file as well. From what I can see, you need to avoid inverted commas in the docker-compose ENV variables.

Anyway, I've tried all these, and still not working.

@jt196
Copy link

jt196 commented Apr 5, 2023

@jmt-gh, what sort of response should we be getting from the URLs: https://soap.server.com/wsdl or https://soap.server.com/manifest?

I get a 200 response but 0 bytes return from the /wsdl, and this response from the /manifest:

{
  "schemaVersion": "1.0",
  "endpoints": [
    {
      "type": "reporting",
      "uri": "https://soap.server.com/wsdl/playback/v2.1/report"
    }
  ]
}

Seems like there should be a bit more in the wsdl response at least.

By the way, if I use this for the env variable in the docker-compose:

- SOAP_URI="https://soap.server.com/wsdl"

The return from the manifest shows this:

      "uri": '"https://soap.server.com/wsdl"/playback/v2.1/report'

When I remove the "", it displays correctly.

@mxdalchau
Copy link
Author

should the abs uri only a http or could be https?

@mxdalchau
Copy link
Author

i get {"schemaVersion":"1.0","endpoints":[{"type":"reporting","uri":"https://soabs.xxxx.de/wsdl/playback/v2.1/report"}]}
what is right, but i can´t access in sonos

@jt196
Copy link

jt196 commented Apr 5, 2023

should the abs uri only a http or could be https?

I'd have thought whatever you have set up. Mine is https, so that's what I've put in.

@mxdalchau
Copy link
Author

ok me too.. but the sonos app can´t read the libary

@jt196
Copy link

jt196 commented Apr 6, 2023

Mine can't either, I get a connection error. There's no feedback on the log of the container, so it's quite hard to debug it.

@mxdalchau
Copy link
Author

schade eigentlich wirkte das Projekt vielversprechend

@robwalster
Copy link

@jt196 did you ever get this working?

@jt196
Copy link

jt196 commented Aug 11, 2023

@jt196 did you ever get this working?

Hacked away at it for half a day but never got it to work. I could add the service to Sonos by unchecking "Support Manifest File", that's about as far as I got. There were no logs on the Docker container when I tried to access it in Sonos, and Sonos itself have disabled a lot of the log checking functions in their speakers. I went a little through their docs, but had little success I'm afraid.

@eendenhart
Copy link

Hi!
I set this up in a docker container on Unraid, Trial and error but it's running except cant find a way to access the library in the sonosapp.
The docker log gives me this error: [getLibraryItems] Error caught. Error: Request failed with status code 404

@jt196
Copy link

jt196 commented Sep 20, 2023

@eendenhart no idea, but maybe post how you got so far here so maybe we can get a solution together?

404 is just a not found error, so likely you've entered the audiobookshelf URL incorrectly.

@eendenhart
Copy link

eendenhart commented Sep 20, 2023

I think the url is correct; I checked many times.
I got a connection in audiobookshelf: when i typ the wrong token he gives in the logs of audiobookshelf an error.

What i did:

  1. create a directory: /mnt/user/appdata/audiobookshelf-sonos
  2. cloned the repository to this folder
  3. Update the sonos.wsdl file with my SOAP_URI
  4. create the docker image: execute in the unraid terminal docker build /mnt/user/appdata/audiobookshelf-sonos
  5. renamed this docker image: node-docker docker tag 'containerid' node-docker
  6. created the container from my dockerhub: https://hub.docker.com/r/eendenhart/audiobookshelf-sonos/
  7. changed the repository in node-docker:latest
  8. port: 80:3333
  9. added ENV-variables: SOAP_URI, ABS_URI, ABS_LIBRARY_ID, ABS_TOKEN, SONOS_WSDL_FILE, SOAP_ENDPOINT
  10. add volume: /mnt/user/appdata/audiobookshelf-sonos:/app/sonos.wsdl

I got the error [getLibraryItems] Error caught. Error: Request failed with status code 404 when i hit the services in sonos

@robwalster
Copy link

robwalster commented Sep 26, 2023

@jt196 did you ever get this working?

Hacked away at it for half a day but never got it to work. I could add the service to Sonos by unchecking "Support Manifest File", that's about as far as I got. There were no logs on the Docker container when I tried to access it in Sonos, and Sonos itself have disabled a lot of the log checking functions in their speakers. I went a little through their docs, but had little success I'm afraid.

I've put a bit of time into this today and got a little further but still not working.

First of all I turned on debugging in the servert.js file by uncommenting line 37. Now we can see incoming requests and how the SOAP server responds.

Now for what I had been doing wrong:

  1. I forgot to update the supplied sonos.wsdl with my SOAP_URI on line 2062
  2. when adding the service to sonos for the secure endpoint don't use https, just use http (unless of course, you have the endpoint running on https)
  3. The library ID isn't "main", nor did mine start with "lib_", in audiobookshelf open your library and it's in the url: "http://127.0.0.1:13378/library/[YOUR LIBRARY ID]", alternatively get it with curl following the instructions here: https://api.audiobookshelf.org/#libraries

The first few requests go through and seem to make it to audiobookshelf, however I'm hitting a wall with the error:

TypeError: Cannot read properties of undefined (reading 'id')

Edit:
A bit more digging and I got there. Comment out lines: 104, 105, 106, 107, 108, 139, 140, 141, 142, 144, 145 in utils.js. It seems if you have any book metadata missing (author, narrator, album art etc) it causes the wrong data to be returned. after commenting out these lines Sonos finally connects to audio book shelf and shows my library.

However, it still does not play any of the books, saying Sonos is unable to connect. I suspect the function getMediaMetadata on line 16 of sonos-service.js needs completing.

@jt196
Copy link

jt196 commented Sep 26, 2023

@robwalster I've played around a little bit and made no progress at all. Some pointers that might be useful.

  1. If you're running Dockerised (and it might be worth trying to run this outside a docker environment, as it can definitely cause issues!), then try adding nodemon to the Dockerfile. If you're sharing the local files, you won't have to restart the dev container.
FROM node:16-alpine
ENV NODE_ENV=production

WORKDIR /app

COPY ["package.json", "package-lock.json", "./"]

RUN npm install --production && npm install -g nodemon

COPY . .

CMD ["nodemon", "server.js"]
  1. Navigate to the page http:///wsdl and see if the wsdl file is served there. I can't see one, maybe I got some stuff wrong. I can't see anything on my Sonos app. If you can, I'd be interested in knowing a bit more about your env variables.
  2. Instead of commenting out the utils, try this code. It'll just enter null if they're empty. You may want to replace the null with '' if that breaks anything.

async function buildLibraryMetadataResult(res) { if (!res || !res.results) { return null; }

let libraryItems = res.results;
let count = res.total;
let total = count;
let mediaMetadata = [];

for (const libraryItem of libraryItems) {
  if (!libraryItem || !libraryItem.media || !libraryItem.media.audioFiles || !libraryItem.media.audioFiles[0]) {
    continue;
  }

  let authorId = libraryItem.media.metadata && libraryItem.media.metadata.authors && libraryItem.media.metadata.authors[0] ? libraryItem.media.metadata.authors[0].id : null;
  let authorName = authorId ? libraryItem.media.metadata.authors[0].name : null;
  let narratorId = libraryItem.media.metadata && libraryItem.media.metadata.narrators && libraryItem.media.metadata.narrators[0] ? libraryItem.media.metadata.narrators[0].id : null;
  let narratorName = narratorId ? libraryItem.media.metadata.narrators[0].name : null;

  var mediaMetadataEntry = {
    itemType: "audiobook",
    id: libraryItem.id,
    mimeType: libraryItem.media.audioFiles[0].mimeType,
    canPlay: true,
    canResume: true,
    title: libraryItem.media.metadata ? libraryItem.media.metadata.title : null,
    summary: libraryItem.media.metadata ? libraryItem.media.metadata.description : null,
    authorId: authorId,
    author: authorName,
    narratorId: narratorId,
    narrator: narratorName,
    albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
  };

  mediaMetadata.push(mediaMetadataEntry);
}

return {
  getMetadataResult: {
    count: count,
    total: total,
    index: 0,
    mediaCollection: mediaMetadata,
  },
};
}

  async function buildAudiobookTrackList(libraryItem, progressData) {
  if (!libraryItem || !libraryItem.media || !libraryItem.media.audioFiles) {
    return null;
  }

let tracks = libraryItem.media.audioFiles;
let icount = tracks.length;
let itotal = tracks.length;
let imediaMetadata = [];

for (const track of tracks) {
  let authorId = libraryItem.media.metadata && libraryItem.media.metadata.authors && libraryItem.media.metadata.authors[0] ? libraryItem.media.metadata.authors[0].id : null;
  let authorName = authorId ? libraryItem.media.metadata.authors[0].name : null;
  let narratorId = libraryItem.media.metadata && libraryItem.media.metadata.narrators && libraryItem.media.metadata.narrators[0] ? libraryItem.media.metadata.narrators[0].id : null;
  let narratorName = narratorId ? libraryItem.media.metadata.narrators[0].name : null;

  var mediaMetadataEntry = {
    id: `${libraryItem.id}/${track.metadata.filename}`,
    itemType: "track",
    title: track.metadata.filename,
    mimeType: track.mimeType,
    trackMetadata: {
      authorId: authorId,
      author: authorName,
      narratorId: narratorId,
      narrator: narratorName,
      duration: track.duration,
      book: libraryItem.media.metadata ? libraryItem.media.metadata.title : null,
      albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
      canPlay: true,
      canAddToFavorites: false,
    },
  };

  imediaMetadata.push(mediaMetadataEntry);
}

let positionInformation = {};
if (progressData) {
  positionInformation = {
    id: `${libraryItem.id}/${progressData.partName}`,
    index: 0,
    offsetMillis: Math.round(progressData.relativeTimeForPart * 1000),
  };
}

return {
  getMetadataResult: {
    count: icount,
    total: itotal,
    index: 0,
    positionInformation: positionInformation,
    mediaMetadata: imediaMetadata,
  },
};
}

Edit, 'scuse the crappy formating, didn't want to paste the whole lot here but the details tags don't play well with code.

@jt196
Copy link

jt196 commented Sep 27, 2023

OK it appears to be an issue with the buildLibraryMetadata function.

This is an object being fed into the loop:

{
  id: '70edd71c-0088-49b8-8ea5-210c8049ce09',
  ino: '370123',
  oldLibraryItemId: 'ab_vm3xuee9z2z7krgw7q',
  libraryId: '96cfd553-cc4e-4a9b-9f67-866838eb62d7',
  folderId: '92fb9312-b5e2-4aae-b1d4-96fd7e521299',
  path: '/audiobooks/C.S. Forester/The Good Shepherd',
  relPath: 'C.S. Forester/The Good Shepherd',
  isFile: false,
  mtimeMs: 1594763569000,
  ctimeMs: 1641490864998,
  birthtimeMs: 1641490864998,
  addedAt: 1646732242162,
  updatedAt: 1646820362213,
  isMissing: false,
  isInvalid: false,
  mediaType: 'book',
  media: {
    id: '43c51480-1e3c-4b50-88b7-b7f045065474',
    metadata: {
      title: 'The Good Shepherd',
      titleIgnorePrefix: 'Good Shepherd, The',
      subtitle: null,
      authorName: 'C.S. Forester',
      authorNameLF: 'Forester, C.S.',
      narratorName: 'Edoardo Ballerini',
      seriesName: '',
      genres: [Array],
      publishedYear: '2020',
      publishedDate: null,
      publisher: 'Podium Audio',
      description: 'The Good Shepherd is now a major motion picture, Greyhound , scripted by and starring Tom Hanks, directed by Aaron Schneider, and produced by Gary Goetzman. A convoy of 37 merchant ships is ploughing through icy, submarine-infested North Atlantic seas during the most critical days of World War II, when the German submarines had the upper hand and Allied shipping was suffering heavy losses. In charge is Commander George Krause, an untested veteran of the US Navy. Hounded by a wolf pack of German U-boats, he faces 48 hours of desperate peril trapped the bridge of the ship. Exhausted beyond measure, he must make countless and terrible decisions as he leads his small fighting force against the relentless U-boats.',
      isbn: null,
      asin: '1774244152',
      language: 'English',
      explicit: false,
      abridged: false
    },
    coverPath: '/audiobooks/C.S. Forester/The Good Shepherd/The Good Shepherd - 001.mp3',
    tags: [],
    numTracks: 17,
    numAudioFiles: 17,
    numChapters: 33,
    numMissingParts: 0,
    numInvalidAudioFiles: 0,
    duration: 28401.437333,
    size: 454976356,
    ebookFormat: null
  },
  numFiles: 17,
  size: 454976356
}

The function expects:

  • media.audioFiles
  • media.metadata.authors
  • media.metadata.narrators

None of these exist in the object, so no wonder it's not returning any results.

According to the API docs, these should be returned in library > library item > book

But for some reason, it's not doing that.

The reason I can see, looks like expected behaviour, getting library items will not retrieve the expected data. The audioFiles and the metadata.authors, metadata.narrators simply aren't there.

@jt196
Copy link

jt196 commented Sep 27, 2023

With the data logging, this amended function will return a soap style object in the console:

async function buildLibraryMetadataResult(res) {
  if (!res || !res.results) {
    return null;
  }

  let libraryItems = res.results;
  let total = count;
  let mediaMetadata = [];

  for (const libraryItem of libraryItems) {

    var mediaMetadataEntry = {
      itemType: "audiobook",
      id: libraryItem.id,
      canPlay: true,
      canResume: true,
      title: libraryItem.media.metadata
        ? libraryItem.media.metadata.title
        : null,
      summary: libraryItem.media.metadata
        ? libraryItem.media.metadata.description
        : null,
      author: libraryItem.media.metadata.authorName,
      narrator: libraryItem.media.metadata.narratorName,
      albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
    };

    mediaMetadata.push(mediaMetadataEntry);
  }

  return {
    getMetadataResult: {
      count: count,
      total: total,
      index: 0,
      mediaCollection: mediaMetadata,
    },
  };
}

But I still can't get it to show the items...

@jt196
Copy link

jt196 commented Sep 27, 2023

I've tried a bunch of stuff and still can't get it to work.

The soap server is working correctly, and returning a correct response, with a properly structured soap xml. I've tested this on SoapUI - even to the point where I'm using the stock responses in the docs here and they still don't work.

I'm wondering at this point whether the customsd form is being filled incorrectly. It's polling the server and SoapUI, but not happy with the result.

Maybe unchecking the "Support Manifest File" is causing the issue? I can't add the service if I don't do this.

@jt196
Copy link

jt196 commented Sep 27, 2023

I've put the updated/worked on files in a new repo. They should maybe get some folks a bit further along the line.

I've also added notes about testing, debugging etc. Still can't get it working though!

@jmt-gh
Copy link
Owner

jmt-gh commented Sep 28, 2023

👋 Hello all. Sorry for not being particularly active on this project. I can't commit to helping resolve everything here, but I'll try and get things up and running locally again and see if there are any glaring issues I find.

A few things to note:

  • This was built against whatever the latest stable version of audiobookshelf was at the time last year when it was first built. At that time, there was no stable public API interfaces to build against, so it's very possible some of the ABS response schemas have changed (@jt196 this is probably what you're seeing in the response above)
  • The sonos app + OS (android specifically) are really finnicky about HTTP/HTTPS, and cert chains. I tried to make it clear what was needed here in the set up instructions, but please double check. I only had this working with a reverse proxy handling the HTTPS -- if you're trying to do it without that, I don't have any explicit answers, but open to updating the README if someone figures out solutions to any issues there

@jmt-gh
Copy link
Owner

jmt-gh commented Sep 28, 2023

tl;dr: I was able to get things up easily still, but not necessairly fully funcitonal and running. The latter due to API changes in ABS.

OK, made some progress debugging. A few things:

  • I'm still able to get things up and running to some extent (things aren't completely busted)
    • It "runs" against the latest version of ABS (2.4.3), but it definitely isn't compatible
    • The sonos app is still able to see the custom abs-sonos application I've added
    • Interacting with it does cause network requests to hit audiobookshelf-sonos docker container

Some initial things I had to change to make some progress:

  1. I had to go get a new library ID. Looks like ABS updated their formatting for that. It is now something more akin to a UUID
  2. It was crashing all over buildLibraryMetadataResults
    • This is the method that actually takes the library results (which come back successfully) from ABS and formats them in a way to hand off to the SOAP server for SONOS to read. Things here got busted at some point due to ABS API updates.
    • At first it was just hard crashing to a white screen in the sonos app.
    • After updating some of the building of mediaMetadataEntry to comment out things that weren't being responded, I was able to get the SONOS app to start displaying my library
    • The "new" version of mediaMetadataEntry:
   for (const libraryItem of libraryItems) {
     // https://developer.sonos.com/build/content-service-add-features/save-resume-playback/
     var mediaMetadataEntry = { 
       itemType: "audiobook",
       id: libraryItem.id,
      //mimeType: libraryItem.media.audioFiles[0].mimeType,
       canPlay: true,
       canResume: true,
       title: libraryItem.media.metadata.title,
       summary: libraryItem.media.metadata.description,
       //authorId: libraryItem.media.metadata.authors[0].id,
       //author: libraryItem.media.metadata.authors[0].name,
       //narratorId: libraryItem.media.metadata.narrators[0].id,
       //narrator: libraryItem.media.metadata.narrators[0].name,
       //albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
     };  

     mediaMetadata.push(mediaMetadataEntry);
   }   

I'll keep poking around, as well as update this repo with the new "debugging support" I've added to a few of thes methods to help. My gut is telling me there's a decent chunk of work that needs to be done here to get it working though, or at least working to the level it was prior. That said, the initial issues that were had in this issue definitely weren't related to this, and were most likely just environmental set up issues.

@jmt-gh
Copy link
Owner

jmt-gh commented Sep 28, 2023

Some more progress:

Had to comment out some more due-to-API-changes fields:

async function buildAudiobookTrackList(libraryItem, progressData) {
  let tracks = libraryItem.media.audioFiles;
  let icount = tracks.length;
  let itotal = tracks.length;
  let imediaMetadata = []; 

  for (const track of tracks) {
    var mediaMetadataEntry = { 
      id: `${libraryItem.id}/${track.metadata.filename}`,
      itemType: "track",
      title: track.metadata.filename,
      mimeType: track.mimeType,
      trackMetadata: {
        authorId: libraryItem.media.metadata.authors[0].id,
        author: libraryItem.media.metadata.authors[0].name,
        //narratorId: libraryItem.media.metadata.narrators[0].id,
        //narrator: libraryItem.media.metadata.narrators[0].name,
        duration: track.duration,
        book: libraryItem.media.metadata.title,
        albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
        canPlay: true,
        canAddToFavorites: false,
      },  
    };  

    imediaMetadata.push(mediaMetadataEntry);
  }

This brings SONOS to actually trying to play the file, but throws an error modal in the app that says "Part01.mp3 is no longer available on audiobookshelf" which is interesting. Though the soap part of the server is actively running and participating at this point, as indicated by these messages in the docker output:

audiobookshelf-sonos    | getMediaURI called
audiobookshelf-sonos    | [soapServer] /playback/v2.1/report/timePlayed called
audiobookshelf-sonos    | [soapServer] /playback/v2.1/report/timePlayed called
audiobookshelf-sonos    | oh it got called?

which is great

@jmt-gh
Copy link
Owner

jmt-gh commented Sep 28, 2023

ABS API reference: https://api.audiobookshelf.org

@jmt-gh
Copy link
Owner

jmt-gh commented Sep 28, 2023

OK. More progress.

I have audio streaming to the speakers again.

This is the function that actually generates the URL telling the speaker where to fetch the audio from. As with the other breakages, this is no longer valid, in a variety of ways.

async function buildMediaURI(id) {
  let path = `${ABS_URI}/s/item/${id}?token=${ABS_TOKEN}`;

  return {
    getMediaURIResult: path,
  };
}

The path needed now resembles something like: <ABS_URI>/api/items/<library_id>/file/<file_id>?token=<auth_token>. Hardcoding path to be the appropriate URL using an auth token from a web session, and the audio starts playing.

This brings up a couple things:

  1. The library item id we've been getting has been updated to a UUID similarly to the library id.
  2. The library item id we had previously been using doesn' seem particularly relevant here
  3. A new API needs to be implemented to get the file_id (which points to the MP3 to play)

@jmt-gh
Copy link
Owner

jmt-gh commented Sep 28, 2023

Number 3 doesn't need to happen. It's available in the libraryItem as the ino field already

@jmt-gh
Copy link
Owner

jmt-gh commented Jan 21, 2024

Anddd improved logging has been put in place. At least in the sense that there should now be some level of logging for most things -- if they are useful or not.. that's a different story haha.

Please feel free to give all of this with the new readme a shot, and let me know how things go.

@mxdalchau
Copy link
Author

hey nice.. step by step... if i want to open audiobookservice in sonos ... i get the message:

Durchsuchen der Musikdateien nicht möglich

but the logs... generate a information from my audiobookshelf

@jmt-gh
Copy link
Owner

jmt-gh commented Jan 21, 2024

This occurs when the Custom Service Descriptor is set up properly, but the app doesn't received anything when you browse to it.

Most likely either the configuration in the docker-compose file is incorrect, or your speakers are unable to communicate with the server / application.

If you post the log output here it could potentially help diagnose the issue. You'll want the full log output of you opening the app, clicking the ABS entry in the sonos app, etc.

I would also double check the environment configurations are correct in the docker-compose.yml file. The values should not be wrapped in quotes, and you need to ensure the ABS library ID and API key are accurate

@jt196
Copy link

jt196 commented Jan 22, 2024

OK dude, just retrying this.

FYI The git clone command currently in the Readme is erroring out, I changed the url to https://github.com/jmt-gh/audiobookshelf-sonos.git and it clones fine. Assume the given URL ([email protected]:jmt-gh/audiobookshelf-sonos.git) might be for the owner of the repo/require credentials?

As per @mxdalchau and my previous experience, I'm getting an "Unable to browse music" message. I've tested this now on a smaller library as well as a test one with just 4 items. Neither works.

The logs produce a list of library items. Here's my logs:

[2024-01-22T11:14:23.852Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: GET /manifest 

[2024-01-22T11:14:23.853Z] [INFO] [Unknown - Unknown:Unknown] /manifest endpoint hit 

[2024-01-22T11:14:28.222Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.233Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.237Z] [DEBUG] [getMetadata - /app/sonos-service.js:8] getMetadata sonos-service called with args {"id":"root","index":0,"count":100}

[2024-01-22T11:14:28.238Z] [INFO] [getLibraryItems - /app/utils.js:17] Fetching library item at: "https://audiobooks.domain.com/api/libraries/<library_id>/items"

[2024-01-22T11:14:28.305Z] [DEBUG] [buildLibraryMetadataResult - /app/utils.js:116] libraryItem for mediaMetadataEntry: {"id":"022f5ead-e66e-4592-a6bc-bea084ae4f01","ino":"369861","oldLibraryItemId":null,"libraryId":"571b1e8a-e2ac-47fb-b0a1-f0f8d7ec15e3","folderId":"1c6a556e-623a-4e53-bb86-29a32c849558","path":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast","relPath":"From the Oasthouse The Alan Partridge Podcast","isFile":false,"mtimeMs":1601981799000,"ctimeMs":1694594837580,"birthtimeMs":1694594837580,"addedAt":1705921897649,"updatedAt":1705921897649,"isMissing":false,"isInvalid":false,"mediaType":"book","media":{"id":"a1fedd4d-3533-45cb-9151-9dfd257bc4a2","metadata":{"title":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","titleIgnorePrefix":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","subtitle":null,"authorName":"Alan Partridge","authorNameLF":"Partridge, Alan","narratorName":"Alan Partridge","seriesName":"","genres":["Comedy, Podcast"],"publishedYear":"2020","publishedDate":null,"publisher":null,"description":"Broadcaster, writer, philanthroper and one of the first public figures to suggest high-visibility clothing for people manning temporary car parks, the public Alan Partridge is a cherished institution. But what of the unseen Alan? For the first time, this","isbn":null,"asin":null,"language":null,"explicit":false,"abridged":false},"coverPath":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast/From the Oasthouse The Alan Partridge Podcast An Audible Original.jpg","tags":[],"numTracks":1,"numAudioFiles":1,"numChapters":17,"numMissingParts":0,"numInvalidAudioFiles":0,"duration":24274.279909,"size":385577371},"numFiles":3,"size":385894072}
... the rest of the library below

I can also confirm that if I make a Postman GET request to the ABS url with the login credentials, it returns a list of library items.

So the request for information is producing a list of metadata, but that for whatever reason isn't displaying in the Sonos app.

Incidentally, I finally ran the Sonos v2 upgrade, thinking this might be the culprit. It seems to have helped adding the service with the "support manifest file" checked, but still producing this error.

I've also played around with changing the SOAP_URI variable, but adding /wsdl to the end doesn't seem to solve it. Incidentally, the list of library items is produced regardless of whether the SOAP_URI is entered correctly, but the getMetadata and getLibraryItems aren't logged if it's incorrect.

Here's my docker compose settings if you notice any glaring errors. No quotes have been used here:

version: "3.8"

services:
  audiobookshelf-sonos:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: audiobookshelf-sonos
    environment:
      - SOAP_URI=https://soap.domain.com # also tried with /wsdl
      - ABS_URI=https://audiobooks.domain.com
      - ABS_LIBRARY_ID=<my_library_id>
      - ABS_TOKEN=<redacted>
      - LOG_LEVEL=debug # set to debug, info, warn, error
    ports:
      - 3333:80
    volumes:
      - ./sonos.wsdl:/app/sonos.wsdl

sonos.wsdl:

    <wsdl:service name="Sonos">
        <wsdl:port name="SonosSoap" binding="tns:SonosSoap">
		<soap:address location="https://soap.domain.com"/> <!-- UPDATE WITH SOAP_URI -->
        </wsdl:port>
    </wsdl:service>

Note, also changing this to https://soap.domain.com/wsdl doesn't fix anything.

/customsd.htm

Secure endpoint URL: https://soap.domain.com/wsdl
Polling interval: 10
Authentication SOAP header policy: Anonymous
Manifest: 
    version: 1
    URI: https://soap.domain.com/manifest
Support manifest file: checked
Playback event logging during track play: checked
Playback duration logging at track end: checked 

This adds to the Sonos services without erroring out.

As it's working on your set up, I have a feeling it's likely something like a config error.

I don't know whether this helps but here's some results to GET requests to the soap URIs.

/manifest:

{
  "schemaVersion": "1.0",
  "endpoints": [
    {
      "type": "reporting",
      "uri": "https://soap.jamestorr.com/playback/v2.1/report"
    }
  ]
}

/wsdl: 200 response, empty.
/playback/v2.1/report: 404 response (just doing that as the endpoint above points to this)

If I make a POST request with the body:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:son="http://www.sonos.com/Services/1.1">
    <soapenv:Header/>
    <soapenv:Body>
        <son:getMetadata>
            <son:id>root</son:id>
            <son:index>0</son:index>
            <son:count>100</son:count>
        </son:getMetadata>
    </soapenv:Body>
</soapenv:Envelope>

To the URL: https://soap.domain.com/wsdl, with content type XML, I successfully receive a response with the correct metadata. Here's what the response looks like:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.sonos.com/Services/1.1">
    <soap:Body>
        <getMetadataResponse xmlns="http://www.sonos.com/Services/1.1">
            <getMetadataResult>
                <count>85</count>
                <total>85</total>
                <index>0</index>
                <mediaCollection>
                    <itemType>audiobook</itemType>
                    <id>74162736-8a64-4b10-a0fc-4c431b398e47</id>
                    <canPlay>true</canPlay>
                    <canResume>true</canResume>
                    <title>Live At the Purple Onion</title>
                    <summary xsi:nil="true"></summary>
                </mediaCollection>
--- continues for the rest of the library ---
            </getMetadataResult>
        </getMetadataResponse>
    </soap:Body>
</soap:Envelope>

Lots of info here, hope it helps. What might be useful would be:

  1. A redacted version of your working config/docker-compose file settings as above.
  2. For you to check POST/GET on your soap server, so we can check our set up.

@fayeinmay
Copy link

OK dude, just retrying this.

FYI The git clone command currently in the Readme is erroring out, I changed the url to https://github.com/jmt-gh/audiobookshelf-sonos.git and it clones fine. Assume the given URL ([email protected]:jmt-gh/audiobookshelf-sonos.git) might be for the owner of the repo/require credentials?

As per @mxdalchau and my previous experience, I'm getting an "Unable to browse music" message. I've tested this now on a smaller library as well as a test one with just 4 items. Neither works.

The logs produce a list of library items. Here's my logs:

[2024-01-22T11:14:23.852Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: GET /manifest 

[2024-01-22T11:14:23.853Z] [INFO] [Unknown - Unknown:Unknown] /manifest endpoint hit 

[2024-01-22T11:14:28.222Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.233Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.237Z] [DEBUG] [getMetadata - /app/sonos-service.js:8] getMetadata sonos-service called with args {"id":"root","index":0,"count":100}

[2024-01-22T11:14:28.238Z] [INFO] [getLibraryItems - /app/utils.js:17] Fetching library item at: "https://audiobooks.domain.com/api/libraries/<library_id>/items"

[2024-01-22T11:14:28.305Z] [DEBUG] [buildLibraryMetadataResult - /app/utils.js:116] libraryItem for mediaMetadataEntry: {"id":"022f5ead-e66e-4592-a6bc-bea084ae4f01","ino":"369861","oldLibraryItemId":null,"libraryId":"571b1e8a-e2ac-47fb-b0a1-f0f8d7ec15e3","folderId":"1c6a556e-623a-4e53-bb86-29a32c849558","path":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast","relPath":"From the Oasthouse The Alan Partridge Podcast","isFile":false,"mtimeMs":1601981799000,"ctimeMs":1694594837580,"birthtimeMs":1694594837580,"addedAt":1705921897649,"updatedAt":1705921897649,"isMissing":false,"isInvalid":false,"mediaType":"book","media":{"id":"a1fedd4d-3533-45cb-9151-9dfd257bc4a2","metadata":{"title":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","titleIgnorePrefix":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","subtitle":null,"authorName":"Alan Partridge","authorNameLF":"Partridge, Alan","narratorName":"Alan Partridge","seriesName":"","genres":["Comedy, Podcast"],"publishedYear":"2020","publishedDate":null,"publisher":null,"description":"Broadcaster, writer, philanthroper and one of the first public figures to suggest high-visibility clothing for people manning temporary car parks, the public Alan Partridge is a cherished institution. But what of the unseen Alan? For the first time, this","isbn":null,"asin":null,"language":null,"explicit":false,"abridged":false},"coverPath":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast/From the Oasthouse The Alan Partridge Podcast An Audible Original.jpg","tags":[],"numTracks":1,"numAudioFiles":1,"numChapters":17,"numMissingParts":0,"numInvalidAudioFiles":0,"duration":24274.279909,"size":385577371},"numFiles":3,"size":385894072}
... the rest of the library below

I can also confirm that if I make a Postman GET request to the ABS url with the login credentials, it returns a list of library items.

So the request for information is producing a list of metadata, but that for whatever reason isn't displaying in the Sonos app.

Incidentally, I finally ran the Sonos v2 upgrade, thinking this might be the culprit. It seems to have helped adding the service with the "support manifest file" checked, but still producing this error.

I've also played around with changing the SOAP_URI variable, but adding /wsdl to the end doesn't seem to solve it. Incidentally, the list of library items is produced regardless of whether the SOAP_URI is entered correctly, but the getMetadata and getLibraryItems aren't logged if it's incorrect.

Here's my docker compose settings if you notice any glaring errors. No quotes have been used here:

version: "3.8"

services:
  audiobookshelf-sonos:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: audiobookshelf-sonos
    environment:
      - SOAP_URI=https://soap.domain.com # also tried with /wsdl
      - ABS_URI=https://audiobooks.domain.com
      - ABS_LIBRARY_ID=<my_library_id>
      - ABS_TOKEN=<redacted>
      - LOG_LEVEL=debug # set to debug, info, warn, error
    ports:
      - 3333:80
    volumes:
      - ./sonos.wsdl:/app/sonos.wsdl

sonos.wsdl:

    <wsdl:service name="Sonos">
        <wsdl:port name="SonosSoap" binding="tns:SonosSoap">
		<soap:address location="https://soap.domain.com"/> <!-- UPDATE WITH SOAP_URI -->
        </wsdl:port>
    </wsdl:service>

Note, also changing this to https://soap.domain.com/wsdl doesn't fix anything.

/customsd.htm

Secure endpoint URL: https://soap.domain.com/wsdl
Polling interval: 10
Authentication SOAP header policy: Anonymous
Manifest: 
    version: 1
    URI: https://soap.domain.com/manifest
Support manifest file: checked
Playback event logging during track play: checked
Playback duration logging at track end: checked 

This adds to the Sonos services without erroring out.

As it's working on your set up, I have a feeling it's likely something like a config error.

I don't know whether this helps but here's some results to GET requests to the soap URIs.

/manifest:

{
  "schemaVersion": "1.0",
  "endpoints": [
    {
      "type": "reporting",
      "uri": "https://soap.jamestorr.com/playback/v2.1/report"
    }
  ]
}

/wsdl: 200 response, empty. /playback/v2.1/report: 404 response (just doing that as the endpoint above points to this)

If I make a POST request with the body:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:son="http://www.sonos.com/Services/1.1">
    <soapenv:Header/>
    <soapenv:Body>
        <son:getMetadata>
            <son:id>root</son:id>
            <son:index>0</son:index>
            <son:count>100</son:count>
        </son:getMetadata>
    </soapenv:Body>
</soapenv:Envelope>

To the URL: https://soap.domain.com/wsdl, with content type XML, I successfully receive a response with the correct metadata. Here's what the response looks like:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.sonos.com/Services/1.1">
    <soap:Body>
        <getMetadataResponse xmlns="http://www.sonos.com/Services/1.1">
            <getMetadataResult>
                <count>85</count>
                <total>85</total>
                <index>0</index>
                <mediaCollection>
                    <itemType>audiobook</itemType>
                    <id>74162736-8a64-4b10-a0fc-4c431b398e47</id>
                    <canPlay>true</canPlay>
                    <canResume>true</canResume>
                    <title>Live At the Purple Onion</title>
                    <summary xsi:nil="true"></summary>
                </mediaCollection>
--- continues for the rest of the library ---
            </getMetadataResult>
        </getMetadataResponse>
    </soap:Body>
</soap:Envelope>

Lots of info here, hope it helps. What might be useful would be:

1. A redacted version of your working config/docker-compose file settings as above.

2. For you to check POST/GET on your soap server, so we can check our set up.

Thought I'm gonna tell you how exactly I got this running pretty quickly, maybe it helps.

  1. Create domain absproxy.mydomain.com
  2. Create SSL certificate for that domain
  3. absproxy.mydomain.com now resolves to my machine on port 8082. Currently this results in a 502 / 404 error as nothing is set up yet.
  4. Follow README "Configuring a Custom Service Descriptor (CSD)", ignore step 4 and 5!
  5. wget https://codeload.github.com/jmt-gh/audiobookshelf-sonos/zip/refs/heads/main
  6. unzip downloaded files
  7. Modify sonos.wsdl line 2062 with location="https://absproxy.mydomain.com"
  8. Run docker build -t sonosabs . (Skip this if using docker-compose)
  9. I converted the docker-compose to a docker run command as I'm running this on UNRAID which does not support docker-compose. I used the following parameters. Make sure to not append any slashes in your setup and always use HTTPS / SSL, otherwise this will not work:
    SOAP_URI=https://absproxy.mydomain.com
    ABS_URI=https://abs.mydomain.com
    ABS_LIBRARY_ID=b72235eb-6d3-4645-c6fd-91208189b1b6
    ABS_TOKEN=eyJhGci......... (long string)
    LOG_LEVEL=info # set to debug, info, warn, error
    ports: 8082:80
  10. I ran my docker run command, but you can now use docker-compose up -d
  11. Now start your Sonos App. Not the old one with S1, but the one that is called "Sonos" in play store.
  12. Make sure your devices are migrated to S2.
  13. Follow README "Configuring a Custom Service Descriptor (CSD)" step 4 and 5.

@fayeinmay
Copy link

Current issue with getting updates back up to ABS is that the sonos side of things just doesn't seem to be trying to reach out to the update endpoint in server.js. I see it reaching out to /manifest, but nothing beyond that.

Was there any solution to this? Doesn't seem like it is doing for me either.

@fayeinmay
Copy link

fayeinmay commented Jan 25, 2024

Current issue with getting updates back up to ABS is that the sonos side of things just doesn't seem to be trying to reach out to the update endpoint in server.js. I see it reaching out to /manifest, but nothing beyond that.

Was there any solution to this? Doesn't seem like it is doing for me either.

I solved this by converting to /playback without any prefix.

@jt196
Copy link

jt196 commented Jan 25, 2024

I solved this by converting to /playback without any prefix.

What exactly do you mean here?

@fayeinmay
Copy link

I solved this by converting to /playback without any prefix.

What exactly do you mean here?

There is EXPRESS_APP.post(`${SOAP_ENDPOINT}/playback... in the server.js source file. I removed the SOAP_ENDPOINT part as the calls were not registering for me otherwise

@jmt-gh
Copy link
Owner

jmt-gh commented Jan 26, 2024

@fayeinmay , glad to hear you've got it working, and thanks for sharing the steps you took. Definetly makes me feel like I've got a bit of a sanity check that things work outside of my environment haha. The reason you've needed to make those changes is because you didn't register the secure URL in the same way it's laid out in the README:

Input the following information:

    Service Name: audiobookshelf
    Secure Endpoint URL: https://<the_url_you_defined_for_this_server_above>/wsdl
    Polling interval: 10
    Authentication SOAP header policy: Anonymous
    Manifest 

In the end, you end up with the same result, but repo currently assuming you defined the URL with appended with the /wsdl path, so puts that in a few places (though maybe we should just look at doing it without for simplicity)

@fayeinmay
Copy link

@fayeinmay , glad to hear you've got it working, and thanks for sharing the steps you took. Definetly makes me feel like I've got a bit of a sanity check that things work outside of my environment haha. The reason you've needed to make those changes is because you didn't register the secure URL in the same way it's laid out in the README:

Input the following information:

    Service Name: audiobookshelf
    Secure Endpoint URL: https://<the_url_you_defined_for_this_server_above>/wsdl
    Polling interval: 10
    Authentication SOAP header policy: Anonymous
    Manifest 

In the end, you end up with the same result, but repo currently assuming you defined the URL with appended with the /wsdl path, so puts that in a few places (though maybe we should just look at doing it without for simplicity)

I'd say you're right, because I did redo the setup step twice and could've forgotten to append /wsdl, but I only needed to change the path on the http calls, not on the soap calls. Except you say for soap sonos does auto apply /wsdl as a suffix.

@mxdalchau
Copy link
Author

haha I´m very stupid.... it doens´t work for me...

version: '3.8'

services:
audiobookshelf-sonos:
build:
context: .
dockerfile: Dockerfile
container_name: audiobookshelf-sonos
environment:
- SOAP_URI=https://soabs.xx.de
- ABS_URI=https://abs.xx.de
- ABS_LIBRARY_ID=52
- ABS_TOKEN=eyJhbGci
- LOG_LEVEL=debug # set to debug, info, warn, error
volumes:
- ./sonos.wsdl:/app/sonos.wsdl
ports:
- 8082:80

	<soap:address location="https://soabs.xx.de/wsdl"/>

proxy:
server {
listen 443 ssl;
listen [::]:443 ssl;

server_name soabs.*;

include /config/nginx/ssl.conf;

location / {
    include /config/nginx/proxy.conf;
    include /config/nginx/resolver.conf;
    set $upstream_app 192.168.2.xx;
    set $upstream_port 8082;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}

}

manifest:
{"schemaVersion":"1.0","endpoints":[{"type":"reporting","uri":"https://soabs.xx.de/playback/v2.1/report"}]}

on sonos Durchsuchen nicht möglich... audiobookshelf von docker.....
[2024-01-26 17:51:10.902] DEBUG: [ApiCacheManager] Cache hit: {"user":"xxx","url":"/libraries/52axx/items"} (ApiCacheManager.js:32)

@jt196
Copy link

jt196 commented Jan 26, 2024

@mxdalchau I doubt it!

The only thing I think you're doing slightly differently is this:

<soap:address location="https://soabs.xx.de/wsdl"/>

instead of this:

<soap:address location="https://soabs.xx.de"/>

I can't really think of any other reason why my config/set up isn't working. I'm on the most recent version of Sonos (v2), Audiobookshelf is up to date as well.

I've tried removing and re-adding the service multiple times, tried several different speakers, tried multiple variations of the URIs.

The only other points I can think of are:

  1. Sonos firmware
  2. ABS version
  3. Regional differences

I'm running mine behind a RP like @fayeinmay, so that shouldn't be the culprit... I'm stumped.

@mxdalchau
Copy link
Author

[2024-01-26T18:21:58.935Z] [DEBUG] [buildLibraryMetadataResult - /app/utils.js:116] libraryItem for mediaMetadataEntry: {"id":"d3d47f08-6aaf-4278-a677-4af3a36c6e41","ino":"13510803856505204","oldLibraryItemId":null,"libraryId":"52a3f946-a069-4e9c-98a6-a91719a39b8d","folderId":"4b1f9440-c4c3-43fc-8079-1a2d771954a5","path":"/MaxKusData/Musik/Hoerspiele/John Sinclair Sonderedition/Horror-Disco - John Sinclair - Promis lesen Sinclair (Ungekürzt)","relPath":"John Sinclair Sonderedition/Horror-Disco - John Sinclair - Promis lesen Sinclair (Ungekürzt)","isFile":false,"mtimeMs":1700421236950,"ctimeMs":1703561864075,"birthtimeMs":0,"addedAt":1700421123319,"updatedAt":1704063629682,"isMissing":false,"isInvalid":false,"mediaType":"book","media":{"id":"07efccc3-c54d-4e30-9ff4-65078c7e561c","metadata":{"title":"Horror-Disco - John Sinclair - Promis lesen Sinclair (Ungekürzt)","titleIgnorePrefix":"Horror-Disco - John Sinclair - Promis lesen Sinclair (Ungekürzt)","subtitle":"John Sinclair - Promis lesen Sinclair (Ungekürzt)","authorName":"Jason Dark","authorNameLF":"Dark, Jason","narratorName":"","seriesName":"","genres":[],"publishedYear":"2023-11-17","publishedDate":null,"publisher":"Lübbe Audio","description":null,"isbn":null,"asin":null,"language":null,"explicit":false,"abridged":false},"coverPath":"/MaxKusData/Musik/Hoerspiele/John Sinclair Sonderedition/Horror-Disco - John Sinclair - Promis lesen Sinclair (Ungekürzt)/cover.jpg","tags":[],"numTracks":60,"numAudioFiles":60,"numChapters":60,"numMissingParts":0,"numInvalidAudioFiles":0,"duration":11536.378773999997,"size":200521291},"numFiles":63,"size":201067798}
[2024-01-26T18:21:58.935Z] [DEBUG] [buildLibraryMetadataResult - /app/utils.js:116] libraryItem for mediaMetadataEntry: {"id":"9468b5f8-96d1-4692-a068-09ee04bfc01f","ino":"13510803856493976","oldLibraryItemId":null,"libraryId":"52a3f946-a069-4e9c-98a6-a91719a39b8d","folderId":"4b1f9440-c4c3-43fc-8079-1a2d771954a5","path":"/MaxKusData/Musik/Hoerspiele/John Sinclair 2000/162 Das Vampir-Internat","relPath":"John Sinclair 2000/162 Das Vampir-Internat","isFile":false,"mtimeMs":1700421289048,"ctimeMs":1703561863380,"birthtimeMs":0,"addedAt":1700421181119,"updatedAt":1704063762022,"isMissing":false,"isInvalid":false,"mediaType":"book","media":{"id":"9063aaa0-d313-4f2f-beff-80823c67ba61","metadata":{"title":"Folge 162: Das Vampir-Internat","titleIgnorePrefix":"Folge 162: Das Vampir-Internat","subtitle":null,"authorName":"John Sinclair","authorNameLF":"Sinclair, John","narratorName":"","seriesName":"","genres":["Film Soundtracks"],"publishedYear":"2023","publishedDate":null,"publisher":null,"description":null,"isbn":null,"asin":null,"language":null,"explicit":false,"abridged":false},"coverPath":"/MaxKusData/Musik/Hoerspiele/John Sinclair 2000/162 Das Vampir-Internat/Cover.jpg","tags":[],"numTracks":17,"numAudioFiles":17,"numChapters":17,"numMissingParts":0,"numInvalidAudioFiles":0,"duration":3065.547755,"size":124516502},"numFiles":20,"size":125018468}

@jt196
Copy link

jt196 commented Jan 26, 2024

Yeah mine is displaying the metadata too, just no result in the app.

@dubwoc
Copy link

dubwoc commented Jan 30, 2024

After initial set up with a coinnection from the sonos app on my phone to abs-sonos I do not see any traffic come from speakers to abs-sonos when I select the application and I get a "unable to browse music" error

Initial adding of the app via sonos app:

[2024-01-30T14:39:49.030Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: GET /manifest 
[2024-01-30T14:39:49.030Z] [INFO] [Unknown - Unknown:Unknown] /manifest endpoint hit 
[2024-01-30T14:39:56.038Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: GET /manifest 
[2024-01-30T14:39:56.039Z] [INFO] [Unknown - Unknown:Unknown] /manifest endpoint hit 
[2024-01-30T14:39:57.265Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: GET /manifest 
[2024-01-30T14:39:57.265Z] [INFO] [Unknown - Unknown:Unknown] /manifest endpoint hit 

I can ping from the server to the speakers no problem and TLS is working properly. When I browse to /manifest I get a URL

When I curl https://soab.domain.org/manifest I get:

{"schemaVersion":"1.0","endpoints":[{"type":"reporting","uri":"https://soab.domain.org/playback/v2.1/report"}]}               

I am not sure where you all are getting the metadata from, I poured over this thread but seem to have missed how you are getting that output from utils.js.

If this is the current state let me know, I'll keep tinkering on my end.

@dstapp
Copy link

dstapp commented Feb 25, 2024

I made some progress on that. I get some output in the list and can play at least some of my audiobooks. My library is quite big which caused no results to show up. Also, progress tracking is not working for me so far. I'll try to get this in shape over the next days and open a PR.

@jt196
Copy link

jt196 commented Feb 25, 2024

@dstapp would you be able to share your config with us (wsdl, Sonos service, version, env variables) as quite a few of us are stuck on not getting any items to display in the Sonos app.

@dstapp
Copy link

dstapp commented Feb 26, 2024

@jt196 Sure thing. Have a look here for my changes: #8
If you want, feel free to try with my fork until it's merged (if it's merged at all ;)).

Setup wise, my SOAP_URI env var is in format of https://xyz/wsdl, my WSDL adjustment also includes "/wsdl" at the end, just the same.

The rest worked for me with the instructions provided in the README.md. Please also see the caveats in my PR (200 file limit).

Btw, m4a/m4b audiobooks indeed are a problem. While I can play them back initially, as soon as there is a progress stored to pick up the playback position from, it does not work. Seems like seeking is not implemented on Sonos side.

@jhlee2222
Copy link

I finally got https working properly on my domain, so I couldn't wait to get this app working. Sadly, easier said than done. I'm using @dstapp version, since it's had more recent changes. At this point, I'm trying to figure out where my issue lies. I'm beginning to think it may be within Sonos's side of things. The Custom Service Descriptor, set up at :1400/customsd.htm, I found is only successful if I designate it as a Container Type of "Sonos Sound Lab". After doing that, I can see the descriptor set up as "AudioBookShelf", per my naming, in the Sonos Windows app. I can't find labs on the mobile app. Though I see it in the Windows Desktop app, clicking on the service does nothing.

Trying to check the other side of things, when I visit the URI in my browser displays the message "Cannot GET /". Appending "/wsdl" to the URL shows only a blank screen. Since things are clearly not working, I'm unsure where the issue is. Has anyone gotten this application to work recently, with progress and adjustments likely made to both Sonos and AudioBookShelf since?

@robwalster
Copy link

I've begun work on my own implementation in ruby which I have working on my system. I'll upload the project soon once I get some time to write up a readme.

But in the meantime Sonos removed the ability to add services through the customsd end point with the new updates earlier this year (although it should still work on S1 systems).

You now need to register your service via their developer portal: https://developer.sonos.com/s/?language=en_US

You also can no longer register the service (even in development) with a local address and need a domain name so you'll need to set up a reverse proxy if you haven't already.

Once it's registered via their developer portal it takes maybe an hour to show up as an available service on your system via the "Add services" screen.

@awdel
Copy link

awdel commented Jan 17, 2025

I've begun work on my own implementation in ruby which I have working on my system. I'll upload the project soon once I get some time to write up a readme.

But in the meantime Sonos removed the ability to add services through the customsd end point with the new updates earlier this year (although it should still work on S1 systems).

You now need to register your service via their developer portal: https://developer.sonos.com/s/?language=en_US

You also can no longer register the service (even in development) with a local address and need a domain name so you'll need to set up a reverse proxy if you haven't already.

Once it's registered via their developer portal it takes maybe an hour to show up as an available service on your system via the "Add services" screen.

@robwalster As you mentioned, the services can no longer be registered on the app, would you mind giving a quick overview of the required fields on the developer portal that you had to fill in to get this working? As they are slightly different from the CDS route directly on the Sonos device. Thanks in advance.

@Fraudelefix
Copy link

I've begun work on my own implementation in ruby which I have working on my system. I'll upload the project soon once I get some time to write up a readme.

Commenting this thread to get notified when you will publish your project and have a readme ready.

@robwalster
Copy link

robwalster commented Jan 27, 2025

@robwalster As you mentioned, the services can no longer be registered on the app, would you mind giving a quick overview of the required fields on the developer portal that you had to fill in to get this working? As they are slightly different from the CDS route directly on the Sonos device. Thanks in advance.

@awdel sure,

First off, make sure your clicking to sign in to create a new content service and NOT a product. (I myself have just been caught out by this)

Then I have the fields filled out as follows:

Page 1 - General Information

General Information

  1. Service Name: Audiobookshelf Sonos
  2. Service Availability: Global

URL Schemes
Leave all blank

Website/Social Media URLs
Home Page: www.[mypersonaldmain].com

Stream Quality
Leave Blank

Page 2 - Sonos Music API

Labels

  1. Integration ID: com.abs.[yourdomain]
  2. Configuration Labels: Version 0.9

End Points

  1. SMAPI Endpoint: https://[YourEndpointUrl]
  2. SMAPI Endpoint Version: 1.1
  3. Radio Endpoint: https://sonos.example.com/radio/v1
  4. Radio Endpoint Version: 2.3
  5. Reporting Endpoint: https://[YourEndpointUrl]/report/v2
  6. Reporting Endpoint Version: 2.3

Authentication
Authentication Method: Anonymous

  1. Browse/Search Results Page Size: 100
  2. Polling Interval: 60

Page 3 - Brand Assets

Service Logo
For all fields just upload any 200x200 square png. Yopu do not need to worry about the png being the correct size. (I just used one of their example images at the bottom of the page)

Full Logo
Again I just used one of their example logos, but this time in SVG format

Badge
And Again SVG format of their example badge

Page 4 - Localization Resources

Localisation File
Leave Blank

Service Summary, Service Description, Service Promo
en-US: any string of text

Explicit Description Filter
Leave Blank

Page 5 - Integration Capabilities

Leave All Blank

Page 6 - Image Replacement Rules

Leave All Blank

Page 7 - Browse Options

Leave All Blank

Page 8 - Search Capabilities

Leave All Blank

Page 9 - Content Actions

Leave All Blank

Page 10 - Service Deployment Settings

Leave everything as the default, Except Sonos ID Which needs to be the ID of your system

Page 11 - Service Configuration

Follow instructions on the page

Page 12 - Object Storage

Follow instructions on the page

@awdel
Copy link

awdel commented Jan 29, 2025

@robwalster As you mentioned, the services can no longer be registered on the app, would you mind giving a quick overview of the required fields on the developer portal that you had to fill in to get this working? As they are slightly different from the CDS route directly on the Sonos device. Thanks in advance.

@awdel sure,

First off, make sure your clicking to sign in to create a new content service and NOT a product. (I myself have just been caught out by this)

Then I have the fields filled out as follows:

Page 1 - General Information

General Information

1. Service Name: Audiobookshelf Sonos

2. Service Availability: Global

URL Schemes Leave all blank

Website/Social Media URLs Home Page: www.[mypersonaldmain].com

Stream Quality Leave Blank

Page 2 - Sonos Music API

Labels

1. Integration ID: com.abs.[yourdomain]

2. Configuration Labels: Version 0.9

End Points

1. **SMAPI Endpoint**: https://[YourEndpointUrl]

2. **SMAPI Endpoint Version**: 1.1

3. **Radio Endpoint**: https://sonos.example.com/radio/v1

4. **Radio Endpoint Version**: 2.3

5. **Reporting Endpoint**: https://[YourEndpointUrl]/report/v2

6. **Reporting Endpoint Version**: 2.3

Authentication Authentication Method: Anonymous

1. **Browse/Search Results Page Size**: 100

2. **Polling Interval**: 60

Page 3 - Brand Assets

Service Logo For all fields just upload any 200x200 square png. Yopu do not need to worry about the png being the correct size. (I just used one of their example images at the bottom of the page)

Full Logo Again I just used one of their example logos, but this time in SVG format

Badge And Again SVG format of their example badge

Page 4 - Localization Resources

Localisation File Leave Blank

Service Summary, Service Description, Service Promo en-US: any string of text

Explicit Description Filter Leave Blank

Page 5 - Integration Capabilities

Leave All Blank

Page 6 - Image Replacement Rules

Leave All Blank

Page 7 - Browse Options

Leave All Blank

Page 8 - Search Capabilities

Leave All Blank

Page 9 - Content Actions

Leave All Blank

Page 10 - Service Deployment Settings

Leave everything as the default, Except Sonos ID Which needs to be the ID of your system

Page 11 - Service Configuration

Follow instructions on the page

Page 12 - Object Storage

Follow instructions on the page

@robwalster Thank you so much for the detailed instructions, I really appreciate the time you took for this.

I am still having an issue where the Sonos Integration does not connect to the server and am wondering about some ambiguity in the original server instructions regarding the URLs for specific settings if anyone can help:

Should the URL for the SMAPI Endpoint in the Sonos Developer Portal be https://[mydomain]/wsdl or just https://[mydomain]?
Should the URL for the SOAP_URI in the docker environment variables be https://[mydomain]/wsdl or just https://[mydomain]?
Should the URL for the soap:address in the sonos.wsdl file be https://[mydomain]/wsdl or just https://[mydomain]?

Additionally, is there an obvious and easy way to determine if my server is set up correctly, prior to setting up the Sonos Integration? When I navigate to https://[mydomain]/wsdl in my browser I get a 200 but no data in the response, but am unsure if this is what I should be seeing.

Thank you in advance for anyone who is able to help with this.

@robwalster
Copy link

@robwalster Thank you so much for the detailed instructions, I really appreciate the time you took for this.

I am still having an issue where the Sonos Integration does not connect to the server and am wondering about some ambiguity in the original server instructions regarding the URLs for specific settings if anyone can help:

Should the URL for the SMAPI Endpoint in the Sonos Developer Portal be https://[mydomain]/wsdl or just https://[mydomain]? Should the URL for the SOAP_URI in the docker environment variables be https://[mydomain]/wsdl or just https://[mydomain]? Should the URL for the soap:address in the sonos.wsdl file be https://[mydomain]/wsdl or just https://[mydomain]?

Additionally, is there an obvious and easy way to determine if my server is set up correctly, prior to setting up the Sonos Integration? When I navigate to https://[mydomain]/wsdl in my browser I get a 200 but no data in the response, but am unsure if this is what I should be seeing.

Thank you in advance for anyone who is able to help with this.

It's been a while since I run this project so not too sure on the docker env vars. But for your other questions, the SMAPI endpoint in the dev portal should just be https://[my domain]
I think the address in the wsdl should just be https://[mydomain] also, but I will need to check that.

I have been using SOAPUI for testing. That should give you an idea if your server is working correctly as it will be able to pick up the wsdl file and generate test calls.

@awdel
Copy link

awdel commented Jan 29, 2025

It's been a while since I run this project so not too sure on the docker env vars. But for your other questions, the SMAPI endpoint in the dev portal should just be https://[my domain] I think the address in the wsdl should just be https://[mydomain] also, but I will need to check that.

I have been using SOAPUI for testing. That should give you an idea if your server is working correctly as it will be able to pick up the wsdl file and generate test calls.

Thanks very much @robwalster, I'll try that.

@awdel
Copy link

awdel commented Jan 29, 2025

I've been testing with SOAPUI and using the Endpoint Explorer I successfully get a result when hitting my /wsdl endpoint. Passing in a "getMetadata" body works both internally and on my external domain and I see the successful logs in docker.

However, when trying to create a new SOAP project using the same endpoint I get a "Premature end of file" error, although loading the "sonos.wsdl" manually in to SOAPUI work fine. It seems as though the server is not serving the wsdl schema correctly, so SOAPUI is not able to build the list of operations. I assume this is why the Sonos Integration is also failing to load.

As I am not accustomed to using SOAPUI, there is a distinct possibility that I have not set it up correctly, so if anyone is able to give me any pointers to help debug, it would be greatly appreciated. Thanks.

@awdel
Copy link

awdel commented Jan 29, 2025

I've been testing with SOAPUI and using the Endpoint Explorer I successfully get a result when hitting my /wsdl endpoint. Passing in a "getMetadata" body works both internally and on my external domain and I see the successful logs in docker.

However, when trying to create a new SOAP project using the same endpoint I get a "Premature end of file" error, although loading the "sonos.wsdl" manually in to SOAPUI work fine. It seems as though the server is not serving the wsdl schema correctly, so SOAPUI is not able to build the list of operations. I assume this is why the Sonos Integration is also failing to load.

As I am not accustomed to using SOAPUI, there is a distinct possibility that I have not set it up correctly, so if anyone is able to give me any pointers to help debug, it would be greatly appreciated. Thanks.

Slight update:

If I append a query string of ?wsdl in the browser so that the url is https://[mydomain]/wsdl?wsdl then I can see the full WSDL schema. In addition to this, it made sense to me that the soap:address in the sonos.wsdl file should be https://[mydomain]/wsdl as that is the endpoint needed for the APIs. Then if I use the same url with the query string (https://[mydomain]/wsdl?wsdl) when creating a new SOAP project in SOAPUI, it successfully builds the list of operations and I can successfully call my endpoints and return all the expected data.

The final step is trying to understand why the Sonos Integration fails every time I try to add it to my services in the app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests