From 6346d5fbe1e4265cc84ba28874b147fdbee4629f Mon Sep 17 00:00:00 2001 From: cclohmar Date: Tue, 20 Oct 2026 08:10:09 +0100 Subject: [PATCH] fix: skip in-progress .part segments and enable MP4 faststart - /api/recordings no longer lists rec_*.part.mp4 files: FFmpeg has not written the moov atom yet, so they can never play. The in-progress segment was always the newest entry at the top of the list. - Record new segments with -movflags +faststart so the MP4 index is at the front. iOS/Safari otherwise tail-seeks the moov and stalls. - Add playsinline to the playback video for inline iOS playback. - Add scripts/remux-faststart.sh to convert the existing archive (dry-run by default, atomic, preserves mtime for retention). --- api.go | 8 ++- public/index.html | 2 +- recorder.go | 1 + scripts/remux-faststart.sh | 133 +++++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100755 scripts/remux-faststart.sh diff --git a/api.go b/api.go index 11b28bc..ef1ffd8 100644 --- a/api.go +++ b/api.go @@ -479,11 +479,17 @@ func (s *Server) handleRecordings(w http.ResponseWriter, r *http.Request) { } name := entry.Name() - // Only process rec_*.mp4 files (not snap_*.jpg). + // Only process completed rec_*.mp4 files (not snap_*.jpg). if !strings.HasPrefix(name, "rec_") || !strings.HasSuffix(strings.ToLower(name), ".mp4") { continue } + // Skip in-progress segments. FFmpeg only writes the MP4 index (moov) + // when it finalizes the file, so a .part.mp4 cannot be played yet. + if strings.HasSuffix(strings.ToLower(name), ".part.mp4") { + continue + } + info, statErr := entry.Info() if statErr != nil { continue diff --git a/public/index.html b/public/index.html index 73ed87d..8ce18b9 100644 --- a/public/index.html +++ b/public/index.html @@ -51,7 +51,7 @@