mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-16 16:37:48 +01:00
VS: Color space detection stuff, dedupe/redupe support , GIF support
This commit is contained in:
@@ -116,6 +116,14 @@ namespace Flowframes.Main
|
|||||||
|
|
||||||
File.WriteAllText(framesFile, fileContent);
|
File.WriteAllText(framesFile, fileContent);
|
||||||
File.WriteAllText(framesFile + ".inputframes.json", JsonConvert.SerializeObject(inputFilenames, Formatting.Indented));
|
File.WriteAllText(framesFile + ".inputframes.json", JsonConvert.SerializeObject(inputFilenames, Formatting.Indented));
|
||||||
|
|
||||||
|
string framesFileVs = Path.Combine(framesPath.GetParentDir(), "frames.vs.json");
|
||||||
|
List<int> frameNums = new List<int>();
|
||||||
|
|
||||||
|
foreach (string line in fileContent.SplitIntoLines().Where(x => x.StartsWith("file ")))
|
||||||
|
frameNums.Add(line.Split('/')[1].Split('.')[0].GetInt() - 1); // Convert filename to 0-indexed number
|
||||||
|
|
||||||
|
File.WriteAllText(framesFileVs, JsonConvert.SerializeObject(frameNums, Formatting.Indented));
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrameFileLine
|
class FrameFileLine
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace Flowframes
|
|||||||
Program.mainForm.SetStatus("Starting...");
|
Program.mainForm.SetStatus("Starting...");
|
||||||
sw.Restart();
|
sw.Restart();
|
||||||
|
|
||||||
if (!AutoEncodeResume.resumeNextRun && !(current.ai.Piped && !current.inputIsFrames))
|
if (!AutoEncodeResume.resumeNextRun && !(current.ai.Piped && !current.inputIsFrames && Config.GetInt(Config.Key.dedupMode) == 0))
|
||||||
{
|
{
|
||||||
await GetFrames();
|
await GetFrames();
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
@@ -184,13 +184,15 @@ namespace Flowframes
|
|||||||
{
|
{
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
|
|
||||||
if (!ai.Piped || ai.Piped && current.inputIsFrames)
|
bool dedupe = Config.GetInt(Config.Key.dedupMode) != 0;
|
||||||
|
|
||||||
|
if (!ai.Piped || (ai.Piped && current.inputIsFrames) || (ai.Piped && dedupe))
|
||||||
{
|
{
|
||||||
await Task.Run(async () => { await Dedupe.CreateDupesFile(current.framesFolder, currentInputFrameCount, current.framesExt); });
|
await Task.Run(async () => { await Dedupe.CreateDupesFile(current.framesFolder, currentInputFrameCount, current.framesExt); });
|
||||||
await Task.Run(async () => { await FrameRename.Rename(); });
|
await Task.Run(async () => { await FrameRename.Rename(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ai.Piped)
|
if (!ai.Piped || (ai.Piped && dedupe))
|
||||||
await Task.Run(async () => { await FrameOrder.CreateFrameOrderFile(current.framesFolder, Config.GetBool(Config.Key.enableLoop), current.interpFactor); });
|
await Task.Run(async () => { await FrameOrder.CreateFrameOrderFile(current.framesFolder, Config.GetBool(Config.Key.enableLoop), current.interpFactor); });
|
||||||
|
|
||||||
Program.mainForm.SetStatus("Downloading models...");
|
Program.mainForm.SetStatus("Downloading models...");
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Flowframes.Media
|
|||||||
{
|
{
|
||||||
class FfmpegUtils
|
class FfmpegUtils
|
||||||
{
|
{
|
||||||
public enum Codec { H264, H265, H264Nvenc, H265Nvenc, Av1, Vp9, ProRes, AviRaw }
|
public enum Codec { H264, H265, H264Nvenc, H265Nvenc, Av1, Vp9, ProRes, AviRaw, Gif }
|
||||||
|
|
||||||
|
|
||||||
public static Codec GetCodec(Interpolate.OutMode mode)
|
public static Codec GetCodec(Interpolate.OutMode mode)
|
||||||
@@ -34,6 +34,9 @@ namespace Flowframes.Media
|
|||||||
if (mode == Interpolate.OutMode.VidAvi)
|
if (mode == Interpolate.OutMode.VidAvi)
|
||||||
return Codec.AviRaw;
|
return Codec.AviRaw;
|
||||||
|
|
||||||
|
if (mode == Interpolate.OutMode.VidGif)
|
||||||
|
return Codec.Gif;
|
||||||
|
|
||||||
return Codec.H264;
|
return Codec.H264;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,12 +52,13 @@ namespace Flowframes.Media
|
|||||||
case Codec.Vp9: return "libvpx-vp9";
|
case Codec.Vp9: return "libvpx-vp9";
|
||||||
case Codec.ProRes: return "prores_ks";
|
case Codec.ProRes: return "prores_ks";
|
||||||
case Codec.AviRaw: return Config.Get(Config.Key.aviCodec);
|
case Codec.AviRaw: return Config.Get(Config.Key.aviCodec);
|
||||||
|
case Codec.Gif: return "gif";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "libx264";
|
return "libx264";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string[] GetEncArgs(Codec codec, Size res, float fps) // Array contains as many entries as there are encoding passes
|
public static string[] GetEncArgs(Codec codec, Size res, float fps, bool realtime = false) // Array contains as many entries as there are encoding passes. If "realtime" is true, force single pass.
|
||||||
{
|
{
|
||||||
int keyint = 10;
|
int keyint = 10;
|
||||||
|
|
||||||
@@ -89,7 +93,7 @@ namespace Flowframes.Media
|
|||||||
{
|
{
|
||||||
int cq = Config.GetInt(Config.Key.av1Crf);
|
int cq = Config.GetInt(Config.Key.av1Crf);
|
||||||
string g = GetKeyIntArg(fps, keyint);
|
string g = GetKeyIntArg(fps, keyint);
|
||||||
return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 -qp {cq} {GetKeyIntArg(fps, keyint)} {GetSvtAv1Speed()} {g} -pix_fmt {GetPixFmt()}" };
|
return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 -qp {cq} {GetSvtAv1Speed()} {g} -pix_fmt {GetPixFmt()}" };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec == Codec.Vp9)
|
if (codec == Codec.Vp9)
|
||||||
@@ -98,8 +102,18 @@ namespace Flowframes.Media
|
|||||||
string qualityStr = (crf > 0) ? $"-crf {crf}" : "-lossless 1";
|
string qualityStr = (crf > 0) ? $"-crf {crf}" : "-lossless 1";
|
||||||
string g = GetKeyIntArg(fps, keyint);
|
string g = GetKeyIntArg(fps, keyint);
|
||||||
string t = GetTilingArgs(res, "-tile-columns ", "-tile-rows ");
|
string t = GetTilingArgs(res, "-tile-columns ", "-tile-rows ");
|
||||||
return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1 {g} -pass 1 -pix_fmt {GetPixFmt()} -an",
|
|
||||||
$"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1 {g} -pass 2 -pix_fmt {GetPixFmt()}" };
|
if (realtime) // Force 1-pass
|
||||||
|
{
|
||||||
|
return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1 {g} -pix_fmt {GetPixFmt()}" };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new string[] {
|
||||||
|
$"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1 {g} -pass 1 -pix_fmt {GetPixFmt()} -an",
|
||||||
|
$"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1 {g} -pass 2 -pix_fmt {GetPixFmt()}"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec == Codec.ProRes)
|
if (codec == Codec.ProRes)
|
||||||
@@ -112,6 +126,11 @@ namespace Flowframes.Media
|
|||||||
return new string[] { $"-c:v {GetEnc(codec)} -pix_fmt {Config.Get(Config.Key.aviColors)}" };
|
return new string[] { $"-c:v {GetEnc(codec)} -pix_fmt {Config.Get(Config.Key.aviColors)}" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (codec == Codec.Gif)
|
||||||
|
{
|
||||||
|
return new string[] { $"-c:v {GetEnc(codec)} -gifflags -offsetting" };
|
||||||
|
}
|
||||||
|
|
||||||
return new string[0];
|
return new string[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +312,7 @@ namespace Flowframes.Media
|
|||||||
{
|
{
|
||||||
containerExt = containerExt.Remove(".");
|
containerExt = containerExt.Remove(".");
|
||||||
|
|
||||||
if (containerExt == "mp4") return "mov_text";
|
if (containerExt == "mp4" || containerExt == "mov") return "mov_text";
|
||||||
if (containerExt == "webm") return "webvtt";
|
if (containerExt == "webm") return "webvtt";
|
||||||
|
|
||||||
return "copy"; // Default: Copy subs
|
return "copy"; // Default: Copy subs
|
||||||
@@ -306,7 +325,7 @@ namespace Flowframes.Media
|
|||||||
Logger.Log($"Subtitles {(supported ? "are supported" : "not supported")} by {containerExt.ToUpper()}", true);
|
Logger.Log($"Subtitles {(supported ? "are supported" : "not supported")} by {containerExt.ToUpper()}", true);
|
||||||
|
|
||||||
if (showWarningIfNotSupported && Config.GetBool(Config.Key.keepSubs) && !supported)
|
if (showWarningIfNotSupported && Config.GetBool(Config.Key.keepSubs) && !supported)
|
||||||
Logger.Log($"Warning: Subtitle transfer is enabled, but {containerExt.ToUpper()} does not support subtitles properly. MKV is recommended instead.");
|
Logger.Log($"Warning: {containerExt.ToUpper()} exports do not include subtitles.");
|
||||||
|
|
||||||
return supported;
|
return supported;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -353,16 +353,24 @@ namespace Flowframes.Os
|
|||||||
$"-vf \"drawtext=fontfile='C\\:/WINDOWS/fonts/consola.ttf':text='%{{pts\\:hms}}':x=-7:y=1:fontcolor=white:fontsize=15\"";
|
$"-vf \"drawtext=fontfile='C\\:/WINDOWS/fonts/consola.ttf':text='%{{pts\\:hms}}':x=-7:y=1:fontcolor=white:fontsize=15\"";
|
||||||
|
|
||||||
Interpolate.current.FullOutPath = Path.Combine(Interpolate.current.outPath, await IoUtils.GetCurrentExportFilename(false, true));
|
Interpolate.current.FullOutPath = Path.Combine(Interpolate.current.outPath, await IoUtils.GetCurrentExportFilename(false, true));
|
||||||
string encArgs = FfmpegUtils.GetEncArgs(FfmpegUtils.GetCodec(Interpolate.current.outMode), (Interpolate.current.ScaledResolution.IsEmpty ? Interpolate.current.InputResolution : Interpolate.current.ScaledResolution), Interpolate.current.outFps.GetFloat()).FirstOrDefault();
|
string encArgs = FfmpegUtils.GetEncArgs(FfmpegUtils.GetCodec(Interpolate.current.outMode), (Interpolate.current.ScaledResolution.IsEmpty ? Interpolate.current.InputResolution : Interpolate.current.ScaledResolution), Interpolate.current.outFps.GetFloat(), true).FirstOrDefault();
|
||||||
string ffmpegArgs = rt ? $"{Path.Combine(avDir, "ffplay").Wrap()} {rtArgs} - " : $"{Path.Combine(avDir, "ffmpeg").Wrap()} -y -i pipe: {encArgs} {Interpolate.current.FullOutPath.Wrap()}";
|
string ffmpegArgs = rt ? $"{Path.Combine(avDir, "ffplay").Wrap()} {rtArgs} - " : $"{Path.Combine(avDir, "ffmpeg").Wrap()} -y -i pipe: {encArgs} {Interpolate.current.FullOutPath.Wrap()}";
|
||||||
|
|
||||||
float scn = Config.GetBool(Config.Key.scnDetect) ? Config.GetFloat(Config.Key.scnDetectValue) : 0f;
|
|
||||||
Size res = InterpolateUtils.GetOutputResolution(Interpolate.current.InputResolution, true, true);
|
|
||||||
|
|
||||||
string pkgDir = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir);
|
string pkgDir = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir);
|
||||||
|
|
||||||
VapourSynthUtils.VsSettings vsSettings = new VapourSynthUtils.VsSettings()
|
VapourSynthUtils.VsSettings vsSettings = new VapourSynthUtils.VsSettings()
|
||||||
{ InterpSettings = Interpolate.current, ModelDir = mdl, Factor = factor, Res = res, Uhd = uhd, SceneDetectSensitivity = scn, Loop = Config.GetBool(Config.Key.enableLoop), MatchDuration = Config.GetBool(Config.Key.fixOutputDuration), Realtime = rt };
|
{
|
||||||
|
InterpSettings = Interpolate.current,
|
||||||
|
ModelDir = mdl,
|
||||||
|
Factor = factor,
|
||||||
|
Res = InterpolateUtils.GetOutputResolution(Interpolate.current.InputResolution, true, true),
|
||||||
|
Uhd = uhd,
|
||||||
|
SceneDetectSensitivity = Config.GetBool(Config.Key.scnDetect) ? Config.GetFloat(Config.Key.scnDetectValue) * 0.7f : 0f,
|
||||||
|
Loop = Config.GetBool(Config.Key.enableLoop),
|
||||||
|
MatchDuration = Config.GetBool(Config.Key.fixOutputDuration),
|
||||||
|
Dedupe = Config.GetInt(Config.Key.dedupMode) != 0,
|
||||||
|
Realtime = rt
|
||||||
|
};
|
||||||
|
|
||||||
rifeNcnnVs.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {pkgDir.Wrap()} & vspipe {VapourSynthUtils.CreateScript(vsSettings).Wrap()} -c y4m - | {ffmpegArgs}";
|
rifeNcnnVs.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {pkgDir.Wrap()} & vspipe {VapourSynthUtils.CreateScript(vsSettings).Wrap()} -c y4m - | {ffmpegArgs}";
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace Flowframes.Os
|
|||||||
public bool Tta { get; set; } = false;
|
public bool Tta { get; set; } = false;
|
||||||
public bool Loop { get; set; } = false;
|
public bool Loop { get; set; } = false;
|
||||||
public bool MatchDuration { get; set; } = false;
|
public bool MatchDuration { get; set; } = false;
|
||||||
|
public bool Dedupe { get; set; } = false;
|
||||||
public bool Realtime { get; set; } = false;
|
public bool Realtime { get; set; } = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,9 +40,9 @@ namespace Flowframes.Os
|
|||||||
int targetFrameCountMatchDuration = (Interpolate.currentInputFrameCount * s.Factor).RoundToInt(); // Target frame count to match original duration (and for loops)
|
int targetFrameCountMatchDuration = (Interpolate.currentInputFrameCount * s.Factor).RoundToInt(); // Target frame count to match original duration (and for loops)
|
||||||
int targetFrameCountTrue = targetFrameCountMatchDuration - endDupeCount; // Target frame count without dupes at the end (only in-between frames added)
|
int targetFrameCountTrue = targetFrameCountMatchDuration - endDupeCount; // Target frame count without dupes at the end (only in-between frames added)
|
||||||
|
|
||||||
List<string> l = new List<string> { "import sys", "import os", "import vapoursynth as vs", "core = vs.core", "" }; // Imports
|
List<string> l = new List<string> { "import sys", "import os", "import json", "import vapoursynth as vs", "core = vs.core", "" }; // Imports
|
||||||
|
|
||||||
if (s.InterpSettings.inputIsFrames)
|
if (s.InterpSettings.inputIsFrames || s.Dedupe)
|
||||||
{
|
{
|
||||||
string first = Path.GetFileNameWithoutExtension(IoUtils.GetFileInfosSorted(s.InterpSettings.framesFolder, false).FirstOrDefault().FullName);
|
string first = Path.GetFileNameWithoutExtension(IoUtils.GetFileInfosSorted(s.InterpSettings.framesFolder, false).FirstOrDefault().FullName);
|
||||||
l.Add($"clip = core.imwri.Read(r'{Path.Combine(s.InterpSettings.framesFolder, $"%0{first.Length}d.png")}', firstnum={first.GetInt()})"); // Load image sequence with imwri
|
l.Add($"clip = core.imwri.Read(r'{Path.Combine(s.InterpSettings.framesFolder, $"%0{first.Length}d.png")}', firstnum={first.GetInt()})"); // Load image sequence with imwri
|
||||||
@@ -67,7 +68,11 @@ namespace Flowframes.Os
|
|||||||
l.Add($"clip = core.misc.SCDetect(clip=clip,threshold={s.SceneDetectSensitivity.ToStringDot()})"); // Scene detection
|
l.Add($"clip = core.misc.SCDetect(clip=clip,threshold={s.SceneDetectSensitivity.ToStringDot()})"); // Scene detection
|
||||||
|
|
||||||
l.Add($"clip = core.rife.RIFE(clip, {9}, {s.Factor.ToStringDot()}, {mdlPath}, {s.GpuId}, {s.GpuThreads}, {s.Tta}, {s.Uhd}, {sc})"); // Interpolate
|
l.Add($"clip = core.rife.RIFE(clip, {9}, {s.Factor.ToStringDot()}, {mdlPath}, {s.GpuId}, {s.GpuThreads}, {s.Tta}, {s.Uhd}, {sc})"); // Interpolate
|
||||||
l.Add($"clip = vs.core.resize.Bicubic(clip, format=vs.YUV444P16, matrix_s=\"709\")"); // Convert RGB to YUV
|
|
||||||
|
if (s.Dedupe)
|
||||||
|
l.AddRange(GetRedupeLines(s));
|
||||||
|
|
||||||
|
l.Add($"clip = vs.core.resize.Bicubic(clip, format=vs.YUV444P16, matrix_s=cMatrix)"); // Convert RGB to YUV
|
||||||
|
|
||||||
if (s.Loop)
|
if (s.Loop)
|
||||||
{
|
{
|
||||||
@@ -101,8 +106,31 @@ namespace Flowframes.Os
|
|||||||
List<string> l = new List<string>();
|
List<string> l = new List<string>();
|
||||||
|
|
||||||
l.Add($"");
|
l.Add($"");
|
||||||
|
l.Add($"cMatrix = '709'");
|
||||||
|
l.Add($"");
|
||||||
|
|
||||||
|
if (!s.InterpSettings.inputIsFrames)
|
||||||
|
{
|
||||||
|
l.Add("try:");
|
||||||
|
l.Add("\tm = clip.get_frame(0).props._Matrix");
|
||||||
|
l.Add("\tif m == 0: cMatrix = 'rgb'");
|
||||||
|
l.Add("\telif m == 4: cMatrix = 'fcc'");
|
||||||
|
l.Add("\telif m == 5: cMatrix = '470bg'");
|
||||||
|
l.Add("\telif m == 6: cMatrix = '170m'");
|
||||||
|
l.Add("\telif m == 7: cMatrix = '240m'");
|
||||||
|
l.Add("\telif m == 8: cMatrix = 'ycgco'");
|
||||||
|
l.Add("\telif m == 9: cMatrix = '2020ncl'");
|
||||||
|
l.Add("\telif m == 10: cMatrix = '2020cl'");
|
||||||
|
l.Add("\telif m == 12: cMatrix = 'chromancl'");
|
||||||
|
l.Add("\telif m == 13: cMatrix = 'chromacl'");
|
||||||
|
l.Add("\telif m == 14: cMatrix = 'ictcp'");
|
||||||
|
l.Add($"except:");
|
||||||
|
l.Add($"\tcMatrix = '709'");
|
||||||
|
l.Add($"");
|
||||||
|
}
|
||||||
|
|
||||||
l.Add($"if clip.format.color_family == vs.YUV:");
|
l.Add($"if clip.format.color_family == vs.YUV:");
|
||||||
l.Add($"\tclip = core.resize.Bicubic(clip=clip, format=vs.RGBS, matrix_in_s=\"709\", range_s=\"limited\"{(resize ? $", width={s.InterpSettings.ScaledResolution.Width}, height={s.InterpSettings.ScaledResolution.Height}" : "")})");
|
l.Add($"\tclip = core.resize.Bicubic(clip=clip, format=vs.RGBS, matrix_in_s=cMatrix, range_s=('full' if clip.get_frame(0).props._ColorRange == 2 else 'limited'){(resize ? $", width={s.InterpSettings.ScaledResolution.Width}, height={s.InterpSettings.ScaledResolution.Height}" : "")})");
|
||||||
l.Add($"");
|
l.Add($"");
|
||||||
l.Add($"if clip.format.color_family == vs.RGB:");
|
l.Add($"if clip.format.color_family == vs.RGB:");
|
||||||
l.Add($"\tclip = core.resize.Bicubic(clip=clip, format=vs.RGBS{(resize ? $", width={s.InterpSettings.ScaledResolution.Width}, height={s.InterpSettings.ScaledResolution.Height}" : "")})");
|
l.Add($"\tclip = core.resize.Bicubic(clip=clip, format=vs.RGBS{(resize ? $", width={s.InterpSettings.ScaledResolution.Width}, height={s.InterpSettings.ScaledResolution.Height}" : "")})");
|
||||||
@@ -111,23 +139,23 @@ namespace Flowframes.Os
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetModelNum(string modelDir)
|
static List<string> GetRedupeLines(VsSettings s)
|
||||||
{
|
{
|
||||||
switch (modelDir)
|
List<string> l = new List<string>();
|
||||||
{
|
|
||||||
case "rife": return 0;
|
|
||||||
case "rife-HD": return 1;
|
|
||||||
case "rife-UHD": return 2;
|
|
||||||
case "rife-anime": return 3;
|
|
||||||
case "rife-v2": return 4;
|
|
||||||
case "rife-v2.3": return 5;
|
|
||||||
case "rife-v2.4": return 6;
|
|
||||||
case "rife-v3.0": return 7;
|
|
||||||
case "rife-v3.1": return 8;
|
|
||||||
case "rife-v4": return 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 9;
|
l.Add(@"reorderedClip = clip[0]");
|
||||||
|
l.Add("");
|
||||||
|
l.Add($"with open(r'{Path.Combine(s.InterpSettings.tempFolder, "frames.vs.json")}') as json_file:");
|
||||||
|
l.Add("\tframeList = json.load(json_file)");
|
||||||
|
l.Add("\t");
|
||||||
|
l.Add("\tfor i in frameList:");
|
||||||
|
l.Add("\t\tif(i < clip.num_frames):");
|
||||||
|
l.Add("\t\t\treorderedClip = reorderedClip + clip[i]");
|
||||||
|
l.Add("");
|
||||||
|
l.Add("clip = reorderedClip.std.Trim(1, reorderedClip.num_frames - 1)");
|
||||||
|
l.Add("");
|
||||||
|
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user