Closed Coriou closed 5 years ago
The play
command accepts both an string or an object. If it is a string is should be an url that is playable. If it is an object it should have at least an uri
property, but you can also specify a metadata
property.
So you could try something like:
let playObject = { uri: 'http://.....', metdata: 'YOUR_GENERATED_META'}
sonos.play(playObject).then(....).error(...);
And have a look at GenerateMetadata
in helpers to check out how the library generates metadata.
We are very curious to your findings, and would gladly incorperate this into the library (if you got a good sample).
Yeah well, as often, after spending a couple hours searching/testing how to do that, I finally decided to open this issue and, within the next 15 minutes, I came across the solution ...
Here's what helped me : https://github.com/denysvitali/sonos-web/blob/master/test/didl.xml
Essentially, Sonos will parse correctly the XML if you send metadata as follows :
<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/">
<item id="[SOME-UNIQUE-ID]" parentID="[SOME-UNIQUE-ID]">
<upnp:class>object.item.audioItem.musicTrack</upnp:class>
<res protocolInfo="http-get:*:audio/mpeg:*" duration="[DURATION-IN-HUMAN-FORMAT]">[MEDIA-URI]</res>
<upnp:albumArtURI>[COVER-URI]</upnp:albumArtURI>
<dc:title>[TRACK-TITLE]</dc:title>
<dc:creator>[TRACK-ARTIST]</dc:creator>
<upnp:album>[TRACK-ALBUM]</upnp:album>
</item>
</DIDL-Lite>
So, you could something like :
Sonos.play( {uri: 'URI', metadata: 'METASTRINGABOVE'} )
The only thing I'm not too happy about, is that it seems that if you omit the duration value in the meta, Sonos will not fallback on reading that info from the media itself. I'm still poking around with this, maybe I'm missing something, but right now if I don't set the duration Sonos will not be able to display the length of the track nor seek through it.
I'll update with more info if I find anything else.
It would be awesome to have this built-in the library indeed, so users could just pass an object with simple keys (artist, title, album_cover, ...) and the library could take care of formatting it.
ReadMe shows a sonos.parseDIDL()
method but it's undefined when called.
Anyway, thanks for sharing @Coriou - this helped me figure out how to send metadata.
@wwwizzarrdry looks like it's moved to sonos.Helpers.parseDIDL()
... https://github.com/bencevans/node-sonos/search?utf8=%E2%9C%93&q=parseDIDL&type=
Would it help if we would add a helper class like:
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
}
Then you could do
sonos.play({uri:'blabla', metadata: sonos.Helpers.GenerateCustomMetadata('url', 'itemId', '00:03:20', 'Track Title',....)})
I think that would be fantastic yes
:tada: This issue has been resolved in version 1.11.0 :tada:
The release is available on:
Your semantic-release bot :package::rocket:
Loving this library and using it I was able to achieve what I was trying to do. There's however something I can't figure out is how to send custom metadata (title, artist, cover, ...) ?
I understand the
play()
methods accepts and object with ameta
key however I can't figure out the format I need to send this information for Sonos to parse it.Is it even possible without using an actual "service" ?
Thanks !
PS : I know it could be done using ID3 tags but I can't edit them in my case