namespace Flaro.Media.Tests; /// Untertitel auf der Zeitachse eines Stroms, der mittendrin anfängt. /// /// /// Der Fehler, den diese Prüfung festhält. Die Zeitstempel zählen ab /// Dateianfang, der Strom zählt ab null. Beim Einstieg bei Minute 30 lag /// damit jeder Satz dreissig Minuten in der Zukunft — und weil ein Strom nur /// bis zum Filmende reicht, erschien überhaupt keiner mehr. Gemeldet wurde /// das als „auf keiner Spur kommt Text". /// public class UntertitelversatzTests { private const string Probe = """ WEBVTT 1 00:00:01.000 --> 00:00:04.000 Ganz am Anfang 2 00:00:09.000 --> 00:00:12.000 Über den Einstieg hinweg 3 00:00:20.000 --> 00:00:24.000 Weit dahinter """; [Test] public void Ohne_Versatz_bleibt_alles_wie_es_war() => Assert.That(Untertitelversatz.Verschieben(Probe, 0), Is.EqualTo(Probe)); [Test] public void Die_Zeiten_rutschen_um_den_Einstieg_nach_vorn() { var heraus = Untertitelversatz.Verschieben(Probe, 10); Assert.That(heraus, Does.Contain("00:00:10.000 --> 00:00:14.000"), "Sekunde 20 im Film ist Sekunde 10 in einem Strom, der bei 10 beginnt."); } /// Was schon vorbei war, fällt weg. /// /// /// Und zwar samt seinem Text: bliebe der Absatz ohne Zeitzeile stehen, /// hinge er als Fliesstext in der Datei und der Browser verschluckt sich /// daran. /// [Test] public void Was_vor_dem_Einstieg_endet_faellt_weg() { var heraus = Untertitelversatz.Verschieben(Probe, 10); Assert.Multiple(() => { Assert.That(heraus, Does.Not.Contain("Ganz am Anfang")); Assert.That(heraus, Does.Not.Contain("00:00:01.000")); }); } /// Ein Satz, der beim Einstieg schon lief, bleibt stehen. /// /// /// Abgeschnitten ist er immer noch lesbar — ihn wegzuwerfen hiesse, beim /// Wiedereinstieg mitten in einem Dialog mit Stille zu beginnen. /// [Test] public void Was_ueber_den_Einstieg_hinwegreicht_faengt_bei_null_an() { var heraus = Untertitelversatz.Verschieben(Probe, 10); Assert.Multiple(() => { Assert.That(heraus, Does.Contain("Über den Einstieg hinweg")); Assert.That(heraus, Does.Contain("00:00:00.000 --> 00:00:02.000")); }); } /// Weggefallene Sätze hinterlassen keine Leerzeilen. /// /// /// Gemessen am echten Film. Bei einem Einstieg nach achteinhalb /// Minuten standen vor dem ersten Satz 52 leere Zeilen — eine je /// weggefallenem Block. Lesbar war das noch, sauber nicht: die Trennzeile /// gehört dem Block und fällt mit ihm weg. /// [Test] public void Weggefallene_Saetze_hinterlassen_keine_Leerzeilen() { var heraus = Untertitelversatz.Verschieben(Probe, 10); Assert.Multiple(() => { Assert.That(heraus, Does.StartWith("WEBVTT\n\n2\n00:00:00.000"), "nach dem Kopf kommt sofort der erste Satz, der noch gilt"); Assert.That(heraus, Does.Not.Contain("\n\n\n"), "zwei Leerzeilen hintereinander heisst, dass ein Block seine Trennzeile zurückliess"); }); } [Test] public void Der_Kopf_bleibt_stehen() => Assert.That(Untertitelversatz.Verschieben(Probe, 10), Does.StartWith("WEBVTT")); /// Die kurze Schreibweise ohne Stunden ist erlaubt. [Test] public void Auch_ohne_Stundenangabe() { var kurz = "WEBVTT\n\n01:05.000 --> 01:09.000\nKurz geschrieben\n"; Assert.That(Untertitelversatz.Verschieben(kurz, 60), Does.Contain("00:00:05.000 --> 00:00:09.000")); } /// Was hinter der Zeitzeile steht, bleibt dran. /// /// /// Dort stehen Platzangaben wie line:90% align:center. Sie /// abzuschneiden hiesse, erzwungene Untertitel mitten ins Bild zu setzen. /// [Test] public void Die_Platzangaben_bleiben_erhalten() { var mitLage = "WEBVTT\n\n00:00:20.000 --> 00:00:24.000 line:90% align:center\nUnten\n"; Assert.That(Untertitelversatz.Verschieben(mitLage, 10), Does.Contain("00:00:10.000 --> 00:00:14.000 line:90% align:center")); } /// Eine Spur, die ganz vor dem Einstieg liegt, wird leer — aber gültig. [Test] public void Eine_leere_Spur_bleibt_lesbares_WebVTT() { var heraus = Untertitelversatz.Verschieben(Probe, 3600); Assert.Multiple(() => { Assert.That(heraus, Does.StartWith("WEBVTT")); Assert.That(heraus, Does.Not.Contain("-->")); }); } }