Detect missing pipewiresrc element before host startup
`gst-launch-1.0` and `pipewiresrc` ship in separate packages on most distros (Arch: `gst-plugin-pipewire`, Debian: `gstreamer1.0-pipewire`, Fedora/openSUSE: `pipewire-gstreamer`). Having the gst binary present was no guarantee the Wayland capture pipeline would actually work — without the plugin gst would bail at runtime with `no element "pipewiresrc"`, which then cascaded into ffmpeg seeing EOF on its stdin and exiting before its HTTP listener bound, then the host hitting "Connection refused" against its own port. Confusing. Now `deps::check_host_binaries` probes `gst-inspect-1.0 --exists pipewiresrc` on Wayland and fails early with a per-distro install hint pointing at the right package.
This commit is contained in:
+42
-10
@@ -1,5 +1,6 @@
|
||||
use anyhow::{Result, bail};
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::common::display::DisplayServer;
|
||||
|
||||
@@ -7,6 +8,8 @@ pub fn check_host_binaries(display: DisplayServer) -> Result<()> {
|
||||
require("ffmpeg")?;
|
||||
if display == DisplayServer::Wayland {
|
||||
require("gst-launch-1.0")?;
|
||||
require("gst-inspect-1.0")?;
|
||||
require_gst_element("pipewiresrc")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -14,11 +17,23 @@ pub fn check_host_binaries(display: DisplayServer) -> Result<()> {
|
||||
fn require(bin: &str) -> Result<PathBuf> {
|
||||
match which(bin) {
|
||||
Some(p) => Ok(p),
|
||||
None => {
|
||||
let hint = install_hint(bin);
|
||||
bail!("`{bin}` not found on PATH.\n{hint}");
|
||||
None => bail!("`{bin}` not found on PATH.\n{}", install_hint_for_bin(bin)),
|
||||
}
|
||||
}
|
||||
|
||||
fn require_gst_element(name: &str) -> Result<()> {
|
||||
let ok = Command::new("gst-inspect-1.0")
|
||||
.args(["--exists", name])
|
||||
.status()
|
||||
.map(|s| s.success())
|
||||
.unwrap_or(false);
|
||||
if !ok {
|
||||
bail!(
|
||||
"GStreamer element `{name}` not available.\n{}",
|
||||
install_hint_for_gst_element(name)
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn which(bin: &str) -> Option<PathBuf> {
|
||||
@@ -32,19 +47,37 @@ fn which(bin: &str) -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
fn install_hint(bin: &str) -> String {
|
||||
fn install_hint_for_bin(bin: &str) -> String {
|
||||
let distro = detect_distro();
|
||||
let pkg = match bin {
|
||||
"ffmpeg" => "ffmpeg",
|
||||
"gst-launch-1.0" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros") => "gst-plugins-base gst-plugins-good",
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-tools gstreamer1.0-plugins-good",
|
||||
Some("fedora" | "nobara") => "gstreamer1-plugins-good",
|
||||
_ => "gstreamer (and tools / good-plugins)",
|
||||
"gst-launch-1.0" | "gst-inspect-1.0" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros") => "gstreamer gst-plugins-base",
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-tools",
|
||||
Some("fedora" | "nobara") => "gstreamer1 gstreamer1-plugins-base-tools",
|
||||
_ => "gstreamer + tools",
|
||||
},
|
||||
_ => bin,
|
||||
};
|
||||
install_command(&distro, pkg)
|
||||
}
|
||||
|
||||
fn install_hint_for_gst_element(name: &str) -> String {
|
||||
let distro = detect_distro();
|
||||
let pkg = match name {
|
||||
"pipewiresrc" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros") => "gst-plugin-pipewire",
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-pipewire",
|
||||
Some("fedora" | "nobara") => "pipewire-gstreamer",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "pipewire-gstreamer",
|
||||
_ => "the GStreamer PipeWire plugin",
|
||||
},
|
||||
_ => name,
|
||||
};
|
||||
install_command(&distro, pkg)
|
||||
}
|
||||
|
||||
fn install_command(distro: &Option<String>, pkg: &str) -> String {
|
||||
let cmd = match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros") => format!("sudo pacman -S {pkg}"),
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => format!("sudo apt install {pkg}"),
|
||||
@@ -52,7 +85,6 @@ fn install_hint(bin: &str) -> String {
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => format!("sudo zypper install {pkg}"),
|
||||
_ => format!("install the `{pkg}` package via your distro's package manager"),
|
||||
};
|
||||
|
||||
format!("Install hint: {cmd}")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user