Switch dashboard to watcher-based multi-disk view, fix transcoding FPS display

- dashboard.html: remove standalone "Mounted Disk" input panel; show all disks
  from GET /api/disks (watcher), auto-refresh every 5s
- detect.go: use avg_frame_rate when r_frame_rate is unrealistic (>120 fps or 0),
  fixes MJPEG/mjpeg showing 90000fps
- transcoder.go: parse fps= from ffmpeg progress output and expose in Progress struct
- copier.go: update task message with real-time encoding fps (@ 45.3 fps),
  clear speed_bps/eta during transcoding to avoid showing stale copy speed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 21:51:39 +03:00
parent 2bad23da3a
commit 839ff494a4
4 changed files with 198 additions and 185 deletions

View File

@@ -393,23 +393,26 @@ func (c *Copier) processVideo(ctx context.Context, taskID string, database *db.D
ext := transcoder.OutputExt(profile.OutputFormat)
dstTranscoded := strings.TrimSuffix(dst, filepath.Ext(dst)) + ext
srcFPS := fmt.Sprintf("%.2f", info.FPS)
msg := fmt.Sprintf("Transcoding %s (%s/%dch/%sfps %s/%s/%dfps %s)",
filepath.Base(src),
info.Codec, info.AudioChannels, srcFPS,
profile.VideoCodec, profile.AudioCodec, profile.MaxFPS, profile.OutputFormat,
)
srcInfo := fmt.Sprintf("%s/%dch/%.0ffps", info.Codec, info.AudioChannels, info.FPS)
dstInfo := fmt.Sprintf("%s/%s/%dfps %s", profile.VideoCodec, profile.AudioCodec, profile.MaxFPS, profile.OutputFormat)
baseMsg := fmt.Sprintf("Transcoding %s (%s → %s)", filepath.Base(src), srcInfo, dstInfo)
c.tasks.Update(taskID, func(t *task.Task) {
t.Phase = task.PhaseTranscoding
t.Message = msg
t.Message = baseMsg
})
if t, ok := c.tasks.Get(taskID); ok {
_ = database.UpdateTask(*t)
}
progressFn := func(pct float64) {
progressFn := func(p transcoder.Progress) {
c.tasks.Update(taskID, func(t *task.Task) {
t.Progress = int(pct * 100)
t.Progress = int(p.Pct * 100)
t.SpeedBPS = 0
t.ETASec = 0
if p.EncodeFPS > 0 {
t.Message = fmt.Sprintf("%s @ %.1f fps", baseMsg, p.EncodeFPS)
}
})
}