2022-05-31 22:17:22 +02:00
|
|
|
|
using Flowframes.Data;
|
|
|
|
|
|
using Flowframes.IO;
|
2022-07-18 20:38:40 +02:00
|
|
|
|
using Flowframes.MiscUtils;
|
|
|
|
|
|
using Flowframes.Ui;
|
2022-05-31 22:17:22 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2024-06-24 11:36:43 +02:00
|
|
|
|
using System.Diagnostics;
|
2022-05-31 22:17:22 +02:00
|
|
|
|
using System.Drawing;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Flowframes.Os
|
|
|
|
|
|
{
|
|
|
|
|
|
class VapourSynthUtils
|
|
|
|
|
|
{
|
2022-05-31 23:47:18 +02:00
|
|
|
|
public class VsSettings
|
2022-05-31 22:17:22 +02:00
|
|
|
|
{
|
2022-05-31 23:47:18 +02:00
|
|
|
|
public InterpSettings InterpSettings { get; set; }
|
|
|
|
|
|
public string ModelDir { get; set; } = "";
|
|
|
|
|
|
public float Factor { get; set; } = 2.0f;
|
|
|
|
|
|
public Size Res { get; set; } = new Size();
|
|
|
|
|
|
public bool Uhd { get; set; } = false;
|
|
|
|
|
|
public float SceneDetectSensitivity { get; set; } = 0.15f;
|
|
|
|
|
|
public int GpuId { get; set; } = 0;
|
|
|
|
|
|
public int GpuThreads { get; set; } = 3;
|
|
|
|
|
|
public bool Tta { get; set; } = false;
|
|
|
|
|
|
public bool Loop { get; set; } = false;
|
|
|
|
|
|
public bool MatchDuration { get; set; } = false;
|
2022-06-06 07:03:27 +02:00
|
|
|
|
public bool Dedupe { get; set; } = false;
|
2022-06-04 12:43:48 +02:00
|
|
|
|
public bool Realtime { get; set; } = false;
|
2022-06-09 00:30:58 +02:00
|
|
|
|
public bool Osd { get; set; } = true;
|
2022-05-31 23:47:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static string CreateScript(VsSettings s)
|
|
|
|
|
|
{
|
2022-07-20 18:29:36 +02:00
|
|
|
|
Logger.Log($"Creating RIFE VS script. Model: {s.ModelDir}, Factor: {s.Factor}, Res: {s.Res.Width}x{s.Res.Height}, UHD: {s.Uhd}, SC Sens: {s.SceneDetectSensitivity}, " +
|
|
|
|
|
|
$"GPU ID: {s.GpuId}, GPU Threads: {s.GpuThreads}, TTA: {s.Tta}, Loop: {s.Loop}, Match Duration: {s.MatchDuration}, Dedupe: {s.Dedupe}, RT: {s.Realtime}{(s.Osd ? $", OSD: {s.Osd}" : "")}", true);
|
|
|
|
|
|
|
2022-05-31 23:47:18 +02:00
|
|
|
|
string inputPath = s.InterpSettings.inPath;
|
2022-06-04 12:43:48 +02:00
|
|
|
|
string mdlPath = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir, s.ModelDir).Replace(@"\", "/").Wrap();
|
|
|
|
|
|
|
2022-05-31 23:47:18 +02:00
|
|
|
|
bool sc = s.SceneDetectSensitivity >= 0.01f;
|
2022-07-20 18:10:31 +02:00
|
|
|
|
long frameCount = (long)Interpolate.currentMediaFile.FrameCount;
|
2022-07-18 20:38:40 +02:00
|
|
|
|
|
|
|
|
|
|
bool trim = QuickSettingsTab.trimEnabled;
|
|
|
|
|
|
long srcTrimStartFrame = trim ? (long)(Math.Round(FormatUtils.TimestampToMs(QuickSettingsTab.trimStart) / 1000f * s.InterpSettings.inFps.GetFloat())) : 0;
|
|
|
|
|
|
long srcTrimEndFrame = trim && QuickSettingsTab.doTrimEnd ? (long)(Math.Round(FormatUtils.TimestampToMs(QuickSettingsTab.trimEnd) / 1000f * s.InterpSettings.inFps.GetFloat())) - 1 : frameCount - 1;
|
|
|
|
|
|
|
|
|
|
|
|
if(trim)
|
|
|
|
|
|
frameCount = srcTrimEndFrame - srcTrimStartFrame;
|
2022-05-31 23:47:18 +02:00
|
|
|
|
|
|
|
|
|
|
int endDupeCount = s.Factor.RoundToInt() - 1;
|
2022-07-18 20:38:40 +02:00
|
|
|
|
int targetFrameCountMatchDuration = (frameCount * s.Factor).RoundToInt(); // Target frame count to match original duration (and for loops)
|
2022-06-01 16:23:00 +02:00
|
|
|
|
int targetFrameCountTrue = targetFrameCountMatchDuration - endDupeCount; // Target frame count without dupes at the end (only in-between frames added)
|
2022-05-31 23:47:18 +02:00
|
|
|
|
|
2022-06-09 00:30:58 +02:00
|
|
|
|
List<string> l = new List<string> { "import sys", "import os", "import json", "import time", "import functools", "import vapoursynth as vs", "core = vs.core", "" }; // Imports
|
|
|
|
|
|
l.Add($"inputPath = r'{inputPath}'");
|
|
|
|
|
|
l.Add($"");
|
2022-06-01 10:27:02 +02:00
|
|
|
|
|
2024-01-09 13:31:02 +01:00
|
|
|
|
bool loadFrames = s.InterpSettings.inputIsFrames;
|
2023-12-22 05:20:22 +01:00
|
|
|
|
|
|
|
|
|
|
if (loadFrames)
|
2022-06-01 15:46:34 +02:00
|
|
|
|
{
|
2023-02-15 18:25:41 +01:00
|
|
|
|
FileInfo[] frames = IoUtils.GetFileInfosSorted(s.InterpSettings.framesFolder, false, "*.*");
|
|
|
|
|
|
string ext = frames.FirstOrDefault().Extension;
|
|
|
|
|
|
string first = Path.GetFileNameWithoutExtension(frames.FirstOrDefault().FullName);
|
|
|
|
|
|
l.Add($"clip = core.imwri.Read(r'{Path.Combine(s.InterpSettings.framesFolder, $"%0{first.Length}d{ext}")}', firstnum={first.GetInt()})"); // Load image sequence with imwri
|
2022-06-01 15:46:34 +02:00
|
|
|
|
l.Add($"clip = core.std.AssumeFPS(clip, fpsnum={s.InterpSettings.inFps.Numerator}, fpsden={s.InterpSettings.inFps.Denominator})"); // Set frame rate for img seq
|
|
|
|
|
|
}
|
2022-06-01 10:27:02 +02:00
|
|
|
|
else
|
2022-06-01 15:46:34 +02:00
|
|
|
|
{
|
2022-06-09 00:30:58 +02:00
|
|
|
|
l.Add("indexFilePath = f'{inputPath}.cache.lwi'");
|
2022-06-04 12:43:48 +02:00
|
|
|
|
l.Add($"if os.path.isdir(r'{s.InterpSettings.tempFolder}'):");
|
2023-01-08 02:28:15 +01:00
|
|
|
|
l.Add($" indexFilePath = r'{Path.Combine(s.InterpSettings.tempFolder, "cache.lwi")}'");
|
2022-06-09 00:30:58 +02:00
|
|
|
|
l.Add($"clip = core.lsmas.LWLibavSource(inputPath, cachefile=indexFilePath)"); // Load video with lsmash
|
2024-06-24 11:36:43 +02:00
|
|
|
|
l.Add(Debugger.IsAttached ? "clip = core.text.FrameNum(clip, alignment=7)" : "");
|
2024-01-09 13:31:02 +01:00
|
|
|
|
l.Add(GetDedupeLines(s));
|
2022-06-01 15:46:34 +02:00
|
|
|
|
}
|
2022-05-31 23:47:18 +02:00
|
|
|
|
|
2022-07-18 20:38:40 +02:00
|
|
|
|
if (trim)
|
|
|
|
|
|
l.Add($"clip = clip.std.Trim({srcTrimStartFrame}, {srcTrimEndFrame})");
|
|
|
|
|
|
|
2022-06-09 00:30:58 +02:00
|
|
|
|
l.Add($"");
|
|
|
|
|
|
|
2022-06-01 16:23:00 +02:00
|
|
|
|
if (s.Loop && !s.InterpSettings.inputIsFrames)
|
2022-05-31 23:47:18 +02:00
|
|
|
|
{
|
|
|
|
|
|
l.Add($"firstFrame = clip[0]"); // Grab first frame
|
|
|
|
|
|
l.Add($"clip = clip + firstFrame"); // Add to end (for seamless loop interpolation)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-22 05:20:22 +01:00
|
|
|
|
l.Add(GetScaleLines(s, loadFrames));
|
2022-05-31 23:47:18 +02:00
|
|
|
|
|
|
|
|
|
|
if (sc)
|
2022-06-09 00:30:58 +02:00
|
|
|
|
l.Add($"clip = core.misc.SCDetect(clip=clip, threshold={s.SceneDetectSensitivity.ToStringDot()})"); // Scene detection
|
2022-05-31 23:47:18 +02:00
|
|
|
|
|
2023-10-27 09:54:34 +02:00
|
|
|
|
Fraction outFps = s.InterpSettings.inFps * s.Factor;
|
2023-12-28 02:59:29 +01:00
|
|
|
|
|
|
|
|
|
|
if (!loadFrames)
|
|
|
|
|
|
{
|
|
|
|
|
|
outFps = Interpolate.currentMediaFile.VideoStreams.First().FpsInfo.SpecifiedFps * s.Factor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-27 09:54:34 +02:00
|
|
|
|
l.Add($"clip = core.rife.RIFE(clip, fps_num={outFps.Numerator}, fps_den={outFps.Denominator}, model_path={mdlPath}, gpu_id={s.GpuId}, gpu_thread={s.GpuThreads}, tta={s.Tta}, uhd={s.Uhd}, sc={sc})"); // Interpolate
|
2022-06-06 07:03:27 +02:00
|
|
|
|
|
2022-06-06 20:54:16 +02:00
|
|
|
|
if (s.Dedupe && !s.Realtime)
|
2023-01-08 02:28:15 +01:00
|
|
|
|
l.Add(GetRedupeLines(s));
|
2022-06-06 07:03:27 +02:00
|
|
|
|
|
2024-06-24 11:36:43 +02:00
|
|
|
|
Console.WriteLine($"In Format: {Interpolate.currentMediaFile.Format.Upper()}");
|
|
|
|
|
|
bool use470bg = loadFrames && !new[] { "GIF", "EXR" }.Contains(Interpolate.currentMediaFile.Format.Upper());
|
2023-12-26 22:59:17 +01:00
|
|
|
|
l.Add($"clip = vs.core.resize.Bicubic(clip, format=vs.YUV444P16, matrix_s={(use470bg ? "'470bg'" : "cMatrix")})"); // Convert RGB to YUV. Always use 470bg if input is YUV frames
|
2022-05-31 23:47:18 +02:00
|
|
|
|
|
2022-06-06 20:54:16 +02:00
|
|
|
|
if (!s.Dedupe) // Ignore trimming code when using deduping that that already handles trimming in the frame order file
|
2022-05-31 23:47:18 +02:00
|
|
|
|
{
|
2022-06-06 20:54:16 +02:00
|
|
|
|
if (s.Loop)
|
|
|
|
|
|
{
|
|
|
|
|
|
l.Add($"clip = clip.std.Trim(0, {targetFrameCountMatchDuration - 1})"); // -1 because we use index, not count
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!s.MatchDuration)
|
|
|
|
|
|
l.Add($"clip = clip.std.Trim(0, {targetFrameCountTrue - 1})"); // -1 because we use index, not count
|
|
|
|
|
|
}
|
2022-05-31 23:47:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-04 12:43:48 +02:00
|
|
|
|
if(s.Realtime && s.Loop)
|
2022-06-09 00:30:58 +02:00
|
|
|
|
l.AddRange(new List<string> { $"clip = clip.std.Loop(0)", "" }); // Can't loop piped video so we loop it before piping it to ffplay
|
|
|
|
|
|
|
|
|
|
|
|
if(s.Realtime && s.Osd)
|
2023-01-08 02:28:15 +01:00
|
|
|
|
l.Add(GetOsdLines());
|
2022-06-04 12:43:48 +02:00
|
|
|
|
|
2022-05-31 23:47:18 +02:00
|
|
|
|
l.Add($"clip.set_output()"); // Set output
|
2022-06-09 00:30:58 +02:00
|
|
|
|
l.Add("");
|
2022-05-31 22:17:22 +02:00
|
|
|
|
|
2022-06-04 12:43:48 +02:00
|
|
|
|
l.Add($"if os.path.isfile(r'{inputPath}.cache.lwi'):");
|
2023-01-08 02:28:15 +01:00
|
|
|
|
l.Add($" os.remove(r'{inputPath}.cache.lwi')");
|
2022-06-04 12:43:48 +02:00
|
|
|
|
|
2022-05-31 22:17:22 +02:00
|
|
|
|
string pkgPath = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir);
|
|
|
|
|
|
string vpyPath = Path.Combine(pkgPath, "rife.vpy");
|
|
|
|
|
|
|
2022-05-31 23:47:18 +02:00
|
|
|
|
File.WriteAllText(vpyPath, string.Join("\n", l));
|
2022-05-31 22:17:22 +02:00
|
|
|
|
|
|
|
|
|
|
return vpyPath;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-22 05:20:22 +01:00
|
|
|
|
static string GetScaleLines(VsSettings settings, bool loadFrames)
|
2022-06-01 15:46:34 +02:00
|
|
|
|
{
|
2023-01-08 02:28:15 +01:00
|
|
|
|
InterpSettings interp = settings.InterpSettings;
|
|
|
|
|
|
bool resize = !interp.ScaledResolution.IsEmpty && interp.ScaledResolution != interp.InputResolution;
|
|
|
|
|
|
string s = "";
|
2022-06-01 15:46:34 +02:00
|
|
|
|
|
2023-01-08 02:28:15 +01:00
|
|
|
|
s += $"\n";
|
|
|
|
|
|
s += $"cMatrix = '709'\n";
|
|
|
|
|
|
s += $"\n";
|
2022-06-06 07:03:27 +02:00
|
|
|
|
|
2023-12-22 05:20:22 +01:00
|
|
|
|
if (!loadFrames)
|
2022-06-06 07:03:27 +02:00
|
|
|
|
{
|
2023-01-08 02:28:15 +01:00
|
|
|
|
s += "try:\n";
|
|
|
|
|
|
s += " m = clip.get_frame(0).props._Matrix\n";
|
|
|
|
|
|
s += " if m == 0: cMatrix = 'rgb'\n";
|
|
|
|
|
|
s += " elif m == 4: cMatrix = 'fcc'\n";
|
|
|
|
|
|
s += " elif m == 5: cMatrix = '470bg'\n";
|
|
|
|
|
|
s += " elif m == 6: cMatrix = '170m'\n";
|
|
|
|
|
|
s += " elif m == 7: cMatrix = '240m'\n";
|
|
|
|
|
|
s += " elif m == 8: cMatrix = 'ycgco'\n";
|
|
|
|
|
|
s += " elif m == 9: cMatrix = '2020ncl'\n";
|
|
|
|
|
|
s += " elif m == 10: cMatrix = '2020cl'\n";
|
|
|
|
|
|
s += " elif m == 12: cMatrix = 'chromancl'\n";
|
|
|
|
|
|
s += " elif m == 13: cMatrix = 'chromacl'\n";
|
|
|
|
|
|
s += " elif m == 14: cMatrix = 'ictcp'\n";
|
|
|
|
|
|
s += $"except:\n";
|
|
|
|
|
|
s += $" cMatrix = '709'\n";
|
|
|
|
|
|
s += $"\n";
|
|
|
|
|
|
s += $"colRange = 'limited'\n";
|
|
|
|
|
|
s += $"\n";
|
|
|
|
|
|
s += $"try:\n";
|
|
|
|
|
|
s += $" if clip.get_frame(0).props._ColorRange == 0: colRange = 'full'\n";
|
|
|
|
|
|
s += $"except:\n";
|
|
|
|
|
|
s += $" colRange = 'limited'\n";
|
|
|
|
|
|
s += $"\n";
|
2022-06-06 07:03:27 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 02:28:15 +01:00
|
|
|
|
s += $"if clip.format.color_family == vs.YUV:\n";
|
|
|
|
|
|
s += $" clip = core.resize.Bicubic(clip=clip, format=vs.RGBS, matrix_in_s=cMatrix, range_s=colRange{(resize ? $", width={interp.ScaledResolution.Width}, height={interp.ScaledResolution.Height}" : "")})\n";
|
|
|
|
|
|
s += $"\n";
|
|
|
|
|
|
s += $"if clip.format.color_family == vs.RGB:\n";
|
|
|
|
|
|
s += $" clip = core.resize.Bicubic(clip=clip, format=vs.RGBS{(resize ? $", width={interp.ScaledResolution.Width}, height={interp.ScaledResolution.Height}" : "")})\n";
|
|
|
|
|
|
s += $"\n";
|
2022-06-01 15:46:34 +02:00
|
|
|
|
|
2023-01-08 02:28:15 +01:00
|
|
|
|
return s;
|
2022-06-01 15:46:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-09 13:31:02 +01:00
|
|
|
|
static string GetDedupeLines(VsSettings settings)
|
|
|
|
|
|
{
|
|
|
|
|
|
string s = "";
|
|
|
|
|
|
|
|
|
|
|
|
string inputJsonPath = Path.Combine(settings.InterpSettings.tempFolder, "input.json");
|
|
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(inputJsonPath))
|
|
|
|
|
|
return s;
|
|
|
|
|
|
|
|
|
|
|
|
s += "reorderedClip = clip[0]\n";
|
|
|
|
|
|
s += "\n";
|
|
|
|
|
|
s += $"with open(r'{inputJsonPath}') as json_file:\n";
|
|
|
|
|
|
s += " frameList = json.load(json_file)\n";
|
|
|
|
|
|
s += " \n";
|
|
|
|
|
|
s += " for i in frameList:\n";
|
|
|
|
|
|
s += " reorderedClip = reorderedClip + clip[i]\n";
|
|
|
|
|
|
s += "\n";
|
|
|
|
|
|
s += "clip = reorderedClip.std.Trim(1, reorderedClip.num_frames - 1)\n";
|
2024-06-24 11:36:43 +02:00
|
|
|
|
s += Debugger.IsAttached ? "clip = core.text.FrameNum(clip, alignment=4)\n" : "";
|
2024-01-09 13:31:02 +01:00
|
|
|
|
s += "\n";
|
|
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-08 02:28:15 +01:00
|
|
|
|
static string GetRedupeLines(VsSettings settings)
|
2022-05-31 22:17:22 +02:00
|
|
|
|
{
|
2023-01-08 02:28:15 +01:00
|
|
|
|
string s = "";
|
|
|
|
|
|
|
2023-01-08 21:53:32 +01:00
|
|
|
|
s += "reorderedClip = clip[0]\n";
|
2023-01-08 02:28:15 +01:00
|
|
|
|
s += "\n";
|
2023-01-08 02:28:54 +01:00
|
|
|
|
s += $"with open(r'{Path.Combine(settings.InterpSettings.tempFolder, "frames.vs.json")}') as json_file:\n";
|
2023-01-08 02:28:15 +01:00
|
|
|
|
s += " frameList = json.load(json_file)\n";
|
|
|
|
|
|
s += " \n";
|
|
|
|
|
|
s += " for i in frameList:\n";
|
|
|
|
|
|
s += " if(i < clip.num_frames):\n";
|
|
|
|
|
|
s += " reorderedClip = reorderedClip + clip[i]\n";
|
|
|
|
|
|
s += "\n";
|
|
|
|
|
|
s += "clip = reorderedClip.std.Trim(1, reorderedClip.num_frames - 1)\n";
|
2024-06-24 11:36:43 +02:00
|
|
|
|
s += Debugger.IsAttached ? "clip = core.text.FrameNum(clip, alignment=1)\n" : "";
|
2023-01-08 02:28:15 +01:00
|
|
|
|
s += "\n";
|
|
|
|
|
|
|
|
|
|
|
|
return s;
|
2022-05-31 22:17:22 +02:00
|
|
|
|
}
|
2022-06-09 00:30:58 +02:00
|
|
|
|
|
2023-01-08 02:28:15 +01:00
|
|
|
|
static string GetOsdLines()
|
2022-06-09 00:30:58 +02:00
|
|
|
|
{
|
2023-01-08 02:28:15 +01:00
|
|
|
|
string s = "";
|
|
|
|
|
|
|
|
|
|
|
|
s += $"framesProducedPrevious = 0 \n";
|
|
|
|
|
|
s += $"framesProducedCurrent = 0 \n";
|
|
|
|
|
|
s += $"lastFpsUpdateTime = time.time() \n";
|
|
|
|
|
|
s += $"startTime = time.time() \n";
|
|
|
|
|
|
s += $" \n";
|
|
|
|
|
|
s += $"def onFrame(n, clip): \n";
|
|
|
|
|
|
s += $" global startTime \n";
|
|
|
|
|
|
s += $" fpsAvgTime = 1 \n";
|
|
|
|
|
|
s += $" \n";
|
|
|
|
|
|
s += $" if time.time() - startTime > fpsAvgTime: \n";
|
|
|
|
|
|
s += $" global framesProducedPrevious \n";
|
|
|
|
|
|
s += $" global framesProducedCurrent \n";
|
|
|
|
|
|
s += $" global lastFpsUpdateTime \n";
|
|
|
|
|
|
s += $" \n";
|
|
|
|
|
|
s += $" fpsFloat = (clip.fps.numerator / clip.fps.denominator) \n";
|
|
|
|
|
|
s += $" videoTimeFloat = (1 / fpsFloat) * n \n";
|
|
|
|
|
|
s += $" framesProducedCurrent+=1 \n";
|
|
|
|
|
|
s += $" \n";
|
|
|
|
|
|
s += $" if time.time() - lastFpsUpdateTime > fpsAvgTime: \n";
|
|
|
|
|
|
s += $" lastFpsUpdateTime = time.time() \n";
|
|
|
|
|
|
s += $" framesProducedPrevious = framesProducedCurrent / fpsAvgTime \n";
|
|
|
|
|
|
s += $" framesProducedCurrent = 0 \n";
|
|
|
|
|
|
s += $" \n";
|
|
|
|
|
|
s += $" speed = (framesProducedPrevious / fpsFloat) * 100 \n";
|
|
|
|
|
|
s += $" osdString = f\"Time: {{time.strftime(\'%H:%M:%S\', time.gmtime(videoTimeFloat))}} - FPS: {{framesProducedPrevious:.2f}}/{{fpsFloat:.2f}} ({{speed:.0f}}%){{\' [!]\' if speed < 95 else \'\'}}\" \n";
|
|
|
|
|
|
s += $" clip = core.text.Text(clip, text=osdString, alignment=7, scale=1) \n";
|
|
|
|
|
|
s += $" return clip \n";
|
|
|
|
|
|
s += $" \n";
|
|
|
|
|
|
s += $"clip = core.std.FrameEval(clip, functools.partial(onFrame, clip=clip)) \n";
|
|
|
|
|
|
s += $" \n";
|
|
|
|
|
|
|
|
|
|
|
|
return s;
|
2022-06-09 00:30:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static int GetSeekSeconds(long videoLengthSeconds)
|
|
|
|
|
|
{
|
|
|
|
|
|
int seekStep = 10;
|
|
|
|
|
|
|
|
|
|
|
|
if(videoLengthSeconds > 2 * 60) seekStep = 20;
|
|
|
|
|
|
if(videoLengthSeconds > 5 * 60) seekStep = 30;
|
|
|
|
|
|
if(videoLengthSeconds > 15 * 60) seekStep = 60;
|
|
|
|
|
|
|
|
|
|
|
|
return seekStep;
|
|
|
|
|
|
}
|
2022-05-31 22:17:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|