Beim Umpacken fällt die Spurwahl an — also wird sie dort getroffen

Dein Befund an „Notruf Hafenkante": keine Spuren, nichts auswählbar. Die
technischen Angaben derselben Folge sagen, warum:

    Container    MKV
    Tonspur      AAC - Stereo - Standard
    Tonspur      Deutsch - German - AAC - Stereo - Standard
    Untertitel   German - Standard - SUBRIP

Die Quelle ist Matroska. AVFoundation öffnet das nicht, also lief der
Download bisher über die zweite Engine — und die meldete die Spurliste leer.
Offline wählen ging damit nie.

**Umpacken allein hätte es nicht gelöst.** Jellyfin bildet in die neue Hülle
genau **eine** Tonspur ab und übernimmt den Untertitel nur, wenn man ihn
nennt. Ohne Angabe nimmt der Server seine eigene Vorgabe — und das ist bei
deutschen Aufnahmen regelmäßig die Spur mit Audiodeskription.

Also fällt die Wahl jetzt beim Herunterladen, mit derselben Abwägung wie beim
Abspielen (`AudioTrackChooser`, der für genau diesen Fall gebaut wurde: die
als deutsch ausgezeichnete Spur ist die mit Audiodeskription). Der Untertitel
geht als `subtitleMethod=Embed` mit — als **Spur**, nicht ins Bild gebrannt,
sonst liesse er sich nicht abschalten.

Die Mediathek bleibt bei der Abwägung aussen vor: sie nachzuschlagen kostet
eine Anfrage je Folge, und Serie und allgemeine Einstellung tragen den Wunsch
ohnehin.

Der Offline-Abzug behauptet nicht mehr, alle Sprachen seien dabei — beim
Umpacken bleibt je eine übrig, und alle zu notieren wäre ein Versprechen, das
die Datei nicht hält.

**Nebenbei richtiggestellt:** die technischen Angaben rechneten mit
`.directPlayOnly` und zeigten deshalb „Direkt (Systemplayer)" direkt über
„iOS öffnet den Container MKV nicht" — zwei Angaben, die sich widersprechen.
Das war früher richtig (ohne Serverhilfe übernahm die zweite Engine und hiess
auch so); jetzt wird mit Serverhilfe gerechnet.

NOCH NICHT AN EINEM ECHTEN SERVER GEPRÜFT.

iOS und tvOS bauen, 494 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-03 08:32:41 +02:00
co-authored by Claude Opus 5
parent 6b927c21b0
commit a432592271
6 changed files with 111 additions and 20 deletions
+4 -1
View File
@@ -12,6 +12,7 @@ struct SeriesDetailView: View {
@Environment(FlixySession.self) private var session
@Environment(DownloadCoordinator.self) private var downloads
@Environment(LanguagePreferences.self) private var languages
@Environment(\.flixyAccent) private var accent
@Environment(\.horizontalSizeClass) private var sizeClass
@State private var children: LoadState<[MediaItem]> = .loading
@@ -295,7 +296,9 @@ struct SeriesDetailView: View {
isWorking = true
defer { isWorking = false }
let service = DownloadService(backend: session.backend, coordinator: downloads)
let service = DownloadService(
backend: session.backend, coordinator: downloads, languages: languages
)
let result = await service.download(selectedEpisodes, quality: quality)
var zeilen = [String(localized: "downloads.batch.queued \(result.accepted)")]
+15 -1
View File
@@ -14,8 +14,22 @@ struct TechnicalDetails: View {
let part: MediaFile
@Binding var isExpanded: Bool
/// Was mit dieser Datei passieren würde.
///
/// **Mit Serverhilfe gerechnet, nicht ohne.** Hier stand `.directPlayOnly`
/// — damals eine brauchbare Auskunft, weil ohne Serverhilfe die zweite
/// Engine übernahm und auch so hiess. Seit es sie nicht mehr gibt, kam
/// dort „Direkt (Systemplayer)" heraus, direkt über der Zeile „iOS öffnet
/// den Container MKV nicht" — zwei Angaben, die sich widersprechen, und
/// die zweite stimmte.
///
/// Ohne Bandbreitengrenze, weil sie von der Verbindung abhängt und diese
/// Seite sie nicht kennt. Gezeigt wird damit der Fall im WLAN.
private var decision: PlaybackDecision {
PlaybackDecider().decide(profile: media.profile(file: part), policy: .directPlayOnly)
PlaybackDecider().decide(
profile: media.profile(file: part),
policy: PlaybackPolicy(allowsTranscoding: true)
)
}
var body: some View {
+8 -2
View File
@@ -28,6 +28,7 @@ struct DownloadButton: View {
@Environment(FlixySession.self) private var session
@Environment(DownloadCoordinator.self) private var downloads
@Environment(LanguagePreferences.self) private var languages
@Environment(\.flixyAccent) private var accent
@State private var refusal: DownloadRefusal?
@@ -158,7 +159,9 @@ struct DownloadButton: View {
}
private func enqueue(quality: DownloadQuality) {
let service = DownloadService(backend: session.backend, coordinator: downloads)
let service = DownloadService(
backend: session.backend, coordinator: downloads, languages: languages
)
do {
_ = try service.download(source, mediaIndex: mediaIndex, quality: quality)
} catch {
@@ -189,6 +192,7 @@ struct DownloadAllButton: View {
@Environment(FlixySession.self) private var session
@Environment(DownloadCoordinator.self) private var downloads
@Environment(LanguagePreferences.self) private var languages
@Environment(\.flixyAccent) private var accent
@State private var isWorking = false
@@ -224,7 +228,9 @@ struct DownloadAllButton: View {
isWorking = true
defer { isWorking = false }
let service = DownloadService(backend: session.backend, coordinator: downloads)
let service = DownloadService(
backend: session.backend, coordinator: downloads, languages: languages
)
let result = await service.downloadAll(in: container)
var lines = [String(localized: "downloads.batch.queued \(result.accepted)")]