Switched to fractional framerates, fixed VFR inputs

This commit is contained in:
N00MKRAD
2021-04-02 14:36:08 +02:00
parent 60ee6c2102
commit b3ab84646b
17 changed files with 379 additions and 75 deletions

View File

@@ -10,6 +10,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualBasic.Logging;
using static Flowframes.AvProcess;
using Utils = Flowframes.Media.FFmpegUtils;
@@ -39,7 +40,7 @@ namespace Flowframes
Logger.Log($"Merging videos...", false, Logger.GetLastLine().Contains("frame"));
string loopStr = (looptimes > 0) ? $"-stream_loop {looptimes}" : "";
string vfrFilename = Path.GetFileName(concatFile);
string args = $" {loopStr} -vsync 1 -f concat -i {vfrFilename} -c copy -movflags +faststart {outPath.Wrap()}";
string args = $" {loopStr} -vsync 1 -f concat -i {vfrFilename} -c copy -movflags +faststart -fflags +genpts {outPath.Wrap()}";
await RunFfmpeg(args, concatFile.GetParentDir(), LogMode.Hidden, TaskType.Merge);
}
@@ -75,15 +76,31 @@ namespace Flowframes
return FormatUtils.TimestampToMs(output);
}
public static async Task<float> GetFramerate(string inputFile)
public static async Task<Fraction> GetFramerate(string inputFile)
{
Logger.Log($"GetFramerate('{inputFile}')", true, false, "ffmpeg");
try
{
string args = $" -i {inputFile.Wrap()}";
string output = await GetFfmpegOutputAsync(args);
string[] entries = output.Split(',');
try
{
string ffprobeArgs =
$"-v panic -select_streams v:0 -show_entries stream=r_frame_rate {inputFile.Wrap()}";
string ffprobeOutput = GetFfprobeOutput(ffprobeArgs);
string fpsStr = ffprobeOutput.SplitIntoLines().Where(x => x.Contains("r_frame_rate")).First();
string[] numbers = fpsStr.Split('=')[1].Split('/');
Logger.Log($"Accurate FPS: {numbers[0]}/{numbers[1]} = {((float)numbers[0].GetInt() / numbers[1].GetInt())}", true, false, "ffmpeg");
return new Fraction(numbers[0].GetInt(), numbers[1].GetInt());
}
catch (Exception ffprobeEx)
{
Logger.Log("GetFramerate ffprobe Error: " + ffprobeEx.Message, true, false);
}
string ffmpegArgs = $" -i {inputFile.Wrap()}";
string ffmpegOutput = await GetFfmpegOutputAsync(ffmpegArgs);
string[] entries = ffmpegOutput.Split(',');
foreach (string entry in entries)
{
@@ -92,16 +109,16 @@ namespace Flowframes
string num = entry.Replace(" fps", "").Trim().Replace(",", ".");
float value;
float.TryParse(num, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
return value;
return new Fraction(value);
}
}
}
catch(Exception e)
catch(Exception ffmpegEx)
{
Logger.Log("GetFramerate Error: " + e.Message, true, false);
Logger.Log("GetFramerate ffmpeg Error: " + ffmpegEx.Message, true, false);
}
return 0f;
return new Fraction(0, 1);
}
public static Size GetSize(string inputFile)