diff --git a/Code/AudioVideo/FFmpegCommands.cs b/Code/AudioVideo/FFmpegCommands.cs
index 808e28d..935599f 100644
--- a/Code/AudioVideo/FFmpegCommands.cs
+++ b/Code/AudioVideo/FFmpegCommands.cs
@@ -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);
diff --git a/Code/Flowframes.csproj b/Code/Flowframes.csproj
index 24024da..e42c650 100644
--- a/Code/Flowframes.csproj
+++ b/Code/Flowframes.csproj
@@ -234,6 +234,7 @@
+
diff --git a/Code/Form1.Designer.cs b/Code/Form1.Designer.cs
index 9230f14..e9acada 100644
--- a/Code/Form1.Designer.cs
+++ b/Code/Form1.Designer.cs
@@ -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;
}
}
diff --git a/Code/Form1.cs b/Code/Form1.cs
index 17b30ac..b4f8e38 100644
--- a/Code/Form1.cs
+++ b/Code/Form1.cs
@@ -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");
+ }
}
}
diff --git a/Code/Main/InterpolateUtils.cs b/Code/Main/InterpolateUtils.cs
index 7e34edd..9a02e4e 100644
--- a/Code/Main/InterpolateUtils.cs
+++ b/Code/Main/InterpolateUtils.cs
@@ -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;
diff --git a/Code/Program.cs b/Code/Program.cs
index dae9c14..9f94c43 100644
--- a/Code/Program.cs
+++ b/Code/Program.cs
@@ -12,7 +12,7 @@ namespace Flowframes
{
static class Program
{
- public const int version = 16;
+ public const int version = 17;
public static Form1 mainForm;
diff --git a/Code/UI/MainUiFunctions.cs b/Code/UI/MainUiFunctions.cs
new file mode 100644
index 0000000..5dc53c5
--- /dev/null
+++ b/Code/UI/MainUiFunctions.cs
@@ -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 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;
+ }
+ }
+ }
+}
diff --git a/README.md b/README.md
index 7c7ba0e..f74cd7c 100644
--- a/README.md
+++ b/README.md
@@ -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.
\ No newline at end of file