Setting a property of type 'au' (pulseaudio volume) produces marshall.js exceptions
Closed this issue · 4 comments
I'm trying to set the "Volume" property of a pulseaudio device via node-dbus. I can't seem to figure out how to do so. I know setting a property that isn't an array works but haven't had to set a property of type 'au' before now.
DBUS_PROPERTIES_INTERFACE = 'org.freedesktop.DBus.Properties';
// Parameters used to lookup the bus name of the pulseaudio dbus server
DBUS_PULSE_INTERFACE = 'org.PulseAudio.ServerLookup1';
DBUS_PULSE_DESTINATION = 'org.PulseAudio1';
DBUS_PULSE_PATH = '/org/pulseaudio/server_lookup1';
// Parameters used to itneract with the pulseaudio dbus service
DBUS_CORE_INTERFACE = 'org.PulseAudio.Core1.Device';
DBUS_CORE_DESTINATION = "org.PulseAudio.Core1.Device"
DBUS_CORE_PATH = '/org/pulseaudio/core1/sink0';
var dbus = require('dbus-native');
var bus = dbus.sessionBus();
var pulseInterface;
var deviceInterface;
bus.getService(DBUS_PULSE_DESTINATION).getInterface(DBUS_PULSE_PATH,
DBUS_PROPERTIES_INTERFACE, function(err, iface)
{
console.log("completion");
if (err)
{
console.log("bus.getInterface ", err);
}
else
{
// retrieve the pulseaudio dbus server path
pulseInterface = iface;
pulseInterface.Get(DBUS_PULSE_INTERFACE, "Address", function(err, result)
{
console.log("err is " + err);
console.log("result is " + result);
console.log(result[1]);
// strip 'unix:path=' from the start of the string
console.log(typeof(result[1][0]))
unixSocketPath = result[1][0].replace("unix:path=", "");
console.log("socket path " + unixSocketPath)
// connect to the pulseaudio server
var pulseServerClient = dbus.createClient({
socket: unixSocketPath,
direct: true
});
// retrieve the volume
pulseServerClient.getService(DBUS_CORE_DESTINATION).getInterface(DBUS_CORE_PATH,
DBUS_PROPERTIES_INTERFACE, function(err, iface) {
if(err)
{
console.log("err from client service is " + err);
}
deviceInterface = iface;
deviceInterface.Get(DBUS_CORE_INTERFACE, "Volume", function(err, result) {
if(err)
{
console.log("err is " + err);
}
console.log("result is " + result);
// set the volume
var volumes = [];
volumes[0] = 5535;
volumes[1] = 5535;
console.log(volumes);
var vol = { v1 : 5665, v2 : 5566};
console.log(vol);
deviceInterface.Set(DBUS_CORE_INTERFACE, "Volume", ['au', volumes], function(err, result) {
if(err)
{
console.log("set error " + err);
}
console.log("set completed");
});
});
});
});
}
});
Produces:
node patest.js
completion
err is null
result is [object Object],unix:path=/run/user/1000/pulse/dbus-socket
[ 'unix:path=/run/user/1000/pulse/dbus-socket' ]
string
socket path /run/user/1000/pulse/dbus-socket
result is [object Object],6,5
[ 5535, 5535 ]
{ v1: 5665, v2: 5566 }
/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/marshall.js:28
throw new Error("Invalid struct data");
^
Error: Invalid struct data
at writeStruct (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/marshall.js:28:11)
at write (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/marshall.js:87:9)
at writeStruct (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/marshall.js:31:5)
at module.exports (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/marshall.js:16:13)
at Object.marshallMessage [as marshall] (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/message.js:84:16)
at EventEmitter.self.message (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/index.js:118:28)
at bus.invoke (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/bus.js:28:24)
at Object.Set (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/introspect.js:112:13)
at Object.<anonymous> (/home/cmorgan/projects/test/panodetest/patest.js:77:37)
at EventEmitter.<anonymous> (/home/cmorgan/projects/test/panodetest/node_modules/dbus-native/lib/bus.js:113:26)
volumes needs to be like [ [5535, 5335] ]
.
Imagine that instead of 'au' you have 'sau' parameter type - that'll be serialized as [ 'foo', [1, 2, 3]]
.
Doh. This did fix things for me. I hope this ticket will help to answer the question for the next person who asks it as I did search around and couldn't find any examples of this particular type of usage.
Thank you again for your help and a cool library.
Yeah, serialisation can become tricky very fast. This needs to be improved somehow (in addition to documentation)
also, I'd like to add properties support to code generator ( see bin/dbus2js
) so api would be like
var bus = connect-to-bus-somehow
var PulseAudioDevice = require('./pulse')['org.PulseAudio.Core1.Device']; // generated module
var d = new PulseAudioDevice(bus, 'org.PulseAudio.Core1.Device', '/org/pulseaudio/core1/sink0');
d.Address = "123" // would call org.freedesktop.DBus.Properties.Set internally. Not implemented yet
// maybe use Promises to return value from props
var p = d.Address;
// can do yield with tj/co
// or use promise directly
p.then( function(addr) {
console.log(addr);
});