59 lines
2.0 KiB
C#
59 lines
2.0 KiB
C#
using System.IO;
|
|
using EmbyToolbox.Models;
|
|
|
|
namespace EmbyToolbox.Services;
|
|
|
|
/// <summary>MPEG-TS remux: генерация PTS и fallback при ошибках mux.</summary>
|
|
public static class MpegTsTimestampHelpers
|
|
{
|
|
/// <summary>Входной файл распознан как MPEG Transport Stream (.ts / m2ts или format_name mpegts).</summary>
|
|
public static bool IsMpegTsInput(MediaAnalysisResult? media, string? fileName)
|
|
{
|
|
if (media is null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var blob = ((media.ContainerFormat ?? string.Empty) + "," + (media.FormatName ?? string.Empty)).ToLowerInvariant();
|
|
if (blob.Contains("mpegts", StringComparison.Ordinal)
|
|
|| blob.Contains("mpeg-ts", StringComparison.Ordinal)
|
|
|| blob.Contains("m2ts", StringComparison.Ordinal))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(fileName))
|
|
{
|
|
var ext = Path.GetExtension(fileName);
|
|
if (ext.Equals(".ts", StringComparison.OrdinalIgnoreCase)
|
|
|| ext.Equals(".m2ts", StringComparison.OrdinalIgnoreCase)
|
|
|| ext.Equals(".mts", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>Сообщения ffmpeg при copy/remux без валидных PTS.</summary>
|
|
public static bool LooksLikeTimestampMuxFailure(string? stderr)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(stderr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var s = stderr.AsSpan();
|
|
return ContainsLoose(s, "unknown timestamp")
|
|
|| ContainsLoose(s, "Timestamps are unset")
|
|
|| ContainsLoose(s, "unset in a packet")
|
|
|| ContainsLoose(s, "Can't write packet with unknown timestamp");
|
|
}
|
|
|
|
private static bool ContainsLoose(ReadOnlySpan<char> haystack, string needle)
|
|
{
|
|
return haystack.Contains(needle, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
}
|