Print vid res on load, set preview to 1st frame on load, updated Readme with basic info

This commit is contained in:
N00MKRAD 2020-11-27 14:35:32 +01:00
parent 64d1d040ef
commit 9e1f3d3421
8 changed files with 137 additions and 52 deletions

View File

@ -47,12 +47,16 @@ namespace Flowframes
DeleteSource(inputFile);
}
public static async void ExtractSingleFrame(string inputFile, int frameNum, bool hdr, bool delSrc)
public static async Task ExtractSingleFrame(string inputFile, int frameNum, bool hdr, bool delSrc)
{
string hdrStr = "";
if (hdr) hdrStr = hdrFilter;
string args = "-i \"" + inputFile + "\" " + hdrStr
+ " -vf \"select=eq(n\\," + frameNum + ")\" -vframes 1 \"" + inputFile + "-frame" + frameNum + ".png\"";
string outPath = $"{inputFile}-frame{frameNum}.png";
await ExtractSingleFrame(inputFile, outPath, frameNum, hdr, delSrc);
}
public static async Task ExtractSingleFrame(string inputFile, string outputPath, int frameNum, bool hdr, bool delSrc)
{
string hdrStr = hdr ? hdrFilter : "";
string args = $"-i {inputFile.Wrap()} {hdrStr }-vf \"select=eq(n\\,{frameNum})\" -vframes 1 {outputPath.Wrap()}";
await AvProcess.RunFfmpeg(args, AvProcess.LogMode.Hidden);
if (delSrc)
DeleteSource(inputFile);

View File

@ -234,6 +234,7 @@
<Compile Include="IO\Setup.cs" />
<Compile Include="UI\FormatUtils.cs" />
<Compile Include="UI\GetWebInfo.cs" />
<Compile Include="UI\MainUiFunctions.cs" />
<Compile Include="UI\UIUtils.cs" />
<Compile Include="UI\UtilsTab.cs" />
<EmbeddedResource Include="Form1.resx">

27
Code/Form1.Designer.cs generated
View File

@ -95,7 +95,7 @@
this.cancelBtn = new System.Windows.Forms.Button();
this.mainTabControl = new HTAlt.WinForms.HTTabControl();
this.welcomeTab = new System.Windows.Forms.TabPage();
this.label22 = new System.Windows.Forms.Label();
this.welcomeLabel2 = new System.Windows.Forms.Label();
this.panel8 = new System.Windows.Forms.Panel();
this.patronsLabel = new System.Windows.Forms.Label();
this.label21 = new System.Windows.Forms.Label();
@ -959,7 +959,7 @@
// welcomeTab
//
this.welcomeTab.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
this.welcomeTab.Controls.Add(this.label22);
this.welcomeTab.Controls.Add(this.welcomeLabel2);
this.welcomeTab.Controls.Add(this.panel8);
this.welcomeTab.Controls.Add(this.panel6);
this.welcomeTab.Controls.Add(this.label11);
@ -970,17 +970,18 @@
this.welcomeTab.TabIndex = 4;
this.welcomeTab.Text = "Welcome";
//
// label22
// welcomeLabel2
//
this.label22.AutoSize = true;
this.label22.Font = new System.Drawing.Font("Yu Gothic UI", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label22.ForeColor = System.Drawing.Color.Gray;
this.label22.Location = new System.Drawing.Point(142, 3);
this.label22.Margin = new System.Windows.Forms.Padding(3, 0, 3, 10);
this.label22.Name = "label22";
this.label22.Size = new System.Drawing.Size(478, 40);
this.label22.TabIndex = 5;
this.label22.Text = "Click The Interpolation Tab To Begin.";
this.welcomeLabel2.AutoSize = true;
this.welcomeLabel2.Font = new System.Drawing.Font("Yu Gothic UI", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.welcomeLabel2.ForeColor = System.Drawing.Color.Gray;
this.welcomeLabel2.Location = new System.Drawing.Point(142, 3);
this.welcomeLabel2.Margin = new System.Windows.Forms.Padding(3, 0, 3, 10);
this.welcomeLabel2.Name = "welcomeLabel2";
this.welcomeLabel2.Size = new System.Drawing.Size(478, 40);
this.welcomeLabel2.TabIndex = 5;
this.welcomeLabel2.Text = "Click The Interpolation Tab To Begin.";
this.welcomeLabel2.Click += new System.EventHandler(this.welcomeLabel2_Click);
//
// panel8
//
@ -1431,7 +1432,7 @@
private System.Windows.Forms.Label patronsLabel;
private System.Windows.Forms.Label label21;
private System.Windows.Forms.Label newsLabel;
private System.Windows.Forms.Label label22;
private System.Windows.Forms.Label welcomeLabel2;
}
}

View File

@ -14,6 +14,7 @@ using System.Windows.Forms;
using HTAlt.WinForms;
using Flowframes.Data;
using Microsoft.WindowsAPICodePack.Taskbar;
using System.Threading.Tasks;
namespace Flowframes
{
@ -125,7 +126,7 @@ namespace Flowframes
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
inputTbox.Text = dialog.FileName;
InitInput();
MainUiFunctions.InitInput(outputTbox, inputTbox, fpsInTbox);
}
}
@ -137,34 +138,10 @@ namespace Flowframes
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
inputTbox.Text = dialog.FileName;
InitInput();
MainUiFunctions.InitInput(outputTbox, inputTbox, fpsInTbox);
}
}
void InitInput()
{
outputTbox.Text = inputTbox.Text.Trim().GetParentDir();
string path = inputTbox.Text.Trim();
Program.lastInputPath = path;
string fpsStr = "Not Found";
float fps = IOUtils.GetFpsFolderOrVideo(path);
if(fps > 0)
{
fpsStr = fps.ToString();
fpsInTbox.Text = fpsStr;
}
Interpolate.SetFps(fps);
Program.lastInputPathIsSsd = OSUtils.DriveIsSSD(path);
if (!Program.lastInputPathIsSsd)
Logger.Log("Your file seems to be on an HDD or USB device. It is recommended to interpolate videos on an SSD drive for best performance.");
if (IOUtils.IsPathDirectory(path))
Logger.Log($"Video FPS (Loaded from fps.ini): {fpsStr} - Total Number Of Frames: {IOUtils.GetAmountOfFiles(path, false)}");
else
Logger.Log($"Video FPS: {fpsStr} - Total Number Of Frames: {FFmpegCommands.GetFrameCount(path)}");
MagickDedupe.ClearCache();
}
private void browseOutBtn_Click(object sender, EventArgs e)
{
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
@ -214,8 +191,7 @@ namespace Flowframes
if (Program.busy) return;
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
inputTbox.Text = files[0];
InitInput();
//FFmpegCommands.GetFramerate(inputTbox.Text);
MainUiFunctions.InitInput(outputTbox, inputTbox, fpsInTbox);
}
void outputTbox_DragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Copy; }
@ -304,7 +280,7 @@ namespace Flowframes
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
inputTbox.Text = files[0];
Logger.Log("Selected video/directory: " + Path.GetFileName(files[0]));
InitInput();
MainUiFunctions.InitInput(outputTbox, inputTbox, fpsInTbox);
}
private async void utilsConvertMp4Btn_Click(object sender, EventArgs e)
@ -386,5 +362,10 @@ namespace Flowframes
if (!initialized || !GetAi().supportsTiling) return;
Config.Set($"tilesize_{GetAi().aiName}", tilesize.GetInt().ToString());
}
private void welcomeLabel2_Click(object sender, EventArgs e)
{
SetTab("interpolation");
}
}
}

