diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..caefd5d
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,15 @@
+
+
+ netstandard2.0
+ en
+ 5.0.0.0
+ default
+ enable
+
+ GitHub
+ https://github.com/rosenbjerg/FFMpegCore
+ https://github.com/rosenbjerg/FFMpegCore
+ MIT
+ en
+
+
\ No newline at end of file
diff --git a/FFMpegCore.Examples/Program.cs b/FFMpegCore.Examples/Program.cs
index ea343f2..e7b93e2 100644
--- a/FFMpegCore.Examples/Program.cs
+++ b/FFMpegCore.Examples/Program.cs
@@ -84,8 +84,8 @@ await FFMpegArguments
var inputImagePath = "/path/to/input/image";
{
FFMpegImage.PosterWithAudio(inputPath, inputAudioPath, outputPath);
- // or
- var image = Image.FromFile(inputImagePath);
+ // or
+ using var image = Image.FromFile(inputImagePath);
image.AddAudio(inputAudioPath, outputPath);
}
diff --git a/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs b/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs
index e549580..6633f69 100644
--- a/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs
+++ b/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs
@@ -12,7 +12,7 @@ public static bool AddAudio(this Image poster, string audio, string output)
poster.Save(destination);
try
{
- return FFMpeg.PosterWithAudio(destination, audio, output);
+ return FFMpegImage.PosterWithAudio(destination, audio, output);
}
finally
{
diff --git a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj
index c2575f7..aafb577 100644
--- a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj
+++ b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj
@@ -1,28 +1,17 @@
- en
- https://github.com/rosenbjerg/FFMpegCore
- https://github.com/rosenbjerg/FFMpegCore
-
- Image extension for FFMpegCore, using System.Common.Drawing
+ true
+ Image extension for FFMpegCore using System.Common.Drawing
+ 5.0.0
- 8
- 4.0.0.0
- 4.0.0
- MIT
- Malte Rosenbjerg, Vlad Jerca, Max Bagryantsev
ffmpeg ffprobe convert video audio mediafile resize analyze muxing
- GitHub
- true
- true
- enable
- netstandard2.0
+ Malte Rosenbjerg, Vlad Jerca, Max Bagryantsev
-
+
diff --git a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs
index 13052a8..467fe6a 100644
--- a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs
+++ b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs
@@ -41,6 +41,7 @@ public static bool JoinImageSequence(string output, double frameRate = 30, param
return FFMpegArguments
.FromFileInput(Path.Combine(tempFolderName, "%09d.png"), false)
.OutputToFile(output, true, options => options
+ .ForcePixelFormat("yuv420p")
.Resize(firstImage.Width, firstImage.Height)
.WithFramerate(frameRate))
.ProcessSynchronously();
@@ -62,22 +63,22 @@ public static bool PosterWithAudio(string image, string audio, string output)
{
FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.Mp4);
using (var img = Image.FromFile(image))
- FFMpegHelper.ConversionSizeExceptionCheck(img);
+ FFMpegHelper.ConversionSizeExceptionCheck(img.Width, img.Height);
return FFMpegArguments
.FromFileInput(image, false, options => options
- .Loop(1))
+ .Loop(1)
+ .ForceFormat("image2"))
.AddFileInput(audio)
.OutputToFile(output, true, options => options
+ .ForcePixelFormat("yuv420p")
.WithVideoCodec(VideoCodec.LibX264)
- .CopyChannel()
.WithConstantRateFactor(21)
.WithAudioBitrate(AudioQuality.Normal)
.UsingShortest())
.ProcessSynchronously();
-
-
}
+
///
/// Saves a 'png' thumbnail to an in-memory bitmap
///
@@ -90,7 +91,7 @@ public static bool PosterWithAudio(string image, string audio, string output)
public static Bitmap Snapshot(string input, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
{
var source = FFProbe.Analyse(input);
- var (arguments, outputOptions) = BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
+ var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
using var ms = new MemoryStream();
arguments
@@ -114,7 +115,7 @@ public static Bitmap Snapshot(string input, Size? size = null, TimeSpan? capture
public static async Task SnapshotAsync(string input, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
{
var source = await FFProbe.AnalyseAsync(input).ConfigureAwait(false);
- var (arguments, outputOptions) = BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
+ var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
using var ms = new MemoryStream();
await arguments
diff --git a/FFMpegCore.Test/FFMpegCore.Test.csproj b/FFMpegCore.Test/FFMpegCore.Test.csproj
index c84f3fe..d606d6b 100644
--- a/FFMpegCore.Test/FFMpegCore.Test.csproj
+++ b/FFMpegCore.Test/FFMpegCore.Test.csproj
@@ -2,42 +2,11 @@
net6.0
-
false
-
disable
-
default
-
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- Always
-
-
-
-
-
- PreserveNewest
-
-
-
@@ -55,46 +24,60 @@
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
PreserveNewest
-
-
-
-
diff --git a/FFMpegCore/FFMpeg/Arguments/AudioFiltersArgument.cs b/FFMpegCore/FFMpeg/Arguments/AudioFiltersArgument.cs
index 50b26b3..dac7d15 100644
--- a/FFMpegCore/FFMpeg/Arguments/AudioFiltersArgument.cs
+++ b/FFMpegCore/FFMpeg/Arguments/AudioFiltersArgument.cs
@@ -34,8 +34,8 @@ private string GetText()
public interface IAudioFilterArgument
{
- public string Key { get; }
- public string Value { get; }
+ string Key { get; }
+ string Value { get; }
}
public class AudioFilterOptions
diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs
index 165ec31..909a96a 100644
--- a/FFMpegCore/FFMpeg/FFMpeg.cs
+++ b/FFMpegCore/FFMpeg/FFMpeg.cs
@@ -1,7 +1,6 @@
using FFMpegCore.Enums;
using FFMpegCore.Exceptions;
using FFMpegCore.Helpers;
-using FFMpegCore.Pipes;
using System;
using System.Collections.Generic;
using System.Drawing;
@@ -12,54 +11,9 @@
namespace FFMpegCore
{
- public static class FFMpeg
+ public static class SnapshotArgumentBuilder
{
- ///
- /// 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.
- /// Selected video stream index.
- /// Input file index
- /// Bitmap with the requested snapshot.
- public static bool Snapshot(string input, string output, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
- {
- if (Path.GetExtension(output) != FileExtension.Png)
- output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png;
-
- var source = FFProbe.Analyse(input);
- var (arguments, outputOptions) = BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
-
- return arguments
- .OutputToFile(output, true, outputOptions)
- .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.
- /// Selected video stream index.
- /// Input file index
- /// Bitmap with the requested snapshot.
- public static async Task SnapshotAsync(string input, string output, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
- {
- if (Path.GetExtension(output) != FileExtension.Png)
- output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png;
-
- var source = await FFProbe.AnalyseAsync(input).ConfigureAwait(false);
- var (arguments, outputOptions) = BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
-
- return await arguments
- .OutputToFile(output, true, outputOptions)
- .ProcessAsynchronously();
- }
-
- private static (FFMpegArguments, Action outputOptions) BuildSnapshotArguments(
+ public static (FFMpegArguments, Action outputOptions) BuildSnapshotArguments(
string input,
IMediaAnalysis source,
Size? size = null,
@@ -109,13 +63,61 @@ private static (FFMpegArguments, Action outputOptions) Bu
return null;
}
+ }
+ public static class FFMpeg
+ {
+ ///
+ /// 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.
+ /// Selected video stream index.
+ /// Input file index
+ /// Bitmap with the requested snapshot.
+ public static bool Snapshot(string input, string output, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
+ {
+ if (Path.GetExtension(output) != FileExtension.Png)
+ output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png;
+
+ var source = FFProbe.Analyse(input);
+ var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
+
+ return arguments
+ .OutputToFile(output, true, outputOptions)
+ .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.
+ /// Selected video stream index.
+ /// Input file index
+ /// Bitmap with the requested snapshot.
+ public static async Task SnapshotAsync(string input, string output, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
+ {
+ if (Path.GetExtension(output) != FileExtension.Png)
+ output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png;
+
+ var source = await FFProbe.AnalyseAsync(input).ConfigureAwait(false);
+ var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
+
+ return await arguments
+ .OutputToFile(output, true, outputOptions)
+ .ProcessAsynchronously();
+ }
+
///
/// Convert a video do a different format.
///
- /// Input video source.
+ /// Input video source.
/// Output information.
- /// Target conversion video type.
+ /// Target conversion video format.
/// Conversion target speed/quality (faster speed = lower quality).
/// Video size.
/// Conversion target audio quality.
@@ -189,35 +191,6 @@ public static bool Convert(
};
}
- ///
- /// Adds a poster image to an audio file.
- ///
- /// Source image file.
- /// Source audio file.
- /// Output video file.
- ///
- public static bool PosterWithAudio(string image, string audio, string output)
- {
- FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.Mp4);
- using (var imageFile = Image.FromFile(image))
- {
- FFMpegHelper.ConversionSizeExceptionCheck(imageFile);
- }
-
- return FFMpegArguments
- .FromFileInput(image, false, options => options
- .Loop(1)
- .ForceFormat("image2"))
- .AddFileInput(audio)
- .OutputToFile(output, true, options => options
- .ForcePixelFormat("yuv420p")
- .WithVideoCodec(VideoCodec.LibX264)
- .WithConstantRateFactor(21)
- .WithAudioBitrate(AudioQuality.Normal)
- .UsingShortest())
- .ProcessSynchronously();
- }
-
///
/// Joins a list of video files.
///
@@ -251,44 +224,6 @@ public static bool Join(string output, params string[] videos)
}
}
- ///
- /// Converts an image sequence to a video.
- ///
- /// Output video file.
- /// FPS
- /// Image sequence collection
- /// Output video information.
- public static bool JoinImageSequence(string output, double frameRate = 30, params ImageInfo[] images)
- {
- var tempFolderName = Path.Combine(GlobalFFOptions.Current.TemporaryFilesFolder, Guid.NewGuid().ToString());
- var temporaryImageFiles = images.Select((imageInfo, index) =>
- {
- using var image = Image.FromFile(imageInfo.FullName);
- FFMpegHelper.ConversionSizeExceptionCheck(image);
- var destinationPath = Path.Combine(tempFolderName, $"{index.ToString().PadLeft(9, '0')}{imageInfo.Extension}");
- Directory.CreateDirectory(tempFolderName);
- File.Copy(imageInfo.FullName, destinationPath);
- return destinationPath;
- }).ToArray();
-
- var firstImage = images.First();
- try
- {
- return FFMpegArguments
- .FromFileInput(Path.Combine(tempFolderName, "%09d.png"), false)
- .OutputToFile(output, true, options => options
- .ForcePixelFormat("yuv420p")
- .Resize(firstImage.Width, firstImage.Height)
- .WithFramerate(frameRate))
- .ProcessSynchronously();
- }
- finally
- {
- Cleanup(temporaryImageFiles);
- Directory.Delete(tempFolderName);
- }
- }
-
///
/// Records M3U8 streams to the specified output.
///
@@ -397,15 +332,15 @@ public static IReadOnlyList GetPixelFormats()
return FFMpegCache.PixelFormats.Values.ToList().AsReadOnly();
}
- public static bool TryGetPixelFormat(string name, out PixelFormat fmt)
+ public static bool TryGetPixelFormat(string name, out PixelFormat format)
{
if (!GlobalFFOptions.Current.UseCache)
{
- fmt = GetPixelFormatsInternal().FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim());
- return fmt != null;
+ format = GetPixelFormatsInternal().FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim());
+ return format != null;
}
else
- return FFMpegCache.PixelFormats.TryGetValue(name, out fmt);
+ return FFMpegCache.PixelFormats.TryGetValue(name, out format);
}
public static PixelFormat GetPixelFormat(string name)
diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj
index e537ab6..ecd0b85 100644
--- a/FFMpegCore/FFMpegCore.csproj
+++ b/FFMpegCore/FFMpegCore.csproj
@@ -1,45 +1,23 @@
-
- en
- https://github.com/rosenbjerg/FFMpegCore
- https://github.com/rosenbjerg/FFMpegCore
-
- A .NET Standard FFMpeg/FFProbe wrapper for easily integrating media analysis and conversion into your .NET applications
- 4.0.0.0
- README.md
- - Fixes for `MetaDataArgument` (thanks @JKamsker)
-- Support for Audible `aaxc` (thanks @JKamsker)
-- Include errordata in `IMediaAnalysis` (thanks @JKamsker)
-- Pass `FFOptions` properly when using ffprobe (thanks @Notheisz57)
-- CancellationToken support for `AnalyseAsync`
-- Case-insensitive dictionaries for `Tags` and `Disposition`
-- Fix for `PosterWithAudio`
-- Fix for `JoinImageSequence`
-- Updates to dependendies
-- A lot of bug fixes
- 8
- 4.8.0
- MIT
- Malte Rosenbjerg, Vlad Jerca, Max Bagryantsev
- ffmpeg ffprobe convert video audio mediafile resize analyze muxing
- GitHub
- true
- true
- enable
- netstandard2.0
-
+
+ true
+ A .NET Standard FFMpeg/FFProbe wrapper for easily integrating media analysis and conversion into your .NET applications
+ 5.0.0
+
+
+ ffmpeg ffprobe convert video audio mediafile resize analyze muxing
+ Malte Rosenbjerg, Vlad Jerca, Max Bagryantsev
+ README.md
+
-
-
- Always
-
-
-
+
+
+
-
-
-
-
+
+
+
+