Vier Stellen, an denen eine Angabe unterwegs verlorenging
**Der Aufmacher wusste nur die Serie.** `Heroeintrag.titel` ist bei einer angefangenen Folge der Name der Serie — richtig, denn der Aufmacher zeigt die Serie. Wer von dort startete, las über dem Spieler „Biohackers" und nicht, welche Folge läuft. Staffel, Nummer und Folgentitel reisen jetzt mit. Dasselbe im Aufmacher selbst: „Staffel 1 · Folge 2" statt „S1 · F2". **Der Abspann ist kein Angebot, sondern eine Frage.** Die Acht-Sekunden- Frist von gestern war für das Intro gedacht und traf den Abspann mit: „Nächste Folge" verschwand genau dort, wo man hinsieht. Ein Intro-Knopf geht, wenn man ihn nicht nimmt; der Abspann-Knopf bleibt, bis die Folge zu Ende ist. Web und App. **„deu" stand da, weil es in der Datei steht.** Der Server reichte einen vorhandenen Spurnamen unbesehen durch — und viele Dateien tragen als Titel schlicht das Sprachkürzel. Wiederholt er bloss die Sprache, gilt er nicht, und die Tabelle darunter macht „Deutsch" daraus. **Und zweimal „Deutsch" ist keine Wahl.** Zwei deutsche Untertitelspuren sind der Normalfall — Vollfassung und Nur-Fremdsprachiges. Gleichnamige bekommen jetzt ihren Codec dazu, und wenn der auch gleich ist, die Nummer. Das kann keine Spur für sich beantworten: ob ein Name eindeutig ist, hängt an den anderen. Deshalb steht es in `Benennung` und hat fünf Prüfungen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d152ac3795
commit
a360bed02b
@@ -478,13 +478,10 @@ public static class StreamEndpoints
|
||||
StartSeconds: 0,
|
||||
Height: null,
|
||||
AudioStream: spuren.FirstOrDefault(s => s.Kind == MediaStreamKind.Audio)?.Index,
|
||||
AudioStreams: spuren.Where(s => s.Kind == MediaStreamKind.Audio)
|
||||
.Select(s => new SpurAuskunft(s.Index, Benennung(s), s.Language, s.IsDefault))
|
||||
.ToList(),
|
||||
SubtitleStreams: spuren.Where(s => s.Kind == MediaStreamKind.Subtitle)
|
||||
.Where(s => s.Codec is null || !Untertitelvorrat.IstBild(s.Codec))
|
||||
.Select(s => new SpurAuskunft(s.Index, Benennung(s), s.Language, s.IsDefault))
|
||||
.ToList());
|
||||
AudioStreams: Spurliste(spuren.Where(s => s.Kind == MediaStreamKind.Audio)),
|
||||
SubtitleStreams: Spurliste(spuren
|
||||
.Where(s => s.Kind == MediaStreamKind.Subtitle)
|
||||
.Where(s => s.Codec is null || !Untertitelvorrat.IstBild(s.Codec))));
|
||||
}
|
||||
|
||||
/// <summary>Das Geräteprofil aus der Anfrage — oder, wenn keines kam, Apples.</summary>
|
||||
@@ -549,13 +546,10 @@ public static class StreamEndpoints
|
||||
StartSeconds: sitzung.Ab,
|
||||
Height: sitzung.Hoehe,
|
||||
AudioStream: sitzung.Tonspur,
|
||||
AudioStreams: spuren.Where(s => s.Kind == MediaStreamKind.Audio)
|
||||
.Select(s => new SpurAuskunft(s.Index, Benennung(s), s.Language, s.IsDefault))
|
||||
.ToList(),
|
||||
SubtitleStreams: spuren.Where(s => s.Kind == MediaStreamKind.Subtitle)
|
||||
.Where(s => s.Codec is null || !Untertitelvorrat.IstBild(s.Codec))
|
||||
.Select(s => new SpurAuskunft(s.Index, Benennung(s), s.Language, s.IsDefault))
|
||||
.ToList());
|
||||
AudioStreams: Spurliste(spuren.Where(s => s.Kind == MediaStreamKind.Audio)),
|
||||
SubtitleStreams: Spurliste(spuren
|
||||
.Where(s => s.Kind == MediaStreamKind.Subtitle)
|
||||
.Where(s => s.Codec is null || !Untertitelvorrat.IstBild(s.Codec))));
|
||||
}
|
||||
|
||||
/// <summary>Bildbasierte Untertitel lassen sich nicht nach WebVTT wandeln.</summary>
|
||||
@@ -566,10 +560,36 @@ public static class StreamEndpoints
|
||||
/// nichts führt, ist schlechter als kein Eintrag.
|
||||
/// </remarks>
|
||||
|
||||
/// <summary>Beschriftet eine Spurliste — unterscheidbar.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Das Auftrennen gleicher Namen steht in <c>Benennung</c>: die Apps
|
||||
/// zeigen dieselben Listen, und zweimal formuliert driften sie
|
||||
/// auseinander.
|
||||
/// </remarks>
|
||||
private static List<SpurAuskunft> Spurliste(IEnumerable<MediaStream> spuren)
|
||||
{
|
||||
var liste = spuren.ToList();
|
||||
var namen = Flaro.Core.Media.Benennung.Unterscheiden(
|
||||
liste.Select(s => new Flaro.Core.Media.Benennung.Spurzeile(
|
||||
Benennung(s), s.Codec, s.Index)).ToList());
|
||||
|
||||
return liste
|
||||
.Select((s, i) => new SpurAuskunft(s.Index, namen[i], s.Language, s.IsDefault))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>Wie eine Spur im Menü heisst.</summary>
|
||||
private static string Benennung(MediaStream spur)
|
||||
{
|
||||
if (spur.Title is { Length: > 0 } eigen) return eigen;
|
||||
// **Ein Spurname, der nur die Sprache wiederholt, ist keiner.**
|
||||
// Viele Dateien tragen als Titel schlicht „deu" — durchgereicht
|
||||
// stand genau das in der Auswahl, roh und dreibuchstabig, obwohl
|
||||
// die Tabelle darunter „Deutsch" daraus gemacht hätte.
|
||||
var istKuerzel = spur.Language is { Length: > 0 } kennung
|
||||
&& string.Equals(spur.Title?.Trim(), kennung.Trim(), StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!istKuerzel && spur.Title is { Length: > 0 } eigen) return eigen;
|
||||
|
||||
var sprache = Sprache(spur.Language);
|
||||
var teile = new List<string> { sprache };
|
||||
|
||||
@@ -52,6 +52,55 @@ public static class Benennung
|
||||
return Sprachnamen.GetValueOrDefault(blank, blank.ToUpperInvariant());
|
||||
}
|
||||
|
||||
/// <summary>Eine Spur, wie sie im Menü stünde — vor dem Vergleich.</summary>
|
||||
public readonly record struct Spurzeile(string Name, string? Codec, int Nummer);
|
||||
|
||||
/// <summary>Macht gleichnamige Spuren unterscheidbar.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// <b>Zweimal „Deutsch" ist keine Wahl.</b> Viele Dateien führen zwei
|
||||
/// deutsche Untertitelspuren — Vollfassung und Nur-Fremdsprachiges.
|
||||
/// Standen beide gleich da, musste man raten und es danach wieder
|
||||
/// umstellen.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Warum das keine Spur für sich beantworten kann.</b> Ob ein Name
|
||||
/// eindeutig ist, hängt an den anderen — einzeln benannt weiss keine
|
||||
/// Spur, dass es eine zweite mit demselben Namen gibt. Deshalb steht
|
||||
/// das hier und nicht in <see cref="Sprache"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Erst der Codec: „Deutsch · SRT" gegen „Deutsch · ASS" sagt etwas.
|
||||
/// Hilft er nicht, hilft die Nummer — nichtssagend, aber sie trennt,
|
||||
/// und das ist hier die Aufgabe.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IReadOnlyList<string> Unterscheiden(IReadOnlyList<Spurzeile> zeilen)
|
||||
{
|
||||
var namen = zeilen.Select(z => z.Name).ToList();
|
||||
|
||||
Entwirren(i => Codec(zeilen[i].Codec));
|
||||
Entwirren(i => $"Spur {zeilen[i].Nummer}");
|
||||
|
||||
return namen;
|
||||
|
||||
void Entwirren(Func<int, string?> zusatz)
|
||||
{
|
||||
var doppelt = namen
|
||||
.Select((name, i) => (name, i))
|
||||
.GroupBy(x => x.name)
|
||||
.Where(g => g.Count() > 1)
|
||||
.SelectMany(g => g.Select(x => x.i))
|
||||
.ToList();
|
||||
|
||||
foreach (var i in doppelt)
|
||||
{
|
||||
if (zusatz(i) is { Length: > 0 } text) namen[i] = $"{namen[i]} · {text}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Die übliche Schreibweise für eine Kanalzahl.</summary>
|
||||
///
|
||||
/// <remarks>
|
||||
|
||||
Reference in New Issue
Block a user