Major improvements to UnifiedPlayer: 1. GetFrameImage() now works when paused for responsive UI updates 2. Play() method properly starts FFmpeg process 3. Frame display loop runs continuously for smooth video display 4. Disabled audio temporarily to fix video playback fundamentals 5. Simplified FFmpeg command to focus on video stream only Player now: - Generates video frames correctly - Shows video when paused - Has responsive progress tracking - Starts playback properly Next steps: Re-enable audio playback once video is stable
122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package app
|
|
|
|
import (
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/internal/async"
|
|
)
|
|
|
|
var _ fyne.Lifecycle = (*Lifecycle)(nil)
|
|
|
|
// Lifecycle represents the various phases that an app can transition through.
|
|
//
|
|
// Since: 2.1
|
|
type Lifecycle struct {
|
|
onForeground func()
|
|
onBackground func()
|
|
onStarted func()
|
|
onStopped func()
|
|
|
|
onStoppedHookExecuted func()
|
|
|
|
eventQueue *async.UnboundedChan[func()]
|
|
}
|
|
|
|
// SetOnStoppedHookExecuted is an internal function that lets Fyne schedule a clean-up after
|
|
// the user-provided stopped hook. It should only be called once during an application start-up.
|
|
func (l *Lifecycle) SetOnStoppedHookExecuted(f func()) {
|
|
l.onStoppedHookExecuted = f
|
|
}
|
|
|
|
// SetOnEnteredForeground hooks into the app becoming foreground.
|
|
func (l *Lifecycle) SetOnEnteredForeground(f func()) {
|
|
l.onForeground = f
|
|
}
|
|
|
|
// SetOnExitedForeground hooks into the app having moved to the background.
|
|
// Depending on the platform it may still be visible but will not receive keyboard events.
|
|
// On some systems hover or desktop mouse move events may still occur.
|
|
func (l *Lifecycle) SetOnExitedForeground(f func()) {
|
|
l.onBackground = f
|
|
}
|
|
|
|
// SetOnStarted hooks into an event that says the app is now running.
|
|
func (l *Lifecycle) SetOnStarted(f func()) {
|
|
l.onStarted = f
|
|
}
|
|
|
|
// SetOnStopped hooks into an event that says the app is no longer running.
|
|
func (l *Lifecycle) SetOnStopped(f func()) {
|
|
l.onStopped = f
|
|
}
|
|
|
|
// OnEnteredForeground returns the focus gained hook, if one is registered.
|
|
func (l *Lifecycle) OnEnteredForeground() func() {
|
|
return l.onForeground
|
|
}
|
|
|
|
// OnExitedForeground returns the focus lost hook, if one is registered.
|
|
func (l *Lifecycle) OnExitedForeground() func() {
|
|
return l.onBackground
|
|
}
|
|
|
|
// OnStarted returns the started hook, if one is registered.
|
|
func (l *Lifecycle) OnStarted() func() {
|
|
return l.onStarted
|
|
}
|
|
|
|
// OnStopped returns the stopped hook, if one is registered.
|
|
func (l *Lifecycle) OnStopped() func() {
|
|
stopped := l.onStopped
|
|
stopHook := l.onStoppedHookExecuted
|
|
if stopped == nil && stopHook == nil {
|
|
return nil
|
|
}
|
|
|
|
if stopHook == nil {
|
|
return stopped
|
|
}
|
|
|
|
if stopped == nil {
|
|
return stopHook
|
|
}
|
|
|
|
// we have a stopped handle and the onStoppedHook
|
|
return func() {
|
|
stopped()
|
|
stopHook()
|
|
}
|
|
}
|
|
|
|
// DestroyEventQueue destroys the event queue.
|
|
func (l *Lifecycle) DestroyEventQueue() {
|
|
l.eventQueue.Close()
|
|
}
|
|
|
|
// InitEventQueue initializes the event queue.
|
|
func (l *Lifecycle) InitEventQueue() {
|
|
// This channel should be closed when the window is closed.
|
|
l.eventQueue = async.NewUnboundedChan[func()]()
|
|
}
|
|
|
|
// QueueEvent uses this method to queue up a callback that handles an event. This ensures
|
|
// user interaction events for a given window are processed in order.
|
|
func (l *Lifecycle) QueueEvent(fn func()) {
|
|
l.eventQueue.In() <- fn
|
|
}
|
|
|
|
// RunEventQueue runs the event queue. This should called inside a go routine.
|
|
// This function blocks.
|
|
func (l *Lifecycle) RunEventQueue(run func(func(), bool)) {
|
|
for fn := range l.eventQueue.Out() {
|
|
run(fn, true)
|
|
}
|
|
}
|
|
|
|
// WaitForEvents wait for all the events.
|
|
func (l *Lifecycle) WaitForEvents() {
|
|
done := make(chan struct{})
|
|
|
|
l.eventQueue.In() <- func() { done <- struct{}{} }
|
|
<-done
|
|
}
|