create-item.lua 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. -- WirePlumber
  2. --
  3. -- Copyright © 2021 Collabora Ltd.
  4. -- @author Julian Bouzas <julian.bouzas@collabora.com>
  5. --
  6. -- SPDX-License-Identifier: MIT
  7. -- Receive script arguments from config.lua
  8. local config = ... or {}
  9. items = {}
  10. function configProperties(node)
  11. local np = node.properties
  12. local properties = {
  13. ["item.node"] = node,
  14. ["item.plugged.usec"] = GLib.get_monotonic_time(),
  15. ["item.features.no-dsp"] = config["audio.no-dsp"],
  16. ["item.features.monitor"] = true,
  17. ["item.features.control-port"] = false,
  18. ["node.id"] = node["bound-id"],
  19. ["client.id"] = np["client.id"],
  20. ["object.path"] = np["object.path"],
  21. ["object.serial"] = np["object.serial"],
  22. ["target.object"] = np["target.object"],
  23. ["priority.session"] = np["priority.session"],
  24. ["device.id"] = np["device.id"],
  25. ["card.profile.device"] = np["card.profile.device"],
  26. }
  27. for k, v in pairs(np) do
  28. if k:find("^node") or k:find("^stream") or k:find("^media") then
  29. properties[k] = v
  30. end
  31. end
  32. local media_class = properties["media.class"] or ""
  33. if not properties["media.type"] then
  34. for _, i in ipairs({ "Audio", "Video", "Midi" }) do
  35. if media_class:find(i) then
  36. properties["media.type"] = i
  37. break
  38. end
  39. end
  40. end
  41. properties["item.node.type"] =
  42. media_class:find("^Stream/") and "stream" or "device"
  43. if media_class:find("Sink") or
  44. media_class:find("Input") or
  45. media_class:find("Duplex") then
  46. properties["item.node.direction"] = "input"
  47. elseif media_class:find("Source") or media_class:find("Output") then
  48. properties["item.node.direction"] = "output"
  49. end
  50. return properties
  51. end
  52. function addItem (node, item_type)
  53. local id = node["bound-id"]
  54. local item
  55. -- create item
  56. item = SessionItem ( item_type )
  57. items[id] = item
  58. -- configure item
  59. if not item:configure(configProperties(node)) then
  60. Log.warning(item, "failed to configure item for node " .. tostring(id))
  61. return
  62. end
  63. item:register ()
  64. -- activate item
  65. items[id]:activate (Features.ALL, function (item, e)
  66. if e then
  67. Log.message(item, "failed to activate item: " .. tostring(e));
  68. if item then
  69. item:remove ()
  70. end
  71. else
  72. Log.info(item, "activated item for node " .. tostring(id))
  73. -- Trigger object managers to update status
  74. item:remove ()
  75. if item["active-features"] ~= 0 then
  76. item:register ()
  77. end
  78. end
  79. end)
  80. end
  81. nodes_om = ObjectManager {
  82. Interest {
  83. type = "node",
  84. Constraint { "media.class", "#", "Stream/*", type = "pw-global" },
  85. },
  86. Interest {
  87. type = "node",
  88. Constraint { "media.class", "#", "Video/*", type = "pw-global" },
  89. },
  90. Interest {
  91. type = "node",
  92. Constraint { "media.class", "#", "Audio/*", type = "pw-global" },
  93. Constraint { "wireplumber.is-endpoint", "-", type = "pw" },
  94. },
  95. }
  96. nodes_om:connect("object-added", function (om, node)
  97. local media_class = node.properties['media.class']
  98. if string.find (media_class, "Audio") then
  99. addItem (node, "si-audio-adapter")
  100. else
  101. addItem (node, "si-node")
  102. end
  103. end)
  104. nodes_om:connect("object-removed", function (om, node)
  105. local id = node["bound-id"]
  106. if items[id] then
  107. items[id]:remove ()
  108. items[id] = nil
  109. end
  110. end)
  111. nodes_om:activate()