roonlabs / node-roon-api Goto Github PK
View Code? Open in Web Editor NEWJavascript Roon API
License: Apache License 2.0
Javascript Roon API
License: Apache License 2.0
I'm requiring this as a dependency for my homebridge plugin as so in the package.json:
"dependencies": {
"node-roon-api": "github:RoonLabs/node-roon-api",
"node-roon-api-status": "github:RoonLabs/node-roon-api-status",
"node-roon-api-transport": "github:RoonLabs/node-roon-api-transport"
},
We're experiencing issues now with homebridge running in docker where it can't install things via github like this. There's a work around I believe, which I'm trying to figure out (again).
Then I wondered why these aren't just released as packages on npmjs.org?
When goPlay is emitted, I get 2 updates shown below in my console logs:
..............>>>> updateZone().now_playing:state.PlayPauseStop=showPlay
..............>>>> updateZone().now_playing:state.PlayPauseStop=showPause <----- this one arrives about 1 second after
But when goPause is emitted, there is this "unexpected" update:
..............>>>> updateZone().now_playing:state.PlayPauseStop=showPause <------- it should be showPlay
Hi,
I have a basic extension running using the transport and source control services, however it seems that the extension is unable to recover from even a small network disruption.
I'm running on RPI3 over wifi and if the network re-connects or if the extension starts before the network is fully connected it does not seem to attempt to reconnect.
In the output, I can see that the ping messages just stop:
<- REQUEST 22 com.roonlabs.ping:1/ping
-> COMPLETE 22 Success
<- REQUEST 23 com.roonlabs.ping:1/ping
-> COMPLETE 23 Success
At the end of my extension I just have
roon.start_discovery();
do I need to do something more to be able to handle network availability?
Thanks!
I've got my Room web playback controller working now. Nice work on the API, extremely easy to setup.
However, every time I start my node app, I have to re-authorize the extension on my roon core. What am I missing, in the Docs, that will tell Roon to remember my app between sessions and restarts?
I obviously shouldn't have to re-authorize every time I stop/start my node server.
I encountered an issue with my rooDial after the latest roon server update
[Roon version 1.8 (build 790) stable (64Bit)].
To discover the zones and also the changes of the zones I use:
let transport = core.services.RoonApiTransport;
transport.subscribe_zones(function (cmd, data) {
my code goes here
}
Since the latest server update I did no more get any callback if a zone was added or removed. I get the callback only once, wenn I start rooDial. There I get the “Subscribed” cmd but never anything else.
It can be verified with the code at the end of this page: https://github.com/RoonLabs/node-roon-api
Hi,
It will be awesome if we can get the technical information of the streaming, like bitrate, sample rate, format :)
The idea is to get information to shopw this in Ropiee 👍
I've noticed that i occasionally get this crash from my roon integration after the last update to the roon core.
Aug 24 00:22:59 DietPi node[448]: /home/dietpi/roon/node_modules/node-roon-api/moo.js:192
Aug 24 00:22:59 DietPi node[448]: let cb = this.requests[msg.request_id].cb;
Aug 24 00:22:59 DietPi node[448]: ^
Aug 24 00:22:59 DietPi node[448]: TypeError: Cannot read property 'cb' of undefined
Aug 24 00:22:59 DietPi node[448]: at Moo.handle_response (/home/dietpi/roon/node_modules/node-roon-api/moo.js:192:44)
There is currently no way to use API to programmatically update album/artist/track names or other metadata. Now, users have to make a minimum of 5 clicks to edit track title per track. For an album of 10 tracks, that's 50 clicks to update the track names. External tagging application won't help with Tidal/Qobuz contents. The only way to override Tidal/qobuz album/track names is via the Roon UI which requires too many click.
I stuck with one Problem.
In one of the images attached you see my roon setup combining two output devices to one zone.
The transport.subscribe_zones API function also delivers the correct setup, also attached.
Now I have programmed a roon extension using the zone dropdown:
l.layout.push({
type: "zone",
title: "Zone",
setting: "zone",
});
In this dropdown only the individual output devices got listed instead of the zones I expected (see attached image)
Is tis an error in the API or have I missed something?
This request is a bit urgent because one of my customers of rooDial complains.
It would be really nice to have full album info.
I’m interested in transferring my starred songs in Subsonic over to Roon, but the playlist watch folder import process is far too clunky for me. I’d like to programmatically create playlists (and tags and loved songs) in Roon for:
transferring playlists from other services eg subsonic via bash/curl/js/python (whatever the binding is) m3u processing and the Roon API
creating playlists within Roon itself, eg creating a trigger that adds a ‘loved’ song to a running playlist so that it is searchable from my iOS Roon app.
The subsonic API is handy for playlist management in case anyone wants a reference: http://www.subsonic.org/pages/api.jsp
See https://community.roonlabs.com/t/how-can-i-deterministically-derive-the-zone-id/127657
The only identifiable metadata returned by the API for a Zone object (or Output object) is:
It would be useful to have additional metadata available to work with the API, such as:
Please say you'll implement this?
Referencing the basic nature of the current browse api -> https://community.roonlabs.com/t/roon-web-controller-2-0-0-alpha-now-available/110504/41?u=mannp
We would welcome the ability to filter and sort the results of the browse api.
Thanks for your consideration.
I am doing a RemoteControl project using qt+qml,
Is there any corresponding api support, or .net core api?
While adding support for Loop, Shuffle, and Auto Radio buttons in the roon-web-controller [1] extension, I noticed that the Loop status in the zone.settings array do not match the official client. The status of "loop" and "loop_one" appear to be reversed from what the official clients on IOS and Mac show.
This one is correct:
Loop Disabled in Official Client
Array of the zone.settings
{"loop":"disabled","shuffle":false,"auto_radio":false}
These two are reversed:
Loop All in Official client
Array of the zone.settings
{"loop":"loop_one","shuffle":false,"auto_radio":false}
Loop One in Official Client
Array of the zone.settings
{"loop":"loop","shuffle":false,"auto_radio":false}
I checked the .js files in the node-roon-api and the node-api-transport projects, but did not see anything obvious. So this may be getting returned from the core incorrectly.
The rest of the zone information correctly reflects the loop setting and I have a workaround in place in my client to take this into account. But I wanted to pass this observation on.
Just curious what MOO stands for.
My mistake:
config.json file is created by the API, and I was requiring 'config.json'.
I am working on a Roon Web Controller implemented as Progressive Web App.
It requires to use the websocket based Roon API via secured websockets (wss).
Supporting only HTTP causes more and more troubles on current browsers.
Would be great to support HTTPS !!!
Is it possible to add an end point that maps to the live audio stream being played by a core?
I'm using the Web Audio API to graph audio channels in my web player. This works fine provided I have a path to the remote stream.
So something similar to how Roon connects to Sonos via a "hash.flac" stream. If Roon could return that url in the transport payload, I'd be able to connect to it and finish the visualizer.
Or, if that's not possible, perhaps the Room Core could analyze the channel frequencies and return an array of the frequencies with the "changed" event that fires every second.
Trying out the web example, there are several issues preventing it from working properly with the native browser WebSocket that I've had to work around or am in the process of working around.
https://github.com/roonlabs/roon-extension-web-testapp
The following methods are used by the Roon library, however are not available in native browser WebSocket: on()
, ping()
, and terminate()
The following polyfills within the example app are working reasonably to get the app running:
WebSocket.prototype.on = function(event, handler) {
this.addEventListener(event, handler);
};
WebSocket.prototype.ping = function() {
this.send("[]");
};
WebSocket.prototype.terminate = function() { this.close(); };
However, ping()
is not sufficient as it's not a true websocket ping message. I still receive the error:
Roon API Connection to 192.168.1.10:9330 closed due to missed heartbeat
And the connection genuinely closes.
However, with those polyfills, the web app does work for a few seconds! Better than nothing.
I've explored how to get the ping() message working from the web, but there doesn't seem to be a reasonable way to send a message with the proper opcode directly from the native WebSocket. It's below the abstraction layer of the browser websocket library, and you don't get to break down and send the right message type for a true ping, whereas the Node library does offer just that.
You can't use the node library in the browser, that's the first thing I tried.
I'm not sure how to get around this ping piece exactly. Ideally, the Roon API itself is a little more open to how native browser WebSocket works (it sends its own ping packets automatically, afaik, on a slightly slower rate than Roon expects it seems).
My next workaround is probably to just do the Roon API connection on a backend instead of in the browser, and message pass to the frontend, but I'd rather not go that direction if it can be helped.
Steps I see:
I could potentially help with the first, but likely not the second! Thanks.
The latest commit breaks the Node 5.x compatibility. It is the addition of a parameter default at line 74 of moo.js.
Was this overseen or is it the idea to increase the minimum Node version to 6.x?
I stumbled on this while performing tests on a Windows XP VM (using XP Embedded updates :) ). The latest Node version that runs on XP is 5.12.0.
I was curious why RoonLabs is using snake_case for their API instead of the more common camelCase convention? The API feels like Ruby because of the snake_case.
The recent update of the ws dependency breaks compatibility with node 6.x and 7.x. The ws change log shows that node 6 support was dropped in ws v7.0.0.
An exception is thrown at startup:
/home/Jan/.RoonExtensions/lib/node_modules/roon-extension-manager/node_modules/ws/lib/websocket.js:347
...options
^^^
SyntaxError: Unexpected token ...
at Object.exports.runInThisContext (vm.js:76:16)
at Module._compile (module.js:542:28)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/home/Jan/.RoonExtensions/lib/node_modules/roon-extension-manager/node_modules/ws/index.js:3:19)
at Module._compile (module.js:570:32)
Assuming that dropping compatibility wasn't intentional and knowing that the vulnerability was already solved in version 3.3.1 it might be enough to stick to ws 3.x. I verified that node 6.9.5 is working again (no exception thrown) by using:
"ws": "^3.3.1"
*** Uncaught Exception:
RollingLog.js:28
*** Message: this.moo.close is not a function
RollingLog.js:36
*** Stack: TypeError: this.moo.close is not a function
RollingLog.js:40
at Transport.close (D:\GitHub\roon-extension-deep-harmony\node_modules\node-roon-api\transport-websocket.js:47:18)
at WebSocket.Transport.ws.onclose (D:\GitHub\roon-extension-deep-harmony\node_modules\node-roon-api\transport-websocket.js:18:14)
at WebSocket.onClose (D:\GitHub\roon-extension-deep-harmony\node_modules\node-roon-api\node_modules\ws\lib\WebSocket.js:446:14)
at WebSocket.emit (events.js:182:13)
at WebSocket.cleanupWebsocketResources (D:\GitHub\roon-extension-deep-harmony\node_modules\node-roon-api\node_modules\ws\lib\WebSocket.js:950:8)
at Socket.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1085:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
in Transport.close (node-roon-api\transport-websocket.js:47:18), there is a call to moo.close() which does not appear to exist.
The simple way to reproduce this enable an extension, then perform an action that will unpair the extension and close its socket, for example, in Roon UI settings, > extension settings, click [View], select an extension and remove it.
I've noticed the info I get in the now_playing
field is not consistent with the info displayed in the Roon App. Namely, I observed the data returned contains the band and every composer mentioned in the credits. However, if I look at the app it only lists performers.
Concrete example. I was playing Confessions, Pt. 2
by BadBadNotGood
and the Roon App displayed it as being played by BadBadNotGood, Colit Stetson
. The data I received through the API had more information, but no succint version as the Roon app has.
{
"seek_position":130,
"length":384,
"one_line":{"line1":"Confessions, Pt. 2 - BadBadNotGood / Colin Stetson / Alexander Sowinski / Leland Whitty / Chester Hansen / Matthew Tavares"},
"two_line":{"line1":"Confessions, Pt. 2","line2":"BadBadNotGood / Colin Stetson / Alexander Sowinski / Leland Whitty / Chester Hansen / Matthew Tavares"},
"three_line":{"line1":"Confessions, Pt. 2","line2":"BadBadNotGood / Colin Stetson / Alexander Sowinski / Leland Whitty / Chester Hansen / Matthew Tavares","line3":"IV"
}
Is there any way to get a more succint version of this data?
I followed the directions at the bottom of the README and also tried the example web app project. On my Mac with Safari/Chrome it errors out and I am not sure why. I am pretty confident I have the host set appropriately to point to my Roon server - it isn't localhost from the browser's point of view, but a machine on my local network. Should it still be working? If so, I can post more details about the issue.
Thanks,
Matt
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.