minifluxmpv/cmd/player.go
2025-02-04 20:20:55 +01:00

88 lines
1.7 KiB
Go

package cmd
import (
"fmt"
"regexp"
"sync"
"time"
tea "github.com/charmbracelet/bubbletea"
)
const (
playerMaxTitleLength = 30
)
var (
regexpPosDur = regexp.MustCompile(`AV: (\d+):(\d+):(\d+) \/ (\d+):(\d+):(\d+)`)
)
type playerModel struct {
// entry *feedEntry
// isPlayingVideo bool
// // video information
// videoDuration time.Duration
// videoPosition time.Duration
// TODO: make this smarter
// finished entries to send messages about
finishedEntries []int64
mpv *MPVPLayer
sync.RWMutex
}
func (m *playerModel) Init() tea.Cmd {
m.mpv = NewMPVPlayer()
return nil
}
func (m *playerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case MsgPlayEntry:
f := feedEntry(msg)
go m.mpv.Queue(f)
}
// send message because it is finished
fe := m.mpv.FinishedPlaying()
if len(fe) > 0 {
var cmds []tea.Cmd
for _, e := range fe {
cmds = append(cmds, func() tea.Msg { return MsgWatchedEntry(e.ID) })
}
return m, tea.Batch(cmds...)
}
return m, nil
}
func (m *playerModel) View() string {
// return "NO DONT ASK"
// return fmt.Sprintf("IsPlaying: %v", m.mpv.IsPlaying())
if m.mpv.IsPlaying() {
timePos := time.Time{}.Add(m.mpv.VideoPosition())
timeDur := time.Time{}.Add(m.mpv.VideoDuration())
// truncate name if needed
// name := m.entry.Name
name := m.mpv.CurrentlyPlaying().Name
if len(name) > playerMaxTitleLength {
name = name[0:playerMaxTitleLength] + "..."
}
return fmt.Sprintf("Playing: %s (%s/%s %.1f%%)",
name,
timePos.Format(time.TimeOnly),
timeDur.Format(time.TimeOnly),
videoPercentageWatched(m.mpv.VideoPosition(), m.mpv.VideoDuration()),
)
}
return ""
}