Merge pull request #397 from rosenbjerg/bugfix/handle-joining-of-non-png-images

[Bugfix] Handle joining of non png images
This commit is contained in:
Malte Rosenbjerg 2023-02-17 00:04:53 +01:00 committed by GitHub
commit 030d0eb304
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 41 deletions

View file

@ -10,7 +10,7 @@ on:
- FFMpegCore.Test/**
pull_request:
branches:
- master
- main
- release
paths:
- .github/workflows/ci.yml

View file

@ -1,15 +1,5 @@
namespace FFMpegCore.Test.Resources
{
public enum AudioType
{
Mp3
}
public enum ImageType
{
Png
}
public static class TestResources
{
public static readonly string Mp4Video = "./Resources/input_3sec.mp4";

View file

@ -413,7 +413,7 @@ public void Video_Snapshot_InMemory()
[TestMethod, Timeout(10000)]
public void Video_Snapshot_PersistSnapshot()
{
var outputPath = new TemporaryFile("out.png");
using var outputPath = new TemporaryFile("out.png");
var input = FFProbe.Analyse(TestResources.Mp4Video);
FFMpeg.Snapshot(TestResources.Mp4Video, outputPath);
@ -427,10 +427,10 @@ public void Video_Snapshot_PersistSnapshot()
[TestMethod, Timeout(10000)]
public void Video_Join()
{
var inputCopy = new TemporaryFile("copy-input.mp4");
using var inputCopy = new TemporaryFile("copy-input.mp4");
File.Copy(TestResources.Mp4Video, inputCopy);
var outputPath = new TemporaryFile("out.mp4");
using var outputPath = new TemporaryFile("out.mp4");
var input = FFProbe.Analyse(TestResources.Mp4Video);
var success = FFMpeg.Join(outputPath, TestResources.Mp4Video, inputCopy);
Assert.IsTrue(success);
@ -461,7 +461,7 @@ public void Video_Join_Image_Sequence()
});
var imageAnalysis = FFProbe.Analyse(imageSet.First());
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var success = FFMpeg.JoinImageSequence(outputFile, frameRate: 10, images: imageSet.ToArray());
Assert.IsTrue(success);
var result = FFProbe.Analyse(outputFile);
@ -484,7 +484,7 @@ public void Video_With_Only_Audio_Should_Extract_Metadata()
public void Video_Duration()
{
var video = FFProbe.Analyse(TestResources.Mp4Video);
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
FFMpegArguments
.FromFileInput(TestResources.Mp4Video)
@ -503,7 +503,7 @@ public void Video_Duration()
[TestMethod, Timeout(10000)]
public void Video_UpdatesProgress()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var percentageDone = 0.0;
var timeDone = TimeSpan.Zero;
@ -544,7 +544,7 @@ void OnTimeProgess(TimeSpan time)
[TestMethod, Timeout(10000)]
public void Video_OutputsData()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var dataReceived = false;
GlobalFFOptions.Configure(opt => opt.Encoding = Encoding.UTF8);
@ -604,7 +604,7 @@ public void Video_TranscodeToMemory()
[TestMethod, Timeout(10000)]
public async Task Video_Cancel_Async()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var task = FFMpegArguments
.FromFileInput("testsrc2=size=320x240[out0]; sine[out1]", false, args => args
@ -628,7 +628,7 @@ public async Task Video_Cancel_Async()
[TestMethod, Timeout(10000)]
public void Video_Cancel()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var task = FFMpegArguments
.FromFileInput("testsrc2=size=320x240[out0]; sine[out1]", false, args => args
.WithCustomArgument("-re")
@ -649,7 +649,7 @@ public void Video_Cancel()
[TestMethod, Timeout(10000)]
public async Task Video_Cancel_Async_With_Timeout()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var task = FFMpegArguments
.FromFileInput("testsrc2=size=320x240[out0]; sine[out1]", false, args => args
@ -679,7 +679,7 @@ public async Task Video_Cancel_Async_With_Timeout()
[TestMethod, Timeout(10000)]
public async Task Video_Cancel_CancellationToken_Async()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var cts = new CancellationTokenSource();
@ -704,7 +704,7 @@ public async Task Video_Cancel_CancellationToken_Async()
[TestMethod, Timeout(10000)]
public async Task Video_Cancel_CancellationToken_Async_Throws()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var cts = new CancellationTokenSource();
@ -727,7 +727,7 @@ public async Task Video_Cancel_CancellationToken_Async_Throws()
[TestMethod, Timeout(10000)]
public void Video_Cancel_CancellationToken_Throws()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var cts = new CancellationTokenSource();
@ -749,7 +749,7 @@ public void Video_Cancel_CancellationToken_Throws()
[TestMethod, Timeout(10000)]
public async Task Video_Cancel_CancellationToken_Async_With_Timeout()
{
var outputFile = new TemporaryFile("out.mp4");
using var outputFile = new TemporaryFile("out.mp4");
var cts = new CancellationTokenSource();

View file

@ -66,25 +66,34 @@ public static async Task<bool> SnapshotAsync(string input, string output, Size?
/// <returns>Output video information.</returns>
public static bool JoinImageSequence(string output, double frameRate = 30, params string[] images)
{
int? width = null, height = null;
var tempFolderName = Path.Combine(GlobalFFOptions.Current.TemporaryFilesFolder, Guid.NewGuid().ToString());
var temporaryImageFiles = images.Select((imagePath, index) =>
var fileExtensions = images.Select(Path.GetExtension).Distinct().ToArray();
if (fileExtensions.Length != 1)
{
var analysis = FFProbe.Analyse(imagePath);
FFMpegHelper.ConversionSizeExceptionCheck(analysis.PrimaryVideoStream!.Width, analysis.PrimaryVideoStream!.Height);
width ??= analysis.PrimaryVideoStream.Width;
height ??= analysis.PrimaryVideoStream.Height;
throw new ArgumentException("All images must have the same extension", nameof(images));
}
var destinationPath = Path.Combine(tempFolderName, $"{index.ToString().PadLeft(9, '0')}{Path.GetExtension(imagePath)}");
Directory.CreateDirectory(tempFolderName);
File.Copy(imagePath, destinationPath);
return destinationPath;
}).ToArray();
var fileExtension = fileExtensions[0].ToLowerInvariant();
int? width = null, height = null;
var tempFolderName = Path.Combine(GlobalFFOptions.Current.TemporaryFilesFolder, Guid.NewGuid().ToString());
Directory.CreateDirectory(tempFolderName);
try
{
var index = 0;
foreach (var imagePath in images)
{
var analysis = FFProbe.Analyse(imagePath);
FFMpegHelper.ConversionSizeExceptionCheck(analysis.PrimaryVideoStream!.Width, analysis.PrimaryVideoStream!.Height);
width ??= analysis.PrimaryVideoStream.Width;
height ??= analysis.PrimaryVideoStream.Height;
var destinationPath = Path.Combine(tempFolderName, $"{index++.ToString().PadLeft(9, '0')}{fileExtension}");
File.Copy(imagePath, destinationPath);
}
return FFMpegArguments
.FromFileInput(Path.Combine(tempFolderName, "%09d.png"), false)
.FromFileInput(Path.Combine(tempFolderName, $"%09d{fileExtension}"), false)
.OutputToFile(output, true, options => options
.ForcePixelFormat("yuv420p")
.Resize(width!.Value, height!.Value)
@ -93,8 +102,7 @@ public static bool JoinImageSequence(string output, double frameRate = 30, param
}
finally
{
Cleanup(temporaryImageFiles);
Directory.Delete(tempFolderName);
Directory.Delete(tempFolderName, true);
}
}

View file

@ -3,7 +3,7 @@
<PropertyGroup>
<IsPackable>true</IsPackable>
<Description>A .NET Standard FFMpeg/FFProbe wrapper for easily integrating media analysis and conversion into your .NET applications</Description>
<PackageVersion>5.0.0</PackageVersion>
<PackageVersion>5.0.1</PackageVersion>
<PackageReleaseNotes>
</PackageReleaseNotes>
<PackageTags>ffmpeg ffprobe convert video audio mediafile resize analyze muxing</PackageTags>