style: apply current rustfmt to the tree
A newer rustfmt wraps over-long match arms and call expressions that the version main was last formatted with left on one line. Pure formatting, no semantic change — split out so the friends-list feature commits stay focused on real changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -84,7 +84,6 @@ pub enum BandwidthStatus {
|
||||
Failed,
|
||||
}
|
||||
|
||||
|
||||
fn default_status() -> BandwidthStatus {
|
||||
BandwidthStatus::Unmeasured
|
||||
}
|
||||
@@ -116,11 +115,9 @@ pub fn save(cfg: &Config) -> Result<()> {
|
||||
let parent = path
|
||||
.parent()
|
||||
.context("config path has no parent directory")?;
|
||||
fs::create_dir_all(parent)
|
||||
.with_context(|| format!("failed to create {}", parent.display()))?;
|
||||
fs::create_dir_all(parent).with_context(|| format!("failed to create {}", parent.display()))?;
|
||||
|
||||
let serialized =
|
||||
toml::to_string_pretty(cfg).context("failed to serialize config to TOML")?;
|
||||
let serialized = toml::to_string_pretty(cfg).context("failed to serialize config to TOML")?;
|
||||
|
||||
let tmp = parent.join(format!(".config.toml.tmp.{}", std::process::id()));
|
||||
{
|
||||
|
||||
+39
-13
@@ -85,7 +85,9 @@ fn install_hint_for_bin(bin: &str) -> String {
|
||||
let distro = detect_distro();
|
||||
let pkg = match bin {
|
||||
"gst-launch-1.0" | "gst-inspect-1.0" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gstreamer gst-plugins-base",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gstreamer gst-plugins-base"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-tools",
|
||||
Some("fedora" | "nobara") => "gstreamer1 gstreamer1-plugins-base-tools",
|
||||
_ => "gstreamer + tools",
|
||||
@@ -98,7 +100,9 @@ fn install_hint_for_bin(bin: &str) -> String {
|
||||
_ => "pulseaudio-utils (provides `pactl`)",
|
||||
},
|
||||
"xwininfo" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "xorg-xwininfo",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"xorg-xwininfo"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "x11-utils",
|
||||
Some("fedora" | "nobara") => "xorg-x11-utils",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "xwininfo",
|
||||
@@ -113,56 +117,74 @@ 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" | "artix" | "garuda") => "gst-plugin-pipewire",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"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",
|
||||
},
|
||||
"vah264enc" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gst-plugin-va",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gst-plugin-va"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-plugins-bad",
|
||||
Some("fedora" | "nobara") => "gstreamer1-plugins-bad-free",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "gstreamer-plugins-bad",
|
||||
_ => "the GStreamer VA-API plugin (requires an H.264-capable GPU; almost all modern GPUs)",
|
||||
_ => {
|
||||
"the GStreamer VA-API plugin (requires an H.264-capable GPU; almost all modern GPUs)"
|
||||
}
|
||||
},
|
||||
"x264enc" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gst-plugins-ugly",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gst-plugins-ugly"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-plugins-ugly",
|
||||
Some("fedora" | "nobara") => "gstreamer1-plugins-ugly",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "gstreamer-plugins-ugly",
|
||||
_ => "the GStreamer x264 plugin (plugins-ugly)",
|
||||
},
|
||||
"ximagesrc" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gst-plugins-good",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gst-plugins-good"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-plugins-good",
|
||||
Some("fedora" | "nobara") => "gstreamer1-plugins-good",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "gstreamer-plugins-good",
|
||||
_ => "the GStreamer X11 plugin (plugins-good)",
|
||||
},
|
||||
"videoscale" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gst-plugins-base",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gst-plugins-base"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-plugins-base",
|
||||
Some("fedora" | "nobara") => "gstreamer1-plugins-base",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "gstreamer-plugins-base",
|
||||
_ => "the GStreamer plugins-base set",
|
||||
},
|
||||
"h264parse" | "mpegtsmux" | "aacparse" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gst-plugins-bad",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gst-plugins-bad"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-plugins-bad",
|
||||
Some("fedora" | "nobara") => "gstreamer1-plugins-bad-free",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "gstreamer-plugins-bad",
|
||||
_ => "the GStreamer plugins-bad set",
|
||||
},
|
||||
"pulsesrc" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gst-plugins-good",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gst-plugins-good"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-pulseaudio",
|
||||
Some("fedora" | "nobara") => "gstreamer1-plugins-good",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "gstreamer-plugins-good",
|
||||
_ => "the GStreamer PulseAudio plugin",
|
||||
},
|
||||
"avenc_aac" => match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => "gst-libav",
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
"gst-libav"
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => "gstreamer1.0-libav",
|
||||
Some("fedora" | "nobara") => "gstreamer1-libav",
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => "gstreamer-libav",
|
||||
@@ -175,10 +197,14 @@ fn install_hint_for_gst_element(name: &str) -> String {
|
||||
|
||||
fn install_command(distro: &Option<String>, pkg: &str) -> String {
|
||||
let cmd = match distro.as_deref() {
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => format!("sudo pacman -S {pkg}"),
|
||||
Some("arch" | "cachyos" | "manjaro" | "endeavouros" | "artix" | "garuda") => {
|
||||
format!("sudo pacman -S {pkg}")
|
||||
}
|
||||
Some("debian" | "ubuntu" | "pop" | "linuxmint") => format!("sudo apt install {pkg}"),
|
||||
Some("fedora" | "nobara") => format!("sudo dnf install {pkg}"),
|
||||
Some("opensuse" | "opensuse-tumbleweed" | "opensuse-leap") => format!("sudo zypper install {pkg}"),
|
||||
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}")
|
||||
|
||||
+12
-4
@@ -261,12 +261,20 @@ mod tests {
|
||||
#[test]
|
||||
fn capture_state_round_trips() {
|
||||
assert!(matches!(
|
||||
parse(Event::Capture { state: EmitState::Started }),
|
||||
ChildEvent::Capture { state: CaptureState::Started }
|
||||
parse(Event::Capture {
|
||||
state: EmitState::Started
|
||||
}),
|
||||
ChildEvent::Capture {
|
||||
state: CaptureState::Started
|
||||
}
|
||||
));
|
||||
assert!(matches!(
|
||||
parse(Event::Capture { state: EmitState::Stopped }),
|
||||
ChildEvent::Capture { state: CaptureState::Stopped }
|
||||
parse(Event::Capture {
|
||||
state: EmitState::Stopped
|
||||
}),
|
||||
ChildEvent::Capture {
|
||||
state: CaptureState::Stopped
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
+23
-19
@@ -52,9 +52,8 @@ impl Routing {
|
||||
let pid = std::process::id();
|
||||
let sink_name = format!("pixelpass_capture_{pid}");
|
||||
|
||||
let sink_module =
|
||||
load_module(&["module-null-sink", &format!("sink_name={sink_name}")])
|
||||
.context("failed to load module-null-sink")?;
|
||||
let sink_module = load_module(&["module-null-sink", &format!("sink_name={sink_name}")])
|
||||
.context("failed to load module-null-sink")?;
|
||||
|
||||
// 20ms loopback latency keeps the mirrored audio tight; pactl's
|
||||
// default of 200ms is enough to be perceptible.
|
||||
@@ -205,7 +204,9 @@ fn parse_sink_inputs(stdout: &[u8]) -> Result<Vec<App>> {
|
||||
serde_json::from_slice(stdout).context("pactl returned unparseable JSON")?;
|
||||
let mut counts: BTreeMap<String, u32> = BTreeMap::new();
|
||||
for entry in entries {
|
||||
let Some(name) = entry.properties.application_name else { continue };
|
||||
let Some(name) = entry.properties.application_name else {
|
||||
continue;
|
||||
};
|
||||
let trimmed = name.trim();
|
||||
if trimmed.is_empty() {
|
||||
continue;
|
||||
@@ -359,16 +360,14 @@ fn run_router(
|
||||
) -> Result<()> {
|
||||
use pipewire::{self as pw, types::ObjectType};
|
||||
|
||||
let main_loop = pw::main_loop::MainLoopRc::new(None)
|
||||
.context("pw main loop construction failed")?;
|
||||
let context = pw::context::ContextRc::new(&main_loop, None)
|
||||
.context("pw context construction failed")?;
|
||||
let main_loop =
|
||||
pw::main_loop::MainLoopRc::new(None).context("pw main loop construction failed")?;
|
||||
let context =
|
||||
pw::context::ContextRc::new(&main_loop, None).context("pw context construction failed")?;
|
||||
let core = context
|
||||
.connect_rc(None)
|
||||
.context("pw core connect failed (is the daemon running?)")?;
|
||||
let registry = core
|
||||
.get_registry_rc()
|
||||
.context("pw get_registry failed")?;
|
||||
let registry = core.get_registry_rc().context("pw get_registry failed")?;
|
||||
|
||||
let state = Rc::new(RefCell::new(RouterState {
|
||||
sink_serial: None,
|
||||
@@ -409,20 +408,21 @@ fn run_router(
|
||||
let _reg_listener = registry
|
||||
.add_listener_local()
|
||||
.global(move |obj| {
|
||||
let Some(reg) = registry_weak.upgrade() else { return };
|
||||
let Some(reg) = registry_weak.upgrade() else {
|
||||
return;
|
||||
};
|
||||
match obj.type_ {
|
||||
ObjectType::Node => {
|
||||
let Some(props) = obj.props.as_ref() else { return };
|
||||
let Some(props) = obj.props.as_ref() else {
|
||||
return;
|
||||
};
|
||||
if props.get("node.name") == Some(sink_name_owned.as_str()) {
|
||||
if let Some(serial) = props
|
||||
.get("object.serial")
|
||||
.and_then(|s| s.parse::<u32>().ok())
|
||||
{
|
||||
state_for_reg.borrow_mut().sink_serial = Some(serial);
|
||||
tracing::info!(
|
||||
serial,
|
||||
"audio routing: pixelpass sink registered"
|
||||
);
|
||||
tracing::info!(serial, "audio routing: pixelpass sink registered");
|
||||
try_flush(&state_for_reg, &event_tx_for_reg);
|
||||
}
|
||||
return;
|
||||
@@ -430,7 +430,9 @@ fn run_router(
|
||||
if props.get("media.class") != Some("Stream/Output/Audio") {
|
||||
return;
|
||||
}
|
||||
let Some(app) = props.get("application.name") else { return };
|
||||
let Some(app) = props.get("application.name") else {
|
||||
return;
|
||||
};
|
||||
if !app.eq_ignore_ascii_case(&filter_lower) {
|
||||
return;
|
||||
}
|
||||
@@ -443,7 +445,9 @@ fn run_router(
|
||||
try_flush(&state_for_reg, &event_tx_for_reg);
|
||||
}
|
||||
ObjectType::Metadata => {
|
||||
let Some(props) = obj.props.as_ref() else { return };
|
||||
let Some(props) = obj.props.as_ref() else {
|
||||
return;
|
||||
};
|
||||
if props.get("metadata.name") != Some("default") {
|
||||
return;
|
||||
}
|
||||
|
||||
+34
-7
@@ -256,7 +256,9 @@ fn spawn_kick_listener(sup_tx: mpsc::Sender<SupervisorMsg>) {
|
||||
let Some(id) = line.trim().strip_prefix("kick ") else {
|
||||
continue;
|
||||
};
|
||||
let msg = SupervisorMsg::KickViewer { id: id.trim().to_string() };
|
||||
let msg = SupervisorMsg::KickViewer {
|
||||
id: id.trim().to_string(),
|
||||
};
|
||||
// blocking_send is valid here: this is a plain thread, not inside
|
||||
// the tokio runtime. An Err means the supervisor closed — stop.
|
||||
if sup_tx.blocking_send(msg).is_err() {
|
||||
@@ -315,7 +317,11 @@ async fn supervise(
|
||||
viewers.insert(id.clone(), cancel);
|
||||
let active = viewers.len() as u32;
|
||||
let _ = reply.send(Ok(port));
|
||||
output::emit(output::Event::ViewerJoined { id: &id, active, max: max_viewers });
|
||||
output::emit(output::Event::ViewerJoined {
|
||||
id: &id,
|
||||
active,
|
||||
max: max_viewers,
|
||||
});
|
||||
tracing::info!(active, cap = max_viewers, "viewer joined");
|
||||
}
|
||||
SupervisorMsg::RemoveViewer { id } => {
|
||||
@@ -325,7 +331,11 @@ async fn supervise(
|
||||
continue;
|
||||
}
|
||||
let active = viewers.len() as u32;
|
||||
output::emit(output::Event::ViewerLeft { id: &id, active, max: max_viewers });
|
||||
output::emit(output::Event::ViewerLeft {
|
||||
id: &id,
|
||||
active,
|
||||
max: max_viewers,
|
||||
});
|
||||
tracing::info!(active, cap = max_viewers, "viewer left");
|
||||
if active == 0
|
||||
&& let Some(h) = handle.take()
|
||||
@@ -372,10 +382,25 @@ fn print_host_banner(
|
||||
eprintln!("┌─ PixelPass · host ─────────────────────────────────────────");
|
||||
eprintln!("│ display server : {display:?}");
|
||||
eprintln!("│ capture : {}", capture_summary(opts));
|
||||
eprintln!("│ quality : {} — {}", quality.label, quality.dimensions_summary());
|
||||
eprintln!(
|
||||
"│ quality : {} — {}",
|
||||
quality.label,
|
||||
quality.dimensions_summary()
|
||||
);
|
||||
eprintln!("│ ({})", quality.note);
|
||||
eprintln!("│ hw encode : {}", if opts.no_hwencode { "off (software x264)" } else { "on (VAAPI H.264)" });
|
||||
eprintln!("│ max viewers : {} ({})", resolution.value, resolution.source.label());
|
||||
eprintln!(
|
||||
"│ hw encode : {}",
|
||||
if opts.no_hwencode {
|
||||
"off (software x264)"
|
||||
} else {
|
||||
"on (VAAPI H.264)"
|
||||
}
|
||||
);
|
||||
eprintln!(
|
||||
"│ max viewers : {} ({})",
|
||||
resolution.value,
|
||||
resolution.source.label()
|
||||
);
|
||||
eprintln!("│");
|
||||
if clipboard_ok {
|
||||
eprintln!("│ Your share code has been copied to your clipboard.");
|
||||
@@ -439,7 +464,9 @@ fn resolve_max_viewers(opts: &HostOpts, effective_bitrate: u32) -> MaxViewersRes
|
||||
let n = bandwidth::recommended_max_viewers(upstream, effective_bitrate);
|
||||
return MaxViewersResolution {
|
||||
value: n,
|
||||
source: MaxViewersSource::BandwidthMeasurement { safe_mbps: upstream },
|
||||
source: MaxViewersSource::BandwidthMeasurement {
|
||||
safe_mbps: upstream,
|
||||
},
|
||||
};
|
||||
}
|
||||
MaxViewersResolution {
|
||||
|
||||
@@ -308,7 +308,9 @@ async fn default_audio_monitor() -> Result<String> {
|
||||
.arg("get-default-sink")
|
||||
.output()
|
||||
.await
|
||||
.context("failed to run `pactl get-default-sink` (install pulseaudio-utils or pipewire-pulse)")?;
|
||||
.context(
|
||||
"failed to run `pactl get-default-sink` (install pulseaudio-utils or pipewire-pulse)",
|
||||
)?;
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"pactl get-default-sink failed: {}",
|
||||
|
||||
+31
-7
@@ -27,10 +27,26 @@ impl Quality {
|
||||
/// values and resolves to one of the others at runtime (see [`resolve_auto`]).
|
||||
fn preset(self) -> Option<Preset> {
|
||||
let p = match self {
|
||||
Quality::Source => Preset { max_height: None, bitrate: 6000, framerate: 30 },
|
||||
Quality::High => Preset { max_height: Some(1080), bitrate: 4000, framerate: 30 },
|
||||
Quality::Medium => Preset { max_height: Some(720), bitrate: 2500, framerate: 30 },
|
||||
Quality::Low => Preset { max_height: Some(480), bitrate: 1000, framerate: 30 },
|
||||
Quality::Source => Preset {
|
||||
max_height: None,
|
||||
bitrate: 6000,
|
||||
framerate: 30,
|
||||
},
|
||||
Quality::High => Preset {
|
||||
max_height: Some(1080),
|
||||
bitrate: 4000,
|
||||
framerate: 30,
|
||||
},
|
||||
Quality::Medium => Preset {
|
||||
max_height: Some(720),
|
||||
bitrate: 2500,
|
||||
framerate: 30,
|
||||
},
|
||||
Quality::Low => Preset {
|
||||
max_height: Some(480),
|
||||
bitrate: 1000,
|
||||
framerate: 30,
|
||||
},
|
||||
Quality::Auto => return None,
|
||||
};
|
||||
Some(p)
|
||||
@@ -49,7 +65,12 @@ impl Quality {
|
||||
|
||||
/// Fixed presets in descending quality order — Auto walks this to find the
|
||||
/// best one whose per-viewer bitrate fits the measured upstream budget.
|
||||
const AUTO_LADDER: [Quality; 4] = [Quality::Source, Quality::High, Quality::Medium, Quality::Low];
|
||||
const AUTO_LADDER: [Quality; 4] = [
|
||||
Quality::Source,
|
||||
Quality::High,
|
||||
Quality::Medium,
|
||||
Quality::Low,
|
||||
];
|
||||
|
||||
/// Auto's fallback when there is no usable bandwidth measurement.
|
||||
const AUTO_FALLBACK: Quality = Quality::Medium;
|
||||
@@ -146,7 +167,9 @@ fn resolve_auto(safe_mbps: Option<f64>, sizing_viewers: u32) -> (Preset, String,
|
||||
(
|
||||
preset,
|
||||
format!("Auto → {}", chosen.name()),
|
||||
format!("auto: {safe_mbps:.1} Mbps safe ÷ {n} viewer(s) = {budget_mbps:.1} Mbps each"),
|
||||
format!(
|
||||
"auto: {safe_mbps:.1} Mbps safe ÷ {n} viewer(s) = {budget_mbps:.1} Mbps each"
|
||||
),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
@@ -154,7 +177,8 @@ fn resolve_auto(safe_mbps: Option<f64>, sizing_viewers: u32) -> (Preset, String,
|
||||
(
|
||||
preset,
|
||||
format!("Auto → {}", AUTO_FALLBACK.name()),
|
||||
"auto fallback — no bandwidth measurement (run `pixelpass --reconfigure`)".to_string(),
|
||||
"auto fallback — no bandwidth measurement (run `pixelpass --reconfigure`)"
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+15
-5
@@ -26,7 +26,11 @@ pub async fn start(opts: &HostOpts, quality: &EffectiveQuality) -> Result<Captur
|
||||
.context("could not reach the xdg-desktop-portal ScreenCast interface")?;
|
||||
let session = proxy.create_session().await?;
|
||||
|
||||
let source = if opts.window { SourceType::Window } else { SourceType::Monitor };
|
||||
let source = if opts.window {
|
||||
SourceType::Window
|
||||
} else {
|
||||
SourceType::Monitor
|
||||
};
|
||||
proxy
|
||||
.select_sources(
|
||||
&session,
|
||||
@@ -70,10 +74,16 @@ pub async fn start(opts: &HostOpts, quality: &EffectiveQuality) -> Result<Captur
|
||||
"do-timestamp=true".to_string(),
|
||||
];
|
||||
|
||||
pipeline::spawn(opts, quality, Some((w as u32, h as u32)), source_args, move || {
|
||||
// Parent no longer needs the pipewire fd — gst inherited its own copy.
|
||||
let _ = close(raw_fd);
|
||||
})
|
||||
pipeline::spawn(
|
||||
opts,
|
||||
quality,
|
||||
Some((w as u32, h as u32)),
|
||||
source_args,
|
||||
move || {
|
||||
// Parent no longer needs the pipewire fd — gst inherited its own copy.
|
||||
let _ = close(raw_fd);
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -180,10 +180,7 @@ async fn preflight_if_needed(theme: &ColorfulTheme) {
|
||||
eprintln!();
|
||||
let Ok(choice) = Select::with_theme(theme)
|
||||
.with_prompt("Last bandwidth test failed. Try again?")
|
||||
.items([
|
||||
"Yes — retry now",
|
||||
"No — use the conservative default",
|
||||
])
|
||||
.items(["Yes — retry now", "No — use the conservative default"])
|
||||
.default(0)
|
||||
.interact()
|
||||
else {
|
||||
@@ -344,5 +341,9 @@ pub fn prompt_player() -> Result<Player> {
|
||||
.items(["mpv", "VLC"])
|
||||
.default(0)
|
||||
.interact()?;
|
||||
Ok(if choice == 0 { Player::Mpv } else { Player::Vlc })
|
||||
Ok(if choice == 0 {
|
||||
Player::Mpv
|
||||
} else {
|
||||
Player::Vlc
|
||||
})
|
||||
}
|
||||
|
||||
+5
-1
@@ -73,7 +73,11 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
fn init_tracing(verbose: bool) {
|
||||
let default = if verbose { "pixelpass=trace,iroh=info" } else { "pixelpass=info,iroh=warn" };
|
||||
let default = if verbose {
|
||||
"pixelpass=trace,iroh=info"
|
||||
} else {
|
||||
"pixelpass=info,iroh=warn"
|
||||
};
|
||||
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(default));
|
||||
// Tracing MUST write to stderr. `tracing_subscriber::fmt()` defaults its
|
||||
// writer to stdout, but with `--output json` stdout carries the JSON event
|
||||
|
||||
+4
-4
@@ -110,9 +110,7 @@ pub async fn run() -> Result<()> {
|
||||
}
|
||||
|
||||
if live_skipped > 0 {
|
||||
println!(
|
||||
"[pixelpass] --repair: left {live_skipped} live pixelpass host(s) alone."
|
||||
);
|
||||
println!("[pixelpass] --repair: left {live_skipped} live pixelpass host(s) alone.");
|
||||
}
|
||||
|
||||
if failed > 0 {
|
||||
@@ -154,7 +152,9 @@ fn list_modules() -> Result<Vec<Module>> {
|
||||
for line in text.lines() {
|
||||
let mut parts = line.splitn(4, '\t');
|
||||
let Some(id_str) = parts.next() else { continue };
|
||||
let Ok(id) = id_str.parse::<u32>() else { continue };
|
||||
let Ok(id) = id_str.parse::<u32>() else {
|
||||
continue;
|
||||
};
|
||||
let Some(name) = parts.next() else { continue };
|
||||
let args = parts.next().unwrap_or("").to_string();
|
||||
modules.push(Module {
|
||||
|
||||
Reference in New Issue
Block a user