diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs
index 6e70354..cc042e3 100644
--- a/FFMpegCore/FFMpeg/FFMpeg.cs
+++ b/FFMpegCore/FFMpeg/FFMpeg.cs
@@ -7,6 +7,7 @@
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
namespace FFMpegCore
{
@@ -22,23 +23,35 @@ public static class FFMpeg
/// Bitmap with the requested snapshot.
public static bool Snapshot(MediaAnalysis source, string output, Size? size = null, TimeSpan? captureTime = null)
{
- captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3);
-
if (Path.GetExtension(output) != FileExtension.Png)
output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png;
- size = PrepareSnapshotSize(source, size);
-
- return FFMpegArguments
- .FromSeekedFiles((source.Path, captureTime ?? TimeSpan.Zero))
- .WithVideoCodec(VideoCodec.Png)
- .WithFrameOutputCount(1)
- .Resize(size)
- .Seek(captureTime)
+ var arguments = BuildSnapshotArguments(source, size, captureTime);
+
+ return arguments
.OutputToFile(output)
.ProcessSynchronously();
}
///
+ /// Saves a 'png' thumbnail from the input video to drive
+ ///
+ /// Source video analysis
+ /// Output video file path
+ /// Seek position where the thumbnail should be taken.
+ /// Thumbnail size. If width or height equal 0, the other will be computed automatically.
+ /// Bitmap with the requested snapshot.
+ public static Task SnapshotAsync(MediaAnalysis source, string output, Size? size = null, TimeSpan? captureTime = null)
+ {
+ if (Path.GetExtension(output) != FileExtension.Png)
+ output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png;
+
+ var arguments = BuildSnapshotArguments(source, size, captureTime);
+
+ return arguments
+ .OutputToFile(output)
+ .ProcessAsynchronously();
+ }
+ ///
/// Saves a 'png' thumbnail to an in-memory bitmap
///
/// Source video file.
@@ -47,17 +60,10 @@ public static bool Snapshot(MediaAnalysis source, string output, Size? size = nu
/// Bitmap with the requested snapshot.
public static Bitmap Snapshot(MediaAnalysis source, Size? size = null, TimeSpan? captureTime = null)
{
- captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3);
-
- size = PrepareSnapshotSize(source, size);
-
+ var arguments = BuildSnapshotArguments(source, size, captureTime);
using var ms = new MemoryStream();
- FFMpegArguments
- .FromInputFiles(source.Path)
- .WithVideoCodec(VideoCodec.Png)
- .WithFrameOutputCount(1)
- .Resize(size)
- .Seek(captureTime)
+
+ arguments
.ForceFormat("rawvideo")
.OutputToPipe(new StreamPipeSink(ms))
.ProcessSynchronously();
@@ -65,6 +71,38 @@ public static Bitmap Snapshot(MediaAnalysis source, Size? size = null, TimeSpan?
ms.Position = 0;
return new Bitmap(ms);
}
+ ///
+ /// Saves a 'png' thumbnail to an in-memory bitmap
+ ///
+ /// Source video file.
+ /// Seek position where the thumbnail should be taken.
+ /// Thumbnail size. If width or height equal 0, the other will be computed automatically.
+ /// Bitmap with the requested snapshot.
+ public static async Task SnapshotAsync(MediaAnalysis source, Size? size = null, TimeSpan? captureTime = null)
+ {
+ var arguments = BuildSnapshotArguments(source, size, captureTime);
+ using var ms = new MemoryStream();
+
+ await arguments
+ .ForceFormat("rawvideo")
+ .OutputToPipe(new StreamPipeSink(ms))
+ .ProcessAsynchronously();
+
+ ms.Position = 0;
+ return new Bitmap(ms);
+ }
+
+ private static FFMpegArguments BuildSnapshotArguments(MediaAnalysis source, Size? size = null, TimeSpan? captureTime = null)
+ {
+ captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3);
+ size = PrepareSnapshotSize(source, size);
+
+ return FFMpegArguments
+ .FromSeekedFiles((source.Path, captureTime ?? TimeSpan.Zero))
+ .WithVideoCodec(VideoCodec.Png)
+ .WithFrameOutputCount(1)
+ .Resize(size);
+ }
private static Size? PrepareSnapshotSize(MediaAnalysis source, Size? size)
{
diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs
index f3f7502..71befc7 100644
--- a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs
+++ b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs
@@ -46,7 +46,7 @@ public FFMpegArgumentProcessor CancellableThrough(out Action cancel)
}
public bool ProcessSynchronously(bool throwOnError = true)
{
- var instance = PrepareInstance(out var cancellationTokenSource);
+ using var instance = PrepareInstance(out var cancellationTokenSource);
var errorCode = -1;
void OnCancelEvent(object sender, EventArgs args)