Reputation: 1
I have the usual situation where iOS applications are not providing pause and play signals to the sink via AVRCP DBus signalling. Android is fine. The only indication of a paused stream on many iOS apps ( if still maximised ) is the transport state will go idle after some time. If the user toggles between pause and play there's no way of knowing this sink end ( i.e. embedded speaker ) apart from actual audio. Android will signal pause and play over AVRCP on the apps I've tested. On iOS once the transport is idle a "play" will immediately place the transport back into an active state. So... Is there a way, Bash, Python, C or whatever that I can force the transport of a connected device ( i.e. iPad ) from active=>idle from the embedded sink side? If it were possible I would then know whenever "play" is pressed making the transport active again. Thanks!
Upvotes: 0
Views: 1021
Reputation: 2330
In short, you need to listen to PropertiesChanged
signal on org.bluez.MediaTransport1
interface and parse the signal for state change.
You can register to Bluez DBUS interface as below during initialization.
g_dbus_connection_signal_subscribe(conn, "org.bluez", "org.freedesktop.DBus.Properties",
"PropertiesChanged", NULL, "org.bluez.MediaTransport1", G_DBUS_SIGNAL_FLAGS_NONE,
bluez_signal_transport_changed, NULL, NULL);
Below sample is the functionality which parses for state change signal,
static void bluez_signal_transport_changed(GDBusConnection *conn, const gchar *sender,
const gchar *path, const gchar *interface, const gchar *signal, GVariant *params,
void *userdata) {
(void)conn;
(void)sender;
(void)interface;
(void)userdata;
const gchar *signature = g_variant_get_type_string(params);
GVariantIter *properties = NULL;
GVariantIter *unknown = NULL;
GVariant *value = NULL;
struct ba_transport *t;
const char *iface;
const char *key;
if (strcmp(signature, "(sa{sv}as)") != 0) {
error("Invalid signature for %s: %s != %s", signal, signature, "(sa{sv}as)");
goto fail;
}
g_variant_get(params, "(&sa{sv}as)", &iface, &properties, &unknown);
debug("Signal: %s: %s", signal, iface);
while (g_variant_iter_next(properties, "{&sv}", &key, &value)) {
if (strcmp(key, "State") == 0) {
if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
error("Invalid argument type for %s: %s != %s", key,
g_variant_get_type_string(value), "s");
goto fail;
}
printf("state is %s\n", g_variant_get_string(value, NULL));
}
g_variant_unref(value);
value = NULL;
}
fail:
if (properties != NULL)
g_variant_iter_free(properties);
if (value != NULL)
g_variant_unref(value);
}
Where g_variant_get_string(value, NULL))
will provide you the current state and you decide the SINK operation based on the current state.
Upvotes: 1