Coalesce player scrub seeks

This commit is contained in:
Stu Leak 2026-01-10 16:25:00 -05:00
parent db841b286d
commit 3fcaa9959b

56
main.go
View File

@ -11209,6 +11209,8 @@ type playSession struct {
frameFunc func(int) // Callback for frame number updates frameFunc func(int) // Callback for frame number updates
img *canvas.Image img *canvas.Image
mu sync.Mutex mu sync.Mutex
seekTimer *time.Timer
seekPending float64
videoCmd *exec.Cmd videoCmd *exec.Cmd
audioCmd *exec.Cmd audioCmd *exec.Cmd
frameN int frameN int
@ -11350,31 +11352,48 @@ func (p *playSession) Seek(offset float64) {
offset = 0 offset = 0
} }
// Use GStreamer player p.seekPending = offset
if p.gstPlayer != nil { if p.seekTimer != nil {
paused := p.paused p.seekTimer.Stop()
_ = p.gstPlayer.SeekToTime(time.Duration(offset * float64(time.Second)))
if paused {
_ = p.gstPlayer.Pause()
} else {
_ = p.gstPlayer.Play()
} }
p.current = offset p.seekTimer = time.AfterFunc(120*time.Millisecond, func() {
p.frameN = int(p.current * p.fps) p.seekNow()
logging.Debug(logging.CatPlayer, "playSession: Seek to %.2fs", offset) })
p.mu.Unlock()
}
func (p *playSession) seekNow() {
p.mu.Lock()
offset := p.seekPending
paused := p.paused
gstPlayer := p.gstPlayer
prog := p.prog prog := p.prog
frameFunc := p.frameFunc frameFunc := p.frameFunc
img := p.img img := p.img
if gstPlayer == nil {
p.mu.Unlock()
return
}
p.current = offset
p.frameN = int(p.current * p.fps)
p.mu.Unlock() p.mu.Unlock()
_ = gstPlayer.SeekToTime(time.Duration(offset * float64(time.Second)))
if paused {
_ = gstPlayer.Pause()
} else {
_ = gstPlayer.Play()
}
logging.Debug(logging.CatPlayer, "playSession: Seek to %.2fs", offset)
if prog != nil { if prog != nil {
prog(p.current) prog(offset)
} }
if frameFunc != nil { if frameFunc != nil {
frameFunc(p.frameN) frameFunc(int(offset * p.fps))
} }
if paused { if paused {
frame, err := p.gstPlayer.GetFrameImage() frame, err := gstPlayer.GetFrameImage()
if err == nil && frame != nil { if err == nil && frame != nil {
fyne.CurrentApp().Driver().DoFromGoroutine(func() { fyne.CurrentApp().Driver().DoFromGoroutine(func() {
if img != nil { if img != nil {
@ -11386,11 +11405,6 @@ func (p *playSession) Seek(offset float64) {
}, false) }, false)
} }
} }
return
}
p.mu.Unlock()
logging.Error(logging.CatPlayer, "playSession: GStreamer player not available")
} }
// StepFrame moves forward or backward by a specific number of frames. // StepFrame moves forward or backward by a specific number of frames.
@ -11612,6 +11626,10 @@ func (p *playSession) stopLocked() {
if p.gstPlayer != nil { if p.gstPlayer != nil {
p.gstPlayer.Stop() p.gstPlayer.Stop()
} }
if p.seekTimer != nil {
p.seekTimer.Stop()
p.seekTimer = nil
}
// Fallback to dual-process cleanup // Fallback to dual-process cleanup
select { select {