From 7afa2f7a7949dd80ce26799239e41ece9dfa9620 Mon Sep 17 00:00:00 2001 From: Frank Skare Date: Wed, 6 May 2020 09:21:44 +0200 Subject: [PATCH] portable support added --- Changelog.md | 14 +-- Controls/SubtitleControl.vb | 2 +- Encoding/VideoEncoder.vb | 2 +- Encoding/x264Enc.vb | 51 ++++++---- Encoding/x265Enc.vb | 32 ++++-- Forms/HelpForm.vb | 2 +- Forms/MainForm.vb | 67 +++++++------ Forms/VideoComparisonForm.vb | 6 +- General/AudioProfile.vb | 4 +- General/Documentation.vb | 4 +- General/Extensions.vb | 161 ++++++++++++++++++++++++++----- General/FrameServer.vb | 9 +- General/General.vb | 182 +---------------------------------- General/GlobalClass.vb | 122 ++++++++++++++++++++--- General/GlobalCommands.vb | 5 - General/Help.vb | 1 + General/Misc.vb | 10 +- General/Package.vb | 181 ++++++++++++++-------------------- General/Project.vb | 4 +- General/VideoScript.vb | 2 +- UI/ImageUtils.vb | 2 +- 21 files changed, 443 insertions(+), 420 deletions(-) diff --git a/Changelog.md b/Changelog.md index 970944ac..05ff02cd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,21 +1,21 @@ -todo: feature list doc page vs avs portable +todo: feature list doc page avisynth vapoursynth portable 2.1.1.1 Beta (not yet available) ============ -- the command line audio encoder uses cmd.exe directly without creating a bat file, - this avoids creating a temporary bat file and adds full unicode support +- mpv.net 5.4.6.0 - MediaInfo.NET 6.3.0.0 - fix invalid nvenc command line generation (Patman86) - fix crash doing multi select drag operation in jobs dialog -- x265 preset fix (Dendraspis) - fix taskbar indication of values below 1 (Dendraspis) -- AviSynth and VapourSynth portable mode support added, many tools - don't support portable mode, only tool authors can fix it +- fix showing the Apps dialog for a tool with non OK status in endless loop +- fix x265 preset (Dendraspis) +- the command line audio encoder uses cmd.exe directly without creating a bat file, + this avoids creating a temporary bat file and adds full unicode support +- portable support added and enabled by default, no need to install anything - nvenc --vpp-transform -- mpv.net 5.4.6.0 2.1.0.9 Beta diff --git a/Controls/SubtitleControl.vb b/Controls/SubtitleControl.vb index 3b67687a..d2d0ac83 100644 --- a/Controls/SubtitleControl.vb +++ b/Controls/SubtitleControl.vb @@ -400,7 +400,7 @@ Public Class SubtitleControl item.ID = id item.TypeName = i.TypeName item.Size = size - item.Filename = FilePath.GetName(i.Path) + item.Filename = i.Path.FileName item.Subtitle = i Items.Add(item) diff --git a/Encoding/VideoEncoder.vb b/Encoding/VideoEncoder.vb index c0fb5b6c..cb546444 100644 --- a/Encoding/VideoEncoder.vb +++ b/Encoding/VideoEncoder.vb @@ -699,7 +699,7 @@ Public Class NullEncoder Dim sourceFile = GetSourceFile() If Not p.VideoEncoder.Muxer.IsSupported(sourceFile.Ext) Then - Select Case FilePath.GetExt(sourceFile) + Select Case sourceFile.Ext Case "mkv" mkvDemuxer.Demux(sourceFile, Nothing, Nothing, Nothing, p, False, True) End Select diff --git a/Encoding/x264Enc.vb b/Encoding/x264Enc.vb index 2ce8ef99..938a5c7f 100644 --- a/Encoding/x264Enc.vb +++ b/Encoding/x264Enc.vb @@ -511,10 +511,19 @@ Public Class x264Params .Switch = "--slow-firstpass", .Text = "Slow Firstpass"} - Property PipingTool As New OptionParam With { + Property PipingToolAVS As New OptionParam With { .Text = "Piping Tool", - .Options = {"Automatic", "None", "vspipe", "avs2pipemod", "ffmpeg"}, - .Values = {"auto", "none", "vspipe", "avs2pipemod", "ffmpeg"}} + .Name = "PipingToolAVS", + .VisibleFunc = Function() p.Script.Engine = ScriptEngine.AviSynth, + .Options = {"Automatic", "None", "avs2pipemod", "ffmpeg"}, + .Values = {"auto", "none", "avs2pipemod", "ffmpeg"}} + + Property PipingToolVS As New OptionParam With { + .Text = "Piping Tool", + .Name = "PipingToolVS", + .VisibleFunc = Function() p.Script.Engine = ScriptEngine.VapourSynth, + .Options = {"Automatic", "None", "vspipe", "ffmpeg"}, + .Values = {"auto", "none", "vspipe", "ffmpeg"}} Sub ApplyValues(isDefault As Boolean) Dim setVal = Sub(param As CommandLineParam, value As Object) @@ -876,7 +885,8 @@ Public Class x264Params New BoolParam With {.Switch = "--dts-compress", .Text = "Eliminate initial delay with container DTS hack"}) Add("Other", New StringParam With {.Switch = "--video-filter", .Switches = {"--vf"}, .Text = "Video Filter"}, - PipingTool, + PipingToolAVS, + PipingToolVS, New OptionParam With {.Switches = {"--tff", "--bff"}, .Text = "Interlaced", .Options = {"Progressive ", "Top Field First", "Bottom Field First"}, .Values = {"", "--tff", "--bff"}}, New OptionParam With {.Switch = "--frame-packing", .Text = "Frame Packing", .IntegerValue = True, .Options = {"Checkerboard", "Column Alternation", "Row Alternation", "Side By Side", "Top Bottom", "Frame Alternation", "Mono", "Tile Format"}}, Deblock, @@ -942,37 +952,39 @@ Public Class x264Params p.VideoEncoder.OutputExtFull, includePaths, includeExecutable) End Function - Overloads Function GetArgs(pass As Integer, - script As VideoScript, - targetPath As String, - includePaths As Boolean, - includeExecutable As Boolean) As String + Overloads Function GetArgs( + pass As Integer, + script As VideoScript, + targetPath As String, + includePaths As Boolean, + includeExecutable As Boolean) As String + ApplyValues(True) Dim args As String If includePaths AndAlso includeExecutable Then - Dim pipeString = "" - Dim pipeTool = PipingTool.ValueText + Dim pipeCmd = "" + Dim pipeTool = If(p.Script.Engine = ScriptEngine.AviSynth, PipingToolAVS, PipingToolVS).ValueText If pipeTool = "auto" Then - If p.Script.Engine = ScriptEngine.VapourSynth Then - pipeTool = "vspipe" - Else + If p.Script.Engine = ScriptEngine.AviSynth Then pipeTool = "avs2pipemod" + Else + pipeTool = "vspipe" End If End If Select Case pipeTool Case "vspipe" - pipeString = Package.vspipe.Path.Escape + " " + script.Path.Escape + " - --y4m | " + pipeCmd = Package.vspipe.Path.Escape + " " + script.Path.Escape + " - --y4m | " Case "avs2pipemod" - pipeString = Package.avs2pipemod.Path.Escape + " -y4mp " + script.Path.Escape + " | " + pipeCmd = Package.avs2pipemod.Path.Escape + " -y4mp " + script.Path.Escape + " | " Case "ffmpeg" - pipeString = Package.ffmpeg.Path.Escape + " -i " + script.Path.Escape + " -f yuv4mpegpipe -strict -1 -loglevel fatal -hide_banner - | " + pipeCmd = Package.ffmpeg.Path.Escape + " -i " + script.Path.Escape + " -f yuv4mpegpipe -strict -1 -loglevel fatal -hide_banner - | " End Select - args += pipeString + Package.x264.Path.Escape + args += pipeCmd + Package.x264.Path.Escape End If If Mode.Value = x264RateMode.TwoPass OrElse Mode.Value = x264RateMode.ThreePass Then @@ -1010,7 +1022,8 @@ Public Class x264Params End If If includePaths Then - Dim input = If(PipingTool.ValueText = "none", script.Path.Escape, "-") + Dim pipeTool = If(p.Script.Engine = ScriptEngine.AviSynth, PipingToolAVS, PipingToolVS) + Dim input = If(pipeTool.ValueText = "none", script.Path.Escape, "-") If input = "-" Then args += " --demuxer y4m --frames " & script.GetFrameCount diff --git a/Encoding/x265Enc.vb b/Encoding/x265Enc.vb index f37d16e3..5a0da59d 100644 --- a/Encoding/x265Enc.vb +++ b/Encoding/x265Enc.vb @@ -212,10 +212,19 @@ Public Class x265Params .Options = {"AviSynth/VapourSynth", "QSVEnc (Intel)", "ffmpeg (Intel)", "ffmpeg (DXVA2)"}, .Values = {"script", "qs", "ffqsv", "ffdxva"}} - Property PipingTool As New OptionParam With { + Property PipingToolAVS As New OptionParam With { .Text = "Piping Tool", - .Options = {"Automatic", "None", "vspipe", "avs2pipemod", "ffmpeg"}, - .Values = {"auto", "none", "vspipe", "avs2pipemod", "ffmpeg"}} + .Name = "PipingToolAVS", + .VisibleFunc = Function() p.Script.Engine = ScriptEngine.AviSynth, + .Options = {"Automatic", "None", "avs2pipemod", "ffmpeg"}, + .Values = {"auto", "none", "avs2pipemod", "ffmpeg"}} + + Property PipingToolVS As New OptionParam With { + .Text = "Piping Tool", + .Name = "PipingToolVS", + .VisibleFunc = Function() p.Script.Engine = ScriptEngine.VapourSynth, + .Options = {"Automatic", "None", "vspipe", "ffmpeg"}, + .Values = {"auto", "none", "vspipe", "ffmpeg"}} Property Quant As New NumParam With { .Switches = {"--crf", "--qp", "-q"}, @@ -965,7 +974,7 @@ Public Class x265Params New StringParam With {.Switch = "--abr-ladder", .Text = "ABR Ladder File", .BrowseFile = True}, New StringParam With {.Switch = "--scaling-list", .Text = "Scaling List"}, New OptionParam With {.Switch = "--high-tier", .NoSwitch = "--no-high-tier", .Text = "High Tier", .Options = {"Undefined", "Yes", "No"}, .Values = {"", "--high-tier", "--no-high-tier"}}, - Decoder, PipingTool, PsyRD, CompCheck, CompCheckAimedQuality, + Decoder, PipingToolAVS, PipingToolVS, PsyRD, CompCheck, CompCheckAimedQuality, New NumParam With {.Switch = "--recon-depth", .Text = "Recon Depth"}, RDpenalty, MaxAuSizeFactor) Add("Other 2", @@ -1045,13 +1054,13 @@ Public Class x265Params Select Case Decoder.ValueText Case "script" Dim pipeString = "" - Dim pipeTool = PipingTool.ValueText + Dim pipeTool = If(p.Script.Engine = ScriptEngine.AviSynth, PipingToolAVS, PipingToolVS).ValueText If pipeTool = "auto" Then - If p.Script.Engine = ScriptEngine.VapourSynth Then - pipeTool = "vspipe" - Else + If p.Script.Engine = ScriptEngine.AviSynth Then pipeTool = "avs2pipemod" + Else + pipeTool = "vspipe" End If End If @@ -1116,7 +1125,9 @@ Public Class x265Params End If If includePaths Then - If PipingTool.ValueText <> "none" Then + Dim pipingTool = If(p.Script.Engine = ScriptEngine.AviSynth, PipingToolAVS, PipingToolVS) + + If pipingTool.ValueText <> "none" Then If Frames.Value = 0 AndAlso Not IsCustom(pass, "--frames") Then sb.Append(" --frames " & script.GetFrameCount) End If @@ -1128,7 +1139,8 @@ Public Class x265Params sb.Append(" --stats " + (p.TempDir + p.TargetFile.Base + ".stats").Escape) End If - Dim input = If(PipingTool.ValueText = "none", script.Path.Escape, "-") + Dim pipeTool = If(p.Script.Engine = ScriptEngine.AviSynth, PipingToolAVS, PipingToolVS) + Dim input = If(pipeTool.ValueText = "none", script.Path.Escape, "-") If (Mode.Value = x265RateMode.ThreePass AndAlso pass < 3) OrElse Mode.Value = x265RateMode.TwoPass AndAlso pass = 1 Then diff --git a/Forms/HelpForm.vb b/Forms/HelpForm.vb index 6375affa..16f85090 100644 --- a/Forms/HelpForm.vb +++ b/Forms/HelpForm.vb @@ -99,7 +99,7 @@ Public Class HelpForm If Browser.DocumentTitle <> "" Then Text = Browser.DocumentTitle ElseIf File.Exists(e.Url.LocalPath) Then - Text = FilePath.GetBase(e.Url.LocalPath) + Text = e.Url.LocalPath.Base End If End Sub diff --git a/Forms/MainForm.vb b/Forms/MainForm.vb index 8d76e0c9..3608bad1 100644 --- a/Forms/MainForm.vb +++ b/Forms/MainForm.vb @@ -1215,10 +1215,17 @@ Public Class MainForm End Sub Function GetIfoFile() As String - Dim ret = FilePath.GetDir(p.SourceFile) - If ret.EndsWith("_temp\") Then ret = DirPath.GetParent(ret) - ret = ret + FilePath.GetName(p.SourceFile).DeleteRight(5) + "0.ifo" - If File.Exists(ret) Then Return ret + Dim ret = p.SourceFile.Dir + + If ret.EndsWith("_temp\") Then + ret = ret.Parent + End If + + ret = ret + p.SourceFile.FileName.DeleteRight(5) + "0.ifo" + + If File.Exists(ret) Then + Return ret + End If End Function Sub RenameDVDTracks() @@ -1238,7 +1245,7 @@ Public Class MainForm For x = 0 To mi.AudioStreams.Count - 1 If mi.GetAudio(x, "ID/String").Contains(" (0x" & dgID & ")") Then Dim stream = mi.AudioStreams(x) - Dim base = FilePath.GetBase(i) + Dim base = i.Base base = regex.Replace(base, " ID" & x & " ") If base.Contains("2_0ch") Then base = base.Replace("2_0ch", "2ch") @@ -1285,7 +1292,7 @@ Public Class MainForm If track = 0 AndAlso iPath.Base = p.Audio1.File.Base Then Continue For If tbOther.Text = iPath Then Continue For - If Not FilePath.GetExt(iPath) = iExt Then Continue For + If Not iPath.Ext = iExt Then Continue For If iPath.Contains("_cut_") Then Continue For If iPath.Contains("_out") Then Continue For If Not g.IsSourceSame(iPath) Then Continue For @@ -1305,7 +1312,7 @@ Public Class MainForm If Not iPath.Contains(lng.Name) Then Continue For End If - If iPath.Ext = "mp4" AndAlso FilePath.IsSameBase(p.SourceFile, iPath) Then + If iPath.Ext = "mp4" AndAlso p.SourceFile.IsSameBase(iPath) Then Continue For End If @@ -1786,7 +1793,7 @@ Public Class MainForm End If For Each i In files - Dim name = FilePath.GetName(i) + Dim name = i.FileName If name.ToUpper Like "VTS_0#_0.VOB" Then If MsgQuestion("Are you sure you want to open the file " + name + "," + BR + @@ -1947,10 +1954,16 @@ Public Class MainForm End If End If - If Not Directory.Exists(targetDir) Then targetDir = p.SourceFile.Dir + If Not Directory.Exists(targetDir) Then + targetDir = p.SourceFile.Dir + End If + Dim targetName = Macro.Expand(p.DefaultTargetName) - If Not FilePath.IsValidFileSystemName(targetName) Then targetName = p.SourceFile.Base + If Not targetName.IsValidFileSystemName Then + targetName = p.SourceFile.Base + End If + tbTargetFile.Text = targetDir + targetName + p.VideoEncoder.Muxer.OutputExtFull If p.SourceFile = p.TargetFile OrElse @@ -1980,7 +1993,7 @@ Public Class MainForm Demux() If p.LastOriginalSourceFile <> p.SourceFile AndAlso - Not FileTypes.VideoText.Contains(FilePath.GetExt(p.SourceFile)) Then + Not FileTypes.VideoText.Contains(p.SourceFile.Ext) Then p.LastOriginalSourceFile = p.SourceFile End If @@ -2009,7 +2022,7 @@ Public Class MainForm RenameDVDTracks() - If FileTypes.VideoAudio.Contains(FilePath.GetExt(p.LastOriginalSourceFile)) Then + If FileTypes.VideoAudio.Contains(p.LastOriginalSourceFile.Ext) Then p.Audio0.Streams = MediaInfo.GetAudioStreams(p.LastOriginalSourceFile) p.Audio1.Streams = p.Audio0.Streams End If @@ -2094,7 +2107,7 @@ Public Class MainForm Else If p.Audio0.File = "" AndAlso p.Audio1.File = "" Then If Not TypeOf p.Audio0 Is NullAudioProfile AndAlso - Not FileTypes.VideoText.Contains(FilePath.GetExt(p.LastOriginalSourceFile)) Then + Not FileTypes.VideoText.Contains(p.LastOriginalSourceFile.Ext) Then tbAudioFile0.Text = p.LastOriginalSourceFile If p.Audio0.Streams.Count = 0 Then tbAudioFile0.Text = "" @@ -2111,7 +2124,7 @@ Public Class MainForm If p.Audio0.Stream.StreamOrder = p.Audio1.Stream.StreamOrder Then For Each i2 In p.Audio1.Streams If i2.StreamOrder <> p.Audio1.Stream.StreamOrder Then - tbAudioFile1.Text = i2.Name + " (" + FilePath.GetExt(p.Audio1.File) + ")" + tbAudioFile1.Text = i2.Name + " (" + p.Audio1.File.Ext + ")" p.Audio1.Stream = i2 UpdateSizeOrBitrate() Exit For @@ -2222,7 +2235,7 @@ Public Class MainForm For Each i In iPref Dim name = i.Name.SplitNoEmptyAndWhiteSpace({",", " "}) - If name.Contains(FilePath.GetExt(p.SourceFile)) Then + If name.Contains(p.SourceFile.Ext) Then Dim filters = scriptingProfiles.Where( Function(v) v.Name = "Source").First.Filters.Where( Function(v) v.Name = i.Value) @@ -2363,7 +2376,7 @@ Public Class MainForm Using proc As New Proc proc.Header = "Extract forced subtitles if existing" proc.SkipString = "# " - proc.WriteLog(FilePath.GetName(path) + BR2) + proc.WriteLog(path.FileName + BR2) proc.File = Package.BDSup2SubPP.Path proc.Arguments = "--forced-only -o " + (path.DirAndBase + "_forced.idx").Escape + " " + path.Escape proc.AllowedExitCodes = {} @@ -2374,7 +2387,7 @@ Public Class MainForm End Sub Sub DemuxVobSubSubtitles() - If Not {"vob", "m2v"}.Contains(FilePath.GetExt(p.LastOriginalSourceFile)) Then Exit Sub + If Not {"vob", "m2v"}.Contains(p.LastOriginalSourceFile.Ext) Then Exit Sub Dim ifoPath = GetIfoFile() If ifoPath = "" Then Exit Sub If File.Exists(p.TempDir + p.SourceFile.Base + ".idx") Then Exit Sub @@ -2793,7 +2806,7 @@ Public Class MainForm End If If File.Exists(p.TargetFile) Then - If FileTypes.VideoText.Contains(FilePath.GetExt(p.SourceFile)) AndAlso + If FileTypes.VideoText.Contains(p.SourceFile.Ext) AndAlso p.SourceFile.ReadAllText.Contains(p.TargetFile) Then If ProcessTip("Source and target name are identical, please select another target name.") Then @@ -2928,7 +2941,7 @@ Public Class MainForm End Function Private Sub OpenTargetFolder() - g.ShellExecute(FilePath.GetDir(p.TargetFile)) + g.ShellExecute(p.TargetFile.Dir) End Sub Dim BlockAudioTextChanged As Boolean @@ -3185,7 +3198,7 @@ Public Class MainForm End If If Not File.Exists(p.SourceFile + ".lwi") AndAlso Not File.Exists(p.TempDir + p.SourceFile.Base + ".lwi") AndAlso - File.Exists(p.Script.Path) AndAlso Not FileTypes.VideoText.Contains(FilePath.GetExt(p.SourceFile)) Then + File.Exists(p.Script.Path) AndAlso Not FileTypes.VideoText.Contains(p.SourceFile.Ext) Then Using proc As New Proc proc.Header = "Index LWLibav" @@ -3258,7 +3271,7 @@ Public Class MainForm td.MainInstruction = "Please select a template" For Each i In Directory.GetFiles(Folder.Template, "*.srip") - td.AddCommand(FilePath.GetBase(i), i) + td.AddCommand(i.Base, i) Next If td.Show <> "" Then @@ -4865,7 +4878,7 @@ Public Class MainForm If form.ShowDialog() = DialogResult.OK AndAlso form.lb.Items.Count > 0 Then Dim files = form.GetFiles - Select Case FilePath.GetExt(files(0)) + Select Case files(0).Ext Case "mpg", "vob" OpenVideoSourceFiles(files) Case Else @@ -4990,7 +5003,7 @@ Public Class MainForm workDir += title End If - If Not DirPath.IsFixedDrive(workDir) Then + If Not g.IsFixedDrive(workDir) Then Using d As New FolderBrowserDialog d.Description = "Please select a folder for temporary files on a fixed local drive." d.SetSelectedPath(s.Storage.GetString("last blu-ray target folder").Parent) @@ -5015,7 +5028,7 @@ Public Class MainForm End Try End If - If Not DirPath.IsFixedDrive(form.OutputFolder) Then + If Not g.IsFixedDrive(form.OutputFolder) Then MsgError("Only fixed local drives are supported as temp dir.") Exit Sub End If @@ -5513,9 +5526,9 @@ Public Class MainForm Dim temp = i If audioFiles.Count > 10 Then - m.Add("Files | " + FilePath.GetName(i), Sub() tb.Text = temp) + m.Add("Files | " + i.FileName, Sub() tb.Text = temp) Else - m.Add(FilePath.GetName(i), Sub() tb.Text = temp) + m.Add(i.FileName, Sub() tb.Text = temp) End If Next @@ -5561,7 +5574,7 @@ Public Class MainForm Sub UpdateSourceFileMenu() SourceFileMenu.Items.ClearAndDisplose - Dim isIndex = FileTypes.VideoIndex.Contains(FilePath.GetExt(p.LastOriginalSourceFile)) + Dim isIndex = FileTypes.VideoIndex.Contains(p.LastOriginalSourceFile.Ext) SourceFileMenu.Add("Open...", AddressOf ShowOpenSourceDialog, "Open source files").SetImage(Symbol.OpenFile) SourceFileMenu.Add("Play", Sub() g.Play(p.LastOriginalSourceFile), File.Exists(p.LastOriginalSourceFile) AndAlso Not isIndex, "Play the source file.").SetImage(Symbol.Play) diff --git a/Forms/VideoComparisonForm.vb b/Forms/VideoComparisonForm.vb index f3191eeb..0366c0a6 100644 --- a/Forms/VideoComparisonForm.vb +++ b/Forms/VideoComparisonForm.vb @@ -53,7 +53,7 @@ Public Class VideoComparisonForm dialog.SetInitDir(s.Storage.GetString("video comparison folder")) If dialog.ShowDialog() = DialogResult.OK Then - s.Storage.SetString("video comparison folder", FilePath.GetDir(dialog.FileName)) + s.Storage.SetString("video comparison folder", dialog.FileName.Dir) For Each i In dialog.FileNames Add(i) @@ -243,7 +243,7 @@ Public Class VideoComparisonForm End Sub Function Open(sourePath As String) As Boolean - Text = FilePath.GetBase(sourePath) + Text = sourePath.Base SourceFile = sourePath Dim script As New VideoScript @@ -361,7 +361,7 @@ Public Class VideoComparisonForm Using g = Graphics.FromImage(ret) g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias - Dim text = FilePath.GetBase(SourceFile) + Dim text = SourceFile.Base Dim fontSize = ret.Height \ 100 If fontSize < 10 Then diff --git a/General/AudioProfile.vb b/General/AudioProfile.vb index 4e9b7229..5cd0d72e 100644 --- a/General/AudioProfile.vb +++ b/General/AudioProfile.vb @@ -101,7 +101,7 @@ Public MustInherit Class AudioProfile ret = File.FileName End If Else - ret = Stream.Name + " (" + FilePath.GetExt(File) + ")" + ret = Stream.Name + " (" + File.Ext + ")" End If Return ret @@ -198,7 +198,7 @@ Public MustInherit Class AudioProfile If File.Base = p.SourceFile.Base Then Return name + " (" + File.Ext + ")" Else - Return name + " (" + FilePath.GetName(File) + ")" + Return name + " (" + File.FileName + ")" End If End Function diff --git a/General/Documentation.vb b/General/Documentation.vb index 540d076c..40104a02 100644 --- a/General/Documentation.vb +++ b/General/Documentation.vb @@ -58,7 +58,7 @@ Public Class Documentation Dim nameAttrib = param.GetCustomAttribute(Of DispNameAttribute) If Not nameAttrib Is Nothing AndAlso - Not nameAttrib.DisplayName.EqualIgnoreCase(param.Name) Then + Not nameAttrib.DisplayName.IsEqualIgnoreCase(param.Name) Then hasDescription = True End If @@ -74,7 +74,7 @@ Public Class Documentation Dim hasName = False If Not nameAttrib Is Nothing AndAlso - Not nameAttrib.DisplayName.EqualIgnoreCase(param.Name) Then + Not nameAttrib.DisplayName.IsEqualIgnoreCase(param.Name) Then sb.Append(nameAttrib.DisplayName) hasName = True End If diff --git a/General/Extensions.vb b/General/Extensions.vb index 536d1474..37d06627 100644 --- a/General/Extensions.vb +++ b/General/Extensions.vb @@ -11,6 +11,36 @@ Imports Microsoft.Win32 Imports VB6 = Microsoft.VisualBasic Module StringExtensions + Private Separator As Char = Path.DirectorySeparatorChar + + + Function TrimTrailingSeparator(instance As String) As String + If instance = "" Then + Return "" + End If + + If instance.EndsWith(Separator) AndAlso Not instance.Length <= 3 Then + Return instance.TrimEnd(Separator) + End If + + Return instance + End Function + + + Function Parent(path As String) As String + If path = "" Then + Return "" + End If + + Dim temp = TrimTrailingSeparator(path) + + If temp.Contains(Separator) Then + path = temp.LeftLast(Separator) + Separator + End If + + Return path + End Function + Function IndentLines(instance As String, value As String) As String If instance = "" Then @@ -130,11 +160,6 @@ Module StringExtensions Return instance End Function - - Function Parent(instance As String) As String - Return DirPath.GetParent(instance) - End Function - Function ExistingParent(instance As String) As String Dim ret = instance.Parent @@ -146,11 +171,6 @@ Module StringExtensions Return ret End Function - - Function Ext(instance As String) As String - Return FilePath.GetExt(instance) - End Function - Function FileExists(instance As String) As Boolean Return File.Exists(instance) @@ -161,29 +181,92 @@ Module StringExtensions Return Directory.Exists(instance) End Function + + Function Ext(instance As String) As String + Return GetExt(instance, False) + End Function + Function ExtFull(instance As String) As String - Return FilePath.GetExtFull(instance) + Return GetExt(instance, True) + End Function + + Function GetExt(filepath As String, includeDot As Boolean) As String + If filepath = "" Then + Return "" + End If + + Dim chars = filepath.ToCharArray() + + For x = filepath.Length - 1 To 0 Step -1 + If chars(x) = Separator Then + Return "" + End If + + If chars(x) = "."c Then + Return filepath.Substring(x + If(includeDot, 0, 1)).ToLower() + End If + Next + + Return "" End Function Function Base(instance As String) As String - Return FilePath.GetBase(instance) + If instance = "" Then + Return "" + End If + + Dim ret = instance + + If ret.Contains(Separator) Then + ret = ret.RightLast(Separator) + End If + + If ret.Contains(".") Then + ret = ret.LeftLast(".") + End If + + Return ret End Function Function Dir(instance As String) As String - Return FilePath.GetDir(instance) + If instance = "" Then + Return "" + End If + + If instance.Contains("\") Then + instance = instance.LeftLast("\") + "\" + End If + + Return instance + End Function + + + Function DirNoSep(instance As String) As String + instance = instance.Dir + + If instance.EndsWith(Separator) Then + instance = instance.TrimTrailingSeparator + End If + + Return instance End Function Function DirName(instance As String) As String - Return DirPath.GetName(instance) + If instance = "" Then + Return "" + End If + + instance = TrimTrailingSeparator(instance) + Return instance.RightLast(Separator) End Function - Function DirAndBase(instance As String) As String - Return FilePath.GetDirAndBase(instance) + Function DirAndBase(path As String) As String + Return path.Dir + path.Base End Function @@ -208,15 +291,15 @@ Module StringExtensions Return "" End If - While instance.EndsWith(DirPath.Separator + DirPath.Separator) + While instance.EndsWith(Separator + Separator) instance = instance.Substring(0, instance.Length - 1) End While - If instance.EndsWith(DirPath.Separator) Then + If instance.EndsWith(Separator) Then Return instance End If - Return instance + DirPath.Separator + Return instance + Separator End Function @@ -401,13 +484,19 @@ Module StringExtensions Function RightLast(value As String, start As String) As String - If value = "" OrElse start = "" Then Return "" - If Not value.Contains(start) Then Return "" + If value = "" OrElse start = "" Then + Return "" + End If + + If Not value.Contains(start) Then + Return "" + End If + Return value.Substring(value.LastIndexOf(start) + start.Length) End Function - Function EqualIgnoreCase(value1 As String, value2 As String) As Boolean + Function IsEqualIgnoreCase(value1 As String, value2 As String) As Boolean Return String.Compare(value1, value2, StringComparison.OrdinalIgnoreCase) = 0 End Function @@ -420,12 +509,38 @@ Module StringExtensions Return value.Substring(0, maxLength) End Function + + Function IsValidFileSystemName(instance As String) As Boolean + If instance = "" Then + Return False + End If + + Dim chars = """*/:<>?\|^".ToCharArray + + For Each i In instance.ToCharArray + If chars.Contains(i) Then + Return False + End If + + If Convert.ToInt32(i) < 32 Then + Return False + End If + Next + + Return True + End Function + + + Function IsSameBase(instance As String, b As String) As Boolean + Return instance.Base.IsEqualIgnoreCase(b.Base) + End Function + Function EscapeIllegalFileSysChars(value As String) As String If value = "" Then Return "" For Each i In value - If Not FilePath.IsValidFileSystemName(i) Then + If Not IsValidFileSystemName(i) Then value = value.Replace(i, "__" + Uri.EscapeDataString(i).TrimStart("%"c) + "__") End If Next diff --git a/General/FrameServer.vb b/General/FrameServer.vb index b6fadc75..6bdbe249 100644 --- a/General/FrameServer.vb +++ b/General/FrameServer.vb @@ -7,15 +7,8 @@ Public Class FrameServer Property Info As ServerInfo Property NativeServer As IFrameServer - Shared WasInitialized As Boolean - Sub New(path As String) - If Not WasInitialized Then - Package.Python.AddToPath() - Package.AviSynth.AddToPath() - Package.VapourSynth.AddToPath() - WasInitialized = True - End If + g.InitFrameServer() If path.EndsWith(".avs") Then NativeServer = CreateAviSynthServer() diff --git a/General/General.vb b/General/General.vb index 6ee5f723..acdca58d 100644 --- a/General/General.vb +++ b/General/General.vb @@ -196,7 +196,7 @@ Public Class Folder Directory.CreateDirectory(ret + "Backup") For Each i In files - FileHelp.Move(i, FilePath.GetDir(i) + "Backup\" + FilePath.GetName(i)) + FileHelp.Move(i, i.Dir + "Backup\" + i.FileName) Next End If @@ -251,180 +251,6 @@ Public Class Folder End Function End Class -Public Class PathBase - Shared ReadOnly Property Separator() As Char - Get - Return Path.DirectorySeparatorChar - End Get - End Property - - Shared Function IsSameBase(a As String, b As String) As Boolean - Return FilePath.GetBase(a).EqualIgnoreCase(FilePath.GetBase(b)) - End Function - - Shared Function IsSameDir(a As String, b As String) As Boolean - Return FilePath.GetDir(a).EqualIgnoreCase(FilePath.GetDir(b)) - End Function - - Shared Function IsValidFileSystemName(name As String) As Boolean - If name = "" Then Return False - Dim chars = """*/:<>?\|^".ToCharArray - - For Each i In name.ToCharArray - If chars.Contains(i) Then Return False - If Convert.ToInt32(i) < 32 Then Return False - Next - - Return True - End Function -End Class - -Public Class DirPath - Inherits PathBase - - Shared Function TrimTrailingSeparator(path As String) As String - If path = "" Then Return "" - - If path.EndsWith(Separator) AndAlso Not path.Length <= 3 Then - Return path.TrimEnd(Separator) - End If - - Return path - End Function - - Shared Function FixSeperator(path As String) As String - If path.Contains("\") AndAlso Separator <> "\" Then - path = path.Replace("\", Separator) - End If - - If path.Contains("/") AndAlso Separator <> "/" Then - path = path.Replace("/", Separator) - End If - - Return path - End Function - - Shared Function GetParent(path As String) As String - If path = "" Then Return "" - Dim temp = TrimTrailingSeparator(path) - If temp.Contains(Separator) Then path = temp.LeftLast(Separator) + Separator - Return path - End Function - - Shared Function GetName(path As String) As String - If path = "" Then Return "" - path = TrimTrailingSeparator(path) - Return path.RightLast(Separator) - End Function - - Shared Function IsInSysDir(path As String) As Boolean - If path = "" Then Return False - If Not path.EndsWith("\") Then path += "\" - Return path.ToUpper.Contains(Folder.Programs.ToUpper) - End Function - - Shared Function IsFixedDrive(path As String) As Boolean - Try - If path <> "" Then Return New DriveInfo(path).DriveType = DriveType.Fixed - Catch ex As Exception - End Try - End Function -End Class - -Public Class FilePath - Inherits PathBase - - Private Value As String - - Sub New(path As String) - Value = path - End Sub - - Shared Function GetDir(path As String) As String - If path = "" Then - Return "" - End If - - If path.Contains("\") Then - path = path.LeftLast("\") + "\" - End If - - Return path - End Function - - Shared Function GetDirAndBase(path As String) As String - Return GetDir(path) + GetBase(path) - End Function - - Shared Function GetName(path As String) As String - If Not path Is Nothing Then - Dim index = path.LastIndexOf(IO.Path.DirectorySeparatorChar) - - If index > -1 Then - Return path.Substring(index + 1) - End If - End If - - Return path - End Function - - Shared Function GetExtFull(filepath As String) As String - Return GetExt(filepath, True) - End Function - - Shared Function GetExt(filepath As String) As String - Return GetExt(filepath, False) - End Function - - Shared Function GetExt(filepath As String, includeDot As Boolean) As String - If filepath = "" Then - Return "" - End If - - Dim chars = filepath.ToCharArray() - - For x = filepath.Length - 1 To 0 Step -1 - If chars(x) = Separator Then - Return "" - End If - - If chars(x) = "."c Then - Return filepath.Substring(x + If(includeDot, 0, 1)).ToLower() - End If - Next - - Return "" - End Function - - Shared Function GetDirNoSep(path As String) As String - path = GetDir(path) - If path.EndsWith(Separator) Then path = TrimSep(path) - Return path - End Function - - Shared Function GetBase(path As String) As String - If path = "" Then Return "" - Dim ret = path - If ret.Contains(Separator) Then ret = ret.RightLast(Separator) - If ret.Contains(".") Then ret = ret.LeftLast(".") - Return ret - End Function - - Shared Function TrimSep(path As String) As String - If path = "" Then Return "" - - If path.EndsWith(Separator) AndAlso Not path.EndsWith(":" + Separator) Then - Return path.TrimEnd(Separator) - End If - - Return path - End Function - - Shared Function GetDirNameOnly(path As String) As String - Return FilePath.GetDirNoSep(path).RightLast("\") - End Function -End Class - Public Class SafeSerialization Shared Sub Serialize(o As Object, path As String) Dim list As New List(Of Object) @@ -954,7 +780,7 @@ Public Class StringPair Me.Value = value End Sub - Function CompareTo(other As StringPair) As Integer Implements System.IComparable(Of StringPair).CompareTo + Function CompareTo(other As StringPair) As Integer Implements IComparable(Of StringPair).CompareTo Return Name.CompareTo(other.Name) End Function End Class @@ -1210,7 +1036,7 @@ Public Class CommandManager End If For Each i In Commands.Keys - If i.EqualIgnoreCase(name) Then + If i.IsEqualIgnoreCase(name) Then Return True End If Next @@ -1222,7 +1048,7 @@ Public Class CommandManager End If For Each i In Commands.Keys - If i.EqualIgnoreCase(name) Then + If i.IsEqualIgnoreCase(name) Then Return Commands(i) End If Next diff --git a/General/GlobalClass.vb b/General/GlobalClass.vb index cf2264d9..16d687ed 100644 --- a/General/GlobalClass.vb +++ b/General/GlobalClass.vb @@ -73,7 +73,7 @@ Public Class GlobalClass Dim path = Environment.GetEnvironmentVariable("path") For Each pack In Package.Items.Values - If Not pack.HelpSwitch Is Nothing AndAlso pack.Path.FileExists Then + If pack.Path.Ext = "exe" AndAlso pack.Path.FileExists Then path = pack.Directory + ";" + path End If Next @@ -81,6 +81,27 @@ Public Class GlobalClass dic("path") = path End Sub + Sub AddToPath(ParamArray dirs As String()) + Dim path = Environment.GetEnvironmentVariable("path") + + For Each d In dirs + If d.DirExists AndAlso Not d.StartsWith(Folder.System) Then + path = d + ";" + path + End If + Next + + Environment.SetEnvironmentVariable("path", path) + End Sub + + Function IsFixedDrive(path As String) As Boolean + Try + If path <> "" Then + Return New DriveInfo(path).DriveType = DriveType.Fixed + End If + Catch + End Try + End Function + Sub ProcessJobs() Dim jobs = Job.ActiveJobs @@ -801,16 +822,22 @@ Public Class GlobalClass End Function Function IsSourceSame(path As String) As Boolean - Return FilePath.GetBase(path).StartsWith(FilePath.GetBase(p.SourceFile)) + Return path.Base.StartsWith(p.SourceFile.Base) End Function Function GetFilesInTempDirAndParent() As List(Of String) Dim ret As New List(Of String) Dim dirs As New HashSet(Of String) - If p.TempDir <> "" Then dirs.Add(p.TempDir) - If p.TempDir?.EndsWith("_temp\") Then dirs.Add(DirPath.GetParent(p.TempDir)) - dirs.Add(FilePath.GetDir(p.FirstOriginalSourceFile)) + If p.TempDir <> "" Then + dirs.Add(p.TempDir) + End If + + If p.TempDir?.EndsWith("_temp\") Then + dirs.Add(p.TempDir.Parent) + End If + + dirs.Add(p.FirstOriginalSourceFile.Dir) For Each i In dirs ret.AddRange(Directory.GetFiles(i)) @@ -821,13 +848,13 @@ Public Class GlobalClass Function IsSourceSimilar(path As String) As Boolean If p.SourceFile.Contains("_") Then - Dim src = FilePath.GetBase(p.SourceFile) + Dim sourceBase = p.SourceFile.Base - While src.Length > 2 AndAlso src.ToCharArray.Last.IsDigit - src = src.DeleteRight(1) + While sourceBase.Length > 2 AndAlso sourceBase.ToCharArray.Last.IsDigit + sourceBase = sourceBase.DeleteRight(1) End While - If src.EndsWith("_") AndAlso FilePath.GetBase(path).StartsWith(src.TrimEnd("_"c)) Then + If sourceBase.EndsWith("_") AndAlso path.Base.StartsWith(sourceBase.TrimEnd("_"c)) Then Return True End If End If @@ -851,7 +878,7 @@ Public Class GlobalClass If File.Exists(p.SourceFile) Then Dim name = p.TargetFile.Base If name = "" Then name = p.SourceFile.Base - Dim path = FilePath.GetDir(p.SourceFile) + "recovery.srip" + Dim path = p.SourceFile.Dir + "recovery.srip" g.MainForm.SaveProjectPath(path) End If @@ -1081,15 +1108,19 @@ Public Class GlobalClass End Function Function BrowseFile(filter As String) As String - Using d As New OpenFileDialog - d.Filter = filter - d.SetInitDir(p.TempDir) - If d.ShowDialog = DialogResult.OK Then Return d.FileName + Using dialog As New OpenFileDialog + dialog.Filter = filter + dialog.SetInitDir(p.TempDir) + + If dialog.ShowDialog = DialogResult.OK Then + Return dialog.FileName + End If End Using End Function Sub CodePreview(code As String) Using form As New StringEditorForm + form.ScaleClientSize(50, 30) form.rtb.ReadOnly = True form.cbWrap.Checked = False form.cbWrap.Visible = False @@ -1343,4 +1374,67 @@ Public Class GlobalClass Function IsWindowsTerminalAvailable() As Boolean Return File.Exists(Folder.AppDataLocal + "Microsoft\WindowsApps\wt.exe") End Function + + Shared WasFrameServerInitialized As Boolean + + Sub InitFrameServer() + If Not WasFrameServerInitialized Then + 'TODO:? + 'Dim dirs = Package.Items.Values.Select(Function(pack) pack.Path.Dir) + + 'dirs = dirs.Concat({Folder.Startup, Package.Python.Directory, + ' Package.AviSynth.Directory, Package.VapourSynth.Directory}) + + 'g.AddToPath(dirs.ToArray) + + g.AddToPath(Folder.Startup, Package.Python.Directory, Package.AviSynth.Directory, + Package.VapourSynth.Directory, Package.FFTW.Directory) + + MakeSymLinks() + WasFrameServerInitialized = True + End If + End Sub + + Sub MakeSymLinks() + 'name, source,target + Dim links As New List(Of (String, String, String)) + + If Package.AviSynth.Path.StartsWith(Folder.Startup) AndAlso + Package.ffmpeg.Path.StartsWith(Folder.Startup) Then + + links.Add(("ffmpeg avisynth", Package.ffmpeg.Directory + "AviSynth.dll", Package.AviSynth.Path)) + End If + + links.Add(("libfftw3 vs fftw", Package.DCTFilterVS.Directory + "libfftw3-3.dll", Package.FFTW.Directory + "libfftw3-3.dll")) + links.Add(("libfftw3f vs fftw", Package.DCTFilterVS.Directory + "libfftw3f-3.dll", Package.FFTW.Directory + "libfftw3f-3.dll")) + + links.Add(("libfftw3 vs fftw", Package.BM3D.Directory + "libfftw3-3.dll", Package.FFTW.Directory + "libfftw3-3.dll")) + links.Add(("libfftw3f vs fftw", Package.BM3D.Directory + "libfftw3f-3.dll", Package.FFTW.Directory + "libfftw3f-3.dll")) + + links.Add(("libfftw3 vs fftw", Package.DFTTestVS.Directory + "libfftw3-3.dll", Package.FFTW.Directory + "libfftw3-3.dll")) + links.Add(("libfftw3f vs fftw", Package.DFTTestVS.Directory + "libfftw3f-3.dll", Package.FFTW.Directory + "libfftw3f-3.dll")) + + For Each i In links + If Not i.Item3.FileExists Then + Continue For + End If + + Dim hash = (i.Item2 & i.Item3 & New FileInfo(i.Item3).Length & Folder.Startup).MD5Hash + + If s.Storage.GetString(i.Item1 + "symlinkhash") <> hash OrElse Not i.Item2.FileExists Then + FileHelp.Delete(i.Item2) + Dim cmd = $"mklink {i.Item2.Escape} {i.Item3.Escape}" + + Using cmdProc As New Process + cmdProc.StartInfo.UseShellExecute = False + cmdProc.StartInfo.CreateNoWindow = True + cmdProc.StartInfo.FileName = "cmd.exe" + cmdProc.StartInfo.Arguments = $"/s /c ""{cmd}""" + cmdProc.Start() + End Using + + s.Storage.SetString(i.Item1 + "symlinkhash", hash) + End If + Next + End Sub End Class diff --git a/General/GlobalCommands.vb b/General/GlobalCommands.vb index a292af4f..0eb6bdba 100644 --- a/General/GlobalCommands.vb +++ b/General/GlobalCommands.vb @@ -238,11 +238,6 @@ Public Class GlobalCommands msg += BR2 + $"# Help file of {pack.Name} don't exist!" End If End If - - 'does setup file exist? - If pack.SetupFilename <> "" AndAlso Not File.Exists(Folder.Apps + pack.SetupFilename) Then - msg += BR2 + $"Setup file of {pack.Name} don't exist!" - End If End If Next diff --git a/General/Help.vb b/General/Help.vb index b1c78785..cb338fd4 100644 --- a/General/Help.vb +++ b/General/Help.vb @@ -116,6 +116,7 @@ Public Class DirectoryHelp End Function End Class +'TODO:remove? Public Class ConsoleHelp Private Shared DosCodePageValue As Integer diff --git a/General/Misc.vb b/General/Misc.vb index 2c34db96..ce3ee896 100644 --- a/General/Misc.vb +++ b/General/Misc.vb @@ -1120,13 +1120,13 @@ Public Class Macro If value.Contains("%source_framerate%") Then value = value.Replace("%source_framerate%", p.SourceFrameRate.ToString("f6", CultureInfo.InvariantCulture)) If Not value.Contains("%") Then Return value - If value.Contains("%source_dir%") Then value = value.Replace("%source_dir%", FilePath.GetDir(p.SourceFile)) + If value.Contains("%source_dir%") Then value = value.Replace("%source_dir%", p.SourceFile.Dir) If Not value.Contains("%") Then Return value - If value.Contains("%source_dir_parent%") Then value = value.Replace("%source_dir_parent%", DirPath.GetParent(FilePath.GetDir(p.SourceFile))) + If value.Contains("%source_dir_parent%") Then value = value.Replace("%source_dir_parent%", p.SourceFile.Dir.Parent) If Not value.Contains("%") Then Return value - If value.Contains("%source_dir_name%") Then value = value.Replace("%source_dir_name%", DirPath.GetName(FilePath.GetDir(p.SourceFile))) + If value.Contains("%source_dir_name%") Then value = value.Replace("%source_dir_name%", p.SourceFile.Dir.DirName) If Not value.Contains("%") Then Return value If value.Contains("%target_width%") Then value = value.Replace("%target_width%", p.TargetWidth.ToString) @@ -1150,7 +1150,7 @@ Public Class Macro If value.Contains("%target_file%") Then value = value.Replace("%target_file%", p.TargetFile) If Not value.Contains("%") Then Return value - If value.Contains("%target_dir%") Then value = value.Replace("%target_dir%", FilePath.GetDir(p.TargetFile)) + If value.Contains("%target_dir%") Then value = value.Replace("%target_dir%", p.TargetFile.Dir) If Not value.Contains("%") Then Return value If value.Contains("%target_name%") Then value = value.Replace("%target_name%", p.TargetFile.Base) @@ -1335,7 +1335,7 @@ Public Class Macro Dim path = package?.Path If path <> "" Then - value = value.Replace(match.Value, FilePath.GetDir(path)) + value = value.Replace(match.Value, path.Dir) If Not value.Contains("%") Then Return value End If diff --git a/General/Package.vb b/General/Package.vb index 7732f6ea..f3784fe6 100644 --- a/General/Package.vb +++ b/General/Package.vb @@ -14,17 +14,17 @@ Public Class Package Property HelpURL As String Property HelpUrlAviSynth As String Property HelpUrlVapourSynth As String - Property HintDirectories As String() Property HintDirFunc As Func(Of String) Property IgnoreNewVersion As Boolean - Property IgnoreVersion As Boolean Property IgnorePath As String + Property IgnoreVersion As Boolean Property IsGUI As Boolean Property IsIncluded As Boolean = True Property Location As String + Property Locations As String() Property Name As String Property RequiredFunc As Func(Of Boolean) - Property SetupFilename As String + Property SetupAction As Action Property StatusFunc As Func(Of String) Property TreePath As String Property Version As String @@ -42,7 +42,6 @@ Public Class Package .WebURL = "http://www.python.org", .HelpSwitch = "-h", .Description = "Python is required by VapourSynth.", - .SetupFilename = "Installers\python-3.8.2-amd64-webinstall.exe", .IgnorePath = "\WindowsApps\", .RequiredFunc = Function() p.Script.Engine = ScriptEngine.VapourSynth, .HintDirFunc = AddressOf GetPythonHintDir}) @@ -84,7 +83,7 @@ Public Class Package .HelpSwitch = "-h", .Required = False, .IsIncluded = False, - .HintDirectories = {Registry.ClassesRoot.GetString("CLSID\" + GUIDS.HaaliMuxer.ToString + "\InprocServer32", Nothing).Dir}, + .Locations = {Registry.ClassesRoot.GetString("CLSID\" + GUIDS.HaaliMuxer.ToString + "\InprocServer32", Nothing).Dir}, .RequiredFunc = Function() CommandLineDemuxer.IsActive("dsmux")}) Shared Property Haali As Package = Add(New Package With { @@ -94,7 +93,7 @@ Public Class Package .Description = "Haali Splitter is used by eac3to and dsmux to write MKV files.", .Required = False, .IsIncluded = False, - .HintDirectories = {Registry.ClassesRoot.GetString("CLSID\" + GUIDS.HaaliMuxer.ToString + "\InprocServer32", Nothing).Dir}}) + .Locations = {Registry.ClassesRoot.GetString("CLSID\" + GUIDS.HaaliMuxer.ToString + "\InprocServer32", Nothing).Dir}}) Shared Property NicAudio As Package = Add(New PluginPackage With { .Name = "NicAudio", @@ -156,7 +155,7 @@ Public Class Package Shared Property GetMediaInfo As Package = Add(New Package With { .Name = "Get-MediaInfo", - .Location = "support\MediaInfo.NET", + .Location = "Support\MediaInfo.NET", .Filename = "Get-MediaInfo.ps1", .Description = "Complete PowerShell MediaInfo solution.", .WebURL = "https://github.com/stax76/Get-MediaInfo", @@ -174,14 +173,31 @@ Public Class Package Shared Property AviSynth As Package = Add(New Package With { .Name = "AviSynth", .Filename = "AviSynth.dll", - .Location = "Support\AviSynth", .WebURL = "https://github.com/AviSynth/AviSynthPlus", .HelpURL = "http://avisynth.nl", .Description = "StaxRip supports both AviSynth and VapourSynth as video processing tool.", - .HintDirectories = {Folder.System}, - .SetupFilename = "Installers\AviSynthPlus-3.5.1_20200402.exe", + .Locations = {"FrameServer\AviSynth", Folder.System}, .RequiredFunc = Function() p.Script.Engine = ScriptEngine.AviSynth}) + Shared Property VapourSynth As Package = Add(New Package With { + .Name = "VapourSynth", + .Filename = "vapoursynth.dll", + .Description = "StaxRip supports both AviSynth and VapourSynth as video processing tool.", + .WebURL = "http://www.vapoursynth.com", + .HelpURL = "http://www.vapoursynth.com/doc", + .RequiredFunc = Function() p.Script.Engine = ScriptEngine.VapourSynth, + .HintDirFunc = Function() Package.VapourSynth.GetVapourSynthHintDir}) + + Shared Property vspipe As Package = Add(New Package With { + .Name = "vspipe", + .Filename = "vspipe.exe", + .Location = "Support\VapourSynth", + .Description = "vspipe is installed by VapourSynth and used to pipe VapourSynth scripts to encoding apps.", + .HelpURL = "http://www.vapoursynth.com/doc/vspipe.html", + .HelpSwitch = "", + .RequiredFunc = Function() p.Script.Engine = ScriptEngine.VapourSynth, + .HintDirFunc = Function() Package.VapourSynth.GetVapourSynthHintDir}) + Shared Property chapterEditor As Package = Add(New Package With { .Name = "chapterEditor", .Location = "Support\chapterEditor", @@ -226,33 +242,13 @@ Public Class Package Shared Property AVSMeter As Package = Add(New Package With { .Name = "AVSMeter", - .Location = "support\AVSMeter", + .Location = "Support\AVSMeter", .Filename = "AVSMeter64.exe", .Description = "AVSMeter displays AviSynth script clip info, CPU and memory usage and the minimum, maximum and average frames processed per second. It measures how fast Avisynth can serve frames to a client application and comes in handy when testing filters/plugins to evaluate their performance and memory requirements.", .HelpFilename = "doc\AVSMeter.html", .WebURL = "http://forum.doom9.org/showthread.php?t=174797", .HelpSwitch = ""}) - Shared Property vspipe As Package = Add(New Package With { - .Name = "vspipe", - .Filename = "vspipe.exe", - .Description = "vspipe is installed by VapourSynth and used to pipe VapourSynth scripts to encoding apps.", - .HelpURL = "http://www.vapoursynth.com/doc/vspipe.html", - .HelpSwitch = "", - .RequiredFunc = Function() p.Script.Engine = ScriptEngine.VapourSynth, - .HintDirFunc = AddressOf Package.GetVapourSynthHintDir}) - - Shared Property VapourSynth As Package = Add(New Package With { - .Name = "VapourSynth", - .Filename = "vapoursynth.dll", - .Location = "Support\VapourSynth", - .Description = "StaxRip supports both AviSynth and VapourSynth as video processing tool.", - .WebURL = "http://www.vapoursynth.com", - .HelpURL = "http://www.vapoursynth.com/doc", - .SetupFilename = "Installers\VapourSynth64-R50-RC2.exe", - .RequiredFunc = Function() p.Script.Engine = ScriptEngine.VapourSynth, - .HintDirFunc = AddressOf Package.GetVapourSynthHintDir}) - Shared Property BDSup2SubPP As Package = Add(New Package With { .Name = "BDSup2Sub++", .Filename = "bdsup2sub++.exe", @@ -305,7 +301,7 @@ Public Class Package .Required = False, .WebURL = "https://sourceforge.net/projects/mpcbe/", .Description = "DirectShow based media player.", - .HintDirectories = {Registry.LocalMachine.GetString("SOFTWARE\MPC-BE", "ExePath").Dir, Folder.Programs + "MPC-BE x64\"}}) + .Locations = {Registry.LocalMachine.GetString("SOFTWARE\MPC-BE", "ExePath").Dir, Folder.Programs + "MPC-BE x64\"}}) Shared Property MpcHC As Package = Add(New Package With { .Name = "MPC-HC", @@ -316,7 +312,7 @@ Public Class Package .Required = False, .WebURL = "https://mpc-hc.org/", .Description = "DirectShow based media player.", - .HintDirectories = {Registry.CurrentUser.GetString("Software\MPC-HC\MPC-HC", "ExePath").Dir, Folder.Programs + "MPC-HC\"}}) + .Locations = {Registry.CurrentUser.GetString("Software\MPC-HC\MPC-HC", "ExePath").Dir, Folder.Programs + "MPC-HC\"}}) Shared Property modPlus As Package = Add(New PluginPackage With { .Name = "modPlus", @@ -371,7 +367,7 @@ Public Class Package Shared Property VSRip As Package = Add(New Package With { .Name = "VSRip", .Filename = "VSRip.exe", - .Location = "subtitles\VSRip", + .Location = "Subtitles\VSRip", .Description = "VSRip rips VobSub subtitles.", .IsGUI = True, .WebURL = "http://sourceforge.net/projects/guliverkli"}) @@ -584,45 +580,10 @@ Public Class Package Shared Property FFTW As Package = Add(New Package With { .Name = "FFTW", - .Location = "support\FFTW", + .Location = "Support\FFTW", .Filename = "libfftw3-3.dll", .Description = "Library required by various AviSynth and VapourSynth plugins.", - .WebURL = "http://www.fftw.org", - .FixedDir = Folder.System, - .RequiredFunc = Function() - For Each filter In p.Script.Filters - If filter.Script.ContainsAny("fft", "FFT") Then - Return True - End If - Next - - Return BM3D.Required OrElse - DCTFilter.Required OrElse - DCTFilterF.Required OrElse - DCTFilterVS.Required OrElse - DFTTestAvs.Required OrElse - DFTTestVS.Required OrElse - FFT3DFilter.Required OrElse - FFT3DGPU.Required OrElse - havsfunc.Required OrElse - MCTemporalDenoise.Required OrElse - muvsfunc.Required OrElse - QTGMC.Required OrElse - SMDegrain.Required - End Function, - .SetupAction = Sub() - Using proc As New Process - proc.StartInfo.FileName = "xcopy.exe" - proc.StartInfo.Arguments = $"""{Folder.Apps + "\support\FFTW\"}*ff*"" ""{Folder.System}"" /Y" - proc.StartInfo.Verb = "runas" - proc.Start() - proc.WaitForExit() - - If proc.ExitCode <> 0 Then - MsgError("FFTW returned an error.") - End If - End Using - End Sub}) + .WebURL = "http://www.fftw.org"}) Shared Property havsfunc As Package = Add(New PluginPackage With { .Name = "havsfunc", @@ -1790,23 +1751,6 @@ Public Class Package Return pack End Function - Private SetupActionValue As Action - - Property SetupAction As Action - Get - If SetupActionValue Is Nothing AndAlso SetupFilename <> "" AndAlso - File.Exists(Folder.Apps + SetupFilename) Then - - SetupActionValue = Sub() g.ShellExecute(Folder.Apps + SetupFilename) - End If - - Return SetupActionValue - End Get - Set(value As Action) - SetupActionValue = value - End Set - End Property - ReadOnly Property ID As String Get If TypeOf Me Is PluginPackage Then @@ -1890,13 +1834,6 @@ Public Class Package End If End Function - Sub AddToPath() - If Path.FileExists Then - Environment.SetEnvironmentVariable("path", Directory + ";" + - Environment.GetEnvironmentVariable("path")) - End If - End Sub - Sub ShowHelp() Dim dic As New SortedDictionary(Of String, String) @@ -1995,6 +1932,10 @@ Public Class Package Using form As New AppsForm form.ShowPackage(Me) form.ShowDialog() + + If GetStatus() <> "" Then + Throw New AbortException() + End If End Using If Required AndAlso GetStatus() <> "" Then @@ -2049,10 +1990,6 @@ Public Class Package Dim pathVar = Path If pathVar = "" Then - If SetupFilename <> "" Then - Return "Please install " + Name + " or click on Path to define the location. After that, restart StaxRip." - End If - If FixedDir <> "" Then Return "App not found at '" + FixedDir.TrimEnd("\"c) + "'" Else @@ -2096,8 +2033,14 @@ Public Class Package End Get End Property - Shared Function GetVapourSynthHintDir() As String - Dim ret = Registry.LocalMachine.GetString("Software\VapourSynth", "VapourSynthDLL").Dir + Function GetVapourSynthHintDir() As String + Dim ret = GetPathFromLocation("FrameServer\VapourSynth") + + If ret <> "" Then + Return ret.Dir + End If + + ret = Registry.LocalMachine.GetString("Software\VapourSynth", "VapourSynthDLL").Dir If File.Exists(ret + "VapourSynth.dll") Then Return ret @@ -2129,6 +2072,10 @@ Public Class Package End Function Shared Function GetPythonHintDir() As String + If (Folder.Apps + "FrameServer\VapourSynth\python.exe").FileExists Then + Return Folder.Apps + "FrameServer\VapourSynth\" + End If + For Each x In {8, 9, 7} For Each rootKey In {Registry.CurrentUser, Registry.LocalMachine} Dim exePath = rootKey.GetString($"SOFTWARE\Python\PythonCore\3.{x}\InstallPath", "ExecutablePath") @@ -2162,16 +2109,16 @@ Public Class Package Return Nothing End If - If Location <> "" AndAlso File.Exists(Folder.Apps + Location + "\" + Filename) Then - Return Folder.Apps + Location + "\" + Filename + ret = GetPathFromLocation(Location) + + If File.Exists(ret) Then + Return ret End If - If Not HintDirectories.NothingOrEmpty Then - For Each hintDir In HintDirectories - If File.Exists(hintDir + Filename) Then - Return hintDir + Filename - End If - Next + ret = GetPathFromLocation(Locations) + + If File.Exists(ret) Then + Return ret End If If Not HintDirFunc Is Nothing Then @@ -2222,6 +2169,20 @@ Public Class Package End Get End Property + Function GetPathFromLocation(ParamArray dirs As String()) As String + If Not dirs.NothingOrEmpty Then + For Each hintDir In dirs + If Not hintDir.Contains(":\") AndAlso Not hintDir.StartsWith("\\") Then + hintDir = Folder.Apps + hintDir + End If + + If File.Exists(hintDir.FixDir + Filename) Then + Return hintDir.FixDir + Filename + End If + Next + End If + End Function + Sub StartProcess(path As String) If path.Ext.EqualsAny("htm", "html") Then Dim broswer = FindEverywhere({"chrome.exe", "firefox.exe"}) @@ -2303,7 +2264,7 @@ Public Class Package For Each folder In paths Dim filepath = folder.FixDir + filename - If File.Exists(filepath) Then + If File.Exists(filepath) AndAlso Not New FileInfo(filepath).Length = 0 Then Return filepath End If Next diff --git a/General/Project.vb b/General/Project.vb index cd2cfa15..ee0010e1 100644 --- a/General/Project.vb +++ b/General/Project.vb @@ -273,7 +273,7 @@ Public Class Project Dim filter As New VideoFilter filter.Category = "Subtitle" - filter.Path = FilePath.GetName(path) + filter.Path = path.FileName filter.Active = True filter.Script = filterName + "(""" + path + """)" Dim insertCat = If(p.Script.IsFilterActive("Crop"), "Crop", "Source") @@ -307,7 +307,7 @@ Public Class Project Dim filter As New VideoFilter filter.Category = "Subtitle" - filter.Path = FilePath.GetName(path) + filter.Path = path.FileName filter.Active = True filter.Script = "clip = " + filterName + "(clip, file = r""" + path + """)" Dim insertCat = If(p.Script.IsFilterActive("Crop"), "Crop", "Source") diff --git a/General/VideoScript.vb b/General/VideoScript.vb index 2f85cb21..ba133954 100644 --- a/General/VideoScript.vb +++ b/General/VideoScript.vb @@ -226,7 +226,7 @@ clipname.set_output() End If If Me.Error <> "" OrElse code <> LastCode OrElse (comparePath AndAlso Path <> LastPath) Then - If Directory.Exists(FilePath.GetDir(Path)) Then + If Path.Dir.DirExists Then If Engine = ScriptEngine.VapourSynth Then ModifyScript(code, Engine).WriteFile(Path, Encoding.UTF8) Else diff --git a/UI/ImageUtils.vb b/UI/ImageUtils.vb index 850b7f16..1f60f870 100644 --- a/UI/ImageUtils.vb +++ b/UI/ImageUtils.vb @@ -203,7 +203,7 @@ Public Class Thumbnails infoSize = CInt(infoLength / 1024 ^ 2).ToString + "MB" End If - Dim caption = "File: " + FilePath.GetName(inputFile) + BR & "Size: " + MediaInfo.GetGeneral(inputFile, "FileSize") + " bytes" + " (" + infoSize + ")" & ", " + "Duration: " + StaxRip.g.GetTimeString(infoDuration / 1000) + ", avg.bitrate: " + MediaInfo.GetGeneral(inputFile, "OverallBitRate_String") + BR + + Dim caption = "File: " + inputFile.FileName + BR & "Size: " + MediaInfo.GetGeneral(inputFile, "FileSize") + " bytes" + " (" + infoSize + ")" & ", " + "Duration: " + StaxRip.g.GetTimeString(infoDuration / 1000) + ", avg.bitrate: " + MediaInfo.GetGeneral(inputFile, "OverallBitRate_String") + BR + "Audio: " + audioCodecs + ", " + MediaInfo.GetAudio(inputFile, "SamplingRate_String") + ", " + audioSound + ", " + MediaInfo.GetAudio(inputFile, "BitRate_String") + BR + "Video: " + MediaInfo.GetVideo(inputFile, "Format") + " (" + profile + ")" + ", " + colorSpace + subSampling + scanType.Shorten(1).ToLower() + ", " + MediaInfo.GetVideo(inputFile, "Width") & "x" & MediaInfo.GetVideo(inputFile, "Height") & ", " + MediaInfo.GetVideo(inputFile, "BitRate_String") + ", " & MediaInfo.GetVideo(inputFile, "FrameRate").ToSingle.ToInvariantString + "fps".Replace(", ", "")