Untertitel kommen aus der Datei, und Fortsetzen geht wieder
Im Spurenblatt stand „CC" und sonst nichts — derselbe Fehler wie beim Ton: das ist AVFoundations Name für den einen Untertitel, den ein umgerechneter Stream mitbringt. Zur Auswahl steht jetzt, was in der Datei liegt, und die Nummer geht als `subtitleStreamIndex` mit in die Anfrage. `-1` heisst dabei ausdrücklich „keine". Das ist nicht dasselbe wie nichts zu schicken: dann sucht der Server sich einen aus, und es steht plötzlich ein Untertitel im Bild, den niemand bestellt hat. Und der Klick ins Bild: Anhalten ging, Fortsetzen nicht. Der Abdunkler hinter der Bedienung deckt das ganze Fenster ab und lag über dem Film — solange die Bedienung zu sehen war, landete jeder Klick auf ihm. Auffallen konnte das nur an einer Stelle: nach dem Pausieren bleibt die Bedienung stehen, also traf der Klick, der wieder starten sollte, nie das Bild. Der Abdunkler ist jetzt unantastbar; er dunkelt ab, mehr nicht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
60194c2d2a
commit
67c679006f
@@ -53,6 +53,13 @@ final class PlayerModel {
|
||||
private(set) var audioStreams: [MediaStream] = []
|
||||
/// Welche davon gerade klingt.
|
||||
private(set) var selectedAudioStream: MediaStream?
|
||||
|
||||
/// Die Untertitel, wie sie **in der Datei** stehen — aus demselben Grund
|
||||
/// wie beim Ton: ein umgerechneter Stream bringt genau einen mit, und der
|
||||
/// heisst dann „CC".
|
||||
private(set) var subtitleStreams: [MediaStream] = []
|
||||
/// Welcher davon zu sehen ist. `nil` heisst: keiner.
|
||||
private(set) var selectedSubtitleStream: MediaStream?
|
||||
private(set) var selectedSubtitleTrack: MediaTrack?
|
||||
|
||||
/// Die Marke, in der wir uns gerade befinden — Grundlage für den
|
||||
@@ -668,7 +675,11 @@ final class PlayerModel {
|
||||
isLocalConnection: isLocalConnection,
|
||||
// Ohne diese Angabe wählt der Server, und bei einem
|
||||
// umgerechneten Stream kommt danach nur noch **eine** Spur an.
|
||||
audioStreamIndex: selectedAudioStream?.index
|
||||
audioStreamIndex: selectedAudioStream?.index,
|
||||
// `-1` statt nichts: ohne Angabe sucht der Server selbst einen
|
||||
// aus, und dann steht plötzlich ein Untertitel im Bild, den
|
||||
// niemand bestellt hat.
|
||||
subtitleStreamIndex: selectedSubtitleStream?.index ?? -1
|
||||
))
|
||||
playbackSession = target.sessionID
|
||||
playbackVersionID = target.versionID
|
||||
@@ -1429,6 +1440,14 @@ final class PlayerModel {
|
||||
backend: any MediaBackend
|
||||
) async {
|
||||
audioStreams = part.audioStreams
|
||||
subtitleStreams = part.subtitleStreams
|
||||
// Untertitel sind eine Zutat, keine Voraussetzung: der Wunsch gilt,
|
||||
// wenn es einen passenden gibt, und sonst bleibt es ohne.
|
||||
selectedSubtitleStream = languages.subtitleLanguage.isEmpty ? nil
|
||||
: subtitleStreams.first {
|
||||
LanguageCode.matches(languages.subtitleLanguage, $0.languageCode)
|
||||
}
|
||||
|
||||
guard !audioStreams.isEmpty else {
|
||||
selectedAudioStream = nil
|
||||
return
|
||||
@@ -1484,6 +1503,32 @@ final class PlayerModel {
|
||||
await restart()
|
||||
}
|
||||
|
||||
/// Stellt die Untertitel um.
|
||||
///
|
||||
/// Dieselbe Bauart wie beim Ton, und aus demselben Grund: rechnet der
|
||||
/// Server um, steckt die Wahl in der Adresse. Bei unveränderter Wiedergabe
|
||||
/// liegen dagegen alle im Stream, und der Player schaltet ohne
|
||||
/// Unterbrechung um.
|
||||
func selectSubtitleStream(_ stream: MediaStream?) async {
|
||||
guard stream != selectedSubtitleStream else { return }
|
||||
selectedSubtitleStream = stream
|
||||
|
||||
if case .directPlay = decision?.method {
|
||||
let treffer = stream.flatMap { gewählt in
|
||||
subtitleTracks.first { LanguageCode.matches(gewählt.languageCode, $0.languageCode) }
|
||||
}
|
||||
// Nur wenn sich die Wahl im Player wirklich abbilden lässt. Sonst
|
||||
// stünde der falsche Untertitel im Bild, und das wäre schlimmer
|
||||
// als eine kurze Unterbrechung.
|
||||
if stream == nil || treffer != nil {
|
||||
selectSubtitleTrack(treffer)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
await restart()
|
||||
}
|
||||
|
||||
/// Was für diese Serie gemerkt ist — für die Anzeige im Spurenblatt.
|
||||
var rememberedTrackName: String? {
|
||||
guard let seriesID = item?.seriesID,
|
||||
|
||||
Reference in New Issue
Block a user