mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-23 19:59:31 +01:00
Retain aspect ratio from input video
This commit is contained in:
@@ -4,14 +4,18 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Flowframes.Data
|
namespace Flowframes.Data
|
||||||
{
|
{
|
||||||
class ColorInfo
|
class VidExtraData
|
||||||
{
|
{
|
||||||
|
// Color
|
||||||
public string colorSpace = "";
|
public string colorSpace = "";
|
||||||
public string colorRange = "";
|
public string colorRange = "";
|
||||||
public string colorTransfer = "";
|
public string colorTransfer = "";
|
||||||
public string colorPrimaries = "";
|
public string colorPrimaries = "";
|
||||||
|
|
||||||
public ColorInfo(string ffprobeOutput)
|
// Aspect Ratio
|
||||||
|
public string displayRatio = "";
|
||||||
|
|
||||||
|
public VidExtraData(string ffprobeOutput)
|
||||||
{
|
{
|
||||||
string[] lines = ffprobeOutput.SplitIntoLines();
|
string[] lines = ffprobeOutput.SplitIntoLines();
|
||||||
|
|
||||||
@@ -40,6 +44,12 @@ namespace Flowframes.Data
|
|||||||
colorPrimaries = line.Split('=').LastOrDefault();
|
colorPrimaries = line.Split('=').LastOrDefault();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (line.Contains("display_aspect_ratio"))
|
||||||
|
{
|
||||||
|
displayRatio = line.Split('=').LastOrDefault();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorSpace.Trim() == "unknown")
|
if (colorSpace.Trim() == "unknown")
|
||||||
@@ -328,7 +328,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Data\AI.cs" />
|
<Compile Include="Data\AI.cs" />
|
||||||
<Compile Include="Data\AudioTrack.cs" />
|
<Compile Include="Data\AudioTrack.cs" />
|
||||||
<Compile Include="Data\ColorInfo.cs" />
|
<Compile Include="Data\VidExtraData.cs" />
|
||||||
<Compile Include="Data\Fraction.cs" />
|
<Compile Include="Data\Fraction.cs" />
|
||||||
<Compile Include="Data\InterpSettings.cs" />
|
<Compile Include="Data\InterpSettings.cs" />
|
||||||
<Compile Include="Data\Networks.cs" />
|
<Compile Include="Data\Networks.cs" />
|
||||||
|
|||||||
@@ -151,8 +151,8 @@ namespace Flowframes.Main
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ColorInfo colorInfo = await FfmpegCommands.GetColorInfo(I.current.inPath);
|
VidExtraData extraData = await FfmpegCommands.GetVidExtraInfo(I.current.inPath);
|
||||||
await FfmpegEncode.FramesToVideo(framesFile, outPath, mode, fps, resampleFps, colorInfo);
|
await FfmpegEncode.FramesToVideo(framesFile, outPath, mode, fps, resampleFps, extraData);
|
||||||
await MuxOutputVideo(I.current.inPath, outPath);
|
await MuxOutputVideo(I.current.inPath, outPath);
|
||||||
await Loop(currentOutFile, await GetLoopTimes());
|
await Loop(currentOutFile, await GetLoopTimes());
|
||||||
}
|
}
|
||||||
@@ -213,19 +213,19 @@ namespace Flowframes.Main
|
|||||||
string max = Config.Get("maxFps");
|
string max = Config.Get("maxFps");
|
||||||
Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat());
|
Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat());
|
||||||
bool fpsLimit = maxFps.GetFloat() != 0 && I.current.outFps.GetFloat() > maxFps.GetFloat();
|
bool fpsLimit = maxFps.GetFloat() != 0 && I.current.outFps.GetFloat() > maxFps.GetFloat();
|
||||||
ColorInfo colorInfo = await FfmpegCommands.GetColorInfo(I.current.inPath);
|
VidExtraData extraData = await FfmpegCommands.GetVidExtraInfo(I.current.inPath);
|
||||||
|
|
||||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
|
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
|
||||||
|
|
||||||
if (!dontEncodeFullFpsVid)
|
if (!dontEncodeFullFpsVid)
|
||||||
await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, new Fraction(), colorInfo, AvProcess.LogMode.Hidden, true); // Encode
|
await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, new Fraction(), extraData, AvProcess.LogMode.Hidden, true); // Encode
|
||||||
|
|
||||||
if (fpsLimit)
|
if (fpsLimit)
|
||||||
{
|
{
|
||||||
string filename = Path.GetFileName(outPath);
|
string filename = Path.GetFileName(outPath);
|
||||||
string newParentDir = outPath.GetParentDir() + Paths.fpsLimitSuffix;
|
string newParentDir = outPath.GetParentDir() + Paths.fpsLimitSuffix;
|
||||||
outPath = Path.Combine(newParentDir, filename);
|
outPath = Path.Combine(newParentDir, filename);
|
||||||
await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, maxFps, colorInfo, AvProcess.LogMode.Hidden, true); // Encode with limited fps
|
await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, maxFps, extraData, AvProcess.LogMode.Hidden, true); // Encode with limited fps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Flowframes.Media
|
namespace Flowframes.Media
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -201,12 +201,11 @@ namespace Flowframes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<ColorInfo> GetColorInfo(string inputFile)
|
public static async Task<VidExtraData> GetVidExtraInfo(string inputFile)
|
||||||
{
|
{
|
||||||
string ffprobeOutput = await GetVideoInfoCached.GetFfprobeInfoAsync(inputFile, "color");
|
string ffprobeOutput = await GetVideoInfoCached.GetFfprobeInfoAsync(inputFile);
|
||||||
ColorInfo colorInfo = new ColorInfo(ffprobeOutput);
|
VidExtraData data = new VidExtraData(ffprobeOutput);
|
||||||
Logger.Log($"Created ColorInfo - Range: {colorInfo.colorRange} - Space: {colorInfo.colorSpace} - Transer: {colorInfo.colorTransfer} - Primaries: {colorInfo.colorPrimaries}", true, false, "ffmpeg");
|
return data;
|
||||||
return colorInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> IsEncoderCompatible(string enc)
|
public static async Task<bool> IsEncoderCompatible(string enc)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Flowframes.Media
|
|||||||
{
|
{
|
||||||
partial class FfmpegEncode : FfmpegCommands
|
partial class FfmpegEncode : FfmpegCommands
|
||||||
{
|
{
|
||||||
public static async Task FramesToVideo(string framesFile, string outPath, Interpolate.OutMode outMode, Fraction fps, Fraction resampleFps, ColorInfo colors, LogMode logMode = LogMode.OnlyLastLine, bool isChunk = false)
|
public static async Task FramesToVideo(string framesFile, string outPath, Interpolate.OutMode outMode, Fraction fps, Fraction resampleFps, VidExtraData extraData, LogMode logMode = LogMode.OnlyLastLine, bool isChunk = false)
|
||||||
{
|
{
|
||||||
if (logMode != LogMode.Hidden)
|
if (logMode != LogMode.Hidden)
|
||||||
Logger.Log((resampleFps.GetFloat() <= 0) ? "Encoding video..." : $"Encoding video resampled to {resampleFps.GetString()} FPS...");
|
Logger.Log((resampleFps.GetFloat() <= 0) ? "Encoding video..." : $"Encoding video resampled to {resampleFps.GetString()} FPS...");
|
||||||
@@ -42,19 +42,27 @@ namespace Flowframes.Media
|
|||||||
if (resampleFps.GetFloat() >= 0.1f)
|
if (resampleFps.GetFloat() >= 0.1f)
|
||||||
filters.Add($"fps=fps={resampleFps}");
|
filters.Add($"fps=fps={resampleFps}");
|
||||||
|
|
||||||
if (colors.HasAllValues())
|
if (extraData.HasAllValues())
|
||||||
{
|
{
|
||||||
Logger.Log($"Applying color transfer ({colors.colorSpace}).", true, false, "ffmpeg");
|
Logger.Log($"Applying color transfer ({extraData.colorSpace}).", true, false, "ffmpeg");
|
||||||
filters.Add($"scale=out_color_matrix={colors.colorSpace}");
|
filters.Add($"scale=out_color_matrix={extraData.colorSpace}");
|
||||||
extraArgs += $" -colorspace {colors.colorSpace} -color_primaries {colors.colorPrimaries} -color_trc {colors.colorTransfer} -color_range:v \"{colors.colorRange}\"";
|
extraArgs += $" -colorspace {extraData.colorSpace} -color_primaries {extraData.colorPrimaries} -color_trc {extraData.colorTransfer} -color_range:v \"{extraData.colorRange}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
string vf = filters.Count > 0 ? $"-vf {string.Join(",", filters)}" : "";
|
string vf = filters.Count > 0 ? $"-vf {string.Join(",", filters)}" : "";
|
||||||
string args = $"-vsync 0 -r {rate} {inArg} {encArgs} {vf} {extraArgs} -threads {Config.GetInt("ffEncThreads")} {outPath.Wrap()}";
|
string args = $"-vsync 0 -r {rate} {inArg} {encArgs} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt("ffEncThreads")} {outPath.Wrap()}";
|
||||||
await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, !isChunk);
|
await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, !isChunk);
|
||||||
IOUtils.TryDeleteIfExists(linksDir);
|
IOUtils.TryDeleteIfExists(linksDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string GetAspectArg (VidExtraData extraData)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(extraData.displayRatio))
|
||||||
|
return $"-aspect {extraData.displayRatio}";
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task FramesToFrames(string framesFile, string outDir, Fraction fps, Fraction resampleFps, string format = "png", LogMode logMode = LogMode.OnlyLastLine)
|
public static async Task FramesToFrames(string framesFile, string outDir, Fraction fps, Fraction resampleFps, string format = "png", LogMode logMode = LogMode.OnlyLastLine)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(outDir);
|
Directory.CreateDirectory(outDir);
|
||||||
|
|||||||
Reference in New Issue
Block a user