Skip to content

Commit 81c799c

Browse files
author
DatanoiseTV
committed
fix: larger audio burst + Ogg page-align fallback + SSE bandwidth rate
- Bandwidth counters in the /admin SSE feed were sending cumulative byte totals, which the dashboard formatted as MB/s (e.g. "636.9 MB/s inbound" on any server with traffic). Compute a per-tick rate from consecutive samples and send that. - Bump listener default burst 128 → 512 KiB, transcoder input burst 32 → 256 KiB, and the listener read chunk 4 → 64 KiB so short network stalls don't drain client caches. - Track 2048 Ogg page offsets (was 128) — with a 512 KiB burst the intended start landed beyond any tracked page, and the page-align fallback used LastPageOffset (near head), dropping the real burst to ~0 bytes. That was the "underrun every 4–5 s on reconnect". - Rework Subscribe Ogg page-align logic: pick the oldest tracked page >= intended start; if none, fall back to the oldest tracked page overall, then LastPageOffset, then raw burst offset.
1 parent 35b34b7 commit 81c799c

32 files changed

Lines changed: 142 additions & 85 deletions

relay/pipeline.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func NewVideoTrack(codec string, bufferSize int) *Track {
9090
Buffer: NewCircularBuffer(bufferSize),
9191
Started: time.Now(),
9292
Enabled: true,
93-
PageOffsets: make([]int64, 128),
93+
PageOffsets: make([]int64, 2048),
9494
},
9595
}
9696
}

relay/relay.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ func (r *Relay) GetOrCreateStreamSized(mount string, bufferSize int) *Stream {
106106
IsOggStream: false,
107107
Enabled: true,
108108
CurrentSong: "N/A",
109-
PageOffsets: make([]int64, 128), // Track last 128 Ogg pages
109+
// Track last 2048 Ogg pages so Subscribe can find a page-boundary
110+
// alignment anywhere in the buffer — 128 covered barely 3–5 s at
111+
// typical Opus framing and truncated the actual burst delivered to
112+
// listeners ("underrun every 4–5 s on reconnect").
113+
PageOffsets: make([]int64, 2048),
110114
Frames: NewFrameHub(),
111115
}
112116
r.Streams[mount] = s

relay/stream.go

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -389,22 +389,37 @@ func (s *Stream) Subscribe(id string, burstSize int) (int64, chan struct{}) {
389389
start = validStart
390390
}
391391

392-
// Find the best page boundary that is >= start and still valid
393-
bestAlign := s.LastPageOffset
394-
found := false
392+
// Prefer the oldest tracked page boundary that is still >= start and
393+
// within the valid buffer range — this maximises the burst delivered
394+
// to the listener. Falling back to LastPageOffset (newest page) used
395+
// to cap the burst at near-zero whenever PageOffsets didn't happen
396+
// to cover far enough back, which manifested as "client underrun
397+
// every few seconds on reconnect".
398+
bestAlign := int64(-1)
399+
oldestValid := int64(-1)
395400
for _, po := range s.PageOffsets {
396-
// Find the smallest PO that is >= start AND is still valid
397-
if po >= start && po >= validStart && po < bestAlign {
401+
if po < validStart || po == 0 {
402+
continue
403+
}
404+
if oldestValid < 0 || po < oldestValid {
405+
oldestValid = po
406+
}
407+
if po >= start && (bestAlign < 0 || po < bestAlign) {
398408
bestAlign = po
399-
found = true
400409
}
401410
}
402-
if found {
411+
switch {
412+
case bestAlign >= 0:
403413
start = bestAlign
404-
} else if bestAlign >= validStart && bestAlign > 0 {
405-
start = bestAlign
406-
} else {
407-
// No valid Ogg page boundaries found — fall back to burst-based offset
414+
case oldestValid >= 0:
415+
// Intended start is older than any tracked page — use the
416+
// oldest we have, which is still newer than the buffer tail.
417+
start = oldestValid
418+
case s.LastPageOffset >= validStart && s.LastPageOffset > 0:
419+
// Absolute last resort: at least align on the most recent page.
420+
start = s.LastPageOffset
421+
default:
422+
// Nothing tracked yet — fall back to burst-based offset.
408423
start = s.Buffer.Head - int64(burstSize)
409424
if start < validStart {
410425
start = validStart

relay/transcode.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ func (tm *TranscoderManager) performTranscode(ctx context.Context, inst *Transco
154154

155155
// 2. Subscribe to input
156156
id := fmt.Sprintf("transcoder-%s", inst.Config.Name)
157-
// We use a small burst to ensure the decoder gets enough data to start
158-
offset, signal := input.Subscribe(id, 32*1024)
157+
// Burst 256 KiB so the decoder has several seconds of data to initialise
158+
// even when the source bitrate is low — 32 KiB left strict Opus / FLAC
159+
// decoders short on bytes at startup, producing a noisy first packet.
160+
offset, signal := input.Subscribe(id, 256*1024)
159161
defer input.Unsubscribe(id)
160162

161163
// For live Ogg inputs, the subscribe offset lands mid-stream. The decoder

relay/webrtc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func (wm *WebRTCManager) HandleSourceOffer(mount string, offer webrtc.SessionDes
167167
stream.IsOggStream = true
168168
stream.SourceIP = "webrtc-source"
169169
// Reset page offsets so we don't sync to old pages from a previous session
170-
stream.PageOffsets = make([]int64, 128)
170+
stream.PageOffsets = make([]int64, 2048)
171171
stream.PageIndex = 0
172172
stream.OggHeaderOffset = headOffset
173173
stream.mu.Unlock()

server/frontend/dist/assets/EqBars-Db0aUDeL.js renamed to server/frontend/dist/assets/EqBars-BHt6JQsg.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/frontend/dist/assets/Nav-DumS6Cj2.js renamed to server/frontend/dist/assets/Nav-Cw59N480.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/frontend/dist/assets/StreamCard-BkWyhser.js renamed to server/frontend/dist/assets/StreamCard-B9_HyUix.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/frontend/dist/assets/VolumeKnob-BZ8bETDw.js renamed to server/frontend/dist/assets/VolumeKnob-DGr6sUgv.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)