fix(screenshare): keep low-latency playback live
This commit is contained in:
@@ -4,6 +4,13 @@ All notable changes to PeerSpeak are documented here.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- **Low-latency screen sharing stays near the live edge again.** mpv's
|
||||
timestamp pacing could let stale frames accumulate across the reliable
|
||||
PixelPass transport until a share was 7–10 seconds behind. Low-latency mode
|
||||
now presents decoded frames immediately; Smooth mode retains timestamp pacing
|
||||
when keeping shared-video audio and video synchronized matters more.
|
||||
|
||||
## [0.6.4] — 2026-07-18
|
||||
|
||||
### Added
|
||||
|
||||
+14
-8
@@ -607,14 +607,13 @@ fn event_for_log(ev: &PixelpassEvent) -> String {
|
||||
/// player is reaped in a background task so it doesn't linger as a zombie when
|
||||
/// its window closes.
|
||||
///
|
||||
/// The flags keep latency low while preserving A/V sync. We deliberately do
|
||||
/// NOT pass mpv's `--untimed`: that displays each video frame the instant it
|
||||
/// decodes, ignoring audio timestamps, which makes a shared *video* drift
|
||||
/// progressively out of sync with its audio. Pacing to the audio clock costs a
|
||||
/// little latency (negligible for pointing at a desktop) and keeps a shared
|
||||
/// video in sync. We also leave hwdec at the `low-latency` default (software
|
||||
/// decode): forcing `--hwdec=auto` froze some viewers on frame 1 while audio
|
||||
/// kept playing.
|
||||
/// The buffering posture chooses the latency/A/V-sync tradeoff. Low latency
|
||||
/// passes mpv's `--untimed`, displaying frames as soon as they decode so a live
|
||||
/// share cannot accumulate several seconds in the reliable QUIC/TCP/player
|
||||
/// buffer chain. Smooth leaves timestamp pacing enabled, which keeps a shared
|
||||
/// video's audio and video synchronized at the cost of extra live latency.
|
||||
/// Hardware decoding remains opt-in: forcing `--hwdec=auto` froze some viewers
|
||||
/// on frame 1 while audio kept playing.
|
||||
fn launch_player(url: &str, settings: &ScreenShareSettings) -> std::io::Result<()> {
|
||||
let mpv_args = mpv_args(settings);
|
||||
let vlc_args = vlc_args(settings);
|
||||
@@ -648,6 +647,12 @@ pub fn mpv_args(settings: &ScreenShareSettings) -> Vec<String> {
|
||||
match settings.buffering {
|
||||
ShareBuffering::LowLatency => {
|
||||
args.push("--profile=low-latency".to_string());
|
||||
// Pixelpass carries MPEG-TS through reliable ordered QUIC/TCP. If
|
||||
// mpv paces a live stream even slightly slower than capture, those
|
||||
// downstream buffers retain stale frames and latency grows into
|
||||
// seconds. Immediate presentation keeps this posture at the live
|
||||
// edge; Smooth deliberately retains timestamp pacing for A/V sync.
|
||||
args.push("--untimed".to_string());
|
||||
args.push("--audio-buffer=0.2".to_string());
|
||||
args.push("--demuxer-readahead-secs=0.5".to_string());
|
||||
}
|
||||
@@ -828,6 +833,7 @@ mod tests {
|
||||
mpv_args(&ScreenShareSettings::default()),
|
||||
vec![
|
||||
"--profile=low-latency",
|
||||
"--untimed",
|
||||
"--audio-buffer=0.2",
|
||||
"--demuxer-readahead-secs=0.5",
|
||||
"--demuxer-max-bytes=2M",
|
||||
|
||||
Reference in New Issue
Block a user