GithubHelp home page GithubHelp logo

Comments (16)

jishi avatar jishi commented on July 17, 2024

Some services will return a full resolution image, others will just give you a 150x150 image. In order to get the full resolution, you would need to resort to the SMAPI that Sonos provided, but that will also require authentication. I resorted to direct integration against some popular services and their open APIs in order to get a full resolution image.

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

@jishi

Hi Jishi,

Thank you for your comment.

Yes we are polling data from a controller running Linux and LUA scripting. From LUA we run a script
that uses LUA socket and we can do anything with UPNP.

We get albumart from UPNP when playing local data or from iPhone, but the hard part is getting albumart working from streaming media.

How do you request the CurrentMetaData DIDL response? I don't see this field with UPNP device spy.

For example when i use GetMediaInfo i get:

CurrentURI: x-sonosapi-stream:s47309?sid=254&flags=8224&sn=0

CurrentURIMetaData: dc:titleNPO SterrenNL/dc:titleupnp:classobject.item.audioItem.audioBroadcast/upnp:classSA_RINCON65031_

When i use GetPositionInfo i get:

TrackURI: aac://icecast.omroep.nl/radio2-sterrennl-aac

TrackMetaData: aac://icecast.omroep.nl/radio2-sterrennl-aac<r:streamContent>/r:streamContentdc:titleradio2-sterrennl-aac/dc:titleupnp:classobject.item/upnp:class

As you can see none of them holds the AlbumArtURI field ...

I don't want to use API keys or any other credentials to keep the scripts simple to include (plug and play) so i'm looking for a way to fetch the album art from a source that is working for longer period.
This to avoid having lots of questions from integrators when it stops working as we do not deliver services or updates / maintainance. The Sonos is just a free nice add-on feature for the controller.

