Bluez 5.48 - Как перевести состояние транспорта Bluetooth из активного состояния в режим ожидания - встроенный приемник - PullRequest
0 голосов
/ 07 ноября 2018

У меня обычная ситуация, когда приложения iOS не предоставляют сигналы паузы и воспроизведения в приемник через сигнализацию AVRCP DBus. Андроид в порядке. Единственное указание приостановленного потока во многих приложениях iOS (если оно все еще развернуто) - это состояние транспорта через некоторое время простаивает. Если пользователь переключается между паузой и воспроизведением, невозможно узнать этот конец приемника (то есть встроенный динамик), кроме реального звука. Android будет показывать паузу и проигрывать через AVRCP в приложениях, которые я тестировал. На iOS, когда транспорт простаивает, «игра» немедленно переводит транспорт в активное состояние. Итак ... Есть ли способ, Bash, Python, C или что-то еще, что я могу заставить транспорта подключенного устройства (например, iPad) из active => idle из встроенного раковина сторона? Если бы это было возможно, я бы знал, что при каждом нажатии «play» транспорт снова становится активным. Спасибо!

1 Ответ

0 голосов
/ 07 ноября 2018

Короче говоря, вам нужно прослушать сигнал PropertiesChanged на интерфейсе org.bluez.MediaTransport1 и проанализировать сигнал для изменения состояния.

Вы можете зарегистрироваться на интерфейсе Bluez DBUS, как показано ниже во время инициализации.

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);

Ниже приведен пример функциональности, которая анализирует сигнал изменения состояния,

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);
}

Где g_variant_get_string(value, NULL)) предоставит вам текущее состояние, и вы решите операцию SINK на основе текущего состояния.

...