Skip to content

Commit 0d352a4

Browse files
committed
feat: player: add automatic retry on stream interruption
- impl retry mechanism when core goes idle after initial playback - attempt reconnection up to `RetryTimesWhenStreamInterrupt` (8) times - bell sound cue when retry attempts
1 parent b81a0ac commit 0d352a4

3 files changed

Lines changed: 26 additions & 4 deletions

File tree

src/ui/playerui.nim

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import
1414
utils
1515
],
1616

17-
../misc/like
17+
../misc/[like, bell]
1818

1919
when not defined(simple):
2020
import
@@ -57,6 +57,9 @@ func getPerCycleSleepTimeFade(vol: int): int =
5757
let steps = int vol / 5
5858
result = int toTime / steps
5959

60+
template tryToPlayAgain(url: string) =
61+
ctx.allocateJobMpv(url)
62+
6063
proc playStation*(ctx: ptr Handle, config: MenuConfig) =
6164
## Plays a radio station and handles user input for playback control.
6265
#try:
@@ -90,6 +93,8 @@ proc playStation*(ctx: ptr Handle, config: MenuConfig) =
9093
var fullTitle: string # Declare fullTitle here
9194
var finishedLoading = false
9295
var spinnerState = 0
96+
var wasTheStreamPlayingForSomeTime: bool
97+
var streamInterruptRetryCount = 1
9398

9499
when not defined(simple):
95100
var metadata = initTable[string, string](8) # Declare metadata here
@@ -130,6 +135,7 @@ proc playStation*(ctx: ptr Handle, config: MenuConfig) =
130135
globalMetadata = updateMetadataUI(config, ctx, state)
131136

132137
if event.eventID in {IDFileLoaded}:
138+
wasTheStreamPlayingForSomeTime = true
133139
when defined(volumeFade):
134140
var volumeForFading = 0
135141
ctx.setVolumeMpv(volumeForFading)
@@ -167,8 +173,22 @@ proc playStation*(ctx: ptr Handle, config: MenuConfig) =
167173
# Periodic checks
168174
if coreIdleCounter >= CheckIdleInterval:
169175
if ctx.isIdle():
170-
handlePlayerError("Player core idle", config)
171-
break
176+
if streamInterruptRetryCount < RetryTimesWhenStreamInterrupt and
177+
wasTheStreamPlayingForSomeTime:
178+
tryToPlayAgain(config.stationUrl)
179+
streamInterruptRetryCount += 1
180+
setCursorPos 4, 7
181+
stdout.write "retrying count "
182+
echo streamInterruptRetryCount
183+
if streamInterruptRetryCount mod 2 != 0:
184+
warnBell()
185+
sleep 500
186+
cursorUp()
187+
eraseLine()
188+
189+
else:
190+
handlePlayerError("Player core idle", config)
191+
break
172192

173193
if event.eventID in {IDEndFile, IDShutdown}:
174194
if config.stationUrl.isValidPlaylistUrl():

src/utils/utils.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ export #utilstypes
129129
DefaultErrorMsg,
130130
MinTerminalWidth,
131131
MaxStationNameLength,
132-
mpvEventLoopTimeout
132+
mpvEventLoopTimeout,
133+
RetryTimesWhenStreamInterrupt
133134

134135
when not defined(simple):
135136
export #utilstypes

src/utils/utilstypes.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,4 @@ const
113113
MinTerminalWidth* = 40
114114
MaxStationNameLength* = 22
115115
mpvEventLoopTimeout* = KeyTimeout.milSecToSec()
116+
RetryTimesWhenStreamInterrupt* = 8

0 commit comments

Comments
 (0)