I prefer to use SMAPI because this will excist as long as SONOS excists (;

The problem i have is that some services like tune-in don't gives a albumArtURI but only TrackURI and Track metadata. I get radio station, current artist but no ART url / uri.

What services / open APIs do you use to get the artwork in that case? (without API key)

Thanks for your help so far.

Best regards,

Erwin van der Zwart
Schneider Electric Netherlands

from node-sonos-discovery.

jishi avatar jishi commented on July 17, 2024

Hi, I'm not using anything special to get the album art, I use the one provided with the event data that I receive when the playback starts. Are you saying that my library has correct album art but it isn't included in the GetMediaInfo call? In that case, it is a difference between evented data and what you retrieve when polling for data.

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

@jishi Hi Jimmy,

I don't know.. I'm just looking for a way to resolve my issue and somehow I think you already use the
correct service i miss / overloop. (:

Maybe i do something wrong. All I know is that I can get albumart from AVtransport service with GetPositionInfo call when playing local media.

When playing radio or Spotify / Deezer / Tune-in radio stream the Albumart URL is not showed in the
SOAP reply, there is no aac:... xxxx Uri where I can add / prefix http://IP:1400/ to get absolute URL. I think / assume i need to do a second (additional) http call and post a SOAP enveloppe with some previous recieved data. I'm kind of in the dank here.,

What service do you poll to get the get the CurrentMetadata Didl? It looks like it shows more data then the GetPositionInfo data

Do you poll the contentdir service for thIs? If yes how does your http post looks like?

I'm happy when I can get 150x150 image from player, higer RES is nice in a later stage..

Thanks again for your help!

BR,

Erwin van der Zwart

PS: If you need help on building automation topics feel free to ask, that's my origin specialty (:
(KNX / BACnet / Modbus / Canbus / Enocean / Zigbee / BLE / Serial / TCP-IP / Web / Javascript / LUA)

from node-sonos-discovery.

jishi avatar jishi commented on July 17, 2024

Okay, did some investigation, and the albumart is indeed part of the event data, but not when you invoke the UPnP endpoints directly. Best way would be to act on the event data if possible, but that requires you to keep an HTTP endpoint available for Sonos to POST data into.

You can take a shortcut, bu instead composing the album art uri yourself. Invoke GetMediaInfo from the active player, then use the CurrentURI node from the response (this would look something like this: x-sonosapi-stream:s20308?sid=254&flags=32

Urlencode it (e.g x-sonosapi-stream%3as20308%3fsid%3d254%26flags%3d32), then use that value for the u option in the following url scheme: /getaa?s=1&u=x-sonosapi-stream%3as20308%3fsid%3d254%26flags%3d32, and send that to any player in your network on port 1400, like this: http://192.168.1.154:1400/getaa?s=1&u=x-sonosapi-stream%3as20308%3fsid%3d254%26flags%3d32

The album art scheme is fixed for these kind of images. Some services gives you high-res version here, other services requires direct invokation against the SMAPI to get a direct CDN url for the high res version.

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

Hi Jimmy,

It's finally working (: Big thanks for your assist!

I was so close now that i see your solution.

I already tried this approach but I 'forgot' to do the urlencode
on the CurrentURI value. Stupid (: I could know by the invalid chars..

Current resolution is good enough for now.

Again thanks!

BR,

Erwin van der Zwart

from node-sonos-discovery.

jishi avatar jishi commented on July 17, 2024

Glad I could help!

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

Hi Jimmy,

I think you should know this in a second, but i browsed the complete UPNP and can't figure out where it is.

How can i get the next track uri that will be played next? Do i need to go through the queue and check what is playing now and grab the next track? In shuffle mode this won't work i guess. Where can i get this from the UPNP structure?

Thanks!

BR,

Erwin

from node-sonos-discovery.

jishi avatar jishi commented on July 17, 2024

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

Hi Jimmy,

I think i know where the problem is comming from, i start a track with SetAVTransportURI

This causes the system to play the track as single track and not as track from the queue, and thats why it doesn't show the next track.

Do you know the correct command to start playing from queue when playing a favorite? When i already play from queue the seek function is working like expected.

I have tried x-rincon-queue:RINCON....#0 but this is not starting the queue when radio is playing.

I hope you an help me out with this last item i have.. (;

Thanks!

BR,

Erwin

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

Hi Jimmy,

I want to create a SONOS doorbell function over UPNP, i can fetch the current queue, and i know the current track, to start playing again. after this i know how to seek correct position and start again.

But i don't know how to restore this fetched queue, so now my playlist is not continued ):

Do you have any tips how to do this? (not by node.js API, i use pure UPNP SOAP commands)

Do you know how to delete a created playlist with SOAP command?

Thanks!

BR,

Erwin

from node-sonos-discovery.

jishi avatar jishi commented on July 17, 2024

Hi.

I do this with the clip-command in the http-api. Basically what it does is:

Remember the state of the player (basically, the correct avtransport and metadata, and if queue playback, the track number and elapsed time).

Send a new SetAVTransportURI with just a url with the audio clip you want to play. It will take mp3, wav, flac or aac files, I think.

Wait for the clip to finish playing (easy if you have a fixed time clip, VERY hard if you need dynamic waiting, trust me on this one ;) )

Restore the previously stored avtransporturi and metadata (important if this was an online radio). If it was a queue (basically, if it started with x-rincon-queue), send the approriate calls for setting current track, and also elapsed time. Then call PLAY!

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

Hi Jimmy,

Got it (; Tracknumber was the thing i was strugling with, it's now working, Thanks for pointing to this!

You might have a answer to another item i have, when grouping players i stop the coordinator, get volume, set this volume to the slave, add slave to coordinator and snapshot the group. After this is set uri and metadata and set mute to 0 and play group again.

All is working but the volume of the slave is not equal to coordinator but is reacting to group volume.
Whatever i try i can't get the volumes in sync so they are all equal in the group.

Any idea what could cause that?

BR,

Erwin

from node-sonos-discovery.

jishi avatar jishi commented on July 17, 2024

My experience is that the volume stays put during grouping, so I find the behavior that you are describing to be odd.

How are you grouping them? what call do you make?

In my lib, I group them first and then set volume, but I don't think it should matter. And also, although Sonos has the notion of "group volume" calls, they aren't actually used by the official controller. The official controller sends individual volume calls, and so do I because the group volume is unpredictable.

from node-sonos-discovery.

ErwinvanderZwart avatar ErwinvanderZwart commented on July 17, 2024

I set them like this (it's lua so you don't see complete function but gives you info you need)

function Add_Player_To_Group(ip, uuid)
if ip and uuid then
--ip = slave
--uuid = master

	-- Get ip address of group master by uuid
	MasterData = Get_Current_Sonos_Player_UUID(uuid)
	MasterIP = MasterData.ip
	
	-- Stop playing on master
	--upnpavcmd(MasterIP, 1400, 'Stop')
	
	-- Get current master volume
	MasterVolume = upnpavcmd(MasterIP, 1400, 'GetVolume','<Channel>Master</Channel><DesiredVolume></DesiredVolume>')

	-- Wait 1/2 second to process changes
	os.sleep(0.5)
	
	-- Set volume on added player same as master volume
	upnpavcmd(ip, 1400, 'SetVolume', '<Channel>Master</Channel><DesiredVolume>' .. MasterVolume .. '</DesiredVolume>')
	
	-- Wait 1/2 second to process changes
	os.sleep(0.5)
	
	-- Get current uri from master
	position_info = upnpavcmd(MasterIP, 1400, 'GetPositionInfo')
	if position_info ~= nil then
		for i in string.gmatch(position_info, '<TrackURI.-</TrackURI>') do
			if i ~= nil then
				current_master_uri =  i:match([[<TrackURI>(.-)</TrackURI>]])
			else
				current_master_uri = 'UNKNOWN'
			end
		end
		for i in string.gmatch(position_info, '<TrackMetaData.-</TrackMetaData>') do
			if i ~= nil then
				current_master_uri_meta_data =  i:match([[<TrackMetaData>(.-)</TrackMetaData>]])
			else
				current_master_uri_meta_data = 'UNKNOWN'
			end
		end
	end

	-- Add new player to group
	uri = '<CurrentURI>x-rincon:' .. uuid .. '</CurrentURI><CurrentURIMetaData/>'
	upnpavcmd(ip, 1400, 'SetAVTransportURI', uri)
	
	-- Wait 1 second to process changes
	os.sleep(1)

	-- Make volume snapshot
	upnpavcmd(MasterIP, 1400, 'SnapshotGroupVolume')

	-- Set group volume
	upnpavcmd(MasterIP, 1400, 'SetGroupVolume', '<Channel>Master</Channel><DesiredVolume>' .. MasterVolume .. '</DesiredVolume>')

	-- Set mute on group as unmute to be sure all players are unmuted
	upnpavcmd(MasterIP, 1400, 'SetGroupMute', '<Channel>Master</Channel><DesiredMute>0</DesiredMute>')

	-- Start playing saved URI
	--MasterUri = '<CurrentURI>' .. current_master_uri .. '</CurrentURI>'
	--MasterMeta = MasterUri .. '<CurrentURIMetadata>' .. current_master_uri_meta_data .. '</CurrentURIMetaData>'
	--upnpavcmd(MasterIP, 1400, 'SetAVTransportURI', MasterMeta)

	-- Start playing again
	Play(MasterIP)

	return true
else
	return false
end

end

BR,

Erwin

from node-sonos-discovery.

jishi avatar jishi commented on July 17, 2024

It's hard to figure out from that part of the code. If you can make network captures somehow of what is actually sent, it would make more sense. But from the looks of it, I can't see anything concrete that differs from my process.

from node-sonos-discovery.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.