diff --git a/cmd/mpv.go b/cmd/mpv.go index 6797792..9612147 100644 --- a/cmd/mpv.go +++ b/cmd/mpv.go @@ -68,15 +68,35 @@ func (mpv *MPVPLayer) Stop() error { } func (mpv *MPVPLayer) VideoDuration() time.Duration { - mpv.RLock() - defer mpv.RUnlock() + mpv.Lock() + defer mpv.Unlock() + + if mpv.c != nil { + data, _ := mpv.c.Get("duration") + if data != nil { + data_s := data.(float64) + if data_s != 0 { + mpv.videoDuration = time.Duration(data_s) * time.Second + } + } + } return mpv.videoDuration } func (mpv *MPVPLayer) VideoPosition() time.Duration { - mpv.RLock() - defer mpv.RUnlock() + mpv.Lock() + defer mpv.Unlock() + + if mpv.c != nil { + data, _ := mpv.c.Get("time-pos") + if data != nil { + data_s := data.(float64) + if data_s != 0 { + mpv.videoPosition = time.Duration(data_s) * time.Second + } + } + } return mpv.videoPosition } @@ -85,7 +105,18 @@ func (mpv *MPVPLayer) IsPlaying() bool { mpv.Lock() defer mpv.Unlock() - if mpv.c != nil && mpv.c.IsClosed() { + if mpv.c == nil { + return false + } + + // closed + if mpv.c.IsClosed() { + return false + } + + // eof + data, _ := mpv.c.Get("eof-reached") + if data != nil && data.(bool) == true { return false } @@ -102,25 +133,12 @@ func (mpv *MPVPLayer) ensurePlayer() error { // TODO: cleanup this file var err error + // mpv.f, err = os.Create(fmt.Sprintf("%s/%s", os.TempDir(), "mpvminiflux")) # no such device or address, etc. errors mpv.f, err = os.CreateTemp("", "mpvminiflux") if err != nil { return err } - // close and delete file - // defer func() { - // if mpv.f == nil { - // return - // } - - // filename := mpv.f.Name() - // mpv.f.Close() - // os.Remove(filename) - // }() - - // defer mpv.finishedVideo() - - // ctx := context.TODO() cmd := exec.Command( "mpv", "--keep-open=yes", @@ -134,64 +152,20 @@ func (mpv *MPVPLayer) ensurePlayer() error { return err } - time.Sleep(100 * time.Millisecond) - mpv.c = mpvipc.NewConnection(mpv.f.Name()) - if err := mpv.c.Open(); err != nil { - return err - } + // try 10 times to open connection + // return error otherwise + for i := 0; i < 10; i++ { + time.Sleep(10 * time.Millisecond) - // setup observe properties - events, _ := mpv.c.NewEventListener() - if _, err = mpv.c.Call("observe_property", 1, "duration"); err != nil { - return err - } - if _, err = mpv.c.Call("observe_property", 2, "time-pos"); err != nil { - return err - } - if _, err = mpv.c.Call("observe_property", 3, "eof-reached"); err != nil { - return err - } - - // TODO: this will never close any old ones, so it will keep spawning new ones - go func() { - for event := range events { - if event.ID == 1 { - if event.Data != nil { - data := event.Data.(float64) - - if data != 0 { - mpv.Lock() - mpv.videoDuration = time.Duration(data) * time.Second - mpv.Unlock() - } - } - } else if event.ID == 2 { - if event.Data != nil { - data := event.Data.(float64) - - if data != 0 { - mpv.Lock() - mpv.videoPosition = time.Duration(data) * time.Second - mpv.Unlock() - } - } - } else if event.ID == 3 { - if event.Data != nil && event.Data.(bool) == true { - mpv.Lock() - mpv.isPlaying = false - mpv.Unlock() - } - // TODO: this might not fire once the media ends - // if event.Data != nil { - // if event.Data.(bool) == true { - // mpv.Lock() - // mpv.finishedVideo() - // mpv.Unlock() - // } - // } - } + mpv.c = mpvipc.NewConnection(mpv.f.Name()) + err = mpv.c.Open() + if err == nil { + break } - }() + } + if err != nil { + return err + } return nil } diff --git a/cmd/player.go b/cmd/player.go index 67117db..67a9809 100644 --- a/cmd/player.go +++ b/cmd/player.go @@ -71,7 +71,7 @@ func (m *playerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *playerModel) View() string { // return "NO DONT ASK" - return fmt.Sprintf("IsPlaying: %v, Pos: %v, Dur: %v, Per: %v", m.mpv.IsPlaying(), m.mpv.VideoPosition(), m.mpv.VideoDuration(), videoPercentageWatched(m.mpv.VideoPosition(), m.mpv.VideoDuration())) + // return fmt.Sprintf("IsPlaying: %v, Pos: %v, Dur: %v, Per: %v", m.mpv.IsPlaying(), m.mpv.VideoPosition(), m.mpv.VideoDuration(), videoPercentageWatched(m.mpv.VideoPosition(), m.mpv.VideoDuration())) if m.mpv.IsPlaying() { timePos := time.Time{}.Add(m.mpv.VideoPosition())