bencevans / node-sonos

🔈 Sonos Media Player Interface/Client

Home Page:https://www.npmjs.com/package/sonos

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can’t get GenerateCustomMetadata Helper to work.

zacariec opened this issue · comments

Expected Behavior

To Generate Custom Metadata from sonos.Helpers.GenerateCustomMetadata()

Current Behavior

I have a defined Sonos. const sonos = new Sonos(ip).

Try to pass the helper function, but doesn’t get recognised.

Sample code or executed example

const { Sonos, Helpers } = require(‘sonos’)
const sonos = new Sonos(192.168.0.1)
var uri = “somelinktouri”

sonos.SetAVTransport(uri, sonos.Helpers.GenerateCustomMetadata({ blah, blah, blah}))
.then((success) => {
  console.log(success);
})
.catch((error) => {
  if (error) {
    console.log(error)
  }
})

Versions (and Environment)

Tried on latest node on OS X with express.
Tried on Windows with node 8.
Node version: Latest on OSX, 8 on Windows
node-sonos version: @latest
OS: Windows & OSX.

The helpers domain isn't available from an instance of the Sonos class. Instead use it directly from the Helpers object that you've imported at the top of your code snippet. Also the IP address must be as a string. I'm unable to test this right now but I think you're looking for the following...

const { Sonos, Helpers } = require(‘sonos’)
const sonos = new Sonos('192.168.0.1')
const uri = 'somelinktouri'

sonos.SetAVTransport(uri, Helpers.GenerateCustomMetadata({ blah, blah, blah}))
.then((success) => {
  console.log(success);
})
.catch((error) => {
  if (error) {
    console.log(error)
  }
})

Hey, I’ve tried it like this as well.

It doesn’t recognise it as a function.

Edit:
It seems to have recognised it as a function finally but it will not change the title it stays the name as the item that is served.

@GPudgima are you able to provide a full example of your usage, that we can use for debugging? As in the example you provided before you're passing an object to GenerateCustomMetadata where it should be individual arguments.

Also related reading:

  • #330
  • /**
    * Generate custom metadata, to be used with the play and/or setAVTransportURI
    * @param {String} streamUri The playback uri
    * @param {String} itemId
    * @param {String} duration The duration of the song, as 'hh:mm:ss'
    * @param {String} title The title of the song
    * @param {String} artist The artist of the sons
    * @param {String} album the album of the song
    * @param {String} coverUrl the coverUrl of the song
    * @param {String} parentId the parentId of the song
    */
    Helpers.GenerateCustomMetadata = function (streamUrl, itemId, duration = '00:00:00', title, artist, album, coverUrl, parentId) {
    let metadata = '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">'
    metadata += `<item id="${itemId}"` + (parentId) ? ` parentID="${parentId}">` : '>'
    metadata += `<res protocolInfo="http-get:*:audio/mpeg:*" duration="${duration}">${streamUrl}</res>`
    if (coverUrl) metadata += `<upnp:albumArtURI>${coverUrl}</upnp:albumArtURI>`
    if (title) metadata += `<dc:title>${title}</dc:title>`
    if (artist) metadata += `<dc:creator>${artist}</dc:creator>`
    if (album) metadata += `<upnp:album>${album}</upnp:album>`
    metadata += '</item></DIDL-Lite>'
    return metadata
    }

Sure, if you're talking about passing each argument as a string I have tried this as well. It doesn't spit an error and it DOES play the song but it doesn't change metadata of the song.

Example code:

const { Sonos, Helpers } = require(‘sonos’)
const sonos = new Sonos('192.168.0.1')
const uri = 'somelinktouri'

(function downloadSong(){
//some function to download song.
})();

sonos.SetAVTransport(uri, Helpers.GenerateCustomMetadata('some title', '00:03:40', 'other metadata', 'other metadata', 'other metadata', 'other metadata'))
.then((success) => {
  console.log(success);
})
.catch((error) => {
  if (error) {
    console.log(error)
  }
})

This appears to work, as it plays the song, but it doesn't send the metadata with the song, changing title & duration etc.

If I try and change the arguments to converted Objects that are dynamically generated it will throw an error and will NOT play the song.

const { Sonos, Helpers } = require(‘sonos’)
const sonos = new Sonos('192.168.0.1')
const ip = require('blah blah');

//this returns the ip of the pc that is running the server.
const uri = `http://${ip.v4.sync()}:4000/1.mp4`

let someTitle = object.toString();
let duration = object.toString();

(function downloadSong(){
  //some function to download song.
})();

(function generateData(){
  //function to generate meta for variables.
})();

function secondsToHHMMSS(){
  //function to change returned seconds to HH:MM:SS format.
}


console.log(someTitle);
//logs the string correctly.

sonos.SetAVTransport(uri, Helpers.GenerateCustomMetadata(`${someTitle}`, `${duration}`, 'other metadata', 'other metadata', 'other metadata', 'other metadata'))
.then((success) => {
  console.log(success);
})
.catch((error) => {
  if (error) {
    console.log(error)
  }
})

This makes it have a hissy fit, I can't remember the error off the top of my head.

The SetAVTransportURI accepts either a single string or an object.

See this comment

sonos.SetAVTransportURI({uri:'http://serverUri....../dddd.mp3', metadata: Helpers.GenerateCustomMetadata('some title', '00:03:40', 'other metadata', 'other metadata', 'other metadata', 'other metadata')})
.then((success) => {
  console.log(success);
})

Closing this issue for now, you can always re-open if you think there is an issue with the GenerateCustomMetadata function.