add shared callback impl between mpv and jukebox players

This commit is contained in:
Drew Weymouth
2024-09-01 08:45:09 -07:00
parent c2efb048e2
commit faf067ce7e
4 changed files with 80 additions and 60 deletions
-1
View File
@@ -279,7 +279,6 @@ func (p *playbackEngine) LoadRadioStation(radio *mediaprovider.RadioStation, ins
func (p *playbackEngine) StopAndClearPlayQueue() {
changed := len(p.playQueue) > 0
p.player.Stop()
p.doUpdateTimePos(false)
p.playQueue = nil
p.nowPlayingIdx = -1
if changed {
+6
View File
@@ -14,6 +14,8 @@ const (
)
type JukeboxPlayer struct {
player.BasePlayerCallbackImpl
provider mediaprovider.JukeboxProvider
state int // stopped, playing, paused
@@ -49,6 +51,7 @@ func (j *JukeboxPlayer) Continue() error {
}
j.state = playing
j.InvokeOnPlaying()
return nil
}
@@ -61,6 +64,7 @@ func (j *JukeboxPlayer) Pause() error {
}
// TODO: calculate paused at time
j.state = paused
j.InvokeOnPaused()
return nil
}
@@ -72,6 +76,7 @@ func (j *JukeboxPlayer) Stop() error {
return err
}
j.state = stopped
j.InvokeOnStopped()
return nil
}
@@ -112,6 +117,7 @@ func (j *JukeboxPlayer) SeekSeconds(secs float64) error {
j.seeking = true
err := j.provider.JukeboxSeek(j.curTrack, int(secs))
j.seeking = false
j.InvokeOnSeek()
return err
}
+9 -59
View File
@@ -7,8 +7,8 @@ import (
"math"
"strconv"
"github.com/supersonic-app/go-mpv"
"github.com/dweymouth/supersonic/backend/player"
"github.com/supersonic-app/go-mpv"
)
// Error returned by many Player functions if called before the player has not been initialized.
@@ -50,6 +50,8 @@ var _ player.URLPlayer = (*Player)(nil)
// Player encapsulates the mpv instance and provides functions
// to control it and to check its status.
type Player struct {
player.BasePlayerCallbackImpl
mpv *mpv.Mpv
initialized bool
vol int
@@ -66,13 +68,6 @@ type Player struct {
peaksEnabled bool
bgCancel context.CancelFunc
// callbacks
onPaused []func()
onStopped []func()
onPlaying []func()
onSeek []func()
onTrackChange []func()
}
// Returns a new player.
@@ -403,33 +398,6 @@ func (p *Player) IsSeeking() bool {
return p.seeking && p.status.State == player.Playing
}
// Registers a callback which is invoked when the player transitions to the Paused state.
func (p *Player) OnPaused(cb func()) {
p.onPaused = append(p.onPaused, cb)
}
// Registers a callback which is invoked when the player transitions to the Stopped state.
func (p *Player) OnStopped(cb func()) {
p.onStopped = append(p.onStopped, cb)
}
// Registers a callback which is invoked when the player transitions to the Playing state.
func (p *Player) OnPlaying(cb func()) {
p.onPlaying = append(p.onPlaying, cb)
}
// Registers a callback which is invoked whenever a seek event occurs.
func (p *Player) OnSeek(cb func()) {
p.onSeek = append(p.onSeek, cb)
}
// Registers a callback which is invoked when the currently playing track changes,
// or when playback begins at any time from the Stopped state.
// Callback is invoked with the index of the currently playing track (zero-based).
func (p *Player) OnTrackChange(cb func()) {
p.onTrackChange = append(p.onTrackChange, cb)
}
// Destroy the player.
func (p *Player) Destroy() {
if p.bgCancel != nil {
@@ -466,23 +434,11 @@ func (p *Player) GetPeaks() (float64, float64, float64, float64) {
func (p *Player) setState(s player.State) {
switch {
case s == player.Playing && p.status.State != player.Playing:
defer func() {
for _, cb := range p.onPlaying {
cb()
}
}()
defer p.InvokeOnPlaying()
case s == player.Paused && p.status.State != player.Paused:
defer func() {
for _, cb := range p.onPaused {
cb()
}
}()
defer p.InvokeOnPaused()
case s == player.Stopped && p.status.State != player.Stopped:
defer func() {
for _, cb := range p.onStopped {
cb()
}
}()
defer p.InvokeOnStopped()
}
p.status.State = s
}
@@ -523,21 +479,15 @@ func (p *Player) eventHandler(ctx context.Context) {
p.seeking = false
}
case mpv.EVENT_SEEK:
for _, cb := range p.onSeek {
cb()
}
p.InvokeOnSeek()
case mpv.EVENT_FILE_LOADED:
p.curPlaylistPos, _ = p.getInt64Property("playlist-pos")
if p.status.State == player.Paused {
// seek while paused switches to a new file
// mpv does not fire seek event in this case
for _, cb := range p.onSeek {
cb()
}
}
for _, cb := range p.onTrackChange {
cb()
p.InvokeOnSeek()
}
p.InvokeOnTrackChange()
case mpv.EVENT_IDLE:
p.status.Duration = 0
p.status.TimePos = 0
+65
View File
@@ -82,3 +82,68 @@ func (r ReplayGainMode) String() string {
return "no"
}
}
type BasePlayerCallbackImpl struct {
onPaused []func()
onStopped []func()
onPlaying []func()
onSeek []func()
onTrackChange []func()
}
// Registers a callback which is invoked when the player transitions to the Paused state.
func (p *BasePlayerCallbackImpl) OnPaused(cb func()) {
p.onPaused = append(p.onPaused, cb)
}
// Registers a callback which is invoked when the player transitions to the Stopped state.
func (p *BasePlayerCallbackImpl) OnStopped(cb func()) {
p.onStopped = append(p.onStopped, cb)
}
// Registers a callback which is invoked when the player transitions to the Playing state.
func (p *BasePlayerCallbackImpl) OnPlaying(cb func()) {
p.onPlaying = append(p.onPlaying, cb)
}
// Registers a callback which is invoked whenever a seek event occurs.
func (p *BasePlayerCallbackImpl) OnSeek(cb func()) {
p.onSeek = append(p.onSeek, cb)
}
// Registers a callback which is invoked when the currently playing track changes,
// or when playback begins at any time from the Stopped state.
// Callback is invoked with the index of the currently playing track (zero-based).
func (p *BasePlayerCallbackImpl) OnTrackChange(cb func()) {
p.onTrackChange = append(p.onTrackChange, cb)
}
func (p *BasePlayerCallbackImpl) InvokeOnPaused() {
for _, cb := range p.onPaused {
cb()
}
}
func (p *BasePlayerCallbackImpl) InvokeOnPlaying() {
for _, cb := range p.onPlaying {
cb()
}
}
func (p *BasePlayerCallbackImpl) InvokeOnStopped() {
for _, cb := range p.onStopped {
cb()
}
}
func (p *BasePlayerCallbackImpl) InvokeOnSeek() {
for _, cb := range p.onSeek {
cb()
}
}
func (p *BasePlayerCallbackImpl) InvokeOnTrackChange() {
for _, cb := range p.onTrackChange {
cb()
}
}