Compare commits
3
Commits
0a253bd919
...
74b4101d4f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74b4101d4f | ||
|
|
6e4d30bfa9 | ||
|
|
15766834f1 |
@@ -27,7 +27,6 @@ Not yet working:
|
|||||||
- X11 capture (stubbed, returns an error)
|
- X11 capture (stubbed, returns an error)
|
||||||
- Per-app audio routing (`--app <name>` is a flag stub)
|
- Per-app audio routing (`--app <name>` is a flag stub)
|
||||||
- Multi-viewer (single viewer per host by design right now)
|
- Multi-viewer (single viewer per host by design right now)
|
||||||
- VLC client renders the H.264 stream as a green screen — mpv works
|
|
||||||
- `--repair` (PipeWire orphan cleanup) is a stub
|
- `--repair` (PipeWire orphan cleanup) is a stub
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
@@ -68,15 +67,26 @@ pixelpass <ticket>
|
|||||||
- `gstreamer`, `gst-plugins-base`, `gst-plugins-good`, `gst-plugins-bad`,
|
- `gstreamer`, `gst-plugins-base`, `gst-plugins-good`, `gst-plugins-bad`,
|
||||||
`gst-plugins-ugly`, `gst-libav`, `gst-plugin-va`, `gst-plugin-pipewire`
|
`gst-plugins-ugly`, `gst-libav`, `gst-plugin-va`, `gst-plugin-pipewire`
|
||||||
- A player: `mpv` (recommended) or `vlc`
|
- A player: `mpv` (recommended) or `vlc`
|
||||||
|
- If you use VLC, two split plugin packages are also needed on Arch-family
|
||||||
|
distros — the base `vlc` package does not pull them in:
|
||||||
|
- `vlc-plugin-dvb` — provides the MPEG-TS demuxer (`libts_plugin.so`).
|
||||||
|
Without it, VLC can't parse the container.
|
||||||
|
- `vlc-plugin-ffmpeg` — provides the H.264 decoder
|
||||||
|
(`libavcodec_plugin.so`). Without it, VLC parses the container,
|
||||||
|
identifies the codec as H.264, then errors with
|
||||||
|
`Codec h264 ... is not supported`.
|
||||||
|
mpv ships its own decoder stack and doesn't share either dependency.
|
||||||
- PipeWire (for screencast portal + audio capture)
|
- PipeWire (for screencast portal + audio capture)
|
||||||
|
|
||||||
On Arch / CachyOS:
|
On Arch / CachyOS / EndeavourOS:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo pacman -S gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad \
|
sudo pacman -S gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad \
|
||||||
gst-plugins-ugly gst-libav gst-plugin-va gst-plugin-pipewire \
|
gst-plugins-ugly gst-libav gst-plugin-va gst-plugin-pipewire \
|
||||||
libva-utils mpv
|
libva-utils mpv
|
||||||
# plus your GPU's VAAPI driver
|
# plus your GPU's VAAPI driver
|
||||||
|
# plus, if you want to use VLC instead of mpv:
|
||||||
|
sudo pacman -S vlc vlc-plugin-dvb vlc-plugin-ffmpeg
|
||||||
```
|
```
|
||||||
|
|
||||||
If the viewer is running on battery, set the CPU governor to performance
|
If the viewer is running on battery, set the CPU governor to performance
|
||||||
@@ -146,9 +156,11 @@ relay path otherwise. Both have been verified end-to-end.
|
|||||||
|
|
||||||
## Known limitations and gotchas
|
## Known limitations and gotchas
|
||||||
|
|
||||||
- **VLC shows a green screen** against a stream mpv handles correctly.
|
- **VLC needs `vlc-plugin-dvb` and `vlc-plugin-ffmpeg`** on Arch-family
|
||||||
Likely a VLC-specific PCR / PMT / alignment expectation; not yet
|
distros — the base `vlc` package doesn't pull these in, and missing
|
||||||
diagnosed. Use mpv until this is fixed.
|
either one breaks playback (the first kills the demuxer, the second
|
||||||
|
kills the H.264 decoder). pixelpass warns at player-launch time if
|
||||||
|
either plugin isn't on disk. mpv doesn't share these dependencies.
|
||||||
- **Audio echo** if the host plays the stream through speakers and
|
- **Audio echo** if the host plays the stream through speakers and
|
||||||
captures system audio — expected, the mic / monitor picks up the
|
captures system audio — expected, the mic / monitor picks up the
|
||||||
playback. Headphones bypass it.
|
playback. Headphones bypass it.
|
||||||
|
|||||||
+1
-8
@@ -225,15 +225,8 @@ async fn serve_capture(listener: TcpListener, mut gst_stdout: ChildStdout) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content-Type intentionally application/octet-stream, not video/mp2t.
|
|
||||||
// VLC eagerly maps video/mp2t to demux="ts" and bypasses content
|
|
||||||
// probing; its ts demuxer's Open then fails on the live HTTP stream
|
|
||||||
// with "no demux modules matched" and the input never opens. With a
|
|
||||||
// non-video Content-Type, VLC falls back to byte-probing, which finds
|
|
||||||
// the TS sync pattern and opens cleanly. mpv probes regardless of
|
|
||||||
// Content-Type, so it's unaffected.
|
|
||||||
const RESPONSE: &[u8] = b"HTTP/1.1 200 OK\r\n\
|
const RESPONSE: &[u8] = b"HTTP/1.1 200 OK\r\n\
|
||||||
Content-Type: application/octet-stream\r\n\
|
Content-Type: video/mp2t\r\n\
|
||||||
Cache-Control: no-cache, no-store\r\n\
|
Cache-Control: no-cache, no-store\r\n\
|
||||||
Connection: close\r\n\
|
Connection: close\r\n\
|
||||||
\r\n";
|
\r\n";
|
||||||
|
|||||||
+42
-4
@@ -68,14 +68,52 @@ impl Player {
|
|||||||
url,
|
url,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Player::Vlc => crate::common::process::spawn_detached(
|
Player::Vlc => {
|
||||||
"vlc",
|
warn_if_vlc_plugins_missing();
|
||||||
&["--network-caching=200", "--live-caching=200", url],
|
crate::common::process::spawn_detached(
|
||||||
),
|
"vlc",
|
||||||
|
&["--network-caching=200", "--live-caching=200", url],
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On Arch-family distros, the base `vlc` package omits two plugins
|
||||||
|
// pixelpass needs: the MPEG-TS demuxer (`vlc-plugin-dvb`) and the
|
||||||
|
// libavcodec-based H.264 decoder (`vlc-plugin-ffmpeg`). Missing either
|
||||||
|
// produces a confusing error chain — warn at launch.
|
||||||
|
fn warn_if_vlc_plugins_missing() {
|
||||||
|
const REQUIRED: &[(&str, &str)] = &[
|
||||||
|
(
|
||||||
|
"/usr/lib/vlc/plugins/demux/libts_plugin.so",
|
||||||
|
"vlc-plugin-dvb",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"/usr/lib/vlc/plugins/codec/libavcodec_plugin.so",
|
||||||
|
"vlc-plugin-ffmpeg",
|
||||||
|
),
|
||||||
|
];
|
||||||
|
let missing: Vec<&(&str, &str)> = REQUIRED
|
||||||
|
.iter()
|
||||||
|
.filter(|(p, _)| !std::path::Path::new(p).exists())
|
||||||
|
.collect();
|
||||||
|
if missing.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eprintln!();
|
||||||
|
eprintln!("Warning: VLC is missing plugins pixelpass needs:");
|
||||||
|
for (path, pkg) in &missing {
|
||||||
|
eprintln!(" - {path} (install `{pkg}`)");
|
||||||
|
}
|
||||||
|
eprintln!("On Arch / CachyOS / EndeavourOS: `sudo pacman -S {}`.", {
|
||||||
|
let names: Vec<&str> = missing.iter().map(|(_, p)| *p).collect();
|
||||||
|
names.join(" ")
|
||||||
|
});
|
||||||
|
eprintln!("mpv is unaffected.");
|
||||||
|
eprintln!();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn prompt_player() -> Result<Player> {
|
pub fn prompt_player() -> Result<Player> {
|
||||||
let theme = ColorfulTheme::default();
|
let theme = ColorfulTheme::default();
|
||||||
let choice = Select::with_theme(&theme)
|
let choice = Select::with_theme(&theme)
|
||||||
|
|||||||
Reference in New Issue
Block a user