emby-toolbox/EmbyToolbox/Services/MpegTsTimestampHelpers.cs
Emby Toolbox 6264b487fe Initial commit: Emby Toolbox (conversion scroll fix, bulk Del for tracks).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 21:33:47 +05:00

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);
}
}