Spider-Man ist nicht 720p, er ist breit
Die Auflösung wurde allein aus der Höhe gebildet. Ein Kinoformat von 2.39:1 liegt als 1920×800 vor — nach der Höhe gerechnet kam „720p" heraus, und das stand so in der Oberfläche. Jetzt zählt die grössere von Breite und Höhe; Hochformat kippt damit nicht, und 4K-Breitbild heisst nicht mehr 1440p. Die Detailansicht hat zwei Leserschaften, und bisher bekamen beide dasselbe. Wer schauen will, sieht jetzt Laufzeit, Auflösung und die Sprachen — jede einmal, statt „Englisch · Englisch · Englisch · Englisch · Deutsch". Wer die Mediathek betreut, sieht darunter Dateiformat, Grösse und den Ordner. Der Ordner verrät eine falsche Zuordnung in einer Sekunde: steht über der Beschreibung „Hanni & Nanni 3" und der Ordner heisst „Hanni und Nanni", ist die Sache klar. Er kommt nur für Administratoren überhaupt vom Server — versteckt im Client wäre er weiterhin auslesbar. Ein geplanter Titel war unsichtbar. Das ist die Hälfte, die nichts bringt: dass er kommt, ist der Sinn des Planens. Er steht jetzt mit „Verfügbar ab …" in der Mediathek, und die Datei geht trotzdem nicht heraus — Download wie Strom lehnen bis zum Termin ab, auch für Administratoren. Wer vorziehen will, hat „Jetzt veröffentlichen"; eine Hintertür für eine Rolle wäre eine Regel, die manchmal gilt. Was ein Auffrischen geändert hat, steht jetzt unter „Zu prüfen" — in einer eigenen Gruppe mit „Zur Kenntnis" statt „Veröffentlichen". Diese Titel sind sichtbar; es gibt nichts freizugeben, nur etwas abzuhaken. Und das Protokoll sagt endlich, wo es knallt. „InvalidOperationException: Nullable object must have a value." ohne eine einzige Zeile Herkunft ist für niemanden eine Diagnose — weder für den Betreiber noch für mich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f44779c899
commit
255eb7c2f0
@@ -169,6 +169,24 @@ public sealed class Movie : Flaro.Core.Metadata.IBebildert
|
||||
/// </remarks>
|
||||
public bool SortTitlePinned { get; set; }
|
||||
|
||||
/// <summary>Seit wann eine Änderung auf ihre Kenntnisnahme wartet.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// <b>Nicht dasselbe wie <see cref="PublishAt"/>.</b> Der Titel bleibt
|
||||
/// sichtbar — es geht nicht darum, ihn zurückzuhalten, sondern darum, dass
|
||||
/// jemand hinsieht. Ein Auffrischen kann einen Titel umbenennen, ein
|
||||
/// Plakat tauschen oder die Zuordnung wechseln; wer eine Mediathek
|
||||
/// betreut, will das mitbekommen und nicht zufällig entdecken.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <c>null</c> heisst: nichts offen. Gesetzt wird es nur, wenn die
|
||||
/// Mediathek auf Prüfung steht — wer keine Prüfung will, soll auch keine
|
||||
/// Liste bekommen.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public DateTimeOffset? ChangedSince { get; set; }
|
||||
|
||||
/// <summary>In welcher Sprache die Angaben geholt wurden.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
@@ -350,6 +368,24 @@ public sealed class Series : Flaro.Core.Metadata.IBebildert
|
||||
/// </remarks>
|
||||
public bool SortTitlePinned { get; set; }
|
||||
|
||||
/// <summary>Seit wann eine Änderung auf ihre Kenntnisnahme wartet.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// <b>Nicht dasselbe wie <see cref="PublishAt"/>.</b> Der Titel bleibt
|
||||
/// sichtbar — es geht nicht darum, ihn zurückzuhalten, sondern darum, dass
|
||||
/// jemand hinsieht. Ein Auffrischen kann einen Titel umbenennen, ein
|
||||
/// Plakat tauschen oder die Zuordnung wechseln; wer eine Mediathek
|
||||
/// betreut, will das mitbekommen und nicht zufällig entdecken.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <c>null</c> heisst: nichts offen. Gesetzt wird es nur, wenn die
|
||||
/// Mediathek auf Prüfung steht — wer keine Prüfung will, soll auch keine
|
||||
/// Liste bekommen.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public DateTimeOffset? ChangedSince { get; set; }
|
||||
|
||||
/// <summary>In welcher Sprache die Angaben geholt wurden.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
|
||||
@@ -88,7 +88,45 @@ public static class Benennung
|
||||
/// Zeilen statt 1080; genau das stand in der Oberfläche und sah aus wie
|
||||
/// ein Fehler. Der genaue Wert gehört in den Tooltip, nicht in die Zeile.
|
||||
/// </remarks>
|
||||
public static string? Aufloesung(int? hoehe) => hoehe switch
|
||||
public static string? Aufloesung(int? hoehe) => AusHoehe(hoehe);
|
||||
|
||||
/// <summary>Die Stufe aus Breite <i>und</i> Höhe — die grössere gewinnt.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// <b>Die Höhe allein lügt bei Breitbild.</b> „Spider-Man" liegt als
|
||||
/// 1920×800 vor — ein Kinoformat von 2.39:1, also Full HD. Nach der Höhe
|
||||
/// gerechnet kam „720p" heraus, und das stand so in der Oberfläche: eine
|
||||
/// Angabe, die jeder sofort als falsch erkennt, der die Datei kennt.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Die grössere der beiden Stufen, nicht die Breite allein.</b> Sonst
|
||||
/// kippt es beim Hochformat: ein 1080×1920 gedrehtes Bild wäre nach der
|
||||
/// Breite „720p". So stimmt beides, und keine Richtung ist bevorzugt.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static string? Aufloesung(int? breite, int? hoehe)
|
||||
{
|
||||
var a = Stufe(hoehe);
|
||||
var b = Stufe(breite * 9 / 16); // Breite auf eine 16:9-Höhe umgerechnet
|
||||
var groessere = Math.Max(a ?? 0, b ?? 0);
|
||||
return groessere > 0 ? AusHoehe(groessere) : null;
|
||||
}
|
||||
|
||||
/// <summary>Die Zeilenzahl, auf die eine Stufe lautet — zum Vergleichen.</summary>
|
||||
private static int? Stufe(int? wert) => wert switch
|
||||
{
|
||||
null or <= 0 => null,
|
||||
>= 2000 => 2160,
|
||||
>= 1400 => 1440,
|
||||
>= 1000 => 1080,
|
||||
>= 700 => 720,
|
||||
>= 500 => 576,
|
||||
>= 300 => 480,
|
||||
_ => wert,
|
||||
};
|
||||
|
||||
private static string? AusHoehe(int? hoehe) => hoehe switch
|
||||
{
|
||||
null or <= 0 => null,
|
||||
>= 2000 => "2160p",
|
||||
@@ -133,10 +171,13 @@ public static class Benennung
|
||||
}
|
||||
|
||||
/// <summary>Die ganze Zeile zu einer Bildspur.</summary>
|
||||
public static string Bildspur(string? codec, int? hoehe)
|
||||
public static string Bildspur(string? codec, int? hoehe) => Bildspur(codec, null, hoehe);
|
||||
|
||||
/// <inheritdoc cref="Bildspur(string?, int?)"/>
|
||||
public static string Bildspur(string? codec, int? breite, int? hoehe)
|
||||
{
|
||||
var teile = new List<string>();
|
||||
if (Aufloesung(hoehe) is { } a) teile.Add(a);
|
||||
if (Aufloesung(breite, hoehe) is { } a) teile.Add(a);
|
||||
if (Codec(codec) is { } c) teile.Add(c);
|
||||
return teile.Count > 0 ? string.Join(" · ", teile) : "Bild";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user