Skip to content

Commit 35a9bff

Browse files
committed
Add example on how to synchronize bluez volume with pulseaudio
1 parent 46e0363 commit 35a9bff

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

examples/bluez-music-notify.php

-2
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,12 @@
2121

2222
$lastItem = null;
2323
while (true) {
24-
$start = microtime(true);
2524
$ffi->dbus_connection_read_write($conn, 0);
2625
$msg = $ffi->dbus_connection_pop_message($conn);
2726
$end = microtime(true);
2827

2928
// loop again if we haven't read a message
3029
if (NULL === $msg) {
31-
//echo "\r".microtime(true)." ".sprintf('%d us ', (int) (($end-$start)*1000000));
3230
usleep(100000);
3331
continue;
3432
}

examples/bluez-volume-sync.php

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
const BLUEZ_TO_PA_FACTOR = 512;
4+
5+
require_once __DIR__.'/../vendor/autoload.php';
6+
$ffi = require_once __DIR__.'/../load.php';
7+
8+
$err = $ffi->new('struct DBusError');
9+
$ffi->dbus_error_init(FFI::addr($err));
10+
$args = $ffi->new('struct DBusMessageIter');
11+
$conn = $ffi->dbus_bus_get(DBus::BUS_SYSTEM, FFI::addr($err));
12+
13+
$ffi->dbus_bus_add_match($conn,
14+
"arg0=org.bluez.MediaTransport1",
15+
FFI::addr($err));
16+
$ffi->dbus_connection_flush($conn);
17+
if ($ffi->dbus_error_is_set(FFI::addr($err))) {
18+
fprintf(stderr, "Match Error (%s)\n", $err->message);
19+
exit(1);
20+
}
21+
22+
$decoder = new DBusMessageIterDecoder($ffi);
23+
24+
$lastItem = null;
25+
while (true) {
26+
$ffi->dbus_connection_read_write($conn, 0);
27+
$msg = $ffi->dbus_connection_pop_message($conn);
28+
$end = microtime(true);
29+
30+
// loop again if we haven't read a message
31+
if (NULL === $msg) {
32+
usleep(100000);
33+
continue;
34+
}
35+
36+
if (!$ffi->dbus_message_iter_init($msg, FFI::addr($args))) {
37+
error_log("Message has no arguments!\n");
38+
continue;
39+
}
40+
41+
$message = new Message();
42+
$message->interface = $ffi->dbus_message_get_interface($msg);
43+
$message->path = $ffi->dbus_message_get_path($msg);
44+
$message->member = $ffi->dbus_message_get_member($msg);
45+
$message->arguments = $decoder->decode($args);
46+
47+
$ffi->dbus_message_unref($msg);
48+
49+
if (strpos($message->path, '/org/bluez') !== 0) {
50+
continue;
51+
}
52+
53+
if ($message->interface !== 'org.freedesktop.DBus.Properties' || $message->member !== 'PropertiesChanged') {
54+
continue;
55+
}
56+
57+
$arguments = $message->arguments;
58+
if (!is_array($arguments)) {
59+
continue;
60+
}
61+
62+
$objectType = $arguments[0];
63+
if ($objectType !== 'org.bluez.MediaTransport1') {
64+
continue;
65+
}
66+
67+
$volume = $arguments[1]['Volume'] ?? null;
68+
if (null === $volume) {
69+
continue;
70+
}
71+
72+
$addr = preg_replace('@^.*/dev_(.*?)(/.*)$@', '$1', $message->path);
73+
$paVolume = BLUEZ_TO_PA_FACTOR * (int) $volume;
74+
echo "Set volume to ".round($paVolume / 65535 * 100).'%'.PHP_EOL;
75+
exec("pactl set-source-volume bluez_source.{$addr}.a2dp_source {$paVolume}");
76+
}

0 commit comments

Comments
 (0)