View File

@ -45,14 +45,21 @@ namespace Flowframes.Main
{
if (bigPreviewForm == null && !preview.Visible /* ||Program.mainForm.WindowState != FormWindowState.Minimized */ /* || !Program.mainForm.IsInFocus()*/) return; // Skip if the preview is not visible or the form is not in focus
Image img = IOUtils.GetImage(latestFramePath);
preview.Image = img;
if (bigPreviewForm != null)
bigPreviewForm.SetImage(img);
SetPreviewImg(img);
}
}
catch { }
}
public static void SetPreviewImg (Image img)
{
if (img == null)
return;
preview.Image = img;
if (bigPreviewForm != null)
bigPreviewForm.SetImage(img);
}
public static int GetProgressWaitTime(int numFrames)
{
float hddMultiplier = 2f;

View File

@ -12,7 +12,7 @@ namespace Flowframes
{
static class Program
{
public const int version = 16;
public const int version = 17;
public static Form1 mainForm;

View File

@ -0,0 +1,61 @@
using Flowframes.IO;
using Flowframes.Magick;
using Flowframes.Main;
using Flowframes.OS;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Flowframes.UI
{
class MainUiFunctions
{
public static async Task InitInput (TextBox outputTbox, TextBox inputTbox, TextBox fpsInTbox)
{
outputTbox.Text = inputTbox.Text.Trim().GetParentDir();
string path = inputTbox.Text.Trim();
Program.lastInputPath = path;
string fpsStr = "Not Found";
float fps = IOUtils.GetFpsFolderOrVideo(path);
if (fps > 0)
{
fpsStr = fps.ToString();
fpsInTbox.Text = fpsStr;
}
Interpolate.SetFps(fps);
Program.lastInputPathIsSsd = OSUtils.DriveIsSSD(path);
if (!Program.lastInputPathIsSsd)
Logger.Log("Your file seems to be on an HDD or USB device. It is recommended to interpolate videos on an SSD drive for best performance.");
if (IOUtils.IsPathDirectory(path))
Logger.Log($"Video FPS (Loaded from fps.ini): {fpsStr} - Total Number Of Frames: {IOUtils.GetAmountOfFiles(path, false)}");
else
Logger.Log($"Video FPS: {fpsStr} - Total Number Of Frames: {FFmpegCommands.GetFrameCount(path)}");
await Task.Delay(10);
Size res = FFmpegCommands.GetSize(path);
Logger.Log($"Video Resolution: {res.Width}x{res.Height}");
MagickDedupe.ClearCache();
await Task.Delay(10);
InterpolateUtils.SetPreviewImg(await GetThumbnail(path));
}
static async Task<Image> GetThumbnail (string videoPath)
{
string imgOnDisk = Path.Combine(Paths.GetDataPath(), "thumb-temp.png");
try
{
await FFmpegCommands.ExtractSingleFrame(videoPath, imgOnDisk, 1, false, false);
return IOUtils.GetImage(imgOnDisk);
}
catch (Exception e)
{
Logger.Log("GetThumbnail Error: " + e.Message, true);
return null;
}
}
}
}

View File

@ -1,2 +1,32 @@
# flowframes
# Flowframes - Windows GUI for Video Interpolation
Flowframes Windows GUI for video interpolation - RIFE, DAIN-NCNN, CAIN-NCNN.
## Installation
* Download the latest version on [itch](https://nmkd.itch.io/flowframes) or, for the most recent beta versions, on [Patreon](https://www.patreon.com/n00mkrad). This repo does not provide downloads.
* Run Flowframes.exe
* Select the components you want to install (certain packages are required, cannot be unticked)
## Using A Pytorch AI
Some of the AI networks run on Tencent's NCNN framework, which allows them to run on any modern (Vulkan-capable) GPU.
However, others (like RIFE) run best via their original Pytorch implementation.
The requirements to run these are the following:
* A **modern Nvidia GPU** (750 Ti, 900/1000/1600/2000/3000 Series).
* A **Python** installation including Pytorch (1.5 or later) as well as the packages `opencv-python` and `imageio`.
* You can install a portable version of all those requirements from the Flowframes Installer. However, this does not support RTX 3000 cards yet.
#### Running A Pytorch AI on Nvidia Ampere (RTX 3000) GPUs
I do not have an Ampere card yet, so I can't fully test Flowframes on an RTX 3000 series GPU.
However, users have reported that you can run it by installing a recent **nightly build of Pytorch**. NCNN-based AIs however should work out of the box.