Ein Sprung in den Vorrat laeuft jetzt sofort weiter

Drei Gruende, und der erste erklaert das ganze Aergernis.

AVPlayer besteht nach einem Sprung darauf, erst seinen eigenen Puffer zu
fuellen. Der stand auf sechzig Sekunden — richtig, solange er selbst
vorladen sollte. Mit einem Speicher davor ist es das Gegenteil: springt man
mitten in den Vorrat, liegt dahinter vielleicht noch eine halbe Minute, zu
wenig fuer seine sechzig, und er wartet auf den Server, obwohl alles da
ist. Der Abstand liegt jetzt bei uns; seiner darf klein sein.

Der Vorrat holte ausserdem weiter Schnipsel hinter der Abspielstelle, wenn
der Player vorausgesprungen war — und der eine, auf den gerade gewartet
wurde, kam als letzter. Er macht jetzt dort weiter, wo gesprungen wurde.

Und dieselbe Liste noch einmal zu holen setzte den Vorrat zurueck. Der
Player holt sie staendig: nach einem Sprung, beim Stufenwechsel, von sich
aus. Zurueckgesetzt wird nur noch bei einem echten Wechsel der Quelle.

Dazu ein latenter Fehler, der beim Umpacken ein Schwarzbild gegeben haette:
in EXT-X-MAP steckt die Adresse des Kopfstuecks einer fragmentierten MP4,
ohne das kein einziger Schnipsel zu dekodieren ist. Sie blieb stehen und
zeigte damit relativ auf den lokalen Server. Der alte Test hielt genau
dieses Verhalten fest — er hat mitgeaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-28 20:36:33 +02:00
co-authored by Claude Opus 5
parent bbd1c3b572
commit 4b084bc926
4 changed files with 85 additions and 8 deletions
@@ -72,7 +72,18 @@ public struct MediaPlaylist: Sendable, Equatable {
for zeile in lines {
let getrimmt = zeile.trimmingCharacters(in: .whitespaces)
if getrimmt.isEmpty || getrimmt.hasPrefix("#") {
if getrimmt.isEmpty {
ergebnis.append(zeile)
} else if getrimmt.hasPrefix("#EXT-X-MAP:") {
// **Die eine Anweisung, in der eine Adresse steckt.**
//
// Sie zeigt auf das Kopfstück einer fragmentierten MP4 — ohne
// das ist kein einziger Schnipsel zu dekodieren. Bliebe sie
// stehen, zeigte sie relativ auf den lokalen Server, und dort
// gibt es sie nicht: schwarzes Bild, ohne dass an den
// Schnipseln irgendetwas falsch wäre.
ergebnis.append(Self.rewritingMapURI(zeile, transform))
} else if getrimmt.hasPrefix("#") {
ergebnis.append(zeile)
} else {
ergebnis.append(transform(getrimmt))
@@ -81,6 +92,24 @@ public struct MediaPlaylist: Sendable, Equatable {
return ergebnis.joined(separator: "\n")
}
/// Tauscht die Adresse in `#EXT-X-MAP:URI="…"` aus, sonst nichts.
private static func rewritingMapURI(
_ zeile: String,
_ transform: (String) -> String
) -> String {
let marke = "URI=\""
guard let start = zeile.range(of: marke),
let ende = zeile[start.upperBound...].firstIndex(of: "\"")
else { return zeile }
let ende2 = ende..<zeile.index(after: ende)
let adresse = String(zeile[start.upperBound..<ende2.lowerBound])
return zeile.replacingCharacters(
in: start.upperBound..<ende2.lowerBound,
with: transform(adresse)
)
}
/// Ob die Liste vollständig ist — dann kommen keine Schnipsel mehr dazu.
///
/// Bei einem laufenden Sender fehlt diese Marke, und die Liste muss