#include #include #include #include #include #include namespace Pipewire { bool link_ports(int out_port_id, int in_port_id); bool destroy_link(int link_id); void set_volume(const QString& target_node, int volume_percent); struct Port { int id; int node_id; QString direction; // "in" or "out" QString channel; }; struct Link { int id; int output_node_id; int input_node_id; }; struct Node { int id; QString node_name; QString application_name; QString media_class; QString get_display_name() const; }; class Graph { public: Graph(); bool refresh(); std::vector get_input_apps() const; std::optional get_node_by_name(const QString& name) const; std::vector get_ports_for_node(int node_id, const QString& direction) const; std::vector get_links_from_node(int output_node_id) const; std::vector get_all_sinks() const; private: std::unordered_map m_nodes; std::unordered_map m_ports; std::unordered_map m_links; }; class Player { public: ~Player(); void play_file(const QString& file_path, const QString& target_node = "auto"); void stop_all(); private: std::vector> m_playing_processes; }; class Sink { public: static std::optional create(const QString& name, Graph& graph); ~Sink(); Sink(Sink&& other); Sink& operator=(Sink&& other); Sink(const Sink&) = delete; Sink& operator=(const Sink&) = delete; int get_id() const; QString get_name() const; private: Sink() = default; static void destroy(int pulse_audio_id); QString m_name; int m_pulse_audio_id = -1; int m_pipewire_id = -1; }; } // namespace Pipewire