FFMpegCore/FFMpegCore.Test/VideoTest.cs

575 lines
23 KiB
C#
Raw Normal View History

2019-02-08 11:19:40 +01:00
using FFMpegCore.Enums;
2019-03-03 00:33:00 +01:00
using FFMpegCore.Test.Resources;
2019-02-08 11:19:40 +01:00
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
2019-02-08 11:19:40 +01:00
using System.Collections.Generic;
using System.Drawing;
2019-02-08 11:19:40 +01:00
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
2020-12-18 00:40:09 +01:00
using System.Text;
2020-05-12 23:52:07 +02:00
using System.Threading.Tasks;
2020-05-09 17:53:03 +02:00
using FFMpegCore.Arguments;
using FFMpegCore.Exceptions;
2020-05-09 17:53:03 +02:00
using FFMpegCore.Pipes;
2019-02-08 11:19:40 +01:00
2019-03-03 00:33:00 +01:00
namespace FFMpegCore.Test
2019-02-08 11:19:40 +01:00
{
[TestClass]
2020-12-07 00:47:47 +01:00
public class VideoTest
2019-02-08 11:19:40 +01:00
{
public bool Convert(ContainerFormat type, bool multithreaded = false, VideoSize size = VideoSize.Original)
2019-02-08 11:19:40 +01:00
{
2020-12-07 00:47:47 +01:00
using var outputFile = new TemporaryFile($"out{type.Extension}");
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
var input = FFProbe.Analyse(TestResources.Mp4Video);
FFMpeg.Convert(input, outputFile, type, size: size, multithreaded: multithreaded);
var outputVideo = FFProbe.Analyse(outputFile);
Assert.IsTrue(File.Exists(outputFile));
Assert.AreEqual(outputVideo.Duration.TotalSeconds, input.Duration.TotalSeconds, 0.1);
if (size == VideoSize.Original)
{
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
}
else
2019-02-08 11:19:40 +01:00
{
2020-12-07 00:47:47 +01:00
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, (int)size);
}
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
return File.Exists(outputFile) &&
outputVideo.Duration == input.Duration &&
(
2019-02-08 11:19:40 +01:00
(
size == VideoSize.Original &&
2020-05-08 11:07:51 +02:00
outputVideo.PrimaryVideoStream.Width == input.PrimaryVideoStream.Width &&
outputVideo.PrimaryVideoStream.Height == input.PrimaryVideoStream.Height
2020-12-07 00:47:47 +01:00
) ||
(
2019-02-08 11:19:40 +01:00
size != VideoSize.Original &&
2020-05-08 11:07:51 +02:00
outputVideo.PrimaryVideoStream.Width != input.PrimaryVideoStream.Width &&
outputVideo.PrimaryVideoStream.Height != input.PrimaryVideoStream.Height &&
outputVideo.PrimaryVideoStream.Height == (int)size
2020-12-07 00:47:47 +01:00
)
);
2019-02-08 11:19:40 +01:00
}
2020-10-24 22:31:54 +02:00
public void Convert(ContainerFormat type, Action<IMediaAnalysis> validationMethod, params IArgument[] arguments)
2019-02-08 11:19:40 +01:00
{
2020-12-07 00:47:47 +01:00
using var outputFile = new TemporaryFile($"out{type.Extension}");
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
var input = FFProbe.Analyse(TestResources.Mp4Video);
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
var processor = FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt =>
2020-10-24 22:31:54 +02:00
{
foreach (var arg in arguments)
opt.WithArgument(arg);
});
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
var scaling = arguments.OfType<ScaleArgument>().FirstOrDefault();
processor.ProcessSynchronously();
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
var outputVideo = FFProbe.Analyse(outputFile);
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
Assert.IsTrue(File.Exists(outputFile));
Assert.AreEqual(outputVideo.Duration.TotalSeconds, input.Duration.TotalSeconds, 0.1);
validationMethod?.Invoke(outputVideo);
if (scaling?.Size == null)
{
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
}
else
{
if (scaling.Size.Value.Width != -1)
2019-02-08 11:19:40 +01:00
{
2020-12-07 00:47:47 +01:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width);
}
2019-02-08 11:19:40 +01:00
2020-12-07 00:47:47 +01:00
if (scaling.Size.Value.Height != -1)
{
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height);
2019-02-08 11:19:40 +01:00
}
2020-12-07 00:47:47 +01:00
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
2019-02-08 11:19:40 +01:00
}
}
public void Convert(ContainerFormat type, params IArgument[] inputArguments)
{
Convert(type, null, inputArguments);
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToMP4()
{
Convert(VideoType.Mp4);
}
[TestMethod, Timeout(10000)]
public void Video_ToMP4_YUV444p()
{
Convert(VideoType.Mp4, (a) => Assert.IsTrue(a.VideoStreams.First().PixelFormat == "yuv444p"),
new ForcePixelFormat("yuv444p"));
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToMP4_Args()
{
Convert(VideoType.Mp4, new VideoCodecArgument(VideoCodec.LibX264));
2019-02-08 11:19:40 +01:00
}
[DataTestMethod, Timeout(10000)]
2020-05-12 16:53:52 +02:00
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
public void Video_ToMP4_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
2020-04-27 18:24:26 +02:00
{
2021-03-05 18:06:40 +01:00
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256));
var success = FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt
.WithVideoCodec(VideoCodec.LibX264))
.ProcessSynchronously();
Assert.IsTrue(success);
2020-04-27 18:24:26 +02:00
}
2020-10-25 17:18:40 +01:00
[TestMethod, Timeout(10000)]
2020-04-27 20:22:05 +02:00
public void Video_ToMP4_Args_StreamPipe()
{
2021-03-05 18:06:40 +01:00
using var input = File.OpenRead(TestResources.WebmVideo);
using var output = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var success = FFMpegArguments
.FromPipeInput(new StreamPipeSource(input))
.OutputToFile(output, false, opt => opt
.WithVideoCodec(VideoCodec.LibX264))
.ProcessSynchronously();
Assert.IsTrue(success);
var outputVideo = FFProbe.Analyse(output);
2020-04-27 20:22:05 +02:00
}
2020-10-25 17:18:40 +01:00
[TestMethod, Timeout(10000)]
2020-05-12 23:52:07 +02:00
public async Task Video_ToMP4_Args_StreamOutputPipe_Async_Failure()
{
2020-05-12 23:52:07 +02:00
await Assert.ThrowsExceptionAsync<FFMpegException>(async () =>
2020-05-12 17:55:31 +02:00
{
await using var ms = new MemoryStream();
2020-05-24 19:17:14 +02:00
var pipeSource = new StreamPipeSink(ms);
2020-05-12 17:55:31 +02:00
await FFMpegArguments
2020-12-07 00:47:47 +01:00
.FromFileInput(TestResources.Mp4Video)
2020-10-24 22:31:54 +02:00
.OutputToPipe(pipeSource, opt => opt.ForceFormat("mkv"))
2020-05-12 17:55:31 +02:00
.ProcessAsynchronously();
});
}
2020-12-03 20:47:20 +01:00
[TestMethod, Timeout(10000)]
public void Video_StreamFile_OutputToMemoryStream()
{
var output = new MemoryStream();
FFMpegArguments
2021-03-05 18:06:40 +01:00
.FromPipeInput(new StreamPipeSource(File.OpenRead(TestResources.WebmVideo)), opt => opt
.ForceFormat("webm"))
.OutputToPipe(new StreamPipeSink(output), opt => opt
2020-12-07 00:47:47 +01:00
.ForceFormat("mpegts"))
2020-12-03 20:47:20 +01:00
.ProcessSynchronously();
output.Position = 0;
var result = FFProbe.Analyse(output);
Console.WriteLine(result.Duration);
}
2020-10-25 17:18:40 +01:00
[TestMethod, Timeout(10000)]
public void Video_ToMP4_Args_StreamOutputPipe_Failure()
{
2021-03-05 18:06:40 +01:00
Assert.ThrowsException<FFMpegException>(() =>
{
using var ms = new MemoryStream();
var processor = FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.OutputToPipe(new StreamPipeSink(ms), opt => opt
.ForceFormat("mkv"))
.ProcessSynchronously();
ms.Position = 0;
var outputVideo = FFProbe.Analyse(ms);
});
}
2020-10-25 17:26:43 +01:00
[TestMethod, Timeout(10000)]
2021-03-05 18:06:40 +01:00
public async Task Video_ToMP4_Args_StreamOutputPipe_Async()
{
2021-03-05 18:06:40 +01:00
await using var ms = new MemoryStream();
2020-05-24 19:17:14 +02:00
var pipeSource = new StreamPipeSink(ms);
2021-03-05 18:06:40 +01:00
await FFMpegArguments
2020-12-07 00:47:47 +01:00
.FromFileInput(TestResources.Mp4Video)
2020-10-24 22:31:54 +02:00
.OutputToPipe(pipeSource, opt => opt
.WithVideoCodec(VideoCodec.LibX264)
.ForceFormat("matroska"))
2021-03-05 18:06:40 +01:00
.ProcessAsynchronously();
}
[TestMethod, Timeout(10000)]
public async Task TestDuplicateRun()
{
2020-12-07 00:47:47 +01:00
FFMpegArguments.FromFileInput(TestResources.Mp4Video)
2020-10-24 22:31:54 +02:00
.OutputToFile("temporary.mp4")
.ProcessSynchronously();
2020-12-07 00:47:47 +01:00
await FFMpegArguments.FromFileInput(TestResources.Mp4Video)
2020-10-24 22:31:54 +02:00
.OutputToFile("temporary.mp4")
.ProcessAsynchronously();
File.Delete("temporary.mp4");
}
2020-10-25 17:26:43 +01:00
[TestMethod, Timeout(10000)]
public void Video_ToMP4_Args_StreamOutputPipe()
{
2021-03-05 18:06:40 +01:00
using var input = new MemoryStream();
var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.OutputToPipe(new StreamPipeSink(input), opt => opt
.WithVideoCodec(VideoCodec.LibVpx)
.ForceFormat("matroska"))
.ProcessSynchronously();
Assert.IsTrue(success);
input.Position = 0;
var inputAnalysis = FFProbe.Analyse(TestResources.Mp4Video);
var outputAnalysis = FFProbe.Analyse(input);
Assert.AreEqual(inputAnalysis.Duration.TotalSeconds, outputAnalysis.Duration.TotalSeconds, 0.3);
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToTS()
{
Convert(VideoType.Ts);
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToTS_Args()
{
Convert(VideoType.Ts,
2020-02-27 21:12:48 +01:00
new CopyArgument(),
new BitStreamFilterArgument(Channel.Video, Filter.H264_Mp4ToAnnexB),
new ForceFormatArgument(VideoType.MpegTs));
2019-02-08 11:19:40 +01:00
}
2020-10-25 17:26:43 +01:00
[DataTestMethod, Timeout(10000)]
2020-05-12 16:53:52 +02:00
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
2021-03-05 18:06:40 +01:00
public async Task Video_ToTS_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
2020-04-27 18:24:26 +02:00
{
2021-03-05 18:06:40 +01:00
using var output = new TemporaryFile($"out{VideoType.Ts.Extension}");
var input = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256));
var success = await FFMpegArguments
.FromPipeInput(input)
.OutputToFile(output, false, opt => opt
.ForceFormat(VideoType.Ts))
.ProcessAsynchronously();
Assert.IsTrue(success);
2019-02-08 11:19:40 +01:00
2021-03-05 18:06:40 +01:00
var analysis = await FFProbe.AnalyseAsync(output);
Assert.AreEqual(VideoType.Ts.Name, analysis.Format.FormatName);
2019-02-08 11:19:40 +01:00
}
[TestMethod, Timeout(10000)]
2021-03-05 18:06:40 +01:00
public async Task Video_ToOGV_Resize()
2019-02-08 11:19:40 +01:00
{
2021-03-05 18:06:40 +01:00
using var outputFile = new TemporaryFile($"out{VideoType.Ogv.Extension}");
var success = await FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt
.Resize(VideoSize.Ed)
.WithVideoCodec(VideoCodec.LibTheora))
.ProcessAsynchronously();
Assert.IsTrue(success);
2019-02-08 11:19:40 +01:00
}
2020-10-25 17:26:43 +01:00
[DataTestMethod, Timeout(10000)]
2020-05-12 16:53:52 +02:00
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
// [DataRow(PixelFormat.Format48bppRgb)]
2021-03-05 18:06:40 +01:00
public void RawVideoPipeSource_Ogv_Scale(System.Drawing.Imaging.PixelFormat pixelFormat)
2020-04-27 18:24:26 +02:00
{
2021-03-05 18:06:40 +01:00
using var outputFile = new TemporaryFile($"out{VideoType.Ogv.Extension}");
var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256));
FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt
.WithVideoFilters(filterOptions => filterOptions
.Scale(VideoSize.Ed))
.WithVideoCodec(VideoCodec.LibTheora))
.ProcessSynchronously();
2020-04-27 18:24:26 +02:00
2021-03-05 18:06:40 +01:00
var analysis = FFProbe.Analyse(outputFile);
Assert.Equals((int)VideoSize.Ed, analysis!.PrimaryVideoStream.Width);
2019-02-08 11:19:40 +01:00
}
[TestMethod, Timeout(10000)]
2021-03-05 18:06:40 +01:00
public void Scale_Mp4_Multithreaded()
2019-02-08 11:19:40 +01:00
{
2021-03-05 18:06:40 +01:00
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt
.UsingMultithreading(true)
.WithVideoFilters(filterOptions => filterOptions
.Scale(VideoSize.Ld))
.WithVideoCodec(VideoCodec.LibX264))
.ProcessSynchronously();
Assert.IsTrue(success);
var analysis = FFProbe.Analyse(outputFile);
Assert.AreEqual((int)VideoSize.Ld, analysis!.PrimaryVideoStream.Width);
2019-02-08 11:19:40 +01:00
}
2020-10-25 17:26:43 +01:00
[DataTestMethod, Timeout(10000)]
2020-05-12 16:53:52 +02:00
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
// [DataRow(PixelFormat.Format48bppRgb)]
2020-05-12 16:53:52 +02:00
public void Video_ToMP4_Resize_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
2020-04-27 18:24:26 +02:00
{
2021-03-05 18:06:40 +01:00
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256));
var success = FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt
.Resize(VideoSize.Ld)
.WithVideoCodec(VideoCodec.LibX264))
.ProcessSynchronously();
Assert.IsTrue(success);
var analysis = FFProbe.Analyse(outputFile);
Assert.AreEqual((int)VideoSize.Ld, analysis!.PrimaryVideoStream.Width);
2020-04-27 18:24:26 +02:00
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToOGV()
{
Convert(VideoType.Ogv);
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToMP4_MultiThread()
{
Convert(VideoType.Mp4, true);
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToTS_MultiThread()
{
Convert(VideoType.Ts, true);
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_ToOGV_MultiThread()
{
Convert(VideoType.Ogv, true);
}
[TestMethod, Timeout(10000)]
public void Video_Snapshot_InMemory()
2019-02-08 11:19:40 +01:00
{
2020-12-07 00:47:47 +01:00
var input = FFProbe.Analyse(TestResources.Mp4Video);
using var bitmap = FFMpeg.Snapshot(input);
Assert.AreEqual(input.PrimaryVideoStream.Width, bitmap.Width);
Assert.AreEqual(input.PrimaryVideoStream.Height, bitmap.Height);
Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png);
2019-02-08 11:19:40 +01:00
}
[TestMethod, Timeout(10000)]
public void Video_Snapshot_PersistSnapshot()
{
2020-12-07 00:47:47 +01:00
var outputPath = new TemporaryFile("out.png");
var input = FFProbe.Analyse(TestResources.Mp4Video);
2020-12-07 00:47:47 +01:00
FFMpeg.Snapshot(input, outputPath);
2020-12-07 00:47:47 +01:00
using var bitmap = Image.FromFile(outputPath);
Assert.AreEqual(input.PrimaryVideoStream.Width, bitmap.Width);
Assert.AreEqual(input.PrimaryVideoStream.Height, bitmap.Height);
Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png);
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_Join()
{
2020-12-07 00:47:47 +01:00
var inputCopy = new TemporaryFile("copy-input.mp4");
File.Copy(TestResources.Mp4Video, inputCopy);
2020-05-24 19:27:55 +02:00
2020-12-07 00:47:47 +01:00
var outputPath = new TemporaryFile("out.mp4");
var input = FFProbe.Analyse(TestResources.Mp4Video);
var success = FFMpeg.Join(outputPath, TestResources.Mp4Video, inputCopy);
Assert.IsTrue(success);
Assert.IsTrue(File.Exists(outputPath));
var expectedDuration = input.Duration * 2;
var result = FFProbe.Analyse(outputPath);
Assert.AreEqual(expectedDuration.Days, result.Duration.Days);
Assert.AreEqual(expectedDuration.Hours, result.Duration.Hours);
Assert.AreEqual(expectedDuration.Minutes, result.Duration.Minutes);
Assert.AreEqual(expectedDuration.Seconds, result.Duration.Seconds);
Assert.AreEqual(input.PrimaryVideoStream.Height, result.PrimaryVideoStream.Height);
Assert.AreEqual(input.PrimaryVideoStream.Width, result.PrimaryVideoStream.Width);
2019-02-08 11:19:40 +01:00
}
[TestMethod, Timeout(10000)]
2019-02-08 11:19:40 +01:00
public void Video_Join_Image_Sequence()
{
2020-12-07 00:47:47 +01:00
var imageSet = new List<ImageInfo>();
Directory.EnumerateFiles(TestResources.ImageCollection)
.Where(file => file.ToLower().EndsWith(".png"))
.ToList()
.ForEach(file =>
2019-02-08 11:19:40 +01:00
{
2020-12-07 00:47:47 +01:00
for (var i = 0; i < 15; i++)
{
imageSet.Add(new ImageInfo(file));
}
});
var outputFile = new TemporaryFile("out.mp4");
var success = FFMpeg.JoinImageSequence(outputFile, images: imageSet.ToArray());
Assert.IsTrue(success);
var result = FFProbe.Analyse(outputFile);
Assert.AreEqual(3, result.Duration.Seconds);
Assert.AreEqual(imageSet.First().Width, result.PrimaryVideoStream.Width);
Assert.AreEqual(imageSet.First().Height, result.PrimaryVideoStream.Height);
2019-02-08 11:19:40 +01:00
}
[TestMethod, Timeout(10000)]
public void Video_With_Only_Audio_Should_Extract_Metadata()
{
2020-12-07 00:47:47 +01:00
var video = FFProbe.Analyse(TestResources.Mp4WithoutVideo);
2020-05-08 11:07:51 +02:00
Assert.AreEqual(null, video.PrimaryVideoStream);
Assert.AreEqual("aac", video.PrimaryAudioStream.CodecName);
2020-10-25 17:16:47 +01:00
Assert.AreEqual(10, video.Duration.TotalSeconds, 0.5);
}
2020-04-27 18:24:26 +02:00
[TestMethod, Timeout(10000)]
2020-04-27 18:24:26 +02:00
public void Video_Duration()
{
2020-12-07 00:47:47 +01:00
var video = FFProbe.Analyse(TestResources.Mp4Video);
var outputFile = new TemporaryFile("out.mp4");
2020-12-07 00:47:47 +01:00
FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt.WithDuration(TimeSpan.FromSeconds(video.Duration.TotalSeconds - 2)))
.ProcessSynchronously();
Assert.IsTrue(File.Exists(outputFile));
var outputVideo = FFProbe.Analyse(outputFile);
Assert.AreEqual(video.Duration.Days, outputVideo.Duration.Days);
Assert.AreEqual(video.Duration.Hours, outputVideo.Duration.Hours);
Assert.AreEqual(video.Duration.Minutes, outputVideo.Duration.Minutes);
Assert.AreEqual(video.Duration.Seconds - 2, outputVideo.Duration.Seconds);
}
2020-04-27 18:24:26 +02:00
[TestMethod, Timeout(10000)]
2020-04-27 18:24:26 +02:00
public void Video_UpdatesProgress()
{
2020-12-07 00:47:47 +01:00
var outputFile = new TemporaryFile("out.mp4");
2020-03-02 22:50:04 +01:00
var percentageDone = 0.0;
2020-05-08 11:07:51 +02:00
var timeDone = TimeSpan.Zero;
void OnPercentageProgess(double percentage) => percentageDone = percentage;
void OnTimeProgess(TimeSpan time) => timeDone = time;
2020-03-02 22:50:04 +01:00
2020-12-07 00:47:47 +01:00
var analysis = FFProbe.Analyse(TestResources.Mp4Video);
var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt
.WithDuration(TimeSpan.FromSeconds(2)))
.NotifyOnProgress(OnPercentageProgess, analysis.Duration)
.NotifyOnProgress(OnTimeProgess)
.ProcessSynchronously();
2020-03-02 22:50:04 +01:00
2020-12-07 00:47:47 +01:00
Assert.IsTrue(success);
Assert.IsTrue(File.Exists(outputFile));
Assert.AreNotEqual(0.0, percentageDone);
Assert.AreNotEqual(TimeSpan.Zero, timeDone);
2020-03-02 22:50:04 +01:00
}
2020-04-28 21:54:39 +02:00
2020-12-18 00:40:09 +01:00
[TestMethod, Timeout(10000)]
public void Video_OutputsData()
{
var outputFile = new TemporaryFile("out.mp4");
var dataReceived = false;
FFMpegOptions.Configure(opt => opt.Encoding = Encoding.UTF8);
var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
.WithGlobalOptions(options => options
.WithVerbosityLevel(VerbosityLevel.Info))
.OutputToFile(outputFile, false, opt => opt
.WithDuration(TimeSpan.FromSeconds(2)))
.NotifyOnOutput((_, _) => dataReceived = true)
.ProcessSynchronously();
Assert.IsTrue(dataReceived);
Assert.IsTrue(success);
Assert.IsTrue(File.Exists(outputFile));
}
2020-10-25 17:18:40 +01:00
[TestMethod, Timeout(10000)]
2020-04-28 21:54:39 +02:00
public void Video_TranscodeInMemory()
{
2020-05-08 11:07:51 +02:00
using var resStream = new MemoryStream();
2020-05-24 19:17:14 +02:00
var reader = new StreamPipeSink(resStream);
var writer = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 128, 128));
2020-05-08 11:07:51 +02:00
FFMpegArguments
2020-10-24 22:31:54 +02:00
.FromPipeInput(writer)
.OutputToPipe(reader, opt => opt
.WithVideoCodec("vp9")
.ForceFormat("webm"))
2020-05-08 11:07:51 +02:00
.ProcessSynchronously();
2020-05-08 11:07:51 +02:00
resStream.Position = 0;
var vi = FFProbe.Analyse(resStream);
Assert.AreEqual(vi.PrimaryVideoStream.Width, 128);
Assert.AreEqual(vi.PrimaryVideoStream.Height, 128);
2020-04-28 21:54:39 +02:00
}
2020-05-12 23:52:07 +02:00
2020-10-25 17:18:40 +01:00
[TestMethod, Timeout(10000)]
2020-05-12 23:52:07 +02:00
public async Task Video_Cancel_Async()
{
2020-12-07 00:47:47 +01:00
var outputFile = new TemporaryFile("out.mp4");
2020-10-28 19:26:33 +01:00
2020-05-12 23:52:07 +02:00
var task = FFMpegArguments
2020-12-07 00:47:47 +01:00
.FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt
2020-10-28 19:26:33 +01:00
.Resize(new Size(1000, 1000))
.WithAudioCodec(AudioCodec.Aac)
.WithVideoCodec(VideoCodec.LibX264)
.WithConstantRateFactor(14)
.WithSpeedPreset(Speed.VerySlow)
.Loop(3))
2020-05-12 23:52:07 +02:00
.CancellableThrough(out var cancel)
.ProcessAsynchronously(false);
2020-12-07 00:47:47 +01:00
await Task.Delay(300);
cancel();
2020-10-28 19:26:33 +01:00
2020-12-07 00:47:47 +01:00
var result = await task;
Assert.IsFalse(result);
2020-05-12 23:52:07 +02:00
}
2019-02-08 11:19:40 +01:00
}
}