@@ -18,6 +18,7 @@ import (
1818
1919 "github.com/dweymouth/supersonic/backend/mediaprovider"
2020 "github.com/dweymouth/supersonic/backend/player"
21+ "github.com/dweymouth/supersonic/backend/player/common"
2122 "github.com/dweymouth/supersonic/backend/util"
2223 "github.com/hashicorp/go-retryablehttp"
2324 "github.com/supersonic-app/go-upnpcast/device"
@@ -83,9 +84,7 @@ type DLNAPlayer struct {
8384 failedToSetNext bool
8485 unsetNextMediaItem * avtransport.MediaItem
8586
86- timerActive atomic.Bool
87- timer * time.Timer
88- resetChan chan (time.Duration )
87+ trackChangeTimer common.TrackChangeTimer
8988}
9089
9190func NewDLNAPlayer (device * device.MediaRenderer ) (* DLNAPlayer , error ) {
@@ -113,11 +112,13 @@ func NewDLNAPlayer(device *device.MediaRenderer) (*DLNAPlayer, error) {
113112 return nil , fmt .Errorf ("failed to connect to %s" , device .FriendlyName )
114113 }
115114
116- return & DLNAPlayer {
115+ d := & DLNAPlayer {
117116 avTransport : avt ,
118117 renderControl : rc ,
119- resetChan : make (chan time.Duration ),
120- }, nil
118+ }
119+ d .trackChangeTimer = common .NewTrackChangeTimer (d .handleOnTrackChange )
120+
121+ return d , nil
121122}
122123
123124func (d * DLNAPlayer ) SetVolume (vol int ) error {
@@ -182,7 +183,7 @@ func (d *DLNAPlayer) PlayFile(urlstr string, meta mediaprovider.MediaItemMetadat
182183 }
183184 d .state = playing
184185 remainingDur := meta .Duration - time .Duration (startTime )* time .Second
185- d .setTrackChangeTimer (remainingDur )
186+ d .trackChangeTimer . Reset (remainingDur )
186187 d .stopwatch .Reset ()
187188 d .stopwatch .Start ()
188189 d .lastStartTime = int (startTime )
@@ -271,7 +272,7 @@ func (d *DLNAPlayer) Continue() error {
271272 nextTrackChange := d .curTrackMeta .Duration - d .curPlayPos ()
272273 d .metaLock .Unlock ()
273274 d .state = playing
274- d .setTrackChangeTimer (nextTrackChange )
275+ d .trackChangeTimer . Reset (nextTrackChange )
275276 d .stopwatch .Start ()
276277 d .InvokeOnPlaying ()
277278 return nil
@@ -288,7 +289,7 @@ func (d *DLNAPlayer) Pause() error {
288289 if err := d .avTransport .Pause (ctx ); err != nil {
289290 return err
290291 }
291- d .setTrackChangeTimer (0 )
292+ d .trackChangeTimer . Reset (0 )
292293 d .stopwatch .Stop ()
293294 d .state = paused
294295 d .InvokeOnPaused ()
@@ -322,7 +323,7 @@ func (d *DLNAPlayer) Stop(force bool) error {
322323 }
323324 fallthrough
324325 case paused :
325- d .setTrackChangeTimer (0 )
326+ d .trackChangeTimer . Reset (0 )
326327 d .stopwatch .Reset ()
327328 d .lastStartTime = 0
328329 d .state = stopped
@@ -354,7 +355,7 @@ func (d *DLNAPlayer) SeekSeconds(secs float64) error {
354355 d .metaLock .Lock ()
355356 nextTrackChange := d .curTrackMeta .Duration - time .Duration (secs )* time .Second
356357 d .metaLock .Unlock ()
357- d .setTrackChangeTimer (nextTrackChange )
358+ d .trackChangeTimer . Reset (nextTrackChange )
358359 d .stopwatch .Start ()
359360 }
360361
@@ -410,7 +411,7 @@ func (d *DLNAPlayer) curPlayPos() time.Duration {
410411
411412func (d * DLNAPlayer ) Destroy () {
412413 d .destroyed = true
413- d .setTrackChangeTimer (0 )
414+ d .trackChangeTimer . Reset (0 )
414415 if d .cancelRequest != nil {
415416 d .cancelRequest ()
416417 }
@@ -431,7 +432,7 @@ func (d *DLNAPlayer) syncPlaybackTime() {
431432 if d .state == playing {
432433 d .stopwatch .Start ()
433434 }
434- d .setTrackChangeTimer (d .curTrackMeta .Duration - time .Duration (d .lastStartTime )* time .Second )
435+ d .trackChangeTimer . Reset (d .curTrackMeta .Duration - time .Duration (d .lastStartTime )* time .Second )
435436 d .InvokeOnSeek ()
436437 }
437438}
@@ -461,51 +462,6 @@ func (d *DLNAPlayer) ensureSetupProxy() error {
461462 return nil
462463}
463464
464- func (d * DLNAPlayer ) setTrackChangeTimer (dur time.Duration ) {
465- if d .timerActive .Swap (true ) {
466- // was active
467- d .resetChan <- dur
468- return
469- }
470- if dur == 0 {
471- d .timerActive .Store (false )
472- return
473- }
474-
475- d .timer = time .NewTimer (dur )
476- go func () {
477- for {
478- select {
479- case dur := <- d .resetChan :
480- if dur == 0 {
481- d .timerActive .Store (false )
482- if ! d .timer .Stop () {
483- select {
484- case <- d .timer .C :
485- default :
486- }
487- }
488- d .timer = nil
489- return
490- }
491- // reset the timer
492- if ! d .timer .Stop () {
493- select {
494- case <- d .timer .C :
495- default :
496- }
497- }
498- d .timer .Reset (dur )
499- case <- d .timer .C :
500- d .timerActive .Store (false )
501- d .timer = nil
502- d .handleOnTrackChange ()
503- return
504- }
505- }
506- }()
507- }
508-
509465func (d * DLNAPlayer ) handleOnTrackChange () {
510466 stopping := false
511467 d .metaLock .Lock ()
@@ -536,7 +492,7 @@ func (d *DLNAPlayer) handleOnTrackChange() {
536492 d .lastStartTime = 0
537493 d .stopwatch .Reset ()
538494 d .stopwatch .Start ()
539- d .setTrackChangeTimer (nextTrackChange )
495+ d .trackChangeTimer . Reset (nextTrackChange )
540496 d .InvokeOnTrackChange ()
541497
542498 go func () {
0 commit comments