Coalesce player scrub seeks
This commit is contained in:
parent
db841b286d
commit
3fcaa9959b
92
main.go
92
main.go
|
|
@ -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,47 +11352,59 @@ 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.seekTimer = time.AfterFunc(120*time.Millisecond, func() {
|
||||||
_ = p.gstPlayer.Pause()
|
p.seekNow()
|
||||||
} else {
|
})
|
||||||
_ = p.gstPlayer.Play()
|
p.mu.Unlock()
|
||||||
}
|
}
|
||||||
p.current = offset
|
|
||||||
p.frameN = int(p.current * p.fps)
|
|
||||||
logging.Debug(logging.CatPlayer, "playSession: Seek to %.2fs", offset)
|
|
||||||
prog := p.prog
|
|
||||||
frameFunc := p.frameFunc
|
|
||||||
img := p.img
|
|
||||||
p.mu.Unlock()
|
|
||||||
|
|
||||||
if prog != nil {
|
func (p *playSession) seekNow() {
|
||||||
prog(p.current)
|
p.mu.Lock()
|
||||||
}
|
offset := p.seekPending
|
||||||
if frameFunc != nil {
|
paused := p.paused
|
||||||
frameFunc(p.frameN)
|
gstPlayer := p.gstPlayer
|
||||||
}
|
prog := p.prog
|
||||||
if paused {
|
frameFunc := p.frameFunc
|
||||||
frame, err := p.gstPlayer.GetFrameImage()
|
img := p.img
|
||||||
if err == nil && frame != nil {
|
if gstPlayer == nil {
|
||||||
fyne.CurrentApp().Driver().DoFromGoroutine(func() {
|
p.mu.Unlock()
|
||||||
if img != nil {
|
|
||||||
img.Resource = nil
|
|
||||||
img.File = ""
|
|
||||||
img.Image = frame
|
|
||||||
img.Refresh()
|
|
||||||
}
|
|
||||||
}, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
p.current = offset
|
||||||
|
p.frameN = int(p.current * p.fps)
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
logging.Error(logging.CatPlayer, "playSession: GStreamer player not available")
|
|
||||||
|
_ = 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 {
|
||||||
|
prog(offset)
|
||||||
|
}
|
||||||
|
if frameFunc != nil {
|
||||||
|
frameFunc(int(offset * p.fps))
|
||||||
|
}
|
||||||
|
if paused {
|
||||||
|
frame, err := gstPlayer.GetFrameImage()
|
||||||
|
if err == nil && frame != nil {
|
||||||
|
fyne.CurrentApp().Driver().DoFromGoroutine(func() {
|
||||||
|
if img != nil {
|
||||||
|
img.Resource = nil
|
||||||
|
img.File = ""
|
||||||
|
img.Image = frame
|
||||||
|
img.Refresh()
|
||||||
|
}
|
||||||
|
}, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user