Compare commits

..
5 Commits
6 changed files with 111 additions and 52 deletions
+4 -1
View File
@@ -1,6 +1,9 @@
- [x] query ffmpeg binary for available encoders and list the ones we know - [x] query ffmpeg binary for available encoders and list the ones we know
- [-] when passing in a directory, list all video files in that directory and have the user choose which ones they want encoded - [-] when passing in a directory, list all video files in that directory and have the user choose which ones they want encoded
- [ ] Scrollable viewport for the files. They currently get cut if there's too many. - [x] Scrollable viewport for the files. They currently get cut if there's too many.
- [ ] CLI Option/Flag to choose the output directory for the encoded video(s) - [ ] CLI Option/Flag to choose the output directory for the encoded video(s)
- [ ] The 'Encoding "XXXXX" ETA: XHXXMXXS' text gets cut instead of wrapping when the text is too long/terminal width too small. Fix
- [ ] Show FPS, bitrate, and current file size when encoding.
- Has to be parsed from the ffmpeg output
- [ ] calculate total progress based on file sizes instead of counts of files for a more accurate progress percentage. - [ ] calculate total progress based on file sizes instead of counts of files for a more accurate progress percentage.
might not do this. might not do this.
+74 -26
View File
@@ -10,6 +10,7 @@ import (
"github.com/charmbracelet/bubbles/progress" "github.com/charmbracelet/bubbles/progress"
"github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/spinner"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
) )
@@ -35,8 +36,10 @@ type Model struct {
IsDirectory bool IsDirectory bool
Path string Path string
CurrentFileName string CurrentFileName string
ViewportFocused bool
FileCount int FileCount int
Files []File Files []File
Viewport viewport.Model
Spinner spinner.Model Spinner spinner.Model
SingleFileProgressBar progress.Model SingleFileProgressBar progress.Model
SingleFileProgress float64 SingleFileProgress float64
@@ -92,6 +95,7 @@ func initialModel(fileInfo os.FileInfo, absolutePath string) *Model {
Path: absolutePath, Path: absolutePath,
FileCount: 0, FileCount: 0,
Files: make([]File, 0), Files: make([]File, 0),
Viewport: viewport.New(0, 0),
Screen: Cfg, Screen: Cfg,
Spinner: s, Spinner: s,
SingleFileProgressBar: progress.New(progress.WithGradient("#1010ff", "#00ff00")), SingleFileProgressBar: progress.New(progress.WithGradient("#1010ff", "#00ff00")),
@@ -133,6 +137,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.Files = msg.files m.Files = msg.files
return m, nil return m, nil
case tea.WindowSizeMsg:
m.Viewport.Width = msg.Width
m.Viewport.Height = msg.Height - lipgloss.Height(FilesScreenViewHeader(m))
} }
switch m.Screen { switch m.Screen {
@@ -144,7 +151,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case "ctrl+c", "esc": case "ctrl+c", "esc":
return m, tea.Quit return m, tea.Quit
case "enter", " ": case "enter", " ":
if m.FocusIndex == 0 && key == "enter" { if !m.ViewportFocused && key == "enter" {
selectAll := !every(m.Files, func(e File) bool { return e.Selected }) selectAll := !every(m.Files, func(e File) bool { return e.Selected })
if m.ChoiceIndex == 0 { if m.ChoiceIndex == 0 {
@@ -161,20 +168,30 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Batch(m.Spinner.Tick, encodeVideo) return m, tea.Batch(m.Spinner.Tick, encodeVideo)
} }
} else if m.FocusIndex != 0 { } else if m.ViewportFocused {
m.Files[m.FocusIndex-1].Selected = !m.Files[m.FocusIndex-1].Selected m.Files[m.FocusIndex].Selected = !m.Files[m.FocusIndex].Selected
// Reset the choice to "Select All" button when no files are selected // Reset the choice to "Select All" button when no files are selected
if !anyOf(m.Files, func(f File) bool { return f.Selected }) { if !anyOf(m.Files, func(f File) bool { return f.Selected }) {
m.ChoiceIndex = 0 m.ChoiceIndex = 0
} }
} }
m.SetViewportContent()
case "g": case "g":
if m.ViewportFocused {
m.FocusIndex = 0 m.FocusIndex = 0
m.SetViewportContent()
m.Viewport.GotoTop()
}
case "G": case "G":
m.FocusIndex = len(m.Files) if m.ViewportFocused {
m.FocusIndex = len(m.Files) - 1
m.SetViewportContent()
m.Viewport.GotoBottom()
}
case "left", "right", "h", "l": case "left", "right", "h", "l":
if m.FocusIndex == 0 && anyOf(m.Files, func(f File) bool { return f.Selected }) { if !m.ViewportFocused && anyOf(m.Files, func(f File) bool { return f.Selected }) {
if key == "right" || key == "l" { if key == "right" || key == "l" {
m.ChoiceIndex++ m.ChoiceIndex++
} else { } else {
@@ -187,17 +204,34 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.ChoiceIndex = 1 m.ChoiceIndex = 1
} }
} }
case "tab", "shift+tab", "up", "down", "j", "k": case "tab", "shift+tab":
if key == "up" || key == "shift+tab" || key == "k" { m.ViewportFocused = !m.ViewportFocused
m.SetViewportContent()
case "up", "down", "j", "k":
if m.ViewportFocused {
if key == "up" || key == "k" {
m.FocusIndex-- m.FocusIndex--
} else { } else {
m.FocusIndex++ m.FocusIndex++
} }
if m.FocusIndex >= len(m.Files)+1 { if (key == "down" || key == "j") && m.FocusIndex >= m.Viewport.Height+m.Viewport.YOffset {
m.Viewport.LineDown(1)
}
if (key == "up" || key == "k") && m.FocusIndex < m.Viewport.YOffset {
m.Viewport.LineUp(1)
}
if m.FocusIndex >= len(m.Files) {
m.Viewport.GotoTop()
m.FocusIndex = 0 m.FocusIndex = 0
} else if m.FocusIndex < 0 { } else if m.FocusIndex < 0 {
m.FocusIndex = len(m.Files) m.Viewport.GotoBottom()
m.FocusIndex = len(m.Files) - 1
}
m.SetViewportContent()
} }
} }
} }
@@ -279,6 +313,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.Screen = Files m.Screen = Files
m.FocusIndex = 0 m.FocusIndex = 0
m.ChoiceIndex = 0 m.ChoiceIndex = 0
m.SetViewportContent()
} else { } else {
m.Screen = Main m.Screen = Main
@@ -354,6 +390,26 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, cmd return m, cmd
} }
func (m *Model) SetViewportContent() {
var files string
for i, file := range m.Files {
selection := " "
if file.Selected {
selection = "x"
}
if m.ViewportFocused && m.FocusIndex == i {
files += fmt.Sprintf(FocusedConfig.UnsetMarginTop().Render("[%s] %s"), selection, filepath.Base(file.Path))
} else {
files += fmt.Sprintf(BlurredConfig.UnsetMarginTop().Render("[%s] %s"), selection, filepath.Base(file.Path))
}
files += "\n"
}
m.Viewport.SetContent(files)
}
func parseConfig(cfg []Config) ParsedConfig { func parseConfig(cfg []Config) ParsedConfig {
vEncoder := find(cfg, "Video Encoder") vEncoder := find(cfg, "Video Encoder")
aEncoder := find(cfg, "Audio Encoder") aEncoder := find(cfg, "Audio Encoder")
@@ -370,9 +426,8 @@ func parseConfig(cfg []Config) ParsedConfig {
} }
} }
func FilesScreenView(m Model) string { func FilesScreenViewHeader(m Model) string {
view := lipgloss.NewStyle().Margin(1, 0).Render("Select the files you wish to encode.") view := lipgloss.NewStyle().Margin(1, 0).Render("Select the files you wish to encode.")
var files string
var buttons string var buttons string
var selectAllBtnText string var selectAllBtnText string
@@ -393,7 +448,7 @@ func FilesScreenView(m Model) string {
focusedStartButton = DisabledStartButton focusedStartButton = DisabledStartButton
} }
if m.FocusIndex == 0 { if !m.ViewportFocused {
if m.ChoiceIndex == 0 { if m.ChoiceIndex == 0 {
buttons = lipgloss.JoinHorizontal(0, FocusedSelectAllButton.Render(selectAllBtnText), blurredStartButton) buttons = lipgloss.JoinHorizontal(0, FocusedSelectAllButton.Render(selectAllBtnText), blurredStartButton)
} else { } else {
@@ -403,24 +458,17 @@ func FilesScreenView(m Model) string {
buttons = lipgloss.JoinHorizontal(0, BlurredSelectAllButton.Render(selectAllBtnText), blurredStartButton) buttons = lipgloss.JoinHorizontal(0, BlurredSelectAllButton.Render(selectAllBtnText), blurredStartButton)
} }
// TODO: files should be a scrollable grid view += buttons
for i, file := range m.Files {
selection := " "
if file.Selected {
selection = "x"
}
if m.FocusIndex == i+1 {
files += fmt.Sprintf(FocusedConfig.Render("[%s] %s"), selection, filepath.Base(file.Path))
} else {
files += fmt.Sprintf(BlurredConfig.Render("[%s] %s"), selection, filepath.Base(file.Path))
}
}
view += lipgloss.JoinVertical(0, buttons, files)
return view return view
} }
func FilesScreenView(m Model) string {
// TODO: files should be a grid (?)
return lipgloss.JoinVertical(0, FilesScreenViewHeader(m), m.Viewport.View())
}
func CfgScreenView(m Model) string { func CfgScreenView(m Model) string {
view := "" view := ""
+6 -6
View File
@@ -6,7 +6,7 @@ require (
github.com/charmbracelet/bubbles v0.10.3 github.com/charmbracelet/bubbles v0.10.3
github.com/charmbracelet/bubbletea v0.23.2 github.com/charmbracelet/bubbletea v0.23.2
github.com/charmbracelet/lipgloss v0.5.0 github.com/charmbracelet/lipgloss v0.5.0
github.com/gabriel-vasile/mimetype v1.4.0 github.com/gabriel-vasile/mimetype v1.4.8
) )
require ( require (
@@ -22,9 +22,9 @@ require (
github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.14.0 // indirect github.com/muesli/termenv v0.14.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125 // indirect golang.org/x/net v0.33.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.21.0 // indirect
) )
+12 -11
View File
@@ -14,8 +14,8 @@ github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
@@ -46,25 +46,26 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125 h1:Ugb8sMTWuWRC3+sz5WeN/4kejDx9BvIwnPUiJBjJE+8= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+1 -1
View File
@@ -125,7 +125,7 @@ func encode(file File, fileName string, teaP *tea.Program, cfg ParsedConfig) {
} }
if !strings.HasPrefix(mType.String(), "video/") { if !strings.HasPrefix(mType.String(), "video/") {
log.Fatalf("%s is not a valid video file\n", fileName) log.Fatalf("%s is not a valid video file. It is %v\n", fileName, mType)
} }
parentDir := filepath.Dir(file.Path) parentDir := filepath.Dir(file.Path)
+7
View File
@@ -42,6 +42,7 @@ func TempSock(totalDuration float64, teaP *tea.Program) string {
go func() { go func() {
re := regexp.MustCompile(`out_time_ms=(\d+)`) re := regexp.MustCompile(`out_time_ms=(\d+)`)
speedRe := regexp.MustCompile(`speed=(\d+\.\d+x)`) speedRe := regexp.MustCompile(`speed=(\d+\.\d+x)`)
totalSizeRe := regexp.MustCompile(`total_size=(\d+)`)
fd, err := l.Accept() fd, err := l.Accept()
if err != nil { if err != nil {
@@ -65,6 +66,12 @@ func TempSock(totalDuration float64, teaP *tea.Program) string {
cp = fmt.Sprintf("%.2f", float64(c)/totalDuration/1000000) cp = fmt.Sprintf("%.2f", float64(c)/totalDuration/1000000)
} }
if strings.Contains(data, "progress=end") { if strings.Contains(data, "progress=end") {
totalSize := totalSizeRe.FindString(data)
if len(totalSize) > 0 && strings.Split(totalSize, "=")[1] == "0" {
// Command failed. Don't send a finishedEncodingVideo message.
// encode() will take care of reporting the error.
continue
}
cp = "done" cp = "done"
teaP.Send(finishedEncodingVideo{}) teaP.Send(finishedEncodingVideo{})
return return