@urun-sh/core 0.2.51 → 0.2.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +27 -0
- package/dist/{chunk-USB2YC4V.mjs → chunk-4IG3DT7P.mjs} +2 -2
- package/dist/{chunk-2MG7ASFV.mjs → chunk-DN7HQ3WI.mjs} +5 -5
- package/dist/index.browser.d.mts +2 -2
- package/dist/index.browser.d.ts +2 -2
- package/dist/index.browser.js +2 -2
- package/dist/index.browser.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/dist/index.mjs +1 -1
- package/dist/internal.browser.d.mts +1 -1
- package/dist/internal.browser.d.ts +1 -1
- package/dist/internal.browser.js +2 -2
- package/dist/internal.browser.mjs +1 -1
- package/dist/internal.d.mts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +3 -3
- package/dist/internal.mjs +1 -1
- package/dist/{stream-data-DLrBWs2N.d.mts → stream-data-CcujVuq3.d.mts} +16 -1
- package/dist/{stream-data-DLrBWs2N.d.ts → stream-data-CcujVuq3.d.ts} +16 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- **Audio receiver jitter-buffer cap** (`AudioPlayoutOptions`, new export). A
|
|
6
|
+
muxed A/V egress reaches the browser as TWO RTP tracks with independent
|
|
7
|
+
receive buffers, and the receiver integrates delivery gaps asymmetrically:
|
|
8
|
+
video renders on arrival (a gap freezes, then drops/fast-forwards — no
|
|
9
|
+
standing delay), while audio's NetEq conceals every gap and plays the late
|
|
10
|
+
real audio AFTER the concealment, so gaps ACCUMULATE standing playout delay.
|
|
11
|
+
The RTCP-SR sync group is the only payback mechanism, and where an SFU
|
|
12
|
+
re-mints sender reports per consumer (each anchored at its own forwarding
|
|
13
|
+
instant, audio's refreshed 5x less often) it structurally cannot pay it back
|
|
14
|
+
— liveavatar measured 2.2–2.7s of standing audio delay behind video.
|
|
15
|
+
|
|
16
|
+
`_onConsume` now caps every inbound AUDIO consumer through the receiver's own
|
|
17
|
+
W3C knob: `RTCRtpReceiver.jitterBufferTarget` (milliseconds) plus the legacy
|
|
18
|
+
Chromium `playoutDelayHint` (seconds) where an engine still exposes it, so
|
|
19
|
+
either vintage is capped. Default **300ms**, tunable via
|
|
20
|
+
`AppOptions.audioPlayout.jitterBufferTargetMs` (a constructor option by
|
|
21
|
+
design — never an env var); `<= 0` sets no target at all. **Video receivers
|
|
22
|
+
are never touched** — video renders on arrival and must not be delayed.
|
|
23
|
+
Nothing bespoke: no resampling, no `playbackRate` nudging, no NetEq shadow.
|
|
24
|
+
|
|
25
|
+
Two new diagnostics make the edges observable instead of silent:
|
|
26
|
+
`audio-jitter-buffer-unsupported` (`debug`) when an engine exposes NEITHER
|
|
27
|
+
property — Firefox and Safari today, a receiver capability the SDK cannot
|
|
28
|
+
emulate, so the cap is inert there — and `audio-jitter-buffer-invalid`
|
|
29
|
+
(`warning`) for a non-finite configured target, which would otherwise slip
|
|
30
|
+
past the `<= 0` check and throw on assignment to the WebIDL double, aborting
|
|
31
|
+
the consume before `resumeConsumer`.
|
|
32
|
+
|
|
5
33
|
- **`SessionDiagnostic.level` gains `'debug'`** (union widened: an exhaustive
|
|
6
34
|
`switch`/`Record` over the level needs a new arm). `debug` diagnostics mirror
|
|
7
35
|
to `console.debug` — hidden at the browser console's default verbosity —
|
package/README.md
CHANGED
|
@@ -54,6 +54,33 @@ consumes the runtime's output. A second producer on the same name fails loud wit
|
|
|
54
54
|
media encode; the client only attaches the inbound `track` to a media element. Tracks arrive
|
|
55
55
|
asynchronously — subscribe with `.on('track', …)`.
|
|
56
56
|
|
|
57
|
+
## Muxed A/V arrives as two tracks — play them through one element
|
|
58
|
+
|
|
59
|
+
A runtime that egresses `ctx.stream("av", video_codec=…, audio_codec=…)` puts TWO RTP tracks on
|
|
60
|
+
the wire. Put both into ONE `MediaStream` on ONE media element so the browser's native A/V sync
|
|
61
|
+
machinery owns the alignment (`@urun-sh/react`'s `<Video stream="av" muted={false} />` is that
|
|
62
|
+
shape, prebaked):
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const stream = new MediaStream()
|
|
66
|
+
element.srcObject = stream
|
|
67
|
+
session.stream('video').on('track', (t) => t && stream.addTrack(t))
|
|
68
|
+
session.stream('audio').on('track', (t) => t && stream.addTrack(t))
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Two separate elements give the browser two independently-buffered playout paths with nothing
|
|
72
|
+
aligning them: the video track renders on arrival (a delivery gap freezes, then drops — no
|
|
73
|
+
standing delay), while the audio track's jitter buffer conceals each gap and plays the late
|
|
74
|
+
audio after it, so gaps ACCUMULATE into standing playout delay. RTCP sender reports are the
|
|
75
|
+
only payback mechanism, and an SFU that re-mints them per track weakens it.
|
|
76
|
+
|
|
77
|
+
The SDK therefore also caps every inbound AUDIO receiver's jitter buffer at 300 ms
|
|
78
|
+
(`RTCRtpReceiver.jitterBufferTarget`, plus the legacy `playoutDelayHint` where present), which
|
|
79
|
+
bounds that accumulation regardless of sender-report quality. Retune it with
|
|
80
|
+
`App(appId, { audioPlayout: { jitterBufferTargetMs: 500 } })`; `<= 0` sets no target at all.
|
|
81
|
+
Engines exposing neither property (Firefox, Safari today) are unaffected and emit an
|
|
82
|
+
`audio-jitter-buffer-unsupported` diagnostic so the gap is visible rather than silent.
|
|
83
|
+
|
|
57
84
|
## The control doc is the reactive desired-state surface
|
|
58
85
|
|
|
59
86
|
The client does NOT call an imperative `start/update/stop`. It writes `desired.*` keys into a
|