Watchdog heisst Watchdog, Engine heisst Engine
Eingedeutschte Fachbegriffe in den Kommentaren — „Wachhund" für Watchdog, „Motor" für Engine. Das liest sich albern und ist unklarer als das Original; niemand sagt Wachhund, wenn er einen Watchdog meint. Acht Stellen berichtigt. Gewöhnliche Sprache bleibt deutsch, der Stil der Kommentare ändert sich nicht. Dazu die Plex-Leiter messbar gemacht: `--leiter` baut dieselbe Anfrage zweimal, mit und ohne `autoAdjustQuality=1`, und zählt die Stufen. Die Zeile steht seit dem Umbau im Code und war nie geprüft — genau die Art ungeprüfter Annahme über Serververhalten, die bei Jellyfin vier Runden gekostet hat. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
314c1a3bfc
commit
e324a474fd
@@ -5,7 +5,7 @@ import Foundation
|
||||
/// Der billige Hebel ist `preferredPeakBitRate`: er wirkt ohne Neuaufbau.
|
||||
/// Wenn er nichts ausrichtet — weil die Playlist nur eine Stufe hat oder weil
|
||||
/// schon die unterste läuft —, bleibt nur der Neuaufbau mit kleinerer Bitrate:
|
||||
/// Transcoder anhalten, Motor abreißen, neu aushandeln, zurückspringen. Das
|
||||
/// Transcoder anhalten, Engine abreißen, neu aushandeln, zurückspringen. Das
|
||||
/// sind Sekunden mit schwarzem Bild.
|
||||
///
|
||||
/// **Ein Notnagel, keine Regelschleife.** Zu oft ausgelöst erzeugt er genau
|
||||
|
||||
@@ -48,7 +48,7 @@ public struct PlaybackDecision: Sendable, Equatable {
|
||||
switch method {
|
||||
case .directPlay(let engine): engine
|
||||
// Der Transcoder liefert HLS, und damit ist AVPlayer der richtige
|
||||
// Motor. **Nicht** aber, wie hier früher stand, „inklusive
|
||||
// Engine. **Nicht** aber, wie hier früher stand, „inklusive
|
||||
// automatischem Bitratenwechsel": den gibt es nur, wenn die Playlist
|
||||
// mehrere Stufen führt, und das muss ausdrücklich bestellt werden.
|
||||
case .transcode: .avPlayer
|
||||
|
||||
@@ -2,7 +2,7 @@ import Foundation
|
||||
|
||||
/// Buch über das Stocken, mit gleitendem Fenster.
|
||||
///
|
||||
/// **Warum es das gibt.** Der Wachhund im Player kannte nur eine Frage: steht
|
||||
/// **Warum es das gibt.** Der Watchdog im Player kannte nur eine Frage: steht
|
||||
/// es seit vierzig Sekunden am Stück? Bei jedem kurzen Erholen setzte er sich
|
||||
/// zurück — zehn Rückler à dreißig Sekunden lösten nichts aus, obwohl die
|
||||
/// halbe Stunde unbrauchbar war. Genau dieser Fall ist der, über den geklagt
|
||||
|
||||
@@ -90,7 +90,7 @@ public final class AVPlayerEngine: VideoPlayerEngine {
|
||||
teardownObservers()
|
||||
state = .loading
|
||||
|
||||
// Die Buchführung gehört zur Quelle, nicht zum Motor: ein neuer Titel
|
||||
// Die Buchführung gehört zur Quelle, nicht zur Engine: ein neuer Titel
|
||||
// fängt bei null an, sonst schleppte die Zahl den vorigen Film mit.
|
||||
variantBitrates = []
|
||||
wantsToPlay = false
|
||||
|
||||
@@ -21,7 +21,7 @@ public struct PlaybackSource: Sendable, Equatable {
|
||||
/// wackelige Leitung ist es zu wenig: der Systemwert ist auf schnellen
|
||||
/// Start ausgelegt, nicht darauf, einen Aussetzer zu überstehen.
|
||||
///
|
||||
/// **Wer das entscheidet, muss mehr wissen als der Motor.** Ob es ein
|
||||
/// **Wer das entscheidet, muss mehr wissen als die Engine.** Ob es ein
|
||||
/// Sender ist, ob die Datei lokal liegt — das weiß der Player, nicht die
|
||||
/// Engine. Deshalb reist die Zahl mit der Quelle, statt dass die Engine
|
||||
/// rät.
|
||||
|
||||
@@ -150,6 +150,42 @@ let firstMovie = await { () async -> PlexItem? in
|
||||
return try? await server.items(inLibrary: movieLibrary, limit: 1).items.first
|
||||
}()
|
||||
|
||||
// MARK: - Die Leiter bei Plex
|
||||
|
||||
// Dieselbe Frage wie bei Jellyfin, und aus demselben Grund gestellt: bei Plex
|
||||
// steht `autoAdjustQuality=1` im Code, und ob sein Transcoder daraufhin
|
||||
// mehrere Stufen liefert, war nie geprüft. Eine ungeprüfte Annahme über
|
||||
// Serververhalten hat uns bei Jellyfin vier Runden gekostet.
|
||||
if CommandLine.arguments.contains("--leiter") {
|
||||
guard let movie = firstMovie else {
|
||||
print("Keine Datei zum Prüfen gefunden.")
|
||||
exit(0)
|
||||
}
|
||||
print("Leiter-Probe mit: \(movie.title)\n")
|
||||
|
||||
let ohne = TranscodeRequest(
|
||||
ratingKey: movie.ratingKey,
|
||||
maximumBitrate: 8_000,
|
||||
isLocal: connection.local
|
||||
)
|
||||
let mit = ohne.askingForLadder()
|
||||
|
||||
for (name, anfrage) in [("ohne autoAdjustQuality", ohne), ("mit autoAdjustQuality=1", mit)] {
|
||||
print("=== \(name) ===")
|
||||
guard let url = server.transcodeURL(for: anfrage) else {
|
||||
print(" Keine Adresse zu bauen.\n")
|
||||
continue
|
||||
}
|
||||
print(await prüfePlaylist(url))
|
||||
print()
|
||||
}
|
||||
|
||||
// Aufräumen: beide Anfragen haben am Server einen Transcoder angeworfen.
|
||||
await server.stopTranscode(sessionIdentifier: ohne.sessionIdentifier)
|
||||
print("Transcoder angehalten.")
|
||||
exit(0)
|
||||
}
|
||||
|
||||
if let movie = firstMovie {
|
||||
let request = TranscodeRequest(
|
||||
ratingKey: movie.ratingKey,
|
||||
|
||||
@@ -65,7 +65,7 @@ public struct TranscodeRequest: Sendable, Equatable {
|
||||
/// Dieselbe Sitzungskennung: es ist **eine** Wiedergabe, und der Server
|
||||
/// soll sie nicht für zwei halten — sonst bliebe beim Aufräumen ein
|
||||
/// Transcoder stehen.
|
||||
func askingForLadder() -> TranscodeRequest {
|
||||
public func askingForLadder() -> TranscodeRequest {
|
||||
TranscodeRequest(
|
||||
ratingKey: ratingKey,
|
||||
mediaIndex: mediaIndex,
|
||||
|
||||
@@ -6,7 +6,7 @@ import Foundation
|
||||
struct StallLedgerTests {
|
||||
/// Der Fall, wegen dem es den Typ gibt.
|
||||
///
|
||||
/// Zehn Rückler à dreißig Sekunden lösten beim alten Wachhund nichts aus,
|
||||
/// Zehn Rückler à dreißig Sekunden lösten beim alten Watchdog nichts aus,
|
||||
/// weil er sich bei jedem Erholen zurücksetzte. Hier muss sichtbar
|
||||
/// werden, dass die Wiedergabe unbrauchbar ist.
|
||||
@Test("Viele kurze Rückler bleiben sichtbar")
|
||||
|
||||
@@ -227,7 +227,7 @@ extension VLCPlayerEngine: VLCMediaPlayerDelegate {
|
||||
/// Aufzählung führt nur `opening`, `playing`, `paused`, `stopped` und
|
||||
/// `error`. Weil diese Methode bisher fehlte, ging der Zustand
|
||||
/// `.buffering` auf dem VLC-Weg **nie** an — und damit löste der
|
||||
/// Wachhund im Player dort nie aus. Ein hängender Strom lief stumm ins
|
||||
/// Watchdog im Player dort nie aus. Ein hängender Strom lief stumm ins
|
||||
/// Nichts, ohne Kreisel, ohne Meldung, ohne Abbruch.
|
||||
///
|
||||
/// Nur aus dem Spielen heraus gewertet. Die Dokumentation sagt, dass vor
|
||||
|
||||
Reference in New Issue
Block a user