feat(stream): device-aware remux (HEVC/AV1 + non-aac audio) + TTFF timers
Hueco #3 / 3c (CLI). NewRemuxSource now copies the video for any browser-decodable codec: h264, or HEVC/AV1 when the web says the device decodes them (caps). HEVC is muxed with -tag:v hvc1 (Apple requirement), and non-aac audio (ac3/eac3/dts) is transcoded to aac while the video is still copied (ActionRemuxAudio) — this covers the very common h264+ac3 mkv. Startup instrumentation for time-to-first-frame diagnosis: - remux branch logs [probe=.. spawn=..] - transcodeSource logs 'first fMP4 bytes after ..' (ffmpeg → first output) - serveGrowing logs reads that block >250ms (client seeking ahead of the live edge) + the first read's offset vs produced/estimated size. Verified: caps gate (hls without caps, remux with), hvc1 retag (ffprobe of the /stream output = hevc/hvc1), HEVC playback confirmed on a real iPhone Safari over Tailscale. LAN timeline: probe 16ms, spawn 1ms, first byte 201ms, no serveGrowing blocks.
This commit is contained in:
parent
c18876471c
commit
957d499658
4 changed files with 59 additions and 4 deletions
|
|
@ -863,6 +863,7 @@ func (ss *StreamServer) serveGrowing(w http.ResponseWriter, r *http.Request, src
|
|||
|
||||
buf := make([]byte, 256*1024)
|
||||
off := start
|
||||
firstRead := true
|
||||
for {
|
||||
if explicitEnd >= 0 && off > explicitEnd {
|
||||
return
|
||||
|
|
@ -870,7 +871,19 @@ func (ss *StreamServer) serveGrowing(w http.ResponseWriter, r *http.Request, src
|
|||
if r.Context().Err() != nil {
|
||||
return // client disconnected / request cancelled
|
||||
}
|
||||
readStart := time.Now()
|
||||
n, err := src.ReadAt(buf, off)
|
||||
// TTFF diagnosis: a read that blocks means the client asked for bytes the
|
||||
// remux hasn't produced yet (a seek ahead of the live edge, or the very
|
||||
// first read before ffmpeg's init lands). Log it so a slow start is
|
||||
// attributable to "waiting on ffmpeg" vs network/decoder.
|
||||
if waited := time.Since(readStart); waited > 250*time.Millisecond {
|
||||
log.Printf("[stream] serveGrowing read off=%d blocked %v (produced=%d est=%d)",
|
||||
off, waited.Round(time.Millisecond), src.Size(), src.EstimatedSize())
|
||||
} else if firstRead {
|
||||
log.Printf("[stream] serveGrowing start off=%d (produced=%d est=%d)", start, src.Size(), src.EstimatedSize())
|
||||
}
|
||||
firstRead = false
|
||||
if n > 0 {
|
||||
toWrite := n
|
||||
if explicitEnd >= 0 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue