node-sonos icon indicating copy to clipboard operation
node-sonos copied to clipboard

Supporting audioClip API

Open gillescastel opened this issue 2 years ago • 2 comments

AudioClip is part of the Sonos API that allows you to play short audio clips (notifications, ...) while other music is playing. Sonos lowers the volume of the playing music, plays the audio clip, then increases the volume again.

While this library already has playNotification that tries to do something similar, this doesn't work when e.g. music is playing through Spotify (it fails to resume feedback). Could audioClip be made accessible from this library (without having to create a developer client id/secret, oauth token, etc.)?

gillescastel avatar Mar 12 '22 23:03 gillescastel

I am new to this topic, but I think I have made a very interesting discovery. The Sonos Control API can also be used on a local network using a websocket connection. I tested their Android sample from the Developer page and was surprised, that it uses the control API on a local network. I was able to successfully test some control API commands including the audioClip command with postman.

An API key is required to establish the connection. In this case, the hard coded API key of the Android sample application is used.

Connection establishment with postman: grafik

Playback pause command:

[{"namespace":"playback:1","command":"pause","groupId":"<insert_group_id>","sessionId":null,"cmdId":null},{}]

Playback play command:

[{"namespace":"playback:1","command":"play","groupId":"<insert_group_id>","sessionId":null,"cmdId":null},{}]

Audioclip loadAudioClip command:

[{"namespace":"audioClip:1","command":"loadAudioClip","playerId":"<insert_player_id>","sessionId":null,"cmdId":null},{"name": "Sonos TTS", "appId": "com.me.sonosspeech", "streamUrl": "https://cdn.smartersoft-group.com/various/pull-bell-short.mp3"}]

As you can see, the endpoint configuration is specified in the first array element of the websocket message and the content of the request is provided as the second element.

thoelzl avatar Feb 14 '23 16:02 thoelzl

I have just been investigating the Sonos AudioClip API too. I got the WebSocket API working but also found that that the HTTP REST API works too:

curl -v --insecure \
  -d '{"name":"Pull Bell","appId":"com.acme.app","streamUrl":"https://cdn.smartersoft-group.com/various/pull-bell-short.mp3"}' \
  -H 'X-Sonos-Api-Key:622493a2-4877-496c-9bba-abcb502908a5' \
  -H 'Content-Type: application/json' \
https://192.168.1.40:1443/api/v1/players/RINCON_XXXXXXX/audioClip

Response:

{
  "id": "b01144c5-24d7-4281-a8a2-5a66a60491a9",
  "name": "Pull Bell",
  "appId": "com.acme.app",
  "priority": "LOW",
  "clipType": "CUSTOM",
  "status": "INACTIVE"
}

It looks like X-Sonos-Api-Key header can be any GUID - it doesn't seem to be validated.

The playerId can be got from this local API call:

curl -v --insecure \
  -H 'X-Sonos-Api-Key:123e4567-e89b-12d3-a456-426655440000' \
  https://192.168.1.40:1443/api/v1/players/local/info

Would be nice to get hold of the CA that issues the device certificates, so that --insecure isn't required:

issuer: C=US; ST=California; L=Santa Barbara; O=Sonos, Inc; OU=Sonos Devices; CN=Sonos Device Authentication Root CA

njh avatar May 01 '23 14:05 njh