ax9d / pw-viz Goto Github PK
View Code? Open in Web Editor NEWPipewire graph editor written in Rust. WIP⚠️
License: GNU General Public License v3.0
Pipewire graph editor written in Rust. WIP⚠️
License: GNU General Public License v3.0
Automatically run rustfmt and perform a build test on push/PRs to main.
I'd like the ability to hide certain nodes on the graph, maybe through a right-click context menu on the node, or otherwise with a keypress or mouse button. For example, I have an external DAC and the extra links to it from every other node in the graph make everything more cluttered. I'm never going to need to make links to or from it since it's the only output device I use. In addition, it would be good to have a dropdown menu from the top bar, say "View > Nodes" which contains a list of every node by name and a checkbox next to it which toggles visibility.
pw-viz uses egui and the binary isn't linked with any graphics-related shared libraries.
When the binary runs it loads these:
/usr/local/lib/libGL.so.1.7.0
/usr/local/lib/libGLX.so.0.0.0
/usr/local/lib/libGLX_nvidia.so.0
/usr/local/lib/libGLdispatch.so.0.0.0
/usr/local/lib/libX11-xcb.so.1.0.0
/usr/local/lib/libX11.so.6.4.0
/usr/local/lib/libXau.so.6.0.0
/usr/local/lib/libXcursor.so.1.0.2
/usr/local/lib/libXdmcp.so.6.0.0
/usr/local/lib/libXext.so.6.4.0
/usr/local/lib/libXfixes.so.3.1.0
/usr/local/lib/libXi.so.6.1.0
/usr/local/lib/libXrandr.so.2.2.0
/usr/local/lib/libXrender.so.1.3.0
/usr/local/lib/libdbus-1.so.3.32.1
/usr/local/lib/libnvidia-glcore.so.1
/usr/local/lib/libnvidia-glsi.so.1
/usr/local/lib/libnvidia-tls.so.1
/usr/local/lib/libpipewire-0.3.so.0.362.0
/usr/local/lib/libxcb-glx.so.0.0.0
/usr/local/lib/libxcb.so.1.1.0
egui can use a variety of external libraries, depending on the backend that is used.
What is the minimal set of run-time dependencies for pw-viz?
How to solve the problem,when i first run the project i encountered?
Running from terminal crashes the terminal, running from gdb shows that the app is running. but no window is visible.
EDIT: Window is extremely small when it opens
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GlutinCreationError(NoAvailablePixelFormat)', /home/atri/.cargo/registry/src/github.com-1ecc6299db9ec823/egui_glium-0.15.0/src/epi_backend.rs:45:70
stack backtrace:
0: 0x563c69a88abd - <unknown>
1: 0x563c698a62cc - <unknown>
2: 0x563c69a87364 - <unknown>
3: 0x563c69a87ac0 - <unknown>
4: 0x563c69a86fa1 - <unknown>
5: 0x563c69aa7ab8 - <unknown>
6: 0x563c69aa7a36 - <unknown>
7: 0x563c69aa79f2 - <unknown>
8: 0x563c69867d70 - <unknown>
9: 0x563c698680a2 - <unknown>
10: 0x563c699940df - <unknown>
11: 0x563c698afb0c - <unknown>
12: 0x563c69a34c83 - <unknown>
13: 0x563c69a19213 - <unknown>
14: 0x563c69a33925 - <unknown>
15: 0x7fc3ee77afd0 - __libc_start_call_main
at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
16: 0x7fc3ee77b07d - __libc_start_main_impl
at ./csu/../csu/libc-start.c:409:3
17: 0x563c6988293e - <unknown>
18: 0x0 - <unknown>
error[E0425]: cannot find function `eventfd` in crate `libc`
--> /usr/ports/net/pw-viz/work/pw-viz-0.1.0-22-g04ffced/cargo-crates/pipewire-0.4.1/src/channel.rs:220:34
|
220 | let eventfd = unsafe { libc::eventfd(0, libc::EFD_CLOEXEC) };
| ^^^^^^^ not found in `libc`
error[E0425]: cannot find function `pw_init` in crate `pw_sys`
--> /usr/ports/net/pw-viz/work/pw-viz-0.1.0-22-g04ffced/cargo-crates/pipewire-0.4.1/src/lib.rs:156:49
|
156 | INITIALIZED.get_or_init(|| unsafe { pw_sys::pw_init(ptr::null_mut(), ptr::null_mut()) });
| ^^^^^^^ not found in `pw_sys`
error[E0425]: cannot find function `pw_deinit` in crate `pw_sys`
--> /usr/ports/net/pw-viz/work/pw-viz-0.1.0-22-g04ffced/cargo-crates/pipewire-0.4.1/src/lib.rs:165:13
|
165 | pw_sys::pw_deinit()
| ^^^^^^^^^ not found in `pw_sys`
The libc crate does contain this function for FreeBSD-13:
libc-0.2.107/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs: pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int;
rev.04ffced
FreeBSD 13.1 STABLE
What are the dependencies for compiling it? I am on Fedora and couldn't compile 0.16.
Is there a Docker image that I could set or grab to compile it?
I'm unable to build pw-viz because:
Compiling pipewire v0.5.0
Compiling simple_logger v4.0.0
error[E0425]: cannot find value `PW_KEY_NODE_TARGET` in crate `pw_sys`
--> /home/johnb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pipewire-0.5.0/src/auto/keys.rs:164:28
|
164 | key_constant!(NODE_TARGET, PW_KEY_NODE_TARGET,
| ^^^^^^^^^^^^^^^^^^ help: a constant with a similar name exists: `PW_KEY_NODE_NAME`
|
::: /home/johnb/Applications/pw-viz/target/release/build/pipewire-sys-40594b83031eb6b0/out/bindings.rs:165:1
|
165 | pub const PW_KEY_NODE_NAME: &[u8; 10usize] = b"node.name\0";
| ------------------------------------------ similarly named constant `PW_KEY_NODE_NAME` defined here
Compiling rand v0.8.5
For more information about this error, try `rustc --explain E0425`.
error: could not compile `pipewire` (lib) due to previous error
warning: build failed, waiting for other jobs to finish...
Currently panning uses the middle mouse button. This is impossible on for example laptops, due to not having a middle mouse button.
Possible solutions:
It seems to be much more intuitive to just remove links by dragging them over the same path again, as you would create them.
Did you have any plans regarding the layout algorithm yet? If so, feel free to just close this.
Overall I quite like the auto-layout and grouping features in patchage, although I wish it would also re-center the viewport when re-generating the layout. This is a feature I would love to see in pw-viz as well, or maybe even re-layout on the fly as nodes appear and disappear from the graph? Live re-layout should probably not touch the viewport and needs an option to toggle it on and off.
As for the algorithm itself a good start would probably be a basic mass-spring system where the nodes 1) have a "gravity" towards left/right based on their ports' directions to determine the rough initial position and 2) push each other away to avoid overlap. Links would act as springs pulling the connected nodes together. For things like effect chains I suppose it's a matter of complexity and preference whether a left-to-right or top-down flow would be preferrable. There is probably a decent heuristic to detect effect nodes (such as 'has "input" and "output" ports but no others' connected) and flip the direction in which the springs are pulling
To reduce clutter it would be handy to be able to collapse nodes into only the title and the layout algorithm could potentially collapse by default nodes that don't currently have any links. This would probably require keeping track of nodes that the user manually expands. Collapsed nodes should also probably have some indicator for what kind of ports they have, not sure what the best way to handle that would be.
If someone is dealing with a great number of nodes, the arrange function is really nice, but sometimes manually panning somewhere, then clicking arrange, can cause the user to need to hunt them down, it would be nice if it would also snap the user back to origin, or have a dedicated button to do so.
Recently, the developers of Blackjack, a 3D modelling app, have released their egui node graph implementation as a crate. It might be worth considering if its better for our use-case versus the existing fork of egui_nodes
.
In comparison to using QjackCtl, if an application has multiple outputs or inputs, they each appear as separate nodes in the graph. Helvum also suffers from this problem. For example, if I open pavucontrol
, each separate input is on a separate node, one for each currently running application, whereas QjackCtl unifies them into a single node. Here's a screenshot of QjackCtl:
You'll notice QjackCtl doesn't unify everything. It puts inputs and outputs in the same node, but not monitors. pw-viz does the opposite, putting inputs and monitors together, but not outputs. I think it would be great to put them all in one node. Additionally, on the pavucontrol node, all the left channels are stacked together, and then the right channels. I think it'd be better to stack pairs together.
error[E0425]: cannot find function `pw_init` in crate `pw_sys`
--> /wrkdirs/usr/ports/multimedia/pw-viz/work/pw-viz-0.3.0/cargo-crates/pipewire-0.8.0/src/lib.rs:158:49
|
158 | INITIALIZED.get_or_init(|| unsafe { pw_sys::pw_init(ptr::null_mut(), ptr::null_mut()) });
| ^^^^^^^ not found in `pw_sys`
error[E0425]: cannot find function `pw_deinit` in crate `pw_sys`
--> /wrkdirs/usr/ports/multimedia/pw-viz/work/pw-viz-0.3.0/cargo-crates/pipewire-0.8.0/src/lib.rs:167:13
|
167 | pw_sys::pw_deinit()
| ^^^^^^^^^ not found in `pw_sys`
Version: 0.3.0
FreeBSD 14.1
pw-viz
panics on Zoom disconnect on my box (Debian unstable pipewire 0.3.42).
Upgrading the dependency on simple_logger
to 2.1.0 and then rebuilding seems to fix it.
Print. Is there a way I could define the scale myself?
Another feature from Blender's node editor that would be neat to have.
When dragging a node and dropping it on top of an existing link, the Blender node editor tries to insert that node between the two endpoints of that link. This should be fairly usable for stuff like building effect chains.
Say you have a graph: A-->B
where A has a mono output or monitor and B has a mono input. Now dragging a node with a mono input and output in top of that link would make it easy to disconnect the link and create links A-->C-->B
using the matching port names. This can be extended to stereo, 5.1, 7.1 etc as long as the port name suffixes match.
AUXn ports could be considered to match named ones with a simple heuristic like, if there is only one link whatever AUXn is involved matches MONO, if there are two then the one with the lower AUXn number matches FL and the higher one FR, if there are more they match the named ports for 5.1, 7.1 etc in a fixed order starting from the first AUXn index of the existing links between the A and B.
Ports marked as UNK are more complicated, not sure what can be done about those. Is there a port number regardless of names in the pipewire API? Those could be used in this case.
Worst case (i.e. when it's not possible to infer the right ports) could be something like flash the dragged node and the link in question and then not doing anything.
Not sure if/how much modding this requires in egui-nodes. The heuristic for choosing the relevant ports should classify as "good first issue" so the difficulty is going to depend largely on how to do it in egui-nodes.
Hello and thank you for this project, it looks great!
The only issue I've seen so far from my very limited testing, is that pw-viz does not support cycles. The usecase I had was using Ardour, an audio work station:
I have a session with two tracks (Top and Bottom in the screenshot), whose audio is routed to the Master bus, and the Master bus is then forwarded to the speakers.
Here's how it looks in Patchage:
In pw-viz, the message ERROR [pw_viz::ui::graph] Cycle detected
is displayed on the terminal.
Here's how it looks:
Thanks again!
I had a failed build on nixOS (output linked below). I'm just reporting this and happy to assist with any debugging that may be needed to find root cause.
This is from the pkgs repository and I'm adding it to my user packages with the below structure in my configuration.nix file.
users.users = {
sighnwaive = {
...;
packages = with pkgs; [
pw-viz
wireplumber
];
...;
};
Links can currently be selected but no action can be taken within that context. I use Alt as my mod key in i3wm, so can't currently use the UI to delete links between nodes, as alt-dragging controls the window position and size for me. I think letting links be deleted by selecting them and hitting Delete would work well. By the way, what controls these keybinds? Do they come from egui_nodes
are from some other crate?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.