I’m trying to use gstreamer to stream a pipewire source, however no matter what I do I keep running into format negotiation errors streaming stopped, reason not-negotiated (-4)
.
Here is the simplest way I have been able to get one:
GST_DEBUG=4 gst-launch-1.0 pipewiresrc path=102 fd=14 ! fakesink
Error log:
Note that I am not the only one who is able to reproduce the error, and this isn’t he only thing I’ve tried to cause it. I have attempted to put caps in, video converter in, and other random things I saw in online examples, with essentially the same error at the end.
Here is a previous post I created about my issue which has a few more details and someone else trying it and encountering an error too:
opened 02:56PM - 21 Jun 25 UTC
documentation
Hey it would be amazing if it was possible to provide a basic example with gstre… amer?
I'd be happy to contribute but I can't seem to figure out how to. I know you have a large example already which does use gstreamer, but I think because it's so big and uses gtk it's hard to really understand what's going on.
This was my attempt, if you can give any advice on where I went wrong I'd be happy to PR my example in:
```rust
pub(crate) async fn initiate_stream() {
let (stream, stream_fd) = open_portal().await.expect("failed to open portal");
let pipewire_node_id = stream.pipe_wire_node_id();
let stream_raw_fd = &stream_fd.try_clone().unwrap().into_raw_fd();
println!("node id {}, fd {}", pipewire_node_id, stream_raw_fd);
gst::init().expect("Unable to start gstreamer");
let pipewire_element = gst::ElementFactory::make("pipewiresrc").build().unwrap();
pipewire_element.set_property("fd", stream_raw_fd);
pipewire_element.set_property("path", pipewire_node_id.to_string());
pipewire_element.set_property("do-timestamp", true);
let convert = gst::ElementFactory::make("videoconvert").build().unwrap();
let encoder = gst::ElementFactory::make("vaapih264enc")
.build()
.expect("Couldn't create video converter");
let rtp_pay = gst::ElementFactory::make("rtph264pay")
.build()
.expect("Couldn't create rtp packet element");
let udp_sink = gst::ElementFactory::make("udpsink")
.property("host", "192.168.12.233")
.property("port", 5911i32)
.build()
.expect("Failed to create udpsink");
let pipeline = gst::Pipeline::new();
pipeline
.add_many([&pipewire_element, &convert, &encoder, &rtp_pay, &udp_sink])
.expect("Failed to add elements to pipeline");
gst::Element::link_many([&pipewire_element, &convert, &encoder, &rtp_pay, &udp_sink])
.expect("Failed to link elements");
pipeline
.set_state(gst::State::Playing)
.expect("Failed to start pipeline");
}
```
I'm not sure if it's possible to create something a lot simpler? The rest of my code is just from the main screenshare example which was really good, I just took the bit at the bottom which had the logging and replaced it with this. Thanks for making this library, looks really cool!
Any help would be much appreciated!
slomo
June 22, 2025, 3:37pm
2
Can you provide a full log with GST_DEBUG=6
? Most likely this is a problem in pipewire though (pipewiresrc
is shipped as part of pipewire).
Here are the logs with GST_DEBUG=6 Untitled - Pastebin Service
slomo
June 22, 2025, 4:06pm
4
0:00:30.561595435 14277 0x7f2ddc000b70 DEBUG pipewiresrc gstpipewiresrc.c:1072:gst_pipewire_src_negotiate:<pipewiresrc0> connect error
is the actual error in here. Unfortunately not much more information but this looks like a pipewire problem one way or another.
Thank you!
@KamWithK would you mind opening an issue on PipeWire / pipewire · GitLab and include those logs? thank you!
Done:
Ran the command myself and added the logs
1 Like