use wrapped processes; fix hls pts bug (#690)

This commit is contained in:
Jason Dove
2022-03-09 14:38:09 -06:00
committed by GitHub
parent 6a1c2b7659
commit f0670b345f
41 changed files with 407 additions and 340 deletions
@@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="Bugsnag" Version="3.0.0" />
<PackageReference Include="CliWrap" Version="3.4.1" />
<PackageReference Include="FluentAssertions" Version="6.5.1" />
<PackageReference Include="LanguageExt.Core" Version="4.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
+30 -39
View File
@@ -2,6 +2,7 @@
using System.Security.Cryptography;
using System.Text;
using Bugsnag;
using CliWrap;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Domain.Filler;
using ErsatzTV.Core.FFmpeg;
@@ -187,8 +188,10 @@ public class TranscodingTests
Watermark watermark,
// [ValueSource(typeof(TestData), nameof(TestData.SoftwareCodecs))] string profileCodec,
// [ValueSource(typeof(TestData), nameof(TestData.NoAcceleration))] HardwareAccelerationKind profileAcceleration)
[ValueSource(typeof(TestData), nameof(TestData.NvidiaCodecs))] string profileCodec,
[ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))] HardwareAccelerationKind profileAcceleration)
[ValueSource(typeof(TestData), nameof(TestData.NvidiaCodecs))]
string profileCodec,
[ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))]
HardwareAccelerationKind profileAcceleration)
// [ValueSource(typeof(TestData), nameof(TestData.VaapiCodecs))] string profileCodec,
// [ValueSource(typeof(TestData), nameof(TestData.VaapiAcceleration))] HardwareAccelerationKind profileAcceleration)
// [ValueSource(typeof(TestData), nameof(TestData.QsvCodecs))] string profileCodec,
@@ -213,9 +216,11 @@ public class TranscodingTests
{
string resolution = padding == Padding.WithPadding ? "1920x1060" : "1920x1080";
string videoFilter = videoScanKind == VideoScanKind.Interlaced ? "-vf tinterlace=interleave_top,fieldorder=tff" : string.Empty;
string videoFilter = videoScanKind == VideoScanKind.Interlaced
? "-vf tinterlace=interleave_top,fieldorder=tff"
: string.Empty;
string flags = videoScanKind == VideoScanKind.Interlaced ? "-flags +ildct+ilme" : string.Empty;
string args =
$"-y -f lavfi -i anoisesrc=color=brown -f lavfi -i testsrc=duration=1:size={resolution}:rate=30 {videoFilter} -c:a aac -c:v {inputFormat.Encoder} -shortest -pix_fmt {inputFormat.PixelFormat} -strict -2 {flags} {file}";
var p1 = new Process
@@ -235,7 +240,7 @@ public class TranscodingTests
}
var imageCache = new Mock<IImageCache>();
// always return the static watermark resource
imageCache.Setup(
ic => ic.GetPathForImage(
@@ -269,11 +274,12 @@ public class TranscodingTests
var metadataRepository = new Mock<IMetadataRepository>();
metadataRepository
.Setup(r => r.UpdateLocalStatistics(It.IsAny<MediaItem>(), It.IsAny<MediaVersion>(), It.IsAny<bool>()))
.Callback<MediaItem, MediaVersion, bool>((_, version, _) =>
{
version.MediaFiles = v.MediaFiles;
v = version;
});
.Callback<MediaItem, MediaVersion, bool>(
(_, version, _) =>
{
version.MediaFiles = v.MediaFiles;
v = version;
});
var localStatisticsProvider = new LocalStatisticsProvider(
metadataRepository.Object,
@@ -345,7 +351,7 @@ public class TranscodingTests
break;
}
Process process = await service.ForPlayoutItem(
using Process process = await service.ForPlayoutItem(
ExecutableName("ffmpeg"),
false,
new Channel(Guid.NewGuid())
@@ -376,13 +382,8 @@ public class TranscodingTests
0,
None);
process.StartInfo.RedirectStandardError = true;
process.EnableRaisingEvents = true;
// Console.WriteLine($"ffmpeg arguments {string.Join(" ", process.StartInfo.ArgumentList)}");
process.Start().Should().BeTrue();
string[] unsupportedMessages =
{
"No support for codec",
@@ -390,41 +391,31 @@ public class TranscodingTests
"Provided device doesn't support"
};
var errorBuffer = new StringBuilder();
process.ErrorDataReceived += (_, errorLine) =>
{
string data = errorLine.Data ?? string.Empty;
errorBuffer.AppendLine(data);
};
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// string error = await process.StandardError.ReadToEndAsync();
var sb = new StringBuilder();
CommandResult result;
var timeoutSignal = new CancellationTokenSource(TimeSpan.FromSeconds(30));
try
{
await process.WaitForExitAsync(timeoutSignal.Token);
// ReSharper disable once MethodHasAsyncOverload
process.WaitForExit();
result = await Cli.Wrap(process.StartInfo.FileName)
.WithArguments(process.StartInfo.ArgumentList)
.WithValidation(CommandResultValidation.None)
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(sb))
.ExecuteAsync(timeoutSignal.Token);
}
catch (OperationCanceledException)
{
process.Kill();
IEnumerable<string> quotedArgs = process.StartInfo.ArgumentList.Map(a => $"\'{a}\'");
Assert.Fail($"Transcode failure (timeout): ffmpeg {string.Join(" ", quotedArgs)}");
return;
}
var error = errorBuffer.ToString();
bool isUnsupported = unsupportedMessages.Any(error.Contains);
string error = sb.ToString();
bool isUnsupported = unsupportedMessages.Any(error.Contains);
if (profileAcceleration != HardwareAccelerationKind.None && isUnsupported)
{
var quotedArgs = process.StartInfo.ArgumentList.Map(a => $"\'{a}\'").ToList();
process.ExitCode.Should().Be(1, $"Error message with successful exit code? {string.Join(" ", quotedArgs)}");
result.ExitCode.Should().Be(1, $"Error message with successful exit code? {string.Join(" ", quotedArgs)}");
Assert.Warn($"Unsupported on this hardware: ffmpeg {string.Join(" ", quotedArgs)}");
}
else if (error.Contains("Impossible to convert between"))
@@ -435,14 +426,14 @@ public class TranscodingTests
else
{
var quotedArgs = process.StartInfo.ArgumentList.Map(a => $"\'{a}\'").ToList();
process.ExitCode.Should().Be(0, errorBuffer + Environment.NewLine + string.Join(" ", quotedArgs));
if (process.ExitCode == 0)
result.ExitCode.Should().Be(0, error + Environment.NewLine + string.Join(" ", quotedArgs));
if (result.ExitCode == 0)
{
Console.WriteLine(string.Join(" ", quotedArgs));
}
}
}
private static string GetStringSha256Hash(string text)
{
if (string.IsNullOrEmpty(text))
@@ -98,7 +98,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -141,7 +142,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -185,7 +187,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -233,7 +236,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -284,7 +288,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -335,7 +340,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -385,7 +391,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -429,7 +436,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -475,7 +483,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -515,7 +524,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -560,7 +570,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();
@@ -590,7 +601,8 @@ public class MovieFolderScannerTests
FFmpegPath,
FFprobePath,
0,
1);
1,
CancellationToken.None);
result.IsRight.Should().BeTrue();