diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46718fb..ae51d97 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,5 @@ name: CI -on: - push: - branches: - - master +on: [push, pull_request] jobs: ci: runs-on: ubuntu-latest diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index e677370..e51fdea 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -159,7 +159,7 @@ private void ConvertToStreamPipe(params IArgument[] inputArguments) } } - public void Convert(ContainerFormat type, Action validationMethod, params IArgument[] inputArguments) + public void Convert(ContainerFormat type, Action validationMethod, params IArgument[] inputArguments) { var output = Input.OutputLocation(type); diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index ca94825..cee64d8 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -21,7 +21,7 @@ public static class FFMpeg /// 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 bool Snapshot(MediaAnalysis source, string output, Size? size = null, TimeSpan? captureTime = null) + public static bool Snapshot(IMediaAnalysis source, string output, Size? size = null, TimeSpan? captureTime = null) { if (Path.GetExtension(output) != FileExtension.Png) output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png; @@ -40,7 +40,7 @@ public static bool Snapshot(MediaAnalysis source, string output, Size? size = nu /// 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) + public static Task SnapshotAsync(IMediaAnalysis source, string output, Size? size = null, TimeSpan? captureTime = null) { if (Path.GetExtension(output) != FileExtension.Png) output = Path.GetFileNameWithoutExtension(output) + FileExtension.Png; @@ -58,7 +58,7 @@ public static Task SnapshotAsync(MediaAnalysis source, string output, Size /// 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 Bitmap Snapshot(MediaAnalysis source, Size? size = null, TimeSpan? captureTime = null) + public static Bitmap Snapshot(IMediaAnalysis source, Size? size = null, TimeSpan? captureTime = null) { var arguments = BuildSnapshotArguments(source, size, captureTime); using var ms = new MemoryStream(); @@ -78,7 +78,7 @@ public static Bitmap Snapshot(MediaAnalysis source, Size? size = null, TimeSpan? /// 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) + public static async Task SnapshotAsync(IMediaAnalysis source, Size? size = null, TimeSpan? captureTime = null) { var arguments = BuildSnapshotArguments(source, size, captureTime); using var ms = new MemoryStream(); @@ -92,7 +92,7 @@ await arguments return new Bitmap(ms); } - private static FFMpegArguments BuildSnapshotArguments(MediaAnalysis source, Size? size = null, TimeSpan? captureTime = null) + private static FFMpegArguments BuildSnapshotArguments(IMediaAnalysis source, Size? size = null, TimeSpan? captureTime = null) { captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3); size = PrepareSnapshotSize(source, size); @@ -104,7 +104,7 @@ private static FFMpegArguments BuildSnapshotArguments(MediaAnalysis source, Size .Resize(size); } - private static Size? PrepareSnapshotSize(MediaAnalysis source, Size? wantedSize) + private static Size? PrepareSnapshotSize(IMediaAnalysis source, Size? wantedSize) { if (wantedSize == null || (wantedSize.Value.Height <= 0 && wantedSize.Value.Width <= 0)) return null; @@ -143,7 +143,7 @@ private static FFMpegArguments BuildSnapshotArguments(MediaAnalysis source, Size /// Is encoding multithreaded. /// Output video information. public static bool Convert( - MediaAnalysis source, + IMediaAnalysis source, string output, ContainerFormat format, Speed speed = Speed.SuperFast, @@ -235,7 +235,7 @@ public static bool PosterWithAudio(string image, string audio, string output) /// Output video file. /// List of vides that need to be joined together. /// Output video information. - public static bool Join(string output, params MediaAnalysis[] videos) + public static bool Join(string output, params IMediaAnalysis[] videos) { var temporaryVideoParts = videos.Select(video => { diff --git a/FFMpegCore/FFMpeg/Pipes/PipeHelpers.cs b/FFMpegCore/FFMpeg/Pipes/PipeHelpers.cs index ddd788c..7e79f55 100644 --- a/FFMpegCore/FFMpeg/Pipes/PipeHelpers.cs +++ b/FFMpegCore/FFMpeg/Pipes/PipeHelpers.cs @@ -1,10 +1,13 @@ using System; +using System.IO; using System.Runtime.InteropServices; namespace FFMpegCore.Pipes { static class PipeHelpers { + static readonly string PipePrefix = Path.Combine(Path.GetTempPath(), "CoreFxPipe_"); + public static string GetUnqiuePipeName() => "FFMpegCore_" + Guid.NewGuid(); public static string GetPipePath(string pipeName) @@ -12,7 +15,7 @@ public static string GetPipePath(string pipeName) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return $@"\\.\pipe\{pipeName}"; else - return $"unix:/tmp/CoreFxPipe_{pipeName}"; // dotnet uses unix sockets on unix, for more see https://github.com/dotnet/runtime/issues/24390 + return $"unix:{PipePrefix}{pipeName}"; // dotnet uses unix sockets on unix, for more see https://github.com/dotnet/runtime/issues/24390 } } } diff --git a/FFMpegCore/FFProbe/FFProbe.cs b/FFMpegCore/FFProbe/FFProbe.cs index 4cf1b33..131f465 100644 --- a/FFMpegCore/FFProbe/FFProbe.cs +++ b/FFMpegCore/FFProbe/FFProbe.cs @@ -11,13 +11,13 @@ namespace FFMpegCore { public static class FFProbe { - public static MediaAnalysis Analyse(string filePath, int outputCapacity = int.MaxValue) + public static IMediaAnalysis Analyse(string filePath, int outputCapacity = int.MaxValue) { using var instance = PrepareInstance(filePath, outputCapacity); instance.BlockUntilFinished(); return ParseOutput(filePath, instance); } - public static MediaAnalysis Analyse(System.IO.Stream stream, int outputCapacity = int.MaxValue) + public static IMediaAnalysis Analyse(System.IO.Stream stream, int outputCapacity = int.MaxValue) { var streamPipeSource = new StreamPipeSource(stream); var pipeArgument = new InputPipeArgument(streamPipeSource); @@ -40,13 +40,13 @@ public static MediaAnalysis Analyse(System.IO.Stream stream, int outputCapacity return ParseOutput(pipeArgument.PipePath, instance); } - public static async Task AnalyseAsync(string filePath, int outputCapacity = int.MaxValue) + public static async Task AnalyseAsync(string filePath, int outputCapacity = int.MaxValue) { using var instance = PrepareInstance(filePath, outputCapacity); await instance.FinishedRunning(); return ParseOutput(filePath, instance); } - public static async Task AnalyseAsync(System.IO.Stream stream, int outputCapacity = int.MaxValue) + public static async Task AnalyseAsync(System.IO.Stream stream, int outputCapacity = int.MaxValue) { var streamPipeSource = new StreamPipeSource(stream); var pipeArgument = new InputPipeArgument(streamPipeSource); @@ -73,7 +73,7 @@ public static async Task AnalyseAsync(System.IO.Stream stream, in return ParseOutput(pipeArgument.PipePath, instance); } - private static MediaAnalysis ParseOutput(string filePath, Instance instance) + private static IMediaAnalysis ParseOutput(string filePath, Instance instance) { var json = string.Join(string.Empty, instance.OutputData); var ffprobeAnalysis = JsonSerializer.Deserialize(json, new JsonSerializerOptions diff --git a/FFMpegCore/FFProbe/IMediaAnalysis.cs b/FFMpegCore/FFProbe/IMediaAnalysis.cs new file mode 100644 index 0000000..04e2ae3 --- /dev/null +++ b/FFMpegCore/FFProbe/IMediaAnalysis.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFMpegCore +{ + public interface IMediaAnalysis + { + string Path { get; } + string Extension { get; } + TimeSpan Duration { get; } + MediaFormat Format { get; } + AudioStream PrimaryAudioStream { get; } + VideoStream PrimaryVideoStream { get; } + List VideoStreams { get; } + List AudioStreams { get; } + } +} diff --git a/FFMpegCore/FFProbe/MediaAnalysis.cs b/FFMpegCore/FFProbe/MediaAnalysis.cs index 019815a..4717a6f 100644 --- a/FFMpegCore/FFProbe/MediaAnalysis.cs +++ b/FFMpegCore/FFProbe/MediaAnalysis.cs @@ -5,7 +5,7 @@ namespace FFMpegCore { - public class MediaAnalysis + internal class MediaAnalysis : IMediaAnalysis { private static readonly Regex DurationRegex = new Regex("^(\\d{1,2}:\\d{1,2}:\\d{1,2}(.\\d{1,7})?)", RegexOptions.Compiled); internal MediaAnalysis(string path, FFProbeAnalysis analysis) diff --git a/FFMpegCore/Helpers/FFMpegHelper.cs b/FFMpegCore/Helpers/FFMpegHelper.cs index f280b08..8553573 100644 --- a/FFMpegCore/Helpers/FFMpegHelper.cs +++ b/FFMpegCore/Helpers/FFMpegHelper.cs @@ -12,7 +12,7 @@ public static void ConversionSizeExceptionCheck(Image image) ConversionSizeExceptionCheck(image.Size); } - public static void ConversionSizeExceptionCheck(MediaAnalysis info) + public static void ConversionSizeExceptionCheck(IMediaAnalysis info) { ConversionSizeExceptionCheck(new Size(info.PrimaryVideoStream.Width, info.PrimaryVideoStream.Height)); }