Cleanup begun

This commit is contained in:
Malte Rosenbjerg 2020-02-11 22:45:02 +01:00
parent 09f1d6e655
commit 8ee92a40ab
33 changed files with 110 additions and 264 deletions

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Abstract class implements basic functionality of ffmpeg arguments

View file

@ -1,9 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
namespace FFMpegCore.FFMPEG.Argument
{
@ -18,11 +17,6 @@ internal static string Speed(int cpu)
return $"-quality good -cpu-used {cpu} -deadline realtime ";
}
internal static string Audio(AudioCodec codec, AudioQuality bitrate)
{
return Audio(codec) + Audio(bitrate);
}
internal static string Audio(AudioCodec codec, int bitrate)
{
return Audio(codec) + Audio(bitrate);
@ -69,11 +63,6 @@ internal static string Threads(int threads)
return $"-threads {threads} ";
}
internal static string Input(Uri uri)
{
return Input(uri.AbsolutePath);
}
internal static string Disable(Channel type)
{
switch (type)
@ -87,21 +76,6 @@ internal static string Disable(Channel type)
}
}
internal static string Input(VideoInfo input)
{
return $"-i \"{input.FullName}\" ";
}
internal static string Input(FileInfo input)
{
return $"-i \"{input.FullName}\" ";
}
internal static string Output(FileInfo output)
{
return $"\"{output.FullName}\"";
}
internal static string Output(string output)
{
return $"\"{output}\"";
@ -122,11 +96,6 @@ internal static string Scale(int width, int height)
return $"-vf scale={width}:{height} ";
}
internal static string Scale(Size size)
{
return Scale(size.Width, size.Height);
}
internal static string Size(Size? size)
{
if (!size.HasValue) return string.Empty;

View file

@ -1,9 +1,4 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,9 +1,4 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,9 +1,5 @@
using System;
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,9 +1,4 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Represents cpu speed parameter

View file

@ -1,9 +1,4 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Represents frame output count parameter

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Represents frame rate parameter

View file

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Represents loop parameter

View file

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Represents override parameter

View file

@ -1,10 +1,5 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{
@ -36,7 +31,7 @@ public ScaleArgument(VideoSize videosize)
/// <returns>String representation of the argument</returns>
public override string GetStringValue()
{
return ArgumentStringifier.Scale(Value);
return ArgumentStringifier.Scale(Value.Width, Value.Height);
}
}
}

View file

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Represents shortest parameter

View file

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using FFMpegCore.FFMPEG.Enums;
namespace FFMpegCore.FFMPEG.Argument
@ -17,7 +12,7 @@ public SizeArgument()
{
}
public SizeArgument(Size? value) : base(value.HasValue ? value.Value : new Size())
public SizeArgument(Size? value) : base(value ?? new Size())
{
}

View file

@ -1,9 +1,4 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
/// <summary>
/// Represents start number parameter

View file

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,9 +1,4 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
{

View file

@ -1,12 +1,4 @@
using FFMpegCore.FFMPEG.Enums;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFMpegCore.FFMPEG.Argument
namespace FFMpegCore.FFMPEG.Argument
{
public interface IArgumentBuilder
{

View file

@ -1,8 +1,5 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using RunProcessAsTask;
@ -86,4 +83,21 @@ protected async Task<string> RunProcessAsync(string filePath, string arguments)
return string.Join("", result.StandardOutput);
}
}
public static class ProcessHelpers
{
public static void RunProcess(string filePath, string arguments)
{
}
public static async Task<string> RunProcessAsync(string fileName, string arguments)
{
var startInfo = new ProcessStartInfo(fileName, arguments);
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
var result = await ProcessEx.RunAsync(startInfo);
return string.Join("", result.StandardOutput);
}
}
}

View file

@ -11,7 +11,6 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
@ -26,7 +25,7 @@ public class FFMpeg : FFBase
/// <summary>
/// Intializes the FFMPEG encoder.
/// </summary>
public FFMpeg(): base()
public FFMpeg() : base()
{
FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory);
@ -49,7 +48,8 @@ public FFMpeg(): base()
/// <param name="size">Thumbnail size. If width or height equal 0, the other will be computed automatically.</param>
/// <param name="persistSnapshotOnFileSystem">By default, it deletes the created image on disk. If set to true, it won't delete the image</param>
/// <returns>Bitmap with the requested snapshot.</returns>
public Bitmap Snapshot(VideoInfo source, FileInfo output, Size? size = null, TimeSpan? captureTime = null, bool persistSnapshotOnFileSystem = false)
public Bitmap Snapshot(VideoInfo source, FileInfo output, Size? size = null, TimeSpan? captureTime = null,
bool persistSnapshotOnFileSystem = false)
{
if (captureTime == null)
captureTime = TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3);
@ -66,28 +66,28 @@ public Bitmap Snapshot(VideoInfo source, FileInfo output, Size? size = null, Tim
{
if (size.Value.Width == 0)
{
var ratio = source.Width / (double)size.Value.Width;
var ratio = source.Width / (double) size.Value.Width;
size = new Size((int)(source.Width * ratio), (int)(source.Height * ratio));
size = new Size((int) (source.Width * ratio), (int) (source.Height * ratio));
}
if (size.Value.Height == 0)
{
var ratio = source.Height / (double)size.Value.Height;
var ratio = source.Height / (double) size.Value.Height;
size = new Size((int)(source.Width * ratio), (int)(source.Height * ratio));
size = new Size((int) (source.Width * ratio), (int) (source.Height * ratio));
}
}
FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output);
var container = new ArgumentContainer(
new InputArgument(source),
new VideoCodecArgument(VideoCodec.Png),
new FrameOutputCountArgument(1),
new SeekArgument(captureTime),
new SizeArgument(size),
new OutputArgument(output)
);
new InputArgument(source),
new VideoCodecArgument(VideoCodec.Png),
new FrameOutputCountArgument(1),
new SeekArgument(captureTime),
new SizeArgument(size),
new OutputArgument(output)
);
if (!RunProcess(container, output))
{
@ -97,7 +97,7 @@ public Bitmap Snapshot(VideoInfo source, FileInfo output, Size? size = null, Tim
output.Refresh();
Bitmap result;
using (var bmp = (Bitmap)Image.FromFile(output.FullName))
using (var bmp = (Bitmap) Image.FromFile(output.FullName))
{
using (var ms = new MemoryStream())
{
@ -129,10 +129,8 @@ public VideoInfo Convert(
VideoInfo source,
FileInfo output,
VideoType type = VideoType.Mp4,
Speed speed =
Speed.SuperFast,
VideoSize size =
VideoSize.Original,
Speed speed = Speed.SuperFast,
VideoSize size = VideoSize.Original,
AudioQuality audioQuality = AudioQuality.Normal,
bool multithreaded = false)
{
@ -142,13 +140,12 @@ public VideoInfo Convert(
_totalTime = source.Duration;
var scale = VideoSize.Original == size ? 1 :
(double)source.Height / (int)size;
var scale = VideoSize.Original == size ? 1 : (double) source.Height / (int) size;
var outputSize = new Size(
(int)(source.Width / scale),
(int)(source.Height / scale)
);
(int) (source.Width / scale),
(int) (source.Height / scale)
);
if (outputSize.Width % 2 != 0)
{
@ -194,7 +191,8 @@ public VideoInfo Convert(
if (!RunProcess(container, output))
{
throw new FFMpegException(FFMpegExceptionType.Conversion, $"The video could not be converted to {Enum.GetName(typeof(VideoType), type)}");
throw new FFMpegException(FFMpegExceptionType.Conversion,
$"The video could not be converted to {Enum.GetName(typeof(VideoType), type)}");
}
_totalTime = TimeSpan.MinValue;
@ -226,7 +224,8 @@ public VideoInfo PosterWithAudio(FileInfo image, FileInfo audio, FileInfo output
if (!RunProcess(container, output))
{
throw new FFMpegException(FFMpegExceptionType.Operation, "An error occured while adding the audio file to the image.");
throw new FFMpegException(FFMpegExceptionType.Operation,
"An error occured while adding the audio file to the image.");
}
return new VideoInfo(output);
@ -248,10 +247,10 @@ public VideoInfo Join(FileInfo output, params VideoInfo[] videos)
FFMpegHelper.ConversionSizeExceptionCheck(video);
var destinationPath = video.FullName.Replace(video.Extension, FileExtension.Ts);
Convert(
video,
new FileInfo(destinationPath),
VideoType.Ts
);
video,
new FileInfo(destinationPath),
VideoType.Ts
);
return destinationPath;
}).ToList();
@ -266,10 +265,11 @@ public VideoInfo Join(FileInfo output, params VideoInfo[] videos)
{
if (!RunProcess(container, output))
{
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not join the provided video files.");
throw new FFMpegException(FFMpegExceptionType.Operation,
"Could not join the provided video files.");
}
return new VideoInfo(output);
return new VideoInfo(output);
}
finally
{
@ -289,7 +289,8 @@ public VideoInfo JoinImageSequence(FileInfo output, double frameRate = 30, param
var temporaryImageFiles = images.Select((image, index) =>
{
FFMpegHelper.ConversionSizeExceptionCheck(Image.FromFile(image.FullName));
var destinationPath = image.FullName.Replace(image.Name, $"{index.ToString().PadLeft(9, '0')}{image.Extension}");
var destinationPath =
image.FullName.Replace(image.Name, $"{index.ToString().PadLeft(9, '0')}{image.Extension}");
File.Copy(image.FullName, destinationPath);
return destinationPath;
@ -311,7 +312,8 @@ public VideoInfo JoinImageSequence(FileInfo output, double frameRate = 30, param
{
if (!RunProcess(container, output))
{
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not join the provided image sequence.");
throw new FFMpegException(FFMpegExceptionType.Operation,
"Could not join the provided image sequence.");
}
return new VideoInfo(output);
@ -341,11 +343,13 @@ public VideoInfo SaveM3U8Stream(Uri uri, FileInfo output)
if (!RunProcess(container, output))
{
throw new FFMpegException(FFMpegExceptionType.Operation, $"Saving the ${uri.AbsoluteUri} stream failed.");
throw new FFMpegException(FFMpegExceptionType.Operation,
$"Saving the ${uri.AbsoluteUri} stream failed.");
}
return new VideoInfo(output);
}
throw new ArgumentException($"Uri: {uri.AbsoluteUri}, does not point to a valid http(s) stream.");
}
@ -395,7 +399,8 @@ public FileInfo ExtractAudio(VideoInfo source, FileInfo output)
if (!RunProcess(container, output))
{
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not extract the audio from the requested video.");
throw new FFMpegException(FFMpegExceptionType.Operation,
"Could not extract the audio from the requested video.");
}
output.Refresh();
@ -436,8 +441,8 @@ public VideoInfo ReplaceAudio(VideoInfo source, FileInfo audio, FileInfo output,
public VideoInfo Convert(ArgumentContainer arguments)
{
var output = ((OutputArgument)arguments[typeof(OutputArgument)]).GetAsFileInfo();
var sources = ((InputArgument)arguments[typeof(InputArgument)]).GetAsVideoInfo();
var output = ((OutputArgument) arguments[typeof(OutputArgument)]).GetAsFileInfo();
var sources = ((InputArgument) arguments[typeof(InputArgument)]).GetAsVideoInfo();
// Sum duration of all sources
_totalTime = TimeSpan.Zero;
@ -475,8 +480,8 @@ public void Stop()
private bool RunProcess(ArgumentContainer container, FileInfo output)
{
var successState = true;
CreateProcess(this.ArgumentBuilder.BuildArguments(container), _ffmpegPath, true, rStandardError: true);
CreateProcess(ArgumentBuilder.BuildArguments(container), _ffmpegPath, true, rStandardError: true);
try
{
@ -506,6 +511,7 @@ private bool RunProcess(ArgumentContainer container, FileInfo output)
throw new FFMpegException(FFMpegExceptionType.Process, _errorOutput);
}
}
return successState;
}
@ -520,6 +526,7 @@ private void Cleanup(IEnumerable<string> pathList)
}
}
private static Regex _progressRegex = new Regex(@"\w\w:\w\w:\w\w", RegexOptions.Compiled);
private void OutputData(object sender, DataReceivedEventArgs e)
{
if (e.Data == null)
@ -532,17 +539,17 @@ private void OutputData(object sender, DataReceivedEventArgs e)
if (OnProgress == null || !IsWorking) return;
var r = new Regex(@"\w\w:\w\w:\w\w");
var m = r.Match(e.Data);
if (!e.Data.Contains("frame")) return;
if (!m.Success) return;
var match = _progressRegex.Match(e.Data);
if (!match.Success) return;
var t = TimeSpan.Parse(m.Value, CultureInfo.InvariantCulture);
var percentage = Math.Round(t.TotalSeconds / _totalTime.TotalSeconds * 100, 2);
var processed = TimeSpan.Parse(match.Value, CultureInfo.InvariantCulture);
var percentage = Math.Round(processed.TotalSeconds / _totalTime.TotalSeconds * 100, 2);
OnProgress(percentage);
}
#endregion
}
}
}

View file

@ -8,8 +8,8 @@ namespace FFMpegCore.FFMPEG
{
public class FFMpegOptions
{
private static string _ConfigFile = Path.Combine(".", "ffmpeg.config.json");
private static string _DefaultRoot = Path.Combine(".", "FFMPEG", "bin");
private static readonly string ConfigFile = Path.Combine(".", "ffmpeg.config.json");
private static readonly string DefaultRoot = Path.Combine(".", "FFMPEG", "bin");
public static FFMpegOptions Options { get; private set; } = new FFMpegOptions();
@ -20,56 +20,37 @@ public static void Configure(FFMpegOptions options)
static FFMpegOptions()
{
if (File.Exists(_ConfigFile))
if (File.Exists(ConfigFile))
{
Options = JsonConvert.DeserializeObject<FFMpegOptions>(File.ReadAllText(_ConfigFile));
Options = JsonConvert.DeserializeObject<FFMpegOptions>(File.ReadAllText(ConfigFile));
}
}
public string RootDirectory { get; set; } = _DefaultRoot;
public string RootDirectory { get; set; } = DefaultRoot;
public string FFmpegBinary
public string FFmpegBinary => FFBinary("FFMpeg");
public string FFProbeBinary => FFBinary("FFProbe");
private static string FFBinary(string name)
{
get
var ffName = name.ToLowerInvariant();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
ffName += ".exe";
var target = Environment.Is64BitProcess ? "x64" : "x86";
if (Directory.Exists(Path.Combine(Options.RootDirectory, target)))
{
var target = Environment.Is64BitProcess ? "x64" : "x86";
var progName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "ffmpeg.exe" : "ffmpeg";
if (Directory.Exists(Path.Combine(Options.RootDirectory, target)))
{
progName = Path.Combine(target, progName);
}
var path = Path.Combine(Options.RootDirectory, progName);
if (!File.Exists(path))
throw new FFMpegException(FFMpegExceptionType.Dependency,
$"FFMpeg cannot be found @ {path}");
return path;
ffName = Path.Combine(target, ffName);
}
}
public string FFProbeBinary
{
get
{
var target = Environment.Is64BitProcess ? "x64" : "x86";
var progName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "ffprobe.exe" : "ffprobe";
var path = Path.Combine(Options.RootDirectory, ffName);
if (Directory.Exists(Path.Combine(Options.RootDirectory, target)))
{
progName = Path.Combine(target, progName);
}
if (!File.Exists(path))
throw new FFMpegException(FFMpegExceptionType.Dependency,
$"{name} cannot be found @ {path}");
var path = Path.Combine(Options.RootDirectory, progName);
if (!File.Exists(path))
throw new FFMpegException(FFMpegExceptionType.Dependency,
$"FFProbe cannot be found @ {path}");
return path;
}
return path;
}
}
}

View file

@ -3,10 +3,7 @@
using Newtonsoft.Json;
using System;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using RunProcessAsTask;
namespace FFMpegCore.FFMPEG
{

View file

@ -11,6 +11,7 @@
<AssemblyVersion>1.0.12.0</AssemblyVersion>
<FileVersion>1.0.12.0</FileVersion>
<PackageReleaseNotes></PackageReleaseNotes>
<LangVersion>8</LangVersion>
</PropertyGroup>
<ItemGroup>
@ -128,6 +129,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Instances" Version="1.1.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="RunProcessAsTask" Version="1.2.4" />

View file

@ -1,7 +1,6 @@
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using FFMpegCore.FFMPEG.Exceptions;
namespace FFMpegCore.Helpers

View file

@ -1,7 +1,4 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using FFMpegCore.FFMPEG.Exceptions;
using FFMpegCore.FFMPEG.Exceptions;
namespace FFMpegCore.Helpers
{

View file

@ -1,10 +1,8 @@
using FFMpegCore.Enums;
using FFMpegCore.FFMPEG;
using FFMpegCore.Helpers;
using System;
using System.Drawing;
using System.IO;
using System.Linq;
namespace FFMpegCore
{

View file

@ -1,6 +1,6 @@
# FFMpegCore
[![NuGet Badge](https://buildstats.info/nuget/FFMpegCore)](https://www.nuget.org/packages/FFMpegCore/)
[![Build Status](https://travis-ci.org/vladjerca/FFMpegCore.svg?branch=master)](https://travis-ci.org/vladjerca/FFMpegCore)
[![Build Status](https://travis-ci.org/rosenbjerg/FFMpegCore.svg)](https://travis-ci.org/vladjerca/FFMpegCore)
# Setup