From b80726c8709692aeb63a19775a6879a0818aaa49 Mon Sep 17 00:00:00 2001 From: IllusionMan1212 Date: Sat, 7 Sep 2024 03:56:09 +0200 Subject: [PATCH] feat: show encoding duration estimate for currently encoding video --- app.go | 30 +++++++++++++++++++++++++++++- cmds.go | 3 +++ progress.go | 17 +++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index e54ea08..03f1f0e 100644 --- a/app.go +++ b/app.go @@ -34,6 +34,7 @@ type model struct { SingleFileProgress float64 TotalProgressBar progress.Model TotalProgress float64 + Estimate int Program *tea.Program Quitting bool Screen Screen @@ -186,6 +187,10 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { totalProgressCmd := m.TotalProgressBar.SetPercent(m.TotalProgress) return m, tea.Batch(singleProgressCmd, totalProgressCmd) + case updateEstimate: + m.Estimate = msg.estimate + + return m, tea.Batch() case quitMsg: m.Quitting = true return m, tea.Quit @@ -265,11 +270,34 @@ func MainScreenView(m model) string { m.SingleFileProgressBar.View()) } - view := fmt.Sprintf("\nEncoding \"%s\"...\n%s", m.CurrentFileName, progress) + eta := formatEstimate(m.Estimate) + + view := fmt.Sprintf("\nEncoding \"%s\"... ETA: %s\n%s", m.CurrentFileName, eta, progress) return view } +func formatEstimate(estimate int) string { + if estimate >= 86400 { + day := estimate / 86400 + hour := (estimate % 86400) / 3600 + min := (estimate % 3600) / 60 + sec := estimate % 60 + return fmt.Sprintf("%dd%dh%dm%ds", day, hour, min, sec) + } else if estimate >= 3600 { + hour := estimate / 3600 + min := (estimate % 3600) / 60 + sec := estimate % 60 + return fmt.Sprintf("%dh%dm%ds", hour, min, sec) + } else if estimate >= 60 { + min := estimate / 60 + sec := estimate % 60 + return fmt.Sprintf("%dm%ds", min, sec) + } + + return fmt.Sprintf("%ds", estimate) +} + func (m model) View() string { if m.Quitting { if m.DryRun { diff --git a/cmds.go b/cmds.go index cbd1fbb..efe38ff 100644 --- a/cmds.go +++ b/cmds.go @@ -16,6 +16,9 @@ type finishedEncodingVideo struct{} type updateProgress struct { progress float64 } +type updateEstimate struct { + estimate int +} type initUi struct { fileCount int diff --git a/progress.go b/progress.go index 119d74c..3aca513 100644 --- a/progress.go +++ b/progress.go @@ -42,6 +42,8 @@ func TempSock(totalDuration float64, teaP *tea.Program) string { go func() { re := regexp.MustCompile(`out_time_ms=(\d+)`) + speedRe := regexp.MustCompile(`speed=(\d+\.\d+x)`) + fd, err := l.Accept() if err != nil { log.Fatal("accept error:", err) @@ -49,6 +51,8 @@ func TempSock(totalDuration float64, teaP *tea.Program) string { buf := make([]byte, 1024) data := "" progress := "" + estimate := 0 + for { _, err := fd.Read(buf) if err != nil { @@ -78,6 +82,19 @@ func TempSock(totalDuration float64, teaP *tea.Program) string { }) } } + + speedMatch := speedRe.FindString(data) + if len(speedMatch) > 0 { + trimmedSpeed := strings.TrimSuffix(strings.Split(speedMatch, "=")[1], "x") + speed, _ := strconv.ParseFloat(trimmedSpeed, 32) + progressFloat, _ := strconv.ParseFloat(progress, 64) + remainingDuration := totalDuration - (totalDuration * progressFloat) + estimate = int(remainingDuration / speed) + } + + teaP.Send(updateEstimate{ + estimate: estimate, + }) } }()