Skip to content

Commit

Permalink
use property changed event to update playback position/duration/volum…
Browse files Browse the repository at this point in the history
…e, huge cpu savings because we don't update our UI with 10fps anymore
  • Loading branch information
spezifisch committed Oct 27, 2023
1 parent d111623 commit 8e95c17
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 50 deletions.
11 changes: 11 additions & 0 deletions event_loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,18 @@ func (ui *Ui) runEventLoops() {
// handle ui updates
func (ui *Ui) guiEventLoop() {
ui.addStarredToList()
events := 0.0
fpsTimer := time.NewTimer(0)

for {
events++

select {
case <-fpsTimer.C:
fpsTimer.Reset(10 * time.Second)
ui.logger.Printf("guiEventLoop: %f events per second", events/10.0)
events = 0

case msg := <-ui.logger.Prints:
// handle log page output
ui.app.QueueUpdateDraw(func() {
Expand All @@ -52,6 +61,8 @@ func (ui *Ui) guiEventLoop() {
})

case mpvEvent := <-ui.mpvEvents:
events++

// handle events from mpv wrapper
switch mpvEvent.Type {
case mpvplayer.EventStatus:
Expand Down
6 changes: 3 additions & 3 deletions gui_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ func makeModal(p tview.Primitive, width, height int) tview.Primitive {
AddItem(p, 1, 1, 1, 1, 0, 0, true)
}

func formatPlayerStatus(volume int64, position float64, duration float64) string {
func formatPlayerStatus(volume int64, position int64, duration int64) string {
if position < 0 {
position = 0.0
position = 0
}

if duration < 0 {
duration = 0.0
duration = 0
}

positionMin, positionSec := secondsToMinAndSec(position)
Expand Down
4 changes: 2 additions & 2 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ func stringOr(firstChoice string, secondChoice string) string {
return secondChoice
}

func secondsToMinAndSec(seconds float64) (int, int) {
minutes := math.Floor(seconds / 60)
func secondsToMinAndSec(seconds int64) (int, int) {
minutes := math.Floor(float64(seconds) / 60)
remainingSeconds := int(seconds) % 60
return int(minutes), remainingSeconds
}
Expand Down
70 changes: 37 additions & 33 deletions mpvplayer/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (
)

func (p *Player) EventLoop() {
if err := p.instance.ObserveProperty(0, "time-pos", mpv.FORMAT_DOUBLE); err != nil {
if err := p.instance.ObserveProperty(0, "playback-time", mpv.FORMAT_INT64); err != nil {
p.logger.PrintError("Observe1", err)
}
if err := p.instance.ObserveProperty(0, "duration", mpv.FORMAT_DOUBLE); err != nil {
if err := p.instance.ObserveProperty(0, "duration", mpv.FORMAT_INT64); err != nil {
p.logger.PrintError("Observe2", err)
}
if err := p.instance.ObserveProperty(0, "volume", mpv.FORMAT_INT64); err != nil {
Expand All @@ -22,6 +22,38 @@ func (p *Player) EventLoop() {
if evt == nil {
// quit signal
break
} else if evt.Event_Id == mpv.EVENT_PROPERTY_CHANGE {
// one of our observed properties changed. which one is probably extractable from evt.Data.. somehow.

position, err := p.instance.GetProperty("time-pos", mpv.FORMAT_INT64)
if err != nil {
p.logger.Printf("mpv.EventLoop (%s): GetProperty %s -- %s", evt.Event_Id.String(), "time-pos", err.Error())
}
duration, err := p.instance.GetProperty("duration", mpv.FORMAT_INT64)
if err != nil {
p.logger.Printf("mpv.EventLoop (%s): GetProperty %s -- %s", evt.Event_Id.String(), "duration", err.Error())
}
volume, err := p.instance.GetProperty("volume", mpv.FORMAT_INT64)
if err != nil {
p.logger.Printf("mpv.EventLoop (%s): GetProperty %s -- %s", evt.Event_Id.String(), "volume", err.Error())
}

if position == nil {
position = int64(0)
}
if duration == nil {
duration = int64(0)
}
if volume == nil {
volume = int64(0)
}

statusData := StatusData{
Volume: volume.(int64),
Position: position.(int64),
Duration: duration.(int64),
}
p.sendGuiDataEvent(EventStatus, statusData)
} else if evt.Event_Id == mpv.EVENT_END_FILE && !p.replaceInProgress {
// we don't want to update anything if we're in the process of replacing the current track

Expand Down Expand Up @@ -66,38 +98,10 @@ func (p *Player) EventLoop() {
}
} else if evt.Event_Id == mpv.EVENT_IDLE || evt.Event_Id == mpv.EVENT_NONE {
continue
} else {
p.logger.Printf("mpv.EventLoop: unhandled event id %v", evt.Event_Id)
continue
}

position, err := p.instance.GetProperty("time-pos", mpv.FORMAT_DOUBLE)
if err != nil {
p.logger.Printf("mpv.EventLoop (%s): GetProperty %s -- %s", evt.Event_Id.String(), "time-pos", err.Error())
}
// TODO only update these as needed
duration, err := p.instance.GetProperty("duration", mpv.FORMAT_DOUBLE)
if err != nil {
p.logger.Printf("mpv.EventLoop (%s): GetProperty %s -- %s", evt.Event_Id.String(), "duration", err.Error())
}
volume, err := p.instance.GetProperty("volume", mpv.FORMAT_INT64)
if err != nil {
p.logger.Printf("mpv.EventLoop (%s): GetProperty %s -- %s", evt.Event_Id.String(), "volume", err.Error())
}

if position == nil {
position = 0.0
}
if duration == nil {
duration = 0.0
}
if volume == nil {
volume = 0
}

statusData := StatusData{
Volume: volume.(int64),
Position: position.(float64),
Duration: duration.(float64),
}
p.sendGuiDataEvent(EventStatus, statusData)
}
}

Expand Down
26 changes: 16 additions & 10 deletions mpvplayer/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,31 @@ type Player struct {
}

func NewPlayer(logger logger.LoggerInterface) (player *Player, err error) {
mpvInstance := mpv.Create()
m := mpv.Create()

// TODO figure out what other mpv options we need
if err = mpvInstance.SetOptionString("audio-display", "no"); err != nil {
mpvInstance.TerminateDestroy()
// cargo-cult what supersonic does
if err = m.SetOptionString("audio-display", "no"); err != nil {
return
}
if err = mpvInstance.SetOptionString("video", "no"); err != nil {
mpvInstance.TerminateDestroy()
if err = m.SetOptionString("video", "no"); err != nil {
return
}
if err = m.SetOptionString("terminal", "no"); err != nil {
return
}
if err = m.SetOptionString("demuxer-max-bytes", "30MiB"); err != nil {
return
}
if err = m.SetOptionString("audio-client-name", "stmp"); err != nil {
return
}

if err = mpvInstance.Initialize(); err != nil {
mpvInstance.TerminateDestroy()
if err = m.Initialize(); err != nil {
return
}

player = &Player{
instance: mpvInstance,
instance: m,
mpvEvents: make(chan *mpv.Event),
eventConsumer: nil, // must be set by calling RegisterEventConsumer()
queue: make([]QueueItem, 0),
Expand All @@ -52,7 +58,7 @@ func NewPlayer(logger logger.LoggerInterface) (player *Player, err error) {
stopped: true,
}

go player.mpvEngineEventHandler(mpvInstance)
go player.mpvEngineEventHandler(m)
return
}

Expand Down
4 changes: 2 additions & 2 deletions mpvplayer/typed_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ type QueueItem struct {
// StatusData is a player progress report for the UI
type StatusData struct {
Volume int64
Position float64
Duration float64
Position int64
Duration int64
}

0 comments on commit 8e95c17

Please sign in to comment.