add mpv player w/ ipc support
This commit is contained in:
parent
a706a38252
commit
6ae627522c
5 changed files with 216 additions and 23 deletions
168
cmd/mpv.go
Normal file
168
cmd/mpv.go
Normal file
|
@ -0,0 +1,168 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/dexterlb/mpvipc"
|
||||
)
|
||||
|
||||
type MPVPLayer struct {
|
||||
entries []*feedEntry
|
||||
|
||||
c *mpvipc.Connection
|
||||
f *os.File
|
||||
|
||||
VideoPosition time.Duration
|
||||
VideoDuration time.Duration
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMPVPlayer() *MPVPLayer {
|
||||
return &MPVPLayer{}
|
||||
}
|
||||
|
||||
func (mpv *MPVPLayer) Exit() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mpv *MPVPLayer) Queue(e feedEntry) error {
|
||||
// TODO(eyJhb): implement checking
|
||||
mpv.entries = append(mpv.entries, &e)
|
||||
|
||||
if len(mpv.entries) == 1 {
|
||||
return mpv.Play(e.Link)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mpv *MPVPLayer) Play(url string) error {
|
||||
if err := mpv.ensurePlayer(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t, err := mpv.c.Call("loadfile", url)
|
||||
fmt.Println(t)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mpv *MPVPLayer) Stop() error {
|
||||
err := mpv.c.Set("pause", true)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mpv *MPVPLayer) IsPlaying() (bool, error) {
|
||||
if mpv.c == nil || mpv.c.IsClosed() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
path, err := mpv.c.Get("path")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return path != "", nil
|
||||
}
|
||||
|
||||
func (mpv *MPVPLayer) finishedVideo() (bool, error) {
|
||||
mpv.Lock()
|
||||
defer mpv.Unlock()
|
||||
|
||||
mpv.entries = mpv.entries[1:]
|
||||
|
||||
if len(mpv.entries) == 1 {
|
||||
if err := mpv.Play(mpv.entries[0].Link); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (mpv *MPVPLayer) ensurePlayer() error {
|
||||
if mpv.c != nil && !mpv.c.IsClosed() {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
mpv.f, err = os.CreateTemp("", "example")
|
||||
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.CommandContext(ctx,
|
||||
"mpv",
|
||||
"--keep-open=yes",
|
||||
"--idle",
|
||||
// fmt.Sprintf("--input-ipc-server=%d", mpv.f.Fd()),
|
||||
fmt.Sprintf("--input-ipc-server=%s", mpv.f.Name()),
|
||||
)
|
||||
|
||||
// start
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
mpv.c = mpvipc.NewConnection(mpv.f.Name())
|
||||
if err := mpv.c.Open(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
go func() {
|
||||
for event := range events {
|
||||
fmt.Println("event", event)
|
||||
mpv.Lock()
|
||||
if event.ID == 1 {
|
||||
if event.Data != nil {
|
||||
mpv.VideoDuration = time.Duration(event.Data.(float64)) * time.Second
|
||||
}
|
||||
} else if event.ID == 2 {
|
||||
if event.Data != nil {
|
||||
mpv.VideoPosition = time.Duration(event.Data.(float64)) * time.Second
|
||||
}
|
||||
} else if event.ID == 3 {
|
||||
if event.Data != nil {
|
||||
mpv.finishedVideo()
|
||||
}
|
||||
}
|
||||
mpv.Unlock()
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
// return cmd.Wait()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue