Apply audio mode to downloaded videos

Downloads bypass stream selection and reach play() as ready-made local
file streams, so audio mode never affected them. Apply the mode at that
choke point instead: swap a local video stream for the separately
downloaded audio track, or play a muxed file with the video track
disabled (vid set per-load in MPVClient, never toggled live). The
transform is bidirectional so stored audio-only queue/history entries
restore full video when the mode is off, and setAudioMode now reloads
downloaded content at the current position in both directions.
This commit is contained in:
Arkadiusz Fal
2026-07-17 09:27:09 +02:00
parent 6514cb426e
commit c2554cee04
4 changed files with 111 additions and 7 deletions

View File

@@ -621,13 +621,24 @@ final class MPVClient: @unchecked Sendable {
/// - audioURL: Optional separate audio track URL (for video-only streams)
/// - httpHeaders: Optional HTTP headers for streaming (cookies, referer, etc.)
/// - useEDL: If true and audioURL is provided, combine streams using EDL for unified caching
/// - disableVideoTrack: If true, load with the video track disabled (audio mode for muxed files)
/// - options: Additional MPV options
func loadFile(_ url: URL, audioURL: URL? = nil, httpHeaders: [String: String]? = nil, useEDL: Bool = true, options: [String] = []) throws {
func loadFile(_ url: URL, audioURL: URL? = nil, httpHeaders: [String: String]? = nil, useEDL: Bool = true, disableVideoTrack: Bool = false, options: [String] = []) throws {
try mpvQueue.sync {
guard mpv != nil, !isDestroyed else {
throw MPVError.commandFailed("loadfile")
}
// Video track selection for the upcoming file. Set as a property
// before the loadfile command (per-file loadfile options moved to
// the 4th argument in mpv 0.38+, so they can't be relied on here).
// Only ever changed between loads, never live - live `vid` toggling
// causes A/V desync (see handlePlayerSheetVisibility).
setPropertyUnsafe("vid", disableVideoTrack ? "no" : "auto")
if disableVideoTrack {
logDebug("Video track disabled for this load (audio mode)")
}
// Set HTTP headers as a property before loading (if provided)
// Use MPV_FORMAT_NODE_ARRAY for proper header handling
if let httpHeaders, !httpHeaders.isEmpty {