mirror of
https://github.com/yattee/yattee.git
synced 2026-07-21 06:42:01 +00:00
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:
@@ -323,14 +323,22 @@ extension QualitySelectorView {
|
||||
@ViewBuilder
|
||||
var generalSectionContent: some View {
|
||||
#if os(tvOS)
|
||||
// tvOS only has the speed row here; style it to match the Settings rows.
|
||||
playbackSpeedRow
|
||||
// tvOS rows are styled individually to match the Settings rows.
|
||||
VStack(spacing: 8) {
|
||||
playbackSpeedRow
|
||||
|
||||
audioModeRow
|
||||
}
|
||||
#else
|
||||
VStack(spacing: 0) {
|
||||
playbackSpeedRow
|
||||
|
||||
Divider()
|
||||
|
||||
audioModeRow
|
||||
|
||||
Divider()
|
||||
|
||||
lockControlsRow
|
||||
}
|
||||
.cardBackground()
|
||||
@@ -408,6 +416,45 @@ extension QualitySelectorView {
|
||||
#endif
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var audioModeRow: some View {
|
||||
#if os(tvOS)
|
||||
Button {
|
||||
onAudioModeToggled?(!isAudioMode)
|
||||
} label: {
|
||||
HStack {
|
||||
Label(String(localized: "player.quality.audioMode"), systemImage: "music.note")
|
||||
.font(.headline)
|
||||
|
||||
Spacer()
|
||||
|
||||
Text(isAudioMode ? String(localized: "common.on") : String(localized: "common.off"))
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
.padding(.vertical, 14)
|
||||
.padding(.horizontal, 20)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(TVSettingsRowButtonStyle())
|
||||
#else
|
||||
HStack {
|
||||
Label(String(localized: "player.quality.audioMode"), systemImage: "music.note")
|
||||
.font(.headline)
|
||||
|
||||
Spacer()
|
||||
|
||||
Toggle("", isOn: Binding(
|
||||
get: { isAudioMode },
|
||||
set: { onAudioModeToggled?($0) }
|
||||
))
|
||||
.labelsHidden()
|
||||
}
|
||||
.padding(.vertical, 12)
|
||||
.padding(.horizontal, 12)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
@ViewBuilder
|
||||
private var lockControlsRow: some View {
|
||||
@@ -751,7 +798,11 @@ extension QualitySelectorView {
|
||||
|
||||
private func handleAudioStreamTap(_ stream: Stream) {
|
||||
selectedAudioStream = stream
|
||||
if let video = selectedVideoStream, video.isVideoOnly {
|
||||
if currentStream?.isAudioOnly == true {
|
||||
// Audio mode / audio-only content: the tapped track IS the main stream
|
||||
onStreamSelected(stream, nil)
|
||||
performDismiss()
|
||||
} else if let video = selectedVideoStream, video.isVideoOnly {
|
||||
onStreamSelected(video, stream)
|
||||
performDismiss()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user