55 "fmt"
66 "io"
77 "sort"
8+ "strings"
89 "sync"
910 "sync/atomic"
1011 "time"
@@ -69,6 +70,40 @@ func (cb *CircularBuffer) ReadAt(start int64, p []byte) (int, int64, bool) {
6970 return actual , start + int64 (actual ), skipped
7071}
7172
73+ // FindNextPageBoundary searches for the next "OggS" magic in the buffer starting from 'start'
74+ func (cb * CircularBuffer ) FindNextPageBoundary (start int64 ) int64 {
75+ cb .mu .RLock ()
76+ defer cb .mu .RUnlock ()
77+
78+ if start < cb .Head - cb .Size {
79+ start = cb .Head - cb .Size
80+ }
81+ if start >= cb .Head - 4 {
82+ return cb .Head
83+ }
84+
85+ for i := start ; i < cb .Head - 4 ; {
86+ pos := i % cb .Size
87+ n := int64 (4096 ) // Search window
88+ if i + n > cb .Head {
89+ n = cb .Head - i
90+ }
91+ if pos + n > cb .Size {
92+ n = cb .Size - pos
93+ }
94+
95+ // Look for OggS in this segment
96+ data := cb .Data [pos : pos + n ]
97+ for j := 0 ; j <= len (data )- 4 ; j ++ {
98+ if data [j ] == 'O' && data [j + 1 ] == 'g' && data [j + 2 ] == 'g' && data [j + 3 ] == 'S' {
99+ return i + int64 (j )
100+ }
101+ }
102+ i += n - 3 // Overlap by 3 bytes to catch split magic
103+ }
104+ return start
105+ }
106+
72107// Stream represents a single mount point (e.g., /stream)
73108type Stream struct {
74109 MountName string
@@ -93,6 +128,7 @@ type Stream struct {
93128
94129 OggHead []byte // Store Ogg headers for Opus/Ogg streams
95130 OggHeaderOffset int64 // Absolute buffer offset where headers end
131+ LastPageOffset int64 // Absolute offset of the last valid Ogg page start
96132
97133 Buffer * CircularBuffer
98134 listeners map [string ]chan struct {} // Signal channel for new data
@@ -239,6 +275,16 @@ func (s *Stream) Broadcast(data []byte, relay *Relay) {
239275 atomic .AddInt64 (& relay .BytesIn , int64 (len (data )))
240276 atomic .AddInt64 (& s .BytesIn , int64 (len (data )))
241277
278+ // Track Ogg Page boundaries for alignment
279+ isOgg := strings .Contains (strings .ToLower (s .ContentType ), "ogg" ) || strings .Contains (strings .ToLower (s .ContentType ), "opus" )
280+ if isOgg {
281+ for i := 0 ; i <= len (data )- 4 ; i ++ {
282+ if data [i ] == 'O' && data [i + 1 ] == 'g' && data [i + 2 ] == 'g' && data [i + 3 ] == 'S' {
283+ s .LastPageOffset = s .Buffer .Head + int64 (i )
284+ }
285+ }
286+ }
287+
242288 // 1. Write to shared buffer
243289 s .Buffer .Write (data )
244290
@@ -270,6 +316,13 @@ func (s *Stream) Subscribe(id string, burstSize int) (int64, chan struct{}) {
270316 if start < 0 {
271317 start = 0
272318 }
319+
320+ // For Ogg/Opus, align to the last known page boundary if we are within the burst
321+ if strings .Contains (strings .ToLower (s .ContentType ), "ogg" ) || strings .Contains (strings .ToLower (s .ContentType ), "opus" ) {
322+ if s .LastPageOffset > start {
323+ start = s .LastPageOffset
324+ }
325+ }
273326
274327 // Ensure we don't go back further than the buffer allows
275328 if s .Buffer .Head - start > s .Buffer .Size {
0 commit comments