using System.Diagnostics;
namespace Halo.Media.Tests;
/// Baut echte Mediendateien mit ffmpeg.
///
///
/// Echte Dateien und keine aufgezeichneten Antworten. Bei TMDB ist das
/// umgekehrt richtig — dort steht ein fremder Dienst dahinter. Hier geht es
/// um das Werkzeug, das Halo im Container ohnehin mitbringt, und die Frage
/// „liest er die zweite Tonspur mitsamt Sprache?" lässt sich nur an einer
/// Datei beantworten, die wirklich zwei hat.
///
public static class Testdateien
{
public static bool FfmpegVorhanden => Suchen("ffmpeg") is not null && Suchen("ffprobe") is not null;
public static string? Suchen(string name)
{
foreach (var ordner in (Environment.GetEnvironmentVariable("PATH") ?? "").Split(Path.PathSeparator))
{
if (ordner.Length == 0) continue;
var pfad = Path.Combine(ordner, name);
if (File.Exists(pfad)) return pfad;
}
return null;
}
/// Zwei Tonspuren mit Sprache und Namen, dazu ein Untertitel.
public static void MitZweiTonspuren(string ziel)
{
var untertitel = Path.ChangeExtension(ziel, ".srt");
File.WriteAllText(untertitel,
"1\n00:00:00,000 --> 00:00:01,000\nEin Untertitel\n\n");
Ausführen("ffmpeg",
[
"-y", "-loglevel", "error",
"-f", "lavfi", "-i", "testsrc=duration=1:size=160x120:rate=10",
"-f", "lavfi", "-i", "sine=frequency=440:duration=1",
"-f", "lavfi", "-i", "sine=frequency=880:duration=1",
"-i", untertitel,
"-map", "0:v", "-map", "1:a", "-map", "2:a", "-map", "3:s",
"-metadata:s:a:0", "language=deu", "-metadata:s:a:0", "title=Deutsch",
"-metadata:s:a:1", "language=deu", "-metadata:s:a:1", "title=Audiodeskription",
"-metadata:s:s:0", "language=deu",
"-c:v", "libx264", "-preset", "ultrafast", "-c:a", "aac", "-c:s", "srt",
ziel,
]);
File.Delete(untertitel);
}
/// Eine schlichte MP4 mit einer Tonspur.
public static void Einfach(string ziel) => Ausführen("ffmpeg",
[
"-y", "-loglevel", "error",
"-f", "lavfi", "-i", "testsrc=duration=1:size=160x120:rate=10",
"-f", "lavfi", "-i", "sine=frequency=440:duration=1",
"-c:v", "libx264", "-preset", "ultrafast", "-c:a", "aac",
ziel,
]);
/// Eine MKV mit einer Tonspur in einem Codec, den Apple nicht kennt.
///
///
/// DTS, also der echte Fall. So liegen Blu-ray-Rips vor, und genau
/// daran entscheidet sich, ob eine sonst tadellose Datei stumm bliebe.
/// Der Encoder gilt bei ffmpeg als erprobungsweise und braucht deshalb
/// -strict -2 — das betrifft nur das Erzeugen dieser Testvorlage,
/// nicht Halo.
///
public static void MitUntauglichemTon(string ziel) => Ausführen("ffmpeg",
[
"-y", "-loglevel", "error",
"-f", "lavfi", "-i", "testsrc=duration=1:size=160x120:rate=10",
"-f", "lavfi", "-i", "sine=frequency=440:duration=1",
"-f", "lavfi", "-i", "sine=frequency=880:duration=1",
"-map", "0:v", "-map", "1:a", "-map", "2:a",
"-metadata:s:a:0", "language=deu", "-metadata:s:a:0", "title=Deutsch",
"-metadata:s:a:1", "language=eng", "-metadata:s:a:1", "title=English",
"-c:v", "libx264", "-preset", "ultrafast",
"-c:a:0", "aac", "-c:a:1", "dca", "-strict", "-2",
ziel,
]);
private static void Ausführen(string werkzeug, string[] argumente)
{
var start = new ProcessStartInfo(Suchen(werkzeug)!) { RedirectStandardError = true, UseShellExecute = false };
foreach (var a in argumente) start.ArgumentList.Add(a);
using var prozess = Process.Start(start)!;
var fehler = prozess.StandardError.ReadToEnd();
prozess.WaitForExit();
if (prozess.ExitCode != 0)
throw new InvalidOperationException($"{werkzeug} scheiterte: {fehler}");
}
}