|
|
|
@ -65,6 +65,12 @@ public class TranscodingTests |
|
|
|
// TODO: animated vs static
|
|
|
|
// TODO: animated vs static
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public enum Subtitle |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
None, |
|
|
|
|
|
|
|
Picture |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private class TestData |
|
|
|
private class TestData |
|
|
|
{ |
|
|
|
{ |
|
|
|
public static Watermark[] Watermarks = |
|
|
|
public static Watermark[] Watermarks = |
|
|
|
@ -73,6 +79,12 @@ public class TranscodingTests |
|
|
|
Watermark.PermanentOpaque, |
|
|
|
Watermark.PermanentOpaque, |
|
|
|
Watermark.PermanentTransparent |
|
|
|
Watermark.PermanentTransparent |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Subtitle[] Subtitles = |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Subtitle.None, |
|
|
|
|
|
|
|
Subtitle.Picture |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
public static Padding[] Paddings = |
|
|
|
public static Padding[] Paddings = |
|
|
|
{ |
|
|
|
{ |
|
|
|
@ -158,6 +170,7 @@ public class TranscodingTests |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Paddings))] Padding padding, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Paddings))] Padding padding, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.VideoScanKinds))] VideoScanKind videoScanKind, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.VideoScanKinds))] VideoScanKind videoScanKind, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Watermarks))] Watermark watermark, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Watermarks))] Watermark watermark, |
|
|
|
|
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Subtitles))] Subtitle subtitle, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.VideoFormats))] FFmpegProfileVideoFormat profileVideoFormat, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.VideoFormats))] FFmpegProfileVideoFormat profileVideoFormat, |
|
|
|
// [ValueSource(typeof(TestData), nameof(TestData.NoAcceleration))] HardwareAccelerationKind profileAcceleration)
|
|
|
|
// [ValueSource(typeof(TestData), nameof(TestData.NoAcceleration))] HardwareAccelerationKind profileAcceleration)
|
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))] HardwareAccelerationKind profileAcceleration) |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))] HardwareAccelerationKind profileAcceleration) |
|
|
|
@ -175,7 +188,7 @@ public class TranscodingTests |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
string name = GetStringSha256Hash( |
|
|
|
string name = GetStringSha256Hash( |
|
|
|
$"{inputFormat.Encoder}_{inputFormat.PixelFormat}_{videoScanKind}_{padding}_{profileResolution}_{profileVideoFormat}_{profileAcceleration}"); |
|
|
|
$"{inputFormat.Encoder}_{inputFormat.PixelFormat}_{videoScanKind}_{padding}_{watermark}_{subtitle}_{profileResolution}_{profileVideoFormat}_{profileAcceleration}"); |
|
|
|
|
|
|
|
|
|
|
|
string file = Path.Combine(TestContext.CurrentContext.TestDirectory, $"{name}.mkv"); |
|
|
|
string file = Path.Combine(TestContext.CurrentContext.TestDirectory, $"{name}.mkv"); |
|
|
|
if (!File.Exists(file)) |
|
|
|
if (!File.Exists(file)) |
|
|
|
@ -203,6 +216,46 @@ public class TranscodingTests |
|
|
|
// ReSharper disable once MethodHasAsyncOverload
|
|
|
|
// ReSharper disable once MethodHasAsyncOverload
|
|
|
|
p1.WaitForExit(); |
|
|
|
p1.WaitForExit(); |
|
|
|
p1.ExitCode.Should().Be(0); |
|
|
|
p1.ExitCode.Should().Be(0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (subtitle) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case Subtitle.Picture: |
|
|
|
|
|
|
|
string sourceFile = Path.GetTempFileName() + ".mkv"; |
|
|
|
|
|
|
|
File.Move(file, sourceFile, true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string tempFileName = Path.GetTempFileName() + ".mkv"; |
|
|
|
|
|
|
|
string subPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "Resources", "test.sup"); |
|
|
|
|
|
|
|
var p2 = new Process |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
StartInfo = new ProcessStartInfo |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FileName = ExecutableName("mkvmerge"), |
|
|
|
|
|
|
|
Arguments = $"-o {tempFileName} {sourceFile} {subPath}" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p2.Start(); |
|
|
|
|
|
|
|
await p2.WaitForExitAsync(); |
|
|
|
|
|
|
|
// ReSharper disable once MethodHasAsyncOverload
|
|
|
|
|
|
|
|
p2.WaitForExit(); |
|
|
|
|
|
|
|
if (p2.ExitCode != 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (File.Exists(sourceFile)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
File.Delete(sourceFile); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (File.Exists(file)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
File.Delete(file); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p2.ExitCode.Should().Be(0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File.Move(tempFileName, file, true); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var imageCache = new Mock<IImageCache>(); |
|
|
|
var imageCache = new Mock<IImageCache>(); |
|
|
|
@ -221,7 +274,7 @@ public class TranscodingTests |
|
|
|
imageCache.Object, |
|
|
|
imageCache.Object, |
|
|
|
new Mock<ITempFilePool>().Object, |
|
|
|
new Mock<ITempFilePool>().Object, |
|
|
|
new Mock<IClient>().Object, |
|
|
|
new Mock<IClient>().Object, |
|
|
|
new Mock<IMemoryCache>().Object, |
|
|
|
new MemoryCache(new MemoryCacheOptions()), |
|
|
|
LoggerFactory.CreateLogger<FFmpegProcessService>()); |
|
|
|
LoggerFactory.CreateLogger<FFmpegProcessService>()); |
|
|
|
|
|
|
|
|
|
|
|
var service = new FFmpegLibraryProcessService( |
|
|
|
var service = new FFmpegLibraryProcessService( |
|
|
|
@ -318,6 +371,12 @@ public class TranscodingTests |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ChannelSubtitleMode subtitleMode = subtitle switch |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Subtitle.Picture => ChannelSubtitleMode.Any, |
|
|
|
|
|
|
|
_ => ChannelSubtitleMode.None |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
using Process process = await service.ForPlayoutItem( |
|
|
|
using Process process = await service.ForPlayoutItem( |
|
|
|
ExecutableName("ffmpeg"), |
|
|
|
ExecutableName("ffmpeg"), |
|
|
|
ExecutableName("ffprobe"), |
|
|
|
ExecutableName("ffprobe"), |
|
|
|
@ -329,9 +388,11 @@ public class TranscodingTests |
|
|
|
{ |
|
|
|
{ |
|
|
|
HardwareAcceleration = profileAcceleration, |
|
|
|
HardwareAcceleration = profileAcceleration, |
|
|
|
VideoFormat = profileVideoFormat, |
|
|
|
VideoFormat = profileVideoFormat, |
|
|
|
AudioFormat = FFmpegProfileAudioFormat.Aac |
|
|
|
AudioFormat = FFmpegProfileAudioFormat.Aac, |
|
|
|
|
|
|
|
DeinterlaceVideo = true |
|
|
|
}, |
|
|
|
}, |
|
|
|
StreamingMode = StreamingMode.TransportStream |
|
|
|
StreamingMode = StreamingMode.TransportStream, |
|
|
|
|
|
|
|
SubtitleMode = subtitleMode |
|
|
|
}, |
|
|
|
}, |
|
|
|
v, |
|
|
|
v, |
|
|
|
v, |
|
|
|
v, |
|
|
|
@ -368,6 +429,7 @@ public class TranscodingTests |
|
|
|
result = await Cli.Wrap(process.StartInfo.FileName) |
|
|
|
result = await Cli.Wrap(process.StartInfo.FileName) |
|
|
|
.WithArguments(process.StartInfo.ArgumentList) |
|
|
|
.WithArguments(process.StartInfo.ArgumentList) |
|
|
|
.WithValidation(CommandResultValidation.None) |
|
|
|
.WithValidation(CommandResultValidation.None) |
|
|
|
|
|
|
|
.WithStandardOutputPipe(PipeTarget.Null) |
|
|
|
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(sb)) |
|
|
|
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(sb)) |
|
|
|
.ExecuteAsync(timeoutSignal.Token); |
|
|
|
.ExecuteAsync(timeoutSignal.Token); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -425,7 +487,7 @@ public class TranscodingTests |
|
|
|
Optional(version.Streams.First(s => s.MediaStreamKind == MediaStreamKind.Audio)).AsTask(); |
|
|
|
Optional(version.Streams.First(s => s.MediaStreamKind == MediaStreamKind.Audio)).AsTask(); |
|
|
|
|
|
|
|
|
|
|
|
public Task<Option<MediaStream>> SelectSubtitleStream(Channel channel, MediaVersion version) => |
|
|
|
public Task<Option<MediaStream>> SelectSubtitleStream(Channel channel, MediaVersion version) => |
|
|
|
Optional(version.Streams.First(s => s.MediaStreamKind == MediaStreamKind.Subtitle)).AsTask(); |
|
|
|
Optional(version.Streams.Find(s => s.MediaStreamKind == MediaStreamKind.Subtitle)).AsTask(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static string ExecutableName(string baseName) => |
|
|
|
private static string ExecutableName(string baseName) => |
|
|
|
|