mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-05 08:58:01 +02:00
wireplumber-cli: update to more recent API and fix some issues
This commit is contained in:
parent
151480f3e4
commit
386c75f3b9
1 changed files with 127 additions and 145 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2019 Collabora Ltd.
|
||||
* Copyright © 2019-2020 Collabora Ltd.
|
||||
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
|
|
@ -44,16 +44,26 @@ print_dev_endpoint (WpEndpoint *ep, WpSession *session, const gchar *type_name)
|
|||
gboolean is_default = (session && type_name != NULL &&
|
||||
wp_session_get_default_endpoint (session, type_name) == id);
|
||||
g_autoptr (WpSpaPod) ctrl = NULL;
|
||||
gboolean has_audio_controls = FALSE;
|
||||
gfloat volume = 0.0;
|
||||
gboolean mute = FALSE;
|
||||
|
||||
ctrl = wp_proxy_get_control (WP_PROXY (ep), "volume");
|
||||
wp_spa_pod_get_float (ctrl, &volume);
|
||||
ctrl = wp_proxy_get_control (WP_PROXY (ep), "mute");
|
||||
wp_spa_pod_get_boolean (ctrl, &mute);
|
||||
if ((ctrl = wp_proxy_get_control (WP_PROXY (ep), "volume"))) {
|
||||
wp_spa_pod_get_float (ctrl, &volume);
|
||||
has_audio_controls = TRUE;
|
||||
}
|
||||
if ((ctrl = wp_proxy_get_control (WP_PROXY (ep), "mute"))) {
|
||||
wp_spa_pod_get_boolean (ctrl, &mute);
|
||||
has_audio_controls = TRUE;
|
||||
}
|
||||
|
||||
g_print (" %c %4u. %60s\tvol: %.2f %s\n", is_default ? '*' : ' ', id,
|
||||
wp_endpoint_get_name (ep), volume, mute ? "MUTE" : "");
|
||||
g_print (" %c %4u. %60s", is_default ? '*' : ' ', id,
|
||||
wp_endpoint_get_name (ep));
|
||||
|
||||
if (has_audio_controls)
|
||||
g_print ("\tvol: %.2f %s\n", volume, mute ? "MUTE" : "");
|
||||
else
|
||||
g_print ("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -68,53 +78,47 @@ static void
|
|||
list_endpoints (WpObjectManager * om, struct WpCliData * d)
|
||||
{
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_autoptr (WpSession) session = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
|
||||
it = wp_object_manager_iterate (om);
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_SESSION);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
session = g_value_dup_object (&val);
|
||||
g_value_unset (&val);
|
||||
break;
|
||||
}
|
||||
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
|
||||
WpSession *session = g_value_get_object (&val);
|
||||
g_autoptr (WpIterator) ep_it = NULL;
|
||||
g_auto (GValue) ep_val = G_VALUE_INIT;
|
||||
g_autoptr (WpProperties) props = wp_proxy_get_properties (WP_PROXY (session));
|
||||
const gchar *name = wp_properties_get (props, "session.name");
|
||||
guint32 id = wp_proxy_get_bound_id (WP_PROXY (session));
|
||||
|
||||
wp_iterator_reset (it);
|
||||
|
||||
g_print ("Audio capture devices:\n");
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Source") == 0)
|
||||
g_print ("Session %u (%s) capture devices:\n", id, name);
|
||||
ep_it = wp_session_iterate_endpoints_filtered (session,
|
||||
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "=s", "Audio/Source",
|
||||
NULL);
|
||||
for (; wp_iterator_next (ep_it, &ep_val); g_value_unset (&ep_val)) {
|
||||
WpEndpoint *ep = g_value_get_object (&ep_val);
|
||||
print_dev_endpoint (ep, session, "wp-session-default-endpoint-audio-source");
|
||||
}
|
||||
}
|
||||
g_clear_pointer (&ep_it, wp_iterator_unref);
|
||||
|
||||
wp_iterator_reset (it);
|
||||
|
||||
g_print ("\nAudio playback devices:\n");
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Sink") == 0)
|
||||
g_print ("\nSession %u (%s) playback devices:\n", id, name);
|
||||
ep_it = wp_session_iterate_endpoints_filtered (session,
|
||||
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "=s", "Audio/Sink",
|
||||
NULL);
|
||||
for (; wp_iterator_next (ep_it, &ep_val); g_value_unset (&ep_val)) {
|
||||
WpEndpoint *ep = g_value_get_object (&ep_val);
|
||||
print_dev_endpoint (ep, session, "wp-session-default-endpoint-audio-sink");
|
||||
}
|
||||
}
|
||||
g_clear_pointer (&ep_it, wp_iterator_unref);
|
||||
|
||||
wp_iterator_reset (it);
|
||||
|
||||
g_print ("\nClient streams:\n");
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
if (g_str_has_suffix (wp_endpoint_get_media_class (ep), "/Audio"))
|
||||
g_print ("\nSession %u (%s) client streams:\n", id, name);
|
||||
ep_it = wp_session_iterate_endpoints_filtered (session,
|
||||
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s", "Stream/*/Audio",
|
||||
NULL);
|
||||
for (; wp_iterator_next (ep_it, &ep_val); g_value_unset (&ep_val)) {
|
||||
WpEndpoint *ep = g_value_get_object (&ep_val);
|
||||
print_client_endpoint (ep);
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
}
|
||||
|
||||
g_main_loop_quit (d->loop);
|
||||
|
|
@ -123,79 +127,63 @@ list_endpoints (WpObjectManager * om, struct WpCliData * d)
|
|||
static void
|
||||
set_default (WpObjectManager * om, struct WpCliData * d)
|
||||
{
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_autoptr (WpSession) session = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
g_autoptr (WpEndpoint) ep = NULL;
|
||||
guint32 id = d->params.set_default.id;
|
||||
|
||||
it = wp_object_manager_iterate (om);
|
||||
ep = wp_object_manager_lookup (om, WP_TYPE_ENDPOINT,
|
||||
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", id,
|
||||
NULL);
|
||||
if (ep) {
|
||||
const gchar * type_name;
|
||||
g_autoptr (WpProperties) props = wp_proxy_get_properties (WP_PROXY (ep));
|
||||
const gchar *sess_id_str = wp_properties_get (props, "session.id");
|
||||
guint32 sess_id = sess_id_str ? atoi (sess_id_str) : 0;
|
||||
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_SESSION);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
session = g_value_dup_object (&val);
|
||||
g_value_unset (&val);
|
||||
break;
|
||||
}
|
||||
session = wp_object_manager_lookup (om, WP_TYPE_SESSION,
|
||||
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", sess_id, NULL);
|
||||
if (!session) {
|
||||
g_print ("%u: invalid sesssion %u\n", id, sess_id);
|
||||
g_main_loop_quit (d->loop);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
g_print ("No Session object - changing the default endpoint is not supported\n");
|
||||
g_main_loop_quit (d->loop);
|
||||
if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Sink") == 0)
|
||||
type_name = "wp-session-default-endpoint-audio-sink";
|
||||
else if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Source") == 0)
|
||||
type_name = "wp-session-default-endpoint-audio-source";
|
||||
else {
|
||||
g_print ("%u: not a device endpoint\n", id);
|
||||
g_main_loop_quit (d->loop);
|
||||
return;
|
||||
}
|
||||
|
||||
wp_session_set_default_endpoint (session, type_name, id);
|
||||
wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d);
|
||||
return;
|
||||
}
|
||||
|
||||
wp_iterator_reset (it);
|
||||
|
||||
for (; wp_iterator_next (it, &val) &&
|
||||
g_type_is_a (G_VALUE_TYPE (&val), WP_TYPE_ENDPOINT);
|
||||
g_value_unset (&val))
|
||||
{
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
guint32 id = wp_proxy_get_bound_id (WP_PROXY (ep));
|
||||
|
||||
if (id == d->params.set_default.id) {
|
||||
const gchar * type_name;
|
||||
if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Sink") == 0)
|
||||
type_name = "wp-session-default-endpoint-audio-sink";
|
||||
else if (g_strcmp0 (wp_endpoint_get_media_class (ep), "Audio/Source") == 0)
|
||||
type_name = "wp-session-default-endpoint-audio-source";
|
||||
else {
|
||||
g_print ("%u: not a device endpoint\n", id);
|
||||
g_main_loop_quit (d->loop);
|
||||
return;
|
||||
}
|
||||
|
||||
wp_session_set_default_endpoint (session, type_name, id);
|
||||
wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_print ("%u: not an endpoint\n", d->params.set_default.id);
|
||||
g_print ("endpoint not found\n");
|
||||
g_main_loop_quit (d->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
set_volume (WpObjectManager * om, struct WpCliData * d)
|
||||
{
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
g_autoptr (WpEndpoint) ep = NULL;
|
||||
guint32 id = d->params.set_volume.id;
|
||||
|
||||
it = wp_object_manager_iterate (om);
|
||||
|
||||
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
|
||||
WpEndpoint *ep = g_value_get_object (&val);
|
||||
guint32 id = wp_proxy_get_bound_id (WP_PROXY (ep));
|
||||
|
||||
if (id == d->params.set_volume.id) {
|
||||
g_autoptr (WpSpaPod) vol = wp_spa_pod_new_float (d->params.set_volume.volume);
|
||||
wp_proxy_set_control (WP_PROXY (ep), "volume", vol);
|
||||
wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d);
|
||||
return;
|
||||
}
|
||||
ep = wp_object_manager_lookup (om, WP_TYPE_ENDPOINT,
|
||||
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", id,
|
||||
NULL);
|
||||
if (ep) {
|
||||
g_autoptr (WpSpaPod) vol = wp_spa_pod_new_float (d->params.set_volume.volume);
|
||||
wp_proxy_set_control (WP_PROXY (ep), "volume", vol);
|
||||
wp_core_sync (d->core, NULL, (GAsyncReadyCallback) async_quit, d);
|
||||
return;
|
||||
}
|
||||
|
||||
g_print ("%u: not an endpoint\n", d->params.set_default.id);
|
||||
g_print ("endpoint not found\n");
|
||||
g_main_loop_quit (d->loop);
|
||||
}
|
||||
|
||||
|
|
@ -207,44 +195,40 @@ device_node_props (WpObjectManager * om, struct WpCliData * d)
|
|||
const struct spa_dict * dict;
|
||||
const struct spa_dict_item *item;
|
||||
|
||||
it = wp_object_manager_iterate (om);
|
||||
|
||||
g_print ("Capture device nodes:\n");
|
||||
|
||||
it = wp_object_manager_iterate_filtered (om, WP_TYPE_NODE,
|
||||
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "=s", "Audio/Source",
|
||||
NULL);
|
||||
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
|
||||
WpProxy *node = g_value_get_object (&val);
|
||||
g_autoptr (WpProperties) props = wp_proxy_get_properties (node);
|
||||
|
||||
if (g_strcmp0 (wp_properties_get (props, "media.class"), "Audio/Source") != 0)
|
||||
continue;
|
||||
|
||||
g_print (" node id: %u\n", wp_proxy_get_bound_id (node));
|
||||
|
||||
dict = wp_properties_peek_dict (props);
|
||||
spa_dict_for_each (item, dict) {
|
||||
g_print (" %s = \"%s\"\n", item->key, item->value);
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
}
|
||||
g_clear_pointer (&it, wp_iterator_unref);
|
||||
|
||||
wp_iterator_reset (it);
|
||||
g_print ("Playback device nodes:\n");
|
||||
|
||||
it = wp_object_manager_iterate_filtered (om, WP_TYPE_NODE,
|
||||
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "=s", "Audio/Sink",
|
||||
NULL);
|
||||
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
|
||||
WpProxy *node = g_value_get_object (&val);
|
||||
g_autoptr (WpProperties) props = wp_proxy_get_properties (node);
|
||||
|
||||
if (g_strcmp0 (wp_properties_get (props, "media.class"), "Audio/Sink") != 0)
|
||||
continue;
|
||||
|
||||
g_print (" node id: %u\n", wp_proxy_get_bound_id (node));
|
||||
|
||||
dict = wp_properties_peek_dict (props);
|
||||
spa_dict_for_each (item, dict) {
|
||||
g_print (" %s = \"%s\"\n", item->key, item->value);
|
||||
}
|
||||
|
||||
g_print ("\n");
|
||||
}
|
||||
|
||||
|
|
@ -274,6 +258,7 @@ main (gint argc, gchar **argv)
|
|||
g_autoptr (WpCore) core = NULL;
|
||||
g_autoptr (WpObjectManager) om = NULL;
|
||||
g_autoptr (GMainLoop) loop = NULL;
|
||||
GCallback func = NULL;
|
||||
|
||||
wp_init (WP_INIT_ALL);
|
||||
|
||||
|
|
@ -290,66 +275,63 @@ main (gint argc, gchar **argv)
|
|||
|
||||
om = wp_object_manager_new ();
|
||||
|
||||
/* ls-endpoints */
|
||||
if (argc == 2 && !g_strcmp0 (argv[1], "ls-endpoints")) {
|
||||
wp_object_manager_add_interest (om, WP_TYPE_ENDPOINT,
|
||||
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
|
||||
WP_PROXY_FEATURE_CONTROLS);
|
||||
wp_object_manager_add_interest (om, WP_TYPE_SESSION,
|
||||
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
|
||||
WP_PROXY_FEATURE_CONTROLS);
|
||||
g_signal_connect (om, "objects-changed", (GCallback) list_endpoints, &data);
|
||||
wp_object_manager_add_interest_1 (om, WP_TYPE_SESSION, NULL);
|
||||
wp_object_manager_request_proxy_features (om, WP_TYPE_SESSION,
|
||||
WP_SESSION_FEATURES_STANDARD);
|
||||
func = (GCallback) list_endpoints;
|
||||
}
|
||||
|
||||
/* set-default <id> */
|
||||
else if (argc == 3 && !g_strcmp0 (argv[1], "set-default")) {
|
||||
long id = strtol (argv[2], NULL, 10);
|
||||
if (id == 0) {
|
||||
if (id <= 0) {
|
||||
g_print ("%s: not a valid id\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
wp_object_manager_add_interest (om, WP_TYPE_ENDPOINT,
|
||||
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND);
|
||||
wp_object_manager_add_interest (om, WP_TYPE_SESSION,
|
||||
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
|
||||
WP_PROXY_FEATURE_CONTROLS);
|
||||
|
||||
data.params.set_default.id = id;
|
||||
g_signal_connect (om, "objects-changed", (GCallback) set_default, &data);
|
||||
wp_object_manager_add_interest_1 (om, WP_TYPE_SESSION, NULL);
|
||||
wp_object_manager_add_interest_1 (om, WP_TYPE_ENDPOINT, NULL);
|
||||
wp_object_manager_request_proxy_features (om, WP_TYPE_PROXY,
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
|
||||
func = (GCallback) set_default;
|
||||
}
|
||||
|
||||
/* set-volume <id> <vol> */
|
||||
else if (argc == 4 && !g_strcmp0 (argv[1], "set-volume")) {
|
||||
long id = strtol (argv[2], NULL, 10);
|
||||
float volume = strtof (argv[3], NULL);
|
||||
if (id == 0) {
|
||||
if (id <= 0) {
|
||||
g_print ("%s: not a valid id\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
wp_object_manager_add_interest (om, WP_TYPE_ENDPOINT,
|
||||
NULL, WP_PROXY_FEATURE_INFO | WP_PROXY_FEATURE_BOUND |
|
||||
WP_PROXY_FEATURE_CONTROLS);
|
||||
|
||||
data.params.set_volume.id = id;
|
||||
data.params.set_volume.volume = volume;
|
||||
g_signal_connect (om, "objects-changed", (GCallback) set_volume, &data);
|
||||
wp_object_manager_add_interest_1 (om, WP_TYPE_ENDPOINT, NULL);
|
||||
wp_object_manager_request_proxy_features (om, WP_TYPE_ENDPOINT,
|
||||
WP_PROXY_FEATURES_STANDARD | WP_PROXY_FEATURE_CONTROLS);
|
||||
func = (GCallback) set_volume;
|
||||
}
|
||||
|
||||
/* device-node-props */
|
||||
else if (argc == 2 && !g_strcmp0 (argv[1], "device-node-props")) {
|
||||
wp_object_manager_add_interest (om, WP_TYPE_NODE, NULL,
|
||||
WP_PROXY_FEATURE_INFO);
|
||||
g_signal_connect (om, "objects-changed", (GCallback) device_node_props,
|
||||
&data);
|
||||
wp_object_manager_add_interest_1 (om, WP_TYPE_NODE, NULL);
|
||||
wp_object_manager_request_proxy_features (om, WP_TYPE_NODE,
|
||||
WP_PROXY_FEATURES_STANDARD);
|
||||
func = (GCallback) device_node_props;
|
||||
}
|
||||
|
||||
else {
|
||||
g_autofree gchar *help = g_option_context_get_help (context, TRUE, NULL);
|
||||
g_print ("%s", help);
|
||||
return 1;
|
||||
}
|
||||
|
||||
wp_core_install_object_manager (core, om);
|
||||
if (wp_core_connect (core))
|
||||
g_main_loop_run (loop);
|
||||
if (!wp_core_connect (core))
|
||||
return 1;
|
||||
|
||||
g_signal_connect (om, "installed", (GCallback) func, &data);
|
||||
wp_core_install_object_manager (core, om);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue