Skip to content

Commit 7f80415

Browse files
committed
fix: cap initial buffer for live radio
1 parent 956fb3d commit 7f80415

7 files changed

Lines changed: 32 additions & 17 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ in mpv; if no station has been started yet, it is ignored.
160160
| key | action |
161161
| --- | --- |
162162
| `j` / `` · `k` / `` | select setting |
163-
| `h` / `` · `l` / `` | adjust by 5 seconds |
163+
| `h` / `` · `l` / `` | adjust by 5 seconds (`initial buffer` is capped at 10s) |
164164
| `0` | turn selected setting off |
165165
| `enter` | save |
166166
| `esc` | cancel |
@@ -241,7 +241,7 @@ on first run with sensible defaults; a documented example sits at
241241
theme: tokyo-night # see Themes below for all built-in theme ids
242242
volume: 60 # initial volume, 0–100
243243
buffer_seconds: 30 # network read-ahead; try 60–120 on flaky Wi-Fi
244-
initial_buffer_seconds: 0 # wait before start/resume; try 5–10 if streams stutter
244+
initial_buffer_seconds: 0 # wait before start/resume; capped at 10s for live radio
245245
246246
stations:
247247
- name: SomaFM Groove Salad

README.ru.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ lofi-player
164164
| клавиша | действие |
165165
| --- | --- |
166166
| `j` / `` · `k` / `` | выбрать настройку |
167-
| `h` / `` · `l` / `` | изменить на 5 секунд |
167+
| `h` / `` · `l` / `` | изменить на 5 секунд (`initial buffer` максимум 10с) |
168168
| `0` | выключить выбранную настройку |
169169
| `enter` | сохранить |
170170
| `esc` | отмена |
@@ -247,7 +247,7 @@ lofi-player --import - < stations.yaml
247247
theme: tokyo-night # все встроенные id см. в разделе «Темы»
248248
volume: 60 # стартовая громкость, 0–100
249249
buffer_seconds: 30 # сетевой запас; для плохого Wi-Fi попробуй 60–120
250-
initial_buffer_seconds: 0 # ждать перед стартом/возобновлением; попробуй 5–10
250+
initial_buffer_seconds: 0 # ждать перед стартом/возобновлением; максимум 10с для live-radio
251251
252252
stations:
253253
- name: SomaFM Groove Salad

internal/audio/player.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ type Options struct {
109109
BufferSeconds int
110110
// InitialBufferSeconds makes mpv wait for this many seconds of cache
111111
// before starting/resuming after a cache stall. 0 starts immediately.
112+
// Values above 10 are clamped because many live-radio streams never
113+
// build a deeper initial cache and would appear stuck.
112114
InitialBufferSeconds int
113115
}
114116

@@ -141,7 +143,11 @@ type Player struct {
141143
lastCacheSec float64
142144
}
143145

144-
const mainInputConf = "PAUSE cycle pause\n"
146+
const (
147+
mainInputConf = "PAUSE cycle pause\n"
148+
maxBufferSeconds = 600
149+
maxInitialBufferSeconds = 10
150+
)
145151

146152
func mainMPVArgs(socketPath string, opts Options) []string {
147153
args := []string{
@@ -162,8 +168,8 @@ func mainMPVArgs(socketPath string, opts Options) []string {
162168
}
163169

164170
func networkCacheArgs(opts Options) []string {
165-
bufferSec := clampSeconds(opts.BufferSeconds, 0, 600)
166-
initialSec := clampSeconds(opts.InitialBufferSeconds, 0, 120)
171+
bufferSec := clampSeconds(opts.BufferSeconds, 0, maxBufferSeconds)
172+
initialSec := clampSeconds(opts.InitialBufferSeconds, 0, maxInitialBufferSeconds)
167173
if initialSec > bufferSec {
168174
bufferSec = initialSec
169175
}

internal/audio/player_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,10 @@ func TestMainMPVArgsConfigureNetworkBuffer(t *testing.T) {
235235
}
236236
}
237237

238-
func TestMainMPVArgsInitialBufferExtendsReadahead(t *testing.T) {
238+
func TestMainMPVArgsInitialBufferIsCappedForLiveRadio(t *testing.T) {
239239
args := mainMPVArgs("/tmp/lofi-player-test.sock", Options{InitialBufferSeconds: 45})
240-
if !hasArg(args, "--demuxer-readahead-secs=45") {
241-
t.Fatalf("main mpv args %v did not extend readahead to initial buffer", args)
240+
if !hasArg(args, "--demuxer-readahead-secs=10") || !hasArg(args, "--cache-pause-wait=10") {
241+
t.Fatalf("main mpv args %v did not cap initial buffer to 10s", args)
242242
}
243243
}
244244

internal/tui/model_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,12 @@ func TestSettingsModalAdjustSaveAndCancel(t *testing.T) {
265265
t.Fatalf("saved buffer settings = %d/%d, want 35/10", cfg.BufferSeconds, cfg.InitialBufferSeconds)
266266
}
267267

268-
m = send(t, m, "o", "0", "esc")
268+
m = send(t, m, "o", "j", "l")
269+
if m.settingsInitialBufferSeconds != 10 {
270+
t.Fatalf("initial buffer exceeded cap: got %d, want 10", m.settingsInitialBufferSeconds)
271+
}
272+
273+
m = send(t, m, "0", "esc")
269274
if cfg.BufferSeconds != 35 || cfg.InitialBufferSeconds != 10 {
270275
t.Fatalf("cancel changed config to %d/%d", cfg.BufferSeconds, cfg.InitialBufferSeconds)
271276
}

internal/tui/update.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import (
1515
"github.com/iRootPro/lofi-player/internal/theme"
1616
)
1717

18-
const volumeStep = 5
18+
const (
19+
volumeStep = 5
20+
settingsMaxBufferSeconds = 600
21+
settingsMaxInitialSeconds = 10
22+
)
1923

2024
// Update applies a message to the model and returns the new model plus
2125
// any commands to run. Receiver is by value; never mutate m through a
@@ -429,8 +433,8 @@ func (m Model) openSettings() Model {
429433
m.modePrev = m.mode
430434
m.mode = modeSettings
431435
m.settingsCursor = 0
432-
m.settingsBufferSeconds = m.cfg.BufferSeconds
433-
m.settingsInitialBufferSeconds = m.cfg.InitialBufferSeconds
436+
m.settingsBufferSeconds = clampInt(m.cfg.BufferSeconds, 0, settingsMaxBufferSeconds)
437+
m.settingsInitialBufferSeconds = clampInt(m.cfg.InitialBufferSeconds, 0, settingsMaxInitialSeconds)
434438
return m
435439
}
436440

@@ -443,9 +447,9 @@ func (m Model) updateSettings(msg tea.Msg) (tea.Model, tea.Cmd) {
443447
adjust := func(delta int) {
444448
switch m.settingsCursor {
445449
case 0:
446-
m.settingsBufferSeconds = clampInt(m.settingsBufferSeconds+delta, 0, 600)
450+
m.settingsBufferSeconds = clampInt(m.settingsBufferSeconds+delta, 0, settingsMaxBufferSeconds)
447451
case 1:
448-
m.settingsInitialBufferSeconds = clampInt(m.settingsInitialBufferSeconds+delta, 0, 120)
452+
m.settingsInitialBufferSeconds = clampInt(m.settingsInitialBufferSeconds+delta, 0, settingsMaxInitialSeconds)
449453
}
450454
}
451455
zero := func() {

internal/tui/view.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func (m Model) viewSettings() string {
238238
{
239239
label: "initial buffer",
240240
value: formatSettingsSeconds(m.settingsInitialBufferSeconds, "off"),
241-
desc: "wait before start/resume after cache stalls",
241+
desc: "wait before start/resume, capped at 10s for live radio",
242242
},
243243
}
244244

0 commit comments

Comments
 (0)