Add audio-only music mode

Persistent per-platform mode that plays only the audio track to save
bandwidth and speed up loads. When enabled, stream selection picks the
best audio-only stream (preferred language, codec, bitrate) and never
fetches the video URL; toggling mid-video reloads at the current
position using the quality-switch path (live vid=no toggling is avoided
due to A/V desync).

- Toggle row in the player quality/settings sheet on iOS, macOS and
  tvOS, next to lock controls
- New audioMode control button type (red when active) for player
  controls and mini player layouts
- Picking a video quality explicitly turns the mode off; audio track
  picks keep it on and now work while audio-only is playing
- Stream URL refresh preserves audio-only playback instead of
  resurrecting video
- Queue preloads and history entries resolved before a toggle are
  discarded so selection re-runs with the current mode
- tvOS player shows the video thumbnail instead of a black screen
  during audio-only playback
- PiP button hidden for audio-only streams
This commit is contained in:
Arkadiusz Fal
2026-07-13 19:06:01 +02:00
parent 66f7602d08
commit 06087220ef
19 changed files with 352 additions and 85 deletions

View File

@@ -271,6 +271,19 @@ struct MacOSControlsSectionRenderer: View {
.opacity(isLocked ? 0.5 : 1.0)
}
case .audioMode:
if actions.onToggleAudioMode != nil {
controlButton(
systemImage: "music.note",
tint: actions.isAudioModeEnabled ? .red : tint,
help: config.buttonType.displayName
) {
actions.onToggleAudioMode?()
}
.disabled(isLocked)
.opacity(isLocked ? 0.5 : 1.0)
}
case .seek:
if let settings = config.seekSettings {
seekButton(settings: settings, config: config)

View File

@@ -211,6 +211,7 @@ struct MacOSPlayerControlsView: View {
currentStream: nil,
currentAudioStream: nil,
isAutoPlayNextEnabled: appEnvironment?.settingsManager.queueAutoPlayNext ?? true,
isAudioModeEnabled: appEnvironment?.settingsManager.audioOnlyModeEnabled ?? false,
yatteeServerURL: yatteeServerURL,
deArrowBrandingProvider: appEnvironment?.deArrowBrandingProvider,
onClose: onClose,
@@ -225,6 +226,11 @@ struct MacOSPlayerControlsView: View {
onToggleAutoPlayNext: { [weak appEnvironment] in
appEnvironment?.settingsManager.queueAutoPlayNext.toggle()
},
onToggleAudioMode: { [weak appEnvironment] in
guard let appEnvironment else { return }
let enabled = !appEnvironment.settingsManager.audioOnlyModeEnabled
Task { await appEnvironment.playerService.setAudioMode(enabled) }
},
onShowSettings: onShowSettings,
onPlayNext: onPlayNext,
onPlayPrevious: onPlayPrevious,