mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2025-12-20 01:50:04 +01:00
scripts: Add script to find a suitable volume control
When using role based priorities a volume slider presented to the user should adjust the volume of the currently playing role. E.g. when a phone has an incoming call and is ringing the default volume slider should adjust the ringing volume and once the call has been picked up it should adjust the call volume and once the call ended it should adjust the media volume again. It's currently hard for e.g. desktop shells to find out what a suitable sink for volume control is so add a script to find a suitable target for volume control (based on media role priority) by storing it's name in the metadata. Signed-off-by: Guido Günther <agx@sigxcpu.org>
This commit is contained in:
parent
93377a8b4f
commit
5ecfe9f555
1 changed files with 94 additions and 0 deletions
94
src/scripts/node/find-media-role-default-volume.lua
Normal file
94
src/scripts/node/find-media-role-default-volume.lua
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
-- WirePlumber
|
||||
--
|
||||
-- Copyright © 2025 Phosh.mobi e.V.
|
||||
-- @author Guido Günther <agx@sigxcpu.org>
|
||||
--
|
||||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- Select the media role default volume
|
||||
|
||||
log = Log.open_topic("s-node")
|
||||
|
||||
local cutils = require ("common-utils")
|
||||
|
||||
function findHighestPriorityRoleNode (node_om)
|
||||
local best_role = nil
|
||||
local best_prio = 0
|
||||
|
||||
local default_role = Settings.get ("node.stream.default-media-role")
|
||||
if default_role then
|
||||
default_role = default_role:parse()
|
||||
end
|
||||
|
||||
for ni in node_om:iterate {
|
||||
type = "node",
|
||||
Constraint { "media.class", "=", "Audio/Sink" },
|
||||
Constraint { "node.name", "#", "input.loopback.sink.role.*" },
|
||||
} do
|
||||
local ni_props = ni.properties
|
||||
local roles = ni_props["device.intended-roles"]
|
||||
local node_name = ni_props ["node.name"]
|
||||
local prio = tonumber(ni_props ["policy.role-based.priority"])
|
||||
|
||||
-- Use the node that handles the default_role as fallback
|
||||
-- when no node is in running state
|
||||
if best_role == nil and roles and default_role then
|
||||
local roles_table = Json.Raw(roles):parse()
|
||||
for i, v in ipairs (roles_table) do
|
||||
if default_role == v then
|
||||
best_role = node_name
|
||||
best_prio = prio
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ni.state == "running" then
|
||||
if prio > best_prio then
|
||||
best_role = node_name
|
||||
best_prio = prio
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
log:info (string.format ("Volume control is on : '%s', prio %d", best_role, best_prio))
|
||||
local metadata = cutils.get_default_metadata_object ()
|
||||
metadata:set (0, "current.role-based.volume.control", "Spa:String:JSON",
|
||||
Json.Object { ["name"] = best_role }:to_string ())
|
||||
end
|
||||
|
||||
SimpleEventHook {
|
||||
name = "node/rescan-for-media-role-volume",
|
||||
interests = {
|
||||
EventInterest {
|
||||
Constraint { "event.type", "=", "rescan-for-media-role-volume" }
|
||||
},
|
||||
},
|
||||
execute = function (event)
|
||||
local source = event:get_source ()
|
||||
local node_om = source:call ("get-object-manager", "node")
|
||||
findHighestPriorityRoleNode (node_om)
|
||||
end
|
||||
}:register ()
|
||||
|
||||
-- Track best volume control for media role based priorities
|
||||
SimpleEventHook {
|
||||
name = "node/find-media-role-default-volume",
|
||||
interests = {
|
||||
EventInterest {
|
||||
Constraint { "event.type", "=", "node-added" },
|
||||
Constraint { "media.class", "=", "Audio/Sink" },
|
||||
Constraint { "node.name", "#", "input.loopback.sink.role.*" }
|
||||
},
|
||||
EventInterest {
|
||||
Constraint { "event.type", "=", "node-state-changed" },
|
||||
Constraint { "media.class", "=", "Audio/Sink" },
|
||||
Constraint { "node.name", "#", "input.loopback.sink.role.*" }
|
||||
},
|
||||
},
|
||||
execute = function (event)
|
||||
local source = event:get_source ()
|
||||
local node_om = source:call ("get-object-manager", "node")
|
||||
source:call ("schedule-rescan", "media-role-volume")
|
||||
end
|
||||
}:register ()
|
||||
Loading…
Add table
Reference in a new issue