FFMpegCore/FFMpegCore.Test/VideoTest.cs

679 lines
25 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-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]
public class VideoTest : BaseTest
{
public bool Convert(ContainerFormat type, bool multithreaded = false, VideoSize size = VideoSize.Original)
2019-02-08 11:19:40 +01:00
{
var output = Input.OutputLocation(type);
try
{
2020-05-08 11:07:51 +02:00
var input = FFProbe.Analyse(Input.FullName);
FFMpeg.Convert(input, output, type, size: size, multithreaded: multithreaded);
var outputVideo = FFProbe.Analyse(output);
2019-02-08 11:19:40 +01:00
2020-05-08 11:07:51 +02:00
Assert.IsTrue(File.Exists(output));
Assert.AreEqual(outputVideo.Duration.TotalSeconds, input.Duration.TotalSeconds, 0.1);
2019-02-08 11:19:40 +01:00
if (size == VideoSize.Original)
{
2020-05-08 11:07:51 +02:00
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-05-08 11:07:51 +02: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-05-08 11:07:51 +02:00
return File.Exists(output) &&
2019-02-08 11:19:40 +01:00
outputVideo.Duration == input.Duration &&
(
(
size == VideoSize.Original &&
2020-05-08 11:07:51 +02:00
outputVideo.PrimaryVideoStream.Width == input.PrimaryVideoStream.Width &&
outputVideo.PrimaryVideoStream.Height == input.PrimaryVideoStream.Height
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
2019-02-08 11:19:40 +01:00
)
);
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
2019-02-08 11:19:40 +01:00
}
}
2020-10-24 22:31:54 +02:00
private void ConvertFromStreamPipe(ContainerFormat type, params IArgument[] arguments)
2020-04-27 20:22:05 +02:00
{
var output = Input.OutputLocation(type);
try
{
2020-05-08 11:07:51 +02:00
var input = FFProbe.Analyse(VideoLibrary.LocalVideoWebm.FullName);
2020-10-24 22:31:54 +02:00
using var inputStream = File.OpenRead(input.Path);
var processor = FFMpegArguments
.FromPipeInput(new StreamPipeSource(inputStream))
.OutputToFile(output, false, opt =>
{
foreach (var arg in arguments)
opt.WithArgument(arg);
});
2020-04-27 20:22:05 +02:00
2020-10-24 22:31:54 +02:00
var scaling = arguments.OfType<ScaleArgument>().FirstOrDefault();
2020-04-27 20:22:05 +02:00
2020-10-24 22:31:54 +02:00
var success = processor.ProcessSynchronously();
2020-04-27 20:22:05 +02:00
2020-10-24 22:31:54 +02:00
var outputVideo = FFProbe.Analyse(output);
2020-10-24 22:31:54 +02:00
Assert.IsTrue(success);
Assert.IsTrue(File.Exists(output));
Assert.IsTrue(Math.Abs((outputVideo.Duration - input.Duration).TotalMilliseconds) < 1000.0 / input.PrimaryVideoStream.FrameRate);
2020-04-27 20:22:05 +02:00
2020-10-24 22:31:54 +02:00
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)
2020-04-27 20:22:05 +02:00
{
2020-10-24 22:31:54 +02:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width);
2020-04-27 20:22:05 +02:00
}
2020-10-24 22:31:54 +02:00
if (scaling.Size.Value.Height != -1)
{
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height);
2020-04-27 20:22:05 +02:00
}
2020-10-24 22:31:54 +02:00
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
2020-04-27 20:22:05 +02:00
}
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
2020-04-27 20:22:05 +02:00
}
}
2019-02-08 11:19:40 +01:00
2020-10-24 22:31:54 +02:00
private void ConvertToStreamPipe(params IArgument[] arguments)
{
2020-05-08 11:07:51 +02:00
using var ms = new MemoryStream();
2020-10-24 22:31:54 +02:00
var processor = FFMpegArguments
.FromFileInput(VideoLibrary.LocalVideo)
.OutputToPipe(new StreamPipeSink(ms), opt =>
{
foreach (var arg in arguments)
opt.WithArgument(arg);
});
2020-10-24 22:31:54 +02:00
var scaling = arguments.OfType<ScaleArgument>().FirstOrDefault();
processor.ProcessSynchronously();
2020-05-08 11:07:51 +02:00
ms.Position = 0;
var outputVideo = FFProbe.Analyse(ms);
2020-05-08 11:07:51 +02:00
var input = FFProbe.Analyse(VideoLibrary.LocalVideo.FullName);
2020-05-08 13:01:59 +02:00
// Assert.IsTrue(Math.Abs((outputVideo.Duration - input.Duration).TotalMilliseconds) < 1000.0 / input.PrimaryVideoStream.FrameRate);
2020-05-08 11:07:51 +02:00
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)
{
2020-05-08 11:07:51 +02:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width);
}
2020-05-08 11:07:51 +02:00
if (scaling.Size.Value.Height != -1)
{
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height);
}
2020-05-08 11:07:51 +02:00
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width);
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height);
}
}
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
{
var output = Input.OutputLocation(type);
try
{
2020-05-08 11:07:51 +02:00
var input = FFProbe.Analyse(Input.FullName);
2019-02-08 11:19:40 +01:00
2020-10-24 22:31:54 +02:00
var processor = FFMpegArguments
.FromFileInput(VideoLibrary.LocalVideo)
.OutputToFile(output, false, opt =>
{
foreach (var arg in arguments)
opt.WithArgument(arg);
});
2019-02-08 11:19:40 +01:00
2020-10-24 22:31:54 +02:00
var scaling = arguments.OfType<ScaleArgument>().FirstOrDefault();
2020-05-08 11:07:51 +02:00
processor.ProcessSynchronously();
2019-02-08 11:19:40 +01:00
2020-05-08 11:07:51 +02:00
var outputVideo = FFProbe.Analyse(output);
2019-02-08 11:19:40 +01:00
2020-05-08 11:07:51 +02:00
Assert.IsTrue(File.Exists(output));
Assert.AreEqual(outputVideo.Duration.TotalSeconds, input.Duration.TotalSeconds, 0.1);
validationMethod?.Invoke(outputVideo);
2020-05-08 11:07:51 +02:00
if (scaling?.Size == null)
2019-02-08 11:19:40 +01:00
{
2020-05-08 11:07:51 +02:00
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-05-08 11:07:51 +02:00
if (scaling.Size.Value.Width != -1)
2019-02-08 11:19:40 +01:00
{
2020-05-08 11:07:51 +02:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width);
2019-02-08 11:19:40 +01:00
}
2020-05-08 11:07:51 +02:00
if (scaling.Size.Value.Height != -1)
2019-02-08 11:19:40 +01:00
{
2020-05-08 11:07:51 +02:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height);
2019-02-08 11:19:40 +01:00
}
2020-05-08 11:07:51 +02: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
}
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
2019-02-08 11:19:40 +01:00
}
}
public void Convert(ContainerFormat type, params IArgument[] inputArguments)
{
Convert(type, null, inputArguments);
}
2020-10-24 22:31:54 +02:00
public void ConvertFromPipe(ContainerFormat type, System.Drawing.Imaging.PixelFormat fmt, params IArgument[] arguments)
2020-04-27 18:24:26 +02:00
{
var output = Input.OutputLocation(type);
try
{
2020-05-24 19:17:14 +02:00
var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, fmt, 256, 256));
2020-10-24 22:31:54 +02:00
var processor = FFMpegArguments.FromPipeInput(videoFramesSource).OutputToFile(output, false, opt =>
{
foreach (var arg in arguments)
opt.WithArgument(arg);
});
var scaling = arguments.OfType<ScaleArgument>().FirstOrDefault();
2020-05-08 11:07:51 +02:00
processor.ProcessSynchronously();
2020-04-27 18:24:26 +02:00
2020-05-08 11:07:51 +02:00
var outputVideo = FFProbe.Analyse(output);
2020-04-27 18:24:26 +02:00
2020-05-08 11:07:51 +02:00
Assert.IsTrue(File.Exists(output));
2020-04-27 18:24:26 +02:00
2020-05-08 11:07:51 +02:00
if (scaling?.Size == null)
2020-04-27 18:24:26 +02:00
{
2020-05-08 11:07:51 +02:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, videoFramesSource.Width);
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, videoFramesSource.Height);
2020-04-27 18:24:26 +02:00
}
else
{
2020-05-08 11:07:51 +02:00
if (scaling.Size.Value.Width != -1)
2020-04-27 18:24:26 +02:00
{
2020-05-08 11:07:51 +02:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width);
2020-04-27 18:24:26 +02:00
}
2020-05-08 11:07:51 +02:00
if (scaling.Size.Value.Height != -1)
2020-04-27 18:24:26 +02:00
{
2020-05-08 11:07:51 +02:00
Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height);
2020-04-27 18:24:26 +02:00
}
2020-05-08 11:07:51 +02:00
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, videoFramesSource.Width);
Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, videoFramesSource.Height);
2020-04-27 18:24:26 +02:00
}
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
2020-04-27 18:24:26 +02:00
}
}
2019-02-08 11:19:40 +01:00
[TestMethod]
public void Video_ToMP4()
{
Convert(VideoType.Mp4);
}
[TestMethod]
public void Video_ToMP4_YUV444p()
{
Convert(VideoType.Mp4, (a) => Assert.IsTrue(a.VideoStreams.First().PixelFormat == "yuv444p"),
new ForcePixelFormat("yuv444p"));
}
2019-02-08 11:19:40 +01:00
[TestMethod]
public void Video_ToMP4_Args()
{
Convert(VideoType.Mp4, new VideoCodecArgument(VideoCodec.LibX264));
2019-02-08 11:19:40 +01:00
}
[DataTestMethod]
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_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
2020-04-27 18:24:26 +02:00
{
ConvertFromPipe(VideoType.Mp4, pixelFormat, new VideoCodecArgument(VideoCodec.LibX264));
2020-04-27 18:24:26 +02:00
}
2020-04-27 20:22:05 +02:00
[TestMethod]
public void Video_ToMP4_Args_StreamPipe()
{
2020-05-08 11:07:51 +02:00
ConvertFromStreamPipe(VideoType.Mp4, new VideoCodecArgument(VideoCodec.LibX264));
2020-04-27 20:22:05 +02:00
}
2020-06-06 15:38:14 +02: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-10-24 22:31:54 +02:00
.FromFileInput(VideoLibrary.LocalVideo)
.OutputToPipe(pipeSource, opt => opt.ForceFormat("mkv"))
2020-05-12 17:55:31 +02:00
.ProcessAsynchronously();
});
}
2020-06-06 15:38:14 +02:00
// [TestMethod, Timeout(10000)]
public void Video_ToMP4_Args_StreamOutputPipe_Failure()
{
2020-05-12 17:55:31 +02:00
Assert.ThrowsException<FFMpegException>(() => ConvertToStreamPipe(new ForceFormatArgument("mkv")));
}
[TestMethod]
public void Video_ToMP4_Args_StreamOutputPipe_Async()
{
2020-05-10 11:31:26 +02:00
using var ms = new MemoryStream();
2020-05-24 19:17:14 +02:00
var pipeSource = new StreamPipeSink(ms);
FFMpegArguments
2020-10-24 22:31:54 +02:00
.FromFileInput(VideoLibrary.LocalVideo)
.OutputToPipe(pipeSource, opt => opt
.WithVideoCodec(VideoCodec.LibX264)
.ForceFormat("matroska"))
2020-05-10 11:31:26 +02:00
.ProcessAsynchronously()
.WaitForResult();
}
[TestMethod]
public async Task TestDuplicateRun()
{
2020-10-24 22:31:54 +02:00
FFMpegArguments.FromFileInput(VideoLibrary.LocalVideo)
.OutputToFile("temporary.mp4")
.ProcessSynchronously();
2020-10-24 22:31:54 +02:00
await FFMpegArguments.FromFileInput(VideoLibrary.LocalVideo)
.OutputToFile("temporary.mp4")
.ProcessAsynchronously();
File.Delete("temporary.mp4");
}
[TestMethod]
public void Video_ToMP4_Args_StreamOutputPipe()
{
2020-05-08 11:07:51 +02:00
ConvertToStreamPipe(new VideoCodecArgument(VideoCodec.LibX264), new ForceFormatArgument("matroska"));
}
2019-02-08 11:19:40 +01:00
[TestMethod]
public void Video_ToTS()
{
Convert(VideoType.Ts);
}
[TestMethod]
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
}
[DataTestMethod]
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_ToTS_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
2020-04-27 18:24:26 +02:00
{
ConvertFromPipe(VideoType.Ts, pixelFormat, new ForceFormatArgument(VideoType.Ts));
2020-04-27 18:24:26 +02:00
}
2019-02-08 11:19:40 +01:00
[TestMethod]
public void Video_ToOGV_Resize()
{
Convert(VideoType.Ogv, true, VideoSize.Ed);
}
[TestMethod]
public void Video_ToOGV_Resize_Args()
{
Convert(VideoType.Ogv, new ScaleArgument(VideoSize.Ed), new VideoCodecArgument(VideoCodec.LibTheora));
2019-02-08 11:19:40 +01:00
}
[DataTestMethod]
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_ToOGV_Resize_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
2020-04-27 18:24:26 +02:00
{
ConvertFromPipe(VideoType.Ogv, pixelFormat, new ScaleArgument(VideoSize.Ed), new VideoCodecArgument(VideoCodec.LibTheora));
2020-04-27 18:24:26 +02:00
}
2019-02-08 11:19:40 +01:00
[TestMethod]
public void Video_ToMP4_Resize()
{
Convert(VideoType.Mp4, true, VideoSize.Ed);
}
[TestMethod]
public void Video_ToMP4_Resize_Args()
{
Convert(VideoType.Mp4, new ScaleArgument(VideoSize.Ld), new VideoCodecArgument(VideoCodec.LibX264));
2019-02-08 11:19:40 +01:00
}
[DataTestMethod]
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
{
ConvertFromPipe(VideoType.Mp4, pixelFormat, new ScaleArgument(VideoSize.Ld), new VideoCodecArgument(VideoCodec.LibX264));
2020-04-27 18:24:26 +02:00
}
2019-02-08 11:19:40 +01:00
[TestMethod]
public void Video_ToOGV()
{
Convert(VideoType.Ogv);
}
[TestMethod]
public void Video_ToMP4_MultiThread()
{
Convert(VideoType.Mp4, true);
}
[TestMethod]
public void Video_ToTS_MultiThread()
{
Convert(VideoType.Ts, true);
}
[TestMethod]
public void Video_ToOGV_MultiThread()
{
Convert(VideoType.Ogv, true);
}
[TestMethod]
public void Video_Snapshot_InMemory()
2019-02-08 11:19:40 +01:00
{
var output = Input.OutputLocation(ImageType.Png);
try
{
2020-05-08 11:07:51 +02:00
var input = FFProbe.Analyse(Input.FullName);
2019-02-08 11:19:40 +01:00
using var bitmap = FFMpeg.Snapshot(input);
2020-05-08 11:07:51 +02:00
Assert.AreEqual(input.PrimaryVideoStream.Width, bitmap.Width);
Assert.AreEqual(input.PrimaryVideoStream.Height, bitmap.Height);
2020-02-27 21:12:48 +01:00
Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png);
2019-02-08 11:19:40 +01:00
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
2019-02-08 11:19:40 +01:00
}
}
[TestMethod]
public void Video_Snapshot_PersistSnapshot()
{
var output = Input.OutputLocation(ImageType.Png);
try
{
2020-05-08 11:07:51 +02:00
var input = FFProbe.Analyse(Input.FullName);
FFMpeg.Snapshot(input, output);
var bitmap = Image.FromFile(output);
2020-05-08 11:07:51 +02:00
Assert.AreEqual(input.PrimaryVideoStream.Width, bitmap.Width);
Assert.AreEqual(input.PrimaryVideoStream.Height, bitmap.Height);
2020-02-27 21:12:48 +01:00
Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png);
2020-05-12 22:50:27 +02:00
bitmap.Dispose();
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
}
}
2019-02-08 11:19:40 +01:00
[TestMethod]
public void Video_Join()
{
var output = Input.OutputLocation(VideoType.Mp4);
var newInput = Input.OutputLocation(VideoType.Mp4.Name, "duplicate");
2019-02-08 11:19:40 +01:00
try
{
2020-05-08 11:07:51 +02:00
var input = FFProbe.Analyse(Input.FullName);
2020-05-24 19:27:55 +02:00
File.Copy(Input.FullName, newInput);
2019-02-08 11:19:40 +01:00
2020-05-24 19:27:55 +02:00
var success = FFMpeg.Join(output, Input.FullName, newInput);
2020-05-08 11:07:51 +02:00
Assert.IsTrue(success);
2020-05-08 11:07:51 +02:00
Assert.IsTrue(File.Exists(output));
2020-02-27 21:12:48 +01:00
var expectedDuration = input.Duration * 2;
2020-05-08 11:07:51 +02:00
var result = FFProbe.Analyse(output);
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);
2020-05-08 11:07:51 +02:00
Assert.AreEqual(input.PrimaryVideoStream.Height, result.PrimaryVideoStream.Height);
Assert.AreEqual(input.PrimaryVideoStream.Width, result.PrimaryVideoStream.Width);
2019-02-08 11:19:40 +01:00
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
2019-02-08 11:19:40 +01:00
2020-05-08 11:07:51 +02:00
if (File.Exists(newInput))
File.Delete(newInput);
2019-02-08 11:19:40 +01:00
}
2020-05-24 19:27:55 +02:00
2019-02-08 11:19:40 +01:00
}
[TestMethod]
public void Video_Join_Image_Sequence()
{
try
{
var imageSet = new List<ImageInfo>();
Directory.EnumerateFiles(VideoLibrary.ImageDirectory.FullName)
.Where(file => file.ToLower().EndsWith(".png"))
.ToList()
.ForEach(file =>
{
2020-02-27 21:12:48 +01:00
for (var i = 0; i < 15; i++)
2019-02-08 11:19:40 +01:00
{
imageSet.Add(new ImageInfo(file));
}
});
2020-05-08 11:07:51 +02:00
var success = FFMpeg.JoinImageSequence(VideoLibrary.ImageJoinOutput.FullName, images: imageSet.ToArray());
Assert.IsTrue(success);
2020-05-08 11:07:51 +02:00
var result = FFProbe.Analyse(VideoLibrary.ImageJoinOutput.FullName);
2019-02-08 11:19:40 +01:00
VideoLibrary.ImageJoinOutput.Refresh();
Assert.IsTrue(VideoLibrary.ImageJoinOutput.Exists);
Assert.AreEqual(3, result.Duration.Seconds);
2020-05-08 11:07:51 +02:00
Assert.AreEqual(imageSet.First().Width, result.PrimaryVideoStream.Width);
Assert.AreEqual(imageSet.First().Height, result.PrimaryVideoStream.Height);
2019-02-08 11:19:40 +01:00
}
finally
{
VideoLibrary.ImageJoinOutput.Refresh();
if (VideoLibrary.ImageJoinOutput.Exists)
{
VideoLibrary.ImageJoinOutput.Delete();
}
}
}
[TestMethod]
public void Video_With_Only_Audio_Should_Extract_Metadata()
{
2020-05-08 11:07:51 +02:00
var video = FFProbe.Analyse(VideoLibrary.LocalVideoAudioOnly.FullName);
Assert.AreEqual(null, video.PrimaryVideoStream);
Assert.AreEqual("aac", video.PrimaryAudioStream.CodecName);
2020-02-18 17:17:59 +01:00
Assert.AreEqual(79.5, video.Duration.TotalSeconds, 0.5);
// Assert.AreEqual(1.25, video.Size);
}
2020-04-27 18:24:26 +02:00
[TestMethod]
2020-04-27 18:24:26 +02:00
public void Video_Duration()
{
2020-05-08 11:07:51 +02:00
var video = FFProbe.Analyse(VideoLibrary.LocalVideo.FullName);
var output = Input.OutputLocation(VideoType.Mp4);
2020-04-27 18:24:26 +02:00
try
{
2020-05-08 11:07:51 +02:00
FFMpegArguments
2020-10-24 22:31:54 +02:00
.FromFileInput(VideoLibrary.LocalVideo)
.OutputToFile(output, false, opt => opt.WithDuration(TimeSpan.FromSeconds(video.Duration.TotalSeconds - 5)))
2020-05-08 11:07:51 +02:00
.ProcessSynchronously();
2020-05-08 11:07:51 +02:00
Assert.IsTrue(File.Exists(output));
var outputVideo = FFProbe.Analyse(output);
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 - 5, outputVideo.Duration.Seconds);
2020-04-27 18:24:26 +02:00
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
}
}
2020-04-27 18:24:26 +02:00
2020-03-02 22:50:04 +01:00
[TestMethod]
2020-04-27 18:24:26 +02:00
public void Video_UpdatesProgress()
{
2020-03-02 22:50:04 +01:00
var output = Input.OutputLocation(VideoType.Mp4);
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-05-08 11:07:51 +02:00
var analysis = FFProbe.Analyse(VideoLibrary.LocalVideo.FullName);
2020-03-02 22:50:04 +01:00
2020-04-27 18:24:26 +02:00
try
{
2020-05-08 11:07:51 +02:00
var success = FFMpegArguments
2020-10-24 22:31:54 +02:00
.FromFileInput(VideoLibrary.LocalVideo, opt => opt
.WithDuration(TimeSpan.FromSeconds(8)))
2020-05-08 11:07:51 +02:00
.OutputToFile(output)
.NotifyOnProgress(OnPercentageProgess, analysis.Duration)
.NotifyOnProgress(OnTimeProgess)
.ProcessSynchronously();
2020-04-27 18:24:26 +02:00
2020-05-08 11:07:51 +02:00
Assert.IsTrue(success);
Assert.IsTrue(File.Exists(output));
2020-03-02 22:50:04 +01:00
Assert.AreNotEqual(0.0, percentageDone);
2020-05-08 11:07:51 +02:00
Assert.AreNotEqual(TimeSpan.Zero, timeDone);
2020-04-27 18:24:26 +02:00
}
finally
{
2020-05-08 11:07:51 +02:00
if (File.Exists(output))
File.Delete(output);
2020-03-02 22:50:04 +01:00
}
}
2020-04-28 21:54:39 +02:00
[TestMethod]
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
[TestMethod]
public async Task Video_Cancel_Async()
{
await using var resStream = new MemoryStream();
2020-05-24 19:17:14 +02:00
var reader = new StreamPipeSink(resStream);
var writer = new RawVideoPipeSource(BitmapSource.CreateBitmaps(512, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 128, 128));
2020-05-12 23:52:07 +02:00
var task = FFMpegArguments
2020-10-24 22:31:54 +02:00
.FromPipeInput(writer)
.OutputToPipe(reader, opt => opt
.WithVideoCodec("vp9")
.ForceFormat("webm"))
2020-05-12 23:52:07 +02:00
.CancellableThrough(out var cancel)
.ProcessAsynchronously(false);
2020-05-13 00:00:02 +02:00
2020-05-13 00:11:53 +02:00
await Task.Delay(300);
2020-05-12 23:52:07 +02:00
cancel();
var result = await task;
Assert.IsFalse(result);
}
2019-02-08 11:19:40 +01:00
}
}