Imports System.ComponentModel Imports System.Drawing.Design Imports System.Drawing.Drawing2D Imports System.Globalization Imports System.Reflection Imports System.Runtime.InteropServices Imports System.Security.Cryptography Imports System.Text Imports System.Text.RegularExpressions Imports System.Threading Imports System.Threading.Tasks Imports Microsoft.VisualBasic Imports StaxRip Imports StaxRip.UI Imports VB6 = Microsoft.VisualBasic Partial Public Class MainForm Inherits FormBase #Region " Designer " Private components As IContainer Private Const _filterHeight As Integer = 640 Public WithEvents bnNext As ButtonEx Public WithEvents tbSourceFile As TextEdit Public WithEvents tbTargetFile As TextEdit Public WithEvents gbAssistant As GroupBoxEx Public WithEvents lgbFilters As LinkGroupBox Public WithEvents tbTargetSize As TextEdit Public WithEvents laBitrate As LabelEx Public WithEvents tbBitrate As TextEdit Public WithEvents lTarget1 As LabelEx Public WithEvents lSource1 As LabelEx Public WithEvents lgbResize As LinkGroupBox Public WithEvents lPixel As LabelEx Public WithEvents lPixelText As LabelEx Public WithEvents tbResize As TrackBar Public WithEvents lZoom As LabelEx Public WithEvents lZoomText As LabelEx Public WithEvents tbTargetHeight As TextEdit Public WithEvents tbTargetWidth As TextEdit Public WithEvents lTargetHeight As LabelEx Public WithEvents lTargetWidth As LabelEx Public WithEvents lDAR As LabelEx Public WithEvents blTargetDarText As ButtonLabel Public WithEvents lCrop As LabelEx Public WithEvents lCropText As LabelEx Public WithEvents lgbSource As LinkGroupBox Public WithEvents lSource2 As LabelEx Public WithEvents lgbTarget As LinkGroupBox Public WithEvents GroupBox1 As GroupBoxEx Public WithEvents laTip As LabelEx Public WithEvents lgbEncoder As LinkGroupBox Public WithEvents laTarget2 As LabelEx Public WithEvents MenuStrip As MenuStrip Public WithEvents pnEncoder As Panel Public WithEvents FiltersListView As StaxRip.FiltersListView Public WithEvents blFilesize As ButtonLabel Public WithEvents llMuxer As ButtonLabel Public WithEvents lPAR As StaxRip.UI.LabelEx Public WithEvents blTargetParText As ButtonLabel Public WithEvents lAspectRatioError As LabelEx Public WithEvents lAspectRatioErrorText As LabelEx Public WithEvents blCropText As ButtonLabel Public WithEvents lCrop2 As LabelEx Public WithEvents gbAudio As GroupBoxEx Public WithEvents blSourceParText As ButtonLabel Public WithEvents lSourcePAR As LabelEx Public WithEvents lSourceDar As LabelEx Public WithEvents lSAR As LabelEx Public WithEvents lSarText As LabelEx Friend WithEvents tlpTarget As TableLayoutPanel Friend WithEvents tlpMain As TableLayoutPanel Friend WithEvents tlpSource As TableLayoutPanel Friend WithEvents tlpResizeValues As TableLayoutPanel Friend WithEvents tlpResize As TableLayoutPanel Friend WithEvents tlpAudio As TableLayoutPanel Friend WithEvents tlpAssistant As TableLayoutPanel Friend WithEvents blSourceDarText As ButtonLabel Friend WithEvents tlpSourceValues As TableLayoutPanel Public WithEvents TipProvider As StaxRip.UI.TipProvider ' Private Sub InitializeComponent() Me.components = New System.ComponentModel.Container() Me.bnNext = New StaxRip.UI.ButtonEx() Me.gbAssistant = New StaxRip.UI.GroupBoxEx() Me.tlpAssistant = New TableLayoutPanel() Me.laTip = New StaxRip.UI.LabelEx() Me.gbAudio = New StaxRip.UI.GroupBoxEx() Me.tlpAudio = New TableLayoutPanel() Me.MenuStrip = New MenuStrip() Me.lgbTarget = New StaxRip.UI.LinkGroupBox() Me.tlpTarget = New TableLayoutPanel() Me.tbTargetFile = New StaxRip.UI.TextEdit() Me.laTarget2 = New StaxRip.UI.LabelEx() Me.tbTargetSize = New StaxRip.UI.TextEdit() Me.lTarget1 = New StaxRip.UI.LabelEx() Me.tbBitrate = New StaxRip.UI.TextEdit() Me.laBitrate = New StaxRip.UI.LabelEx() Me.blFilesize = New StaxRip.UI.ButtonLabel() Me.lgbSource = New StaxRip.UI.LinkGroupBox() Me.tlpSource = New TableLayoutPanel() Me.tlpSourceValues = New TableLayoutPanel() Me.blSourceDarText = New StaxRip.UI.ButtonLabel() Me.lSourcePAR = New StaxRip.UI.LabelEx() Me.blSourceParText = New StaxRip.UI.ButtonLabel() Me.lCrop = New StaxRip.UI.LabelEx() Me.lCropText = New StaxRip.UI.LabelEx() Me.lSourceDar = New StaxRip.UI.LabelEx() Me.tbSourceFile = New StaxRip.UI.TextEdit() Me.lSource1 = New StaxRip.UI.LabelEx() Me.lSource2 = New StaxRip.UI.LabelEx() Me.lgbResize = New StaxRip.UI.LinkGroupBox() Me.tlpResize = New TableLayoutPanel() Me.tlpResizeValues = New TableLayoutPanel() Me.blTargetDarText = New StaxRip.UI.ButtonLabel() Me.lAspectRatioError = New StaxRip.UI.LabelEx() Me.lPAR = New StaxRip.UI.LabelEx() Me.lZoom = New StaxRip.UI.LabelEx() Me.lSarText = New StaxRip.UI.LabelEx() Me.lPixel = New StaxRip.UI.LabelEx() Me.blTargetParText = New StaxRip.UI.ButtonLabel() Me.lAspectRatioErrorText = New StaxRip.UI.LabelEx() Me.lCrop2 = New StaxRip.UI.LabelEx() Me.blCropText = New StaxRip.UI.ButtonLabel() Me.lDAR = New StaxRip.UI.LabelEx() Me.lZoomText = New StaxRip.UI.LabelEx() Me.lPixelText = New StaxRip.UI.LabelEx() Me.lSAR = New StaxRip.UI.LabelEx() Me.tbResize = New TrackBar() Me.lTargetWidth = New StaxRip.UI.LabelEx() Me.tbTargetWidth = New StaxRip.UI.TextEdit() Me.lTargetHeight = New StaxRip.UI.LabelEx() Me.tbTargetHeight = New StaxRip.UI.TextEdit() Me.lgbFilters = New StaxRip.UI.LinkGroupBox() Me.FiltersListView = New StaxRip.FiltersListView() Me.lgbEncoder = New StaxRip.UI.LinkGroupBox() Me.llMuxer = New StaxRip.UI.ButtonLabel() Me.pnEncoder = New Panel() Me.TipProvider = New StaxRip.UI.TipProvider(Me.components) Me.tlpMain = New TableLayoutPanel() Me.gbAssistant.SuspendLayout() Me.tlpAssistant.SuspendLayout() Me.gbAudio.SuspendLayout() Me.tlpAudio.SuspendLayout() Me.lgbTarget.SuspendLayout() Me.tlpTarget.SuspendLayout() Me.lgbSource.SuspendLayout() Me.tlpSource.SuspendLayout() Me.tlpSourceValues.SuspendLayout() Me.lgbResize.SuspendLayout() Me.tlpResize.SuspendLayout() Me.tlpResizeValues.SuspendLayout() CType(Me.tbResize, System.ComponentModel.ISupportInitialize).BeginInit() Me.lgbFilters.SuspendLayout() Me.lgbEncoder.SuspendLayout() Me.tlpMain.SuspendLayout() Me.SuspendLayout() ' 'bnNext ' Me.bnNext.Anchor = AnchorStyles.None Me.bnNext.AutoSize = False Me.bnNext.AutoSizeMode = AutoSizeMode.GrowAndShrink Me.bnNext.Cursor = Cursors.Default Me.bnNext.FlatStyle = FlatStyle.Flat Me.bnNext.Location = New System.Drawing.Point(1880, 33) Me.bnNext.Margin = New Padding(0, 0, 20, 5) 'Me.bnNext.MinimumSize = New System.Drawing.Size(265, 85) Me.bnNext.Size = New System.Drawing.Size(CInt(285 * s.UIScaleFactor), CInt(105 * s.UIScaleFactor)) Me.bnNext.UseCompatibleTextRendering = True ' 'gbAssistant ' Me.gbAssistant.Anchor = CType((((AnchorStyles.Top) Or AnchorStyles.Left) Or AnchorStyles.Right), AnchorStyles) Me.tlpMain.SetColumnSpan(Me.gbAssistant, 4) Me.gbAssistant.Controls.Add(Me.tlpAssistant) Me.gbAssistant.Dock = DockStyle.Fill Me.gbAssistant.AutoSize = False Me.gbAssistant.AutoSizeMode = AutoSizeMode.GrowAndShrink Me.gbAssistant.Location = New System.Drawing.Point(9, 1534) Me.gbAssistant.Margin = New Padding(9, 0, 9, 9) Me.gbAssistant.Name = "gbAssistant" Me.gbAssistant.Padding = New Padding(6, 6, 6, 6) Me.gbAssistant.TabIndex = 44 Me.gbAssistant.TabStop = False Me.gbAssistant.Text = "Assistant" ' 'tlpAssistant ' Me.tlpAssistant.Anchor = CType((((AnchorStyles.Top) Or AnchorStyles.Left) Or AnchorStyles.Right), AnchorStyles) Me.tlpAssistant.AutoSize = True Me.tlpAssistant.AutoSizeMode = AutoSizeMode.GrowAndShrink Me.tlpAssistant.ColumnCount = 2 Me.tlpAssistant.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 75.0!)) Me.tlpAssistant.ColumnStyles.Add(New ColumnStyle()) Me.tlpAssistant.Controls.Add(Me.laTip, 0, 0) Me.tlpAssistant.Controls.Add(Me.bnNext, 1, 0) Me.tlpAssistant.Dock = DockStyle.Fill Me.tlpAssistant.Location = New System.Drawing.Point(6, 48) Me.tlpAssistant.Margin = New Padding(0) Me.tlpAssistant.Name = "tlpAssistant" Me.tlpAssistant.RowCount = 1 Me.tlpAssistant.RowStyles.Add(New RowStyle(SizeType.Percent, 100.0!)) Me.tlpAssistant.TabIndex = 62 ' 'laTip ' Me.laTip.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.laTip.Dock = DockStyle.Fill Me.laTip.Location = New System.Drawing.Point(0, 0) Me.laTip.Margin = New Padding(20, 5, 20, 5) Me.laTip.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'gbAudio ' Me.gbAudio.Anchor = CType(((AnchorStyles.Top Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.tlpMain.SetColumnSpan(Me.gbAudio, 4) Me.gbAudio.Controls.Add(Me.tlpAudio) Me.gbAudio.Location = New System.Drawing.Point(9, 724) Me.gbAudio.Margin = New Padding(9, 0, 9, 0) Me.gbAudio.Name = "gbAudio" Me.gbAudio.Padding = New Padding(6, 0, 6, 6) Me.gbAudio.Size = New System.Drawing.Size(2031, 510) Me.gbAudio.AutoSize = True Me.gbAudio.AutoSizeMode = AutoSizeMode.GrowAndShrink Me.gbAudio.TabIndex = 59 Me.gbAudio.TabStop = False Me.gbAudio.Text = "Audio" ' 'tlpAudio ' Me.tlpAudio.ColumnCount = 5 Me.tlpAudio.ColumnStyles.Add(New ColumnStyle()) Me.tlpAudio.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100.0!)) Me.tlpAudio.ColumnStyles.Add(New ColumnStyle()) Me.tlpAudio.ColumnStyles.Add(New ColumnStyle()) Me.tlpAudio.ColumnStyles.Add(New ColumnStyle()) Me.tlpAudio.Dock = DockStyle.Fill Me.tlpAudio.Location = New System.Drawing.Point(6, 48) Me.tlpAudio.Margin = New Padding(0) Me.tlpAudio.Name = "tlpAudio" Me.tlpAudio.RowCount = 0 Me.tlpAudio.Size = New System.Drawing.Size(2019, 456) Me.tlpAudio.TabIndex = 62 Me.tlpAudio.AutoSize = True Me.tlpAudio.AutoSizeMode = AutoSizeMode.GrowAndShrink ' 'MenuStrip ' Me.MenuStrip.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.MenuStrip.AutoSize = True Me.tlpMain.SetColumnSpan(Me.MenuStrip, 4) Me.MenuStrip.Dock = DockStyle.Fill Me.MenuStrip.GripMargin = New Padding(2, 2, 0, 2) Me.MenuStrip.ImageScalingSize = New System.Drawing.Size(24, 24) Me.MenuStrip.Location = New System.Drawing.Point(0, 0) Me.MenuStrip.Name = "MenuStrip" Me.MenuStrip.Padding = New Padding(6, 6, 0, 6) Me.MenuStrip.TabIndex = 60 Me.MenuStrip.Text = "MenuStrip" ' 'lgbTarget ' Me.lgbTarget.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.tlpMain.SetColumnSpan(Me.lgbTarget, 2) Me.lgbTarget.Controls.Add(Me.tlpTarget) Me.lgbTarget.Location = New System.Drawing.Point(1029, 81) Me.lgbTarget.Margin = New Padding(6, 0, 9, 0) Me.lgbTarget.Name = "lgbTarget" Me.lgbTarget.Padding = New Padding(6, 0, 6, 6) Me.lgbTarget.Size = New System.Drawing.Size(1011, 357) Me.lgbTarget.TabIndex = 58 Me.lgbTarget.TabStop = False Me.lgbTarget.Text = "Target" ' 'tlpTarget ' Me.tlpTarget.ColumnCount = 4 Me.tlpTarget.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpTarget.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpTarget.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpTarget.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpTarget.Controls.Add(Me.tbTargetFile, 0, 0) Me.tlpTarget.Controls.Add(Me.blFilesize, 0, 1) Me.tlpTarget.Controls.Add(Me.tbTargetSize, 1, 1) Me.tlpTarget.Controls.Add(Me.laBitrate, 2, 1) Me.tlpTarget.Controls.Add(Me.tbBitrate, 3, 1) Me.tlpTarget.Controls.Add(Me.lTarget1, 0, 2) Me.tlpTarget.Controls.Add(Me.laTarget2, 0, 3) Me.tlpTarget.Dock = DockStyle.Fill Me.tlpTarget.Location = New System.Drawing.Point(6, 48) Me.tlpTarget.Margin = New Padding(0) Me.tlpTarget.Name = "tlpTarget" Me.tlpTarget.RowCount = 4 Me.tlpTarget.RowStyles.Add(New RowStyle(SizeType.Percent, 34.0!)) Me.tlpTarget.RowStyles.Add(New RowStyle(SizeType.Percent, 22.0!)) Me.tlpTarget.RowStyles.Add(New RowStyle(SizeType.Percent, 22.0!)) Me.tlpTarget.RowStyles.Add(New RowStyle(SizeType.Percent, 22.0!)) Me.tlpTarget.Size = New System.Drawing.Size(999, 303) Me.tlpTarget.TabIndex = 62 ' 'tbTargetFile ' Me.tlpTarget.SetColumnSpan(Me.tbTargetFile, 4) Me.tbTargetFile.Anchor = CType((AnchorStyles.Left Or AnchorStyles.Right), AnchorStyles) Me.tbTargetFile.AutoSize = True Me.tbTargetFile.Location = New System.Drawing.Point(6, 10) Me.tbTargetFile.Margin = New Padding(6, CInt(FontHeight / 1.5), 6, FontHeight \ 2) Me.tbTargetFile.Padding = New Padding(6, FontHeight \ 2, 6, FontHeight \ 2) Me.tbTargetFile.Name = "tbTargetFile" Me.tbTargetFile.ReadOnly = False Me.tbTargetFile.TabIndex = 0 ' 'laTarget2 ' Me.laTarget2.Anchor = CType((AnchorStyles.Left Or AnchorStyles.Right), AnchorStyles) Me.tlpTarget.SetColumnSpan(Me.laTarget2, 4) Me.laTarget2.ImeMode = ImeMode.NoControl Me.laTarget2.Location = New System.Drawing.Point(6, 234) Me.laTarget2.Margin = New Padding(6, 0, 6, 0) Me.laTarget2.Size = New System.Drawing.Size(987, 60) Me.laTarget2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'tbTargetSize ' Me.tbTargetSize.Anchor = AnchorStyles.Left Me.tbTargetSize.Location = New System.Drawing.Point(249, 85) Me.tbTargetSize.Margin = New Padding(0) Me.tbTargetSize.Name = "tbTargetSize" Me.tbTargetSize.ReadOnly = False Me.tbTargetSize.Size = New System.Drawing.Size(136, 55) Me.tbTargetSize.TabIndex = 55 Me.tbTargetSize.TextBox.TextAlign = HorizontalAlignment.Center ' 'lTarget1 ' Me.lTarget1.Anchor = CType((AnchorStyles.Left Or AnchorStyles.Right), AnchorStyles) Me.tlpTarget.SetColumnSpan(Me.lTarget1, 4) Me.lTarget1.Location = New System.Drawing.Point(6, 157) Me.lTarget1.Margin = New Padding(6, 0, 6, 0) Me.lTarget1.Size = New System.Drawing.Size(987, 60) Me.lTarget1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'tbBitrate ' Me.tbBitrate.Anchor = AnchorStyles.Left Me.tbBitrate.Location = New System.Drawing.Point(747, 85) Me.tbBitrate.Margin = New Padding(0) Me.tbBitrate.Name = "tbBitrate" Me.tbBitrate.ReadOnly = False Me.tbBitrate.Size = New System.Drawing.Size(139, 55) Me.tbBitrate.TabIndex = 41 Me.tbBitrate.TextBox.TextAlign = HorizontalAlignment.Center ' 'laBitrate ' Me.laBitrate.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.laBitrate.Location = New System.Drawing.Point(498, 75) Me.laBitrate.Margin = New Padding(0) Me.laBitrate.Size = New System.Drawing.Size(249, 75) Me.laBitrate.Text = "Video Bitrate:" Me.laBitrate.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'blFilesize ' Me.blFilesize.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.blFilesize.Location = New System.Drawing.Point(6, 75) Me.blFilesize.Margin = New Padding(6, 0, 0, 0) Me.blFilesize.Name = "blFilesize" Me.blFilesize.Size = New System.Drawing.Size(243, 75) Me.blFilesize.TabIndex = 59 Me.blFilesize.TabStop = True Me.blFilesize.Text = "Size:" Me.blFilesize.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lgbSource ' Me.lgbSource.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.tlpMain.SetColumnSpan(Me.lgbSource, 2) Me.lgbSource.Controls.Add(Me.tlpSource) Me.lgbSource.Location = New System.Drawing.Point(9, 81) Me.lgbSource.Margin = New Padding(9, 0, 6, 0) Me.lgbSource.Name = "lgbSource" Me.lgbSource.Padding = New Padding(6, 0, 6, 6) Me.lgbSource.Size = New System.Drawing.Size(1008, 357) Me.lgbSource.TabIndex = 57 Me.lgbSource.TabStop = False Me.lgbSource.Text = "Source" ' 'tlpSource ' Me.tlpSource.ColumnCount = 1 Me.tlpSource.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 50.0!)) Me.tlpSource.Controls.Add(Me.tbSourceFile, 0, 0) Me.tlpSource.Controls.Add(Me.lSource1, 0, 1) Me.tlpSource.Controls.Add(Me.lSource2, 0, 2) Me.tlpSource.Controls.Add(Me.tlpSourceValues, 0, 3) Me.tlpSource.Dock = DockStyle.Fill Me.tlpSource.Location = New System.Drawing.Point(6, 48) Me.tlpSource.Margin = New Padding(0) Me.tlpSource.Name = "tlpSource" Me.tlpSource.RowCount = 4 Me.tlpSource.RowStyles.Add(New RowStyle(SizeType.Percent, 34.0!)) Me.tlpSource.RowStyles.Add(New RowStyle(SizeType.Percent, 22.0!)) Me.tlpSource.RowStyles.Add(New RowStyle(SizeType.Percent, 22.0!)) Me.tlpSource.RowStyles.Add(New RowStyle(SizeType.Percent, 22.0!)) Me.tlpSource.Size = New System.Drawing.Size(996, 303) Me.tlpSource.TabIndex = 62 ' 'tlpSourceValues ' Me.tlpSourceValues.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.tlpSourceValues.ColumnCount = 7 Me.tlpSourceValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpSourceValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpSourceValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpSourceValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpSourceValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpSourceValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpSourceValues.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100.0!)) Me.tlpSourceValues.Controls.Add(Me.blSourceDarText, 4, 0) Me.tlpSourceValues.Controls.Add(Me.lSourcePAR, 3, 0) Me.tlpSourceValues.Controls.Add(Me.blSourceParText, 2, 0) Me.tlpSourceValues.Controls.Add(Me.lCrop, 1, 0) Me.tlpSourceValues.Controls.Add(Me.lCropText, 0, 0) Me.tlpSourceValues.Controls.Add(Me.lSourceDar, 5, 0) Me.tlpSourceValues.Location = New System.Drawing.Point(0, 225) Me.tlpSourceValues.Margin = New Padding(0) Me.tlpSourceValues.Name = "tlpSourceValues" Me.tlpSourceValues.RowCount = 1 Me.tlpSourceValues.RowStyles.Add(New RowStyle(SizeType.Percent, 100.0!)) Me.tlpSourceValues.Size = New System.Drawing.Size(996, 78) Me.tlpSourceValues.TabIndex = 1 ' 'blSourceDarText ' Me.blSourceDarText.Anchor = AnchorStyles.None Me.blSourceDarText.AutoSize = True Me.blSourceDarText.Location = New System.Drawing.Point(446, 15) Me.blSourceDarText.Name = "blSourceDarText" Me.blSourceDarText.Size = New System.Drawing.Size(97, 48) Me.blSourceDarText.TabIndex = 51 Me.blSourceDarText.Text = "DAR:" Me.blSourceDarText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lSourcePAR ' Me.lSourcePAR.Anchor = AnchorStyles.None Me.lSourcePAR.AutoSize = True Me.lSourcePAR.Location = New System.Drawing.Point(400, 15) Me.lSourcePAR.Margin = New Padding(9, 0, 9, 0) Me.lSourcePAR.Size = New System.Drawing.Size(34, 48) Me.lSourcePAR.Text = "-" Me.lSourcePAR.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'blSourceParText ' Me.blSourceParText.Anchor = AnchorStyles.None Me.blSourceParText.AutoSize = True Me.blSourceParText.Location = New System.Drawing.Point(291, 15) Me.blSourceParText.Margin = New Padding(9, 0, 9, 0) Me.blSourceParText.Name = "blSourceParText" Me.blSourceParText.Size = New System.Drawing.Size(91, 48) Me.blSourceParText.TabIndex = 45 Me.blSourceParText.TabStop = True Me.blSourceParText.Text = "PAR:" Me.blSourceParText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lCrop ' Me.lCrop.Anchor = AnchorStyles.None Me.lCrop.AutoSize = True Me.lCrop.Location = New System.Drawing.Point(120, 15) Me.lCrop.Margin = New Padding(9, 0, 9, 0) Me.lCrop.Size = New System.Drawing.Size(153, 48) Me.lCrop.Text = "disabled" Me.lCrop.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lCropText ' Me.lCropText.Anchor = AnchorStyles.None Me.lCropText.AutoSize = True Me.lCropText.Location = New System.Drawing.Point(3, 15) Me.lCropText.Size = New System.Drawing.Size(105, 48) Me.lCropText.TabStop = True Me.lCropText.Text = "Crop:" Me.lCropText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lSourceDar ' Me.lSourceDar.Anchor = AnchorStyles.None Me.lSourceDar.AutoSize = True Me.lSourceDar.Location = New System.Drawing.Point(549, 15) Me.lSourceDar.Size = New System.Drawing.Size(34, 48) Me.lSourceDar.Text = "-" Me.lSourceDar.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'tbSourceFile ' Me.tbSourceFile.Anchor = CType((AnchorStyles.Left Or AnchorStyles.Right), AnchorStyles) Me.tbSourceFile.AutoSize = True Me.tbSourceFile.Location = New System.Drawing.Point(6, 10) Me.tbSourceFile.Margin = New Padding(6, CInt(FontHeight / 1.5), 6, FontHeight \ 2) Me.tbSourceFile.Padding = New Padding(6, FontHeight \ 2, 6, FontHeight \ 2) Me.tbSourceFile.Name = "tbSourceFile" Me.tbSourceFile.ReadOnly = False Me.tbSourceFile.TabIndex = 2 ' 'lSource1 ' Me.lSource1.Anchor = CType((AnchorStyles.Left Or AnchorStyles.Right), AnchorStyles) Me.lSource1.Location = New System.Drawing.Point(6, 84) Me.lSource1.Margin = New Padding(6, 0, 6, 0) Me.lSource1.Size = New System.Drawing.Size(984, 57) Me.lSource1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lSource2 ' Me.lSource2.Anchor = CType((AnchorStyles.Left Or AnchorStyles.Right), AnchorStyles) Me.lSource2.Location = New System.Drawing.Point(6, 159) Me.lSource2.Margin = New Padding(6, 0, 6, 0) Me.lSource2.Size = New System.Drawing.Size(984, 57) Me.lSource2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lgbResize ' Me.lgbResize.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Me.tlpMain.SetColumnSpan(Me.lgbResize, 2) Me.lgbResize.Controls.Add(Me.tlpResize) Me.lgbResize.Location = New System.Drawing.Point(688, 438) Me.lgbResize.Margin = New Padding(6, 0, 6, 0) Me.lgbResize.Name = "lgbResize" Me.lgbResize.Padding = New Padding(6, 0, 6, 6) Me.lgbResize.Size = New System.Drawing.Size(670, _filterHeight) Me.lgbResize.TabIndex = 55 Me.lgbResize.TabStop = False Me.lgbResize.Text = "Resize" ' 'tlpResize ' Me.tlpResize.ColumnCount = 4 Me.tlpResize.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpResize.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpResize.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpResize.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 25.0!)) Me.tlpResize.Controls.Add(Me.tlpResizeValues, 0, 2) Me.tlpResize.Controls.Add(Me.tbResize, 0, 1) Me.tlpResize.Controls.Add(Me.lTargetWidth, 0, 0) Me.tlpResize.Controls.Add(Me.tbTargetWidth, 1, 0) Me.tlpResize.Controls.Add(Me.lTargetHeight, 2, 0) Me.tlpResize.Controls.Add(Me.tbTargetHeight, 3, 0) Me.tlpResize.Dock = DockStyle.Fill Me.tlpResize.Location = New System.Drawing.Point(6, 48) Me.tlpResize.Name = "tlpResize" Me.tlpResize.RowCount = 3 Me.tlpResize.RowStyles.Add(New RowStyle(SizeType.Absolute, 81.0!)) Me.tlpResize.RowStyles.Add(New RowStyle(SizeType.Absolute, 81.0!)) Me.tlpResize.RowStyles.Add(New RowStyle(SizeType.Percent, 100.0!)) Me.tlpResize.Size = New System.Drawing.Size(658, 232) Me.tlpResize.TabIndex = 63 Me.tlpResize.SetColumnSpan(Me.tlpResizeValues, 4) ' 'tlpResizeValues ' Me.tlpResizeValues.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) Or AnchorStyles.Left) Or AnchorStyles.Right), AnchorStyles) Me.tlpResizeValues.ColumnCount = 4 Me.tlpResizeValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpResizeValues.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 33.0!)) Me.tlpResizeValues.ColumnStyles.Add(New ColumnStyle()) Me.tlpResizeValues.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 40.0!)) Me.tlpResizeValues.Controls.Add(Me.blCropText, 0, 1) Me.tlpResizeValues.Controls.Add(Me.lCrop2, 1, 1) Me.tlpResizeValues.SetColumnSpan(Me.lCrop2, 3) Me.tlpResizeValues.Controls.Add(Me.blTargetDarText, 0, 2) Me.tlpResizeValues.Controls.Add(Me.lDAR, 1, 2) Me.tlpResizeValues.Controls.Add(Me.lPixelText, 2, 2) Me.tlpResizeValues.Controls.Add(Me.lPixel, 3, 2) Me.tlpResizeValues.Controls.Add(Me.lSarText, 0, 3) Me.tlpResizeValues.Controls.Add(Me.lSAR, 1, 3) Me.tlpResizeValues.Controls.Add(Me.lZoomText, 2, 3) Me.tlpResizeValues.Controls.Add(Me.lZoom, 3, 3) Me.tlpResizeValues.Controls.Add(Me.blTargetParText, 0, 4) Me.tlpResizeValues.Controls.Add(Me.lPAR, 1, 4) Me.tlpResizeValues.Controls.Add(Me.lAspectRatioErrorText, 2, 4) Me.tlpResizeValues.Controls.Add(Me.lAspectRatioError, 3, 4) Me.tlpResizeValues.Location = New System.Drawing.Point(0, 162) Me.tlpResizeValues.Margin = New Padding(0) Me.tlpResizeValues.Name = "tlpResizeValues" Me.tlpResizeValues.RowCount = 11 Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 5.0!)) Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 15.0!)) Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 15.0!)) Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 15.0!)) Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 15.0!)) Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 15.0!)) Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 15.0!)) Me.tlpResizeValues.RowStyles.Add(New RowStyle(SizeType.Percent, 5.0!)) Me.tlpResizeValues.Size = New System.Drawing.Size(658, 70) Me.tlpResizeValues.TabIndex = 62 ' 'blTargetDarText ' Me.blTargetDarText.Anchor = AnchorStyles.Left Me.blTargetDarText.AutoSize = True Me.blTargetDarText.ImeMode = ImeMode.NoControl Me.blTargetDarText.Location = New System.Drawing.Point(0, 0) Me.blTargetDarText.Margin = New Padding(0) Me.blTargetDarText.Name = "blTargetDarText" Me.blTargetDarText.Size = New System.Drawing.Size(97, 23) Me.blTargetDarText.TabIndex = 23 Me.blTargetDarText.Text = "DAR:" Me.blTargetDarText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lPAR ' Me.lPAR.Anchor = AnchorStyles.Left Me.lPAR.AutoSize = True Me.lPAR.Location = New System.Drawing.Point(97, 46) Me.lPAR.Margin = New Padding(0) Me.lPAR.Size = New System.Drawing.Size(34, 24) Me.lPAR.Text = "-" Me.lPAR.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lZoom ' Me.lZoom.Anchor = AnchorStyles.Left Me.lZoom.AutoSize = True Me.lZoom.Location = New System.Drawing.Point(253, 23) Me.lZoom.Margin = New Padding(0) Me.lZoom.Size = New System.Drawing.Size(34, 23) Me.lZoom.Text = "-" Me.lZoom.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lSarText ' Me.lSarText.Anchor = AnchorStyles.Left Me.lSarText.AutoSize = True Me.lSarText.Location = New System.Drawing.Point(0, 23) Me.lSarText.Margin = New Padding(0) Me.lSarText.Size = New System.Drawing.Size(92, 23) Me.lSarText.Text = "SAR:" Me.lSarText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lPixel ' Me.lPixel.Anchor = AnchorStyles.Left Me.lPixel.AutoSize = True Me.lPixel.Location = New System.Drawing.Point(253, 0) Me.lPixel.Margin = New Padding(0) Me.lPixel.Size = New System.Drawing.Size(34, 23) Me.lPixel.Text = "-" Me.lPixel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'blTargetParText ' Me.blTargetParText.Anchor = AnchorStyles.Left Me.blTargetParText.AutoSize = True Me.blTargetParText.Location = New System.Drawing.Point(0, 46) Me.blTargetParText.Margin = New Padding(0) Me.blTargetParText.Name = "blTargetParText" Me.blTargetParText.Size = New System.Drawing.Size(91, 24) Me.blTargetParText.TabIndex = 51 Me.blTargetParText.Text = "PAR:" Me.blTargetParText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lAspectRatioError ' Me.lAspectRatioError.Anchor = AnchorStyles.Left Me.lAspectRatioError.AutoSize = True Me.lAspectRatioError.Location = New System.Drawing.Point(253, 46) Me.lAspectRatioError.Margin = New Padding(0) Me.lAspectRatioError.Size = New System.Drawing.Size(34, 24) Me.lAspectRatioError.Text = "-" Me.lAspectRatioError.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lAspectRatioErrorText ' Me.lAspectRatioErrorText.Anchor = AnchorStyles.Left Me.lAspectRatioErrorText.AutoSize = True Me.lAspectRatioErrorText.Location = New System.Drawing.Point(131, 46) Me.lAspectRatioErrorText.Margin = New Padding(0) Me.lAspectRatioErrorText.Size = New System.Drawing.Size(106, 24) Me.lAspectRatioErrorText.Text = "Error:" Me.lAspectRatioErrorText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lCrop2 ' Me.lCrop2.Anchor = AnchorStyles.Left Me.lCrop2.AutoSize = True Me.lCrop2.Location = New System.Drawing.Point(253, 46) Me.lCrop2.Margin = New Padding(0) Me.lCrop2.Size = New System.Drawing.Size(34, 24) Me.lCrop2.Text = "-" Me.lCrop2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'blCropText ' Me.blCropText.Anchor = AnchorStyles.Left Me.blCropText.AutoSize = True Me.blCropText.Location = New System.Drawing.Point(131, 46) Me.blCropText.Margin = New Padding(0) Me.blCropText.Size = New System.Drawing.Size(106, 24) Me.blCropText.Text = "Crop:" Me.blCropText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft Me.blCropText.ClickAction = AddressOf ShowCropDialog ' 'lDAR ' Me.lDAR.Anchor = AnchorStyles.Left Me.lDAR.AutoSize = True Me.lDAR.ImeMode = ImeMode.NoControl Me.lDAR.Location = New System.Drawing.Point(97, 0) Me.lDAR.Margin = New Padding(0) Me.lDAR.Size = New System.Drawing.Size(34, 23) Me.lDAR.Text = "-" Me.lDAR.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lZoomText ' Me.lZoomText.Anchor = AnchorStyles.Left Me.lZoomText.AutoSize = True Me.lZoomText.Location = New System.Drawing.Point(131, 23) Me.lZoomText.Margin = New Padding(0) Me.lZoomText.Size = New System.Drawing.Size(122, 23) Me.lZoomText.Text = "Zoom:" Me.lZoomText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lPixelText ' Me.lPixelText.Anchor = AnchorStyles.Left Me.lPixelText.AutoSize = True Me.lPixelText.Location = New System.Drawing.Point(131, 0) Me.lPixelText.Margin = New Padding(0) Me.lPixelText.Size = New System.Drawing.Size(102, 23) Me.lPixelText.Text = "Pixel:" Me.lPixelText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'lSAR ' Me.lSAR.Anchor = AnchorStyles.Left Me.lSAR.AutoSize = True Me.lSAR.Location = New System.Drawing.Point(97, 23) Me.lSAR.Margin = New Padding(0) Me.lSAR.Size = New System.Drawing.Size(34, 23) Me.lSAR.Text = "-" Me.lSAR.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'tbResize ' Me.tbResize.Anchor = CType((((AnchorStyles.Top Or AnchorStyles.Bottom) _ Or AnchorStyles.Left) _ Or AnchorStyles.Right), AnchorStyles) Me.tbResize.AutoSize = False Me.tlpResize.SetColumnSpan(Me.tbResize, 4) Me.tbResize.Location = New System.Drawing.Point(0, 81) Me.tbResize.Margin = New Padding(0) Me.tbResize.Minimum = 0 Me.tbResize.TickFrequency = TrackBarTicks Me.tbResize.Name = "tbResize" Me.tbResize.Size = New System.Drawing.Size(658, 81) Me.tbResize.TabIndex = 46 ' 'lTargetWidth ' Me.lTargetWidth.Anchor = AnchorStyles.Left Me.lTargetWidth.AutoSize = True Me.lTargetWidth.Location = New System.Drawing.Point(3, 16) Me.lTargetWidth.Size = New System.Drawing.Size(124, 48) Me.lTargetWidth.Text = "Width:" Me.lTargetWidth.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'tbTargetWidth ' Me.tbTargetWidth.Anchor = AnchorStyles.Left Me.tbTargetWidth.BorderStyle = BorderStyle.FixedSingle Me.tbTargetWidth.Location = New System.Drawing.Point(167, 13) Me.tbTargetWidth.Name = "tbTargetWidth" Me.tbTargetWidth.ReadOnly = False Me.tbTargetWidth.Size = New System.Drawing.Size(145, 55) Me.tbTargetWidth.TabIndex = 39 Me.tbTargetWidth.TextBox.TextAlign = HorizontalAlignment.Center ' 'lTargetHeight ' Me.lTargetHeight.Anchor = AnchorStyles.Left Me.lTargetHeight.AutoSize = True Me.lTargetHeight.Location = New System.Drawing.Point(331, 16) Me.lTargetHeight.Size = New System.Drawing.Size(135, 48) Me.lTargetHeight.Text = "Height:" Me.lTargetHeight.TextAlign = System.Drawing.ContentAlignment.MiddleLeft ' 'tbTargetHeight ' Me.tbTargetHeight.Anchor = AnchorStyles.Left Me.tbTargetHeight.BorderStyle = BorderStyle.FixedSingle Me.tbTargetHeight.Location = New System.Drawing.Point(495, 13) Me.tbTargetHeight.Name = "tbTargetHeight" Me.tbTargetHeight.ReadOnly = False Me.tbTargetHeight.Size = New System.Drawing.Size(145, 55) Me.tbTargetHeight.TabIndex = 40 Me.tbTargetHeight.TextBox.TextAlign = HorizontalAlignment.Center ' 'lgbFilters ' Me.lgbFilters.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Me.lgbFilters.Controls.Add(Me.FiltersListView) Me.lgbFilters.Location = New System.Drawing.Point(9, 438) Me.lgbFilters.Margin = New Padding(9, 0, 6, 0) Me.lgbFilters.Name = "lgbFilters" Me.lgbFilters.Padding = New Padding(6, CInt(FontHeight / 1.5), 6, FontHeight \ 4) Me.lgbFilters.Size = New System.Drawing.Size(667, _filterHeight) Me.lgbFilters.TabIndex = 53 Me.lgbFilters.TabStop = False ' 'FiltersListView ' Me.FiltersListView.AllowDrop = True Me.FiltersListView.AutoCheckMode = StaxRip.UI.AutoCheckMode.None Me.FiltersListView.CheckBoxes = True Me.FiltersListView.Dock = DockStyle.Fill Me.FiltersListView.FullRowSelect = True Me.FiltersListView.HeaderStyle = ColumnHeaderStyle.None Me.FiltersListView.HideSelection = False Me.FiltersListView.IsLoading = False Me.FiltersListView.Location = New System.Drawing.Point(9, 81) Me.FiltersListView.Margin = New Padding(6, FontHeight \ 2, 6, FontHeight \ 4) Me.FiltersListView.MultiSelect = False Me.FiltersListView.Name = "FiltersListView" Me.FiltersListView.OwnerDraw = True Me.FiltersListView.Padding = New Padding(6, FontHeight \ 2, 6, FontHeight \ 4) Me.FiltersListView.Size = New System.Drawing.Size(649, 226) Me.FiltersListView.TabIndex = 0 Me.FiltersListView.UseCompatibleStateImageBehavior = False Me.FiltersListView.View = View.Details ' 'lgbEncoder ' Me.lgbEncoder.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Me.lgbEncoder.Controls.Add(Me.llMuxer) Me.lgbEncoder.Controls.Add(Me.pnEncoder) Me.lgbEncoder.Location = New System.Drawing.Point(1370, 438) Me.lgbEncoder.Margin = New Padding(6, 0, 9, 0) Me.lgbEncoder.Name = "lgbEncoder" Me.lgbEncoder.Padding = New Padding(6, CInt(FontHeight / 1.5), 6, FontHeight \ 4) Me.lgbEncoder.Size = New System.Drawing.Size(670, _filterHeight) Me.lgbEncoder.TabIndex = 51 Me.lgbEncoder.TabStop = False ' 'llMuxer ' Me.llMuxer.Anchor = AnchorStyles.Top Or AnchorStyles.Right Me.llMuxer.AutoSize = True Me.llMuxer.Location = New System.Drawing.Point(536, 0) Me.llMuxer.Name = "llMuxer" Me.llMuxer.Size = New System.Drawing.Size(201, 48) Me.llMuxer.TabIndex = 1 Me.llMuxer.TabStop = True Me.llMuxer.Text = "Muxer" Me.llMuxer.TextAlign = ContentAlignment.MiddleRight ' 'pnEncoder ' Me.pnEncoder.Dock = DockStyle.Fill Me.pnEncoder.Location = New System.Drawing.Point(9, 51) Me.pnEncoder.Name = "pnEncoder" Me.pnEncoder.Margin = New Padding(6, FontHeight \ 2, 6, FontHeight \ 4) Me.pnEncoder.Padding = New Padding(6, 0, 6, 0) Me.pnEncoder.Size = New System.Drawing.Size(652, 226) Me.pnEncoder.TabIndex = 0 ' 'tlpMain ' Me.tlpMain.AutoSize = False Me.tlpMain.ColumnCount = 4 Me.tlpMain.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 33.33!)) Me.tlpMain.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 375.0!)) Me.tlpMain.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 375.0!)) Me.tlpMain.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 33.33!)) Me.tlpMain.Controls.Add(Me.MenuStrip, 0, 0) Me.tlpMain.Controls.Add(Me.lgbSource, 0, 1) Me.tlpMain.Controls.Add(Me.lgbTarget, 2, 1) Me.tlpMain.Controls.Add(Me.lgbFilters, 0, 2) Me.tlpMain.Controls.Add(Me.lgbResize, 1, 2) Me.tlpMain.Controls.Add(Me.lgbEncoder, 3, 2) Me.tlpMain.Controls.Add(Me.gbAudio, 0, 3) Me.tlpMain.Controls.Add(Me.gbAssistant, 0, 4) Me.tlpMain.Dock = DockStyle.Fill Me.tlpMain.Location = New System.Drawing.Point(0, 0) Me.tlpMain.Margin = New Padding(0) Me.tlpMain.Name = "tlpMain" Me.tlpMain.RowCount = 5 Me.tlpMain.RowStyles.Add(New RowStyle(SizeType.Absolute, 81.0!)) Me.tlpMain.RowStyles.Add(New RowStyle(SizeType.Absolute, 357.0!)) Me.tlpMain.RowStyles.Add(New RowStyle(SizeType.Absolute, _filterHeight)) Me.tlpMain.RowStyles.Add(New RowStyle(SizeType.AutoSize)) Me.tlpMain.RowStyles.Add(New RowStyle(SizeType.Absolute, 250.0!)) Me.tlpMain.TabIndex = 61 ' 'MainForm ' Me.AllowDrop = True Me.AutoScaleDimensions = New System.Drawing.SizeF(288.0!, 288.0!) Me.AutoScaleMode = AutoScaleMode.Dpi Me.Controls.Add(Me.tlpMain) Me.FormBorderStyle = FormBorderStyle.Sizable Me.HelpButton = True Me.MainMenuStrip = Me.MenuStrip Me.Margin = New Padding(9, 12, 9, 12) Me.MaximizeBox = False Me.Name = "MainForm" Me.Text = $"{g.DefaultCommands.GetApplicationDetails()}" Me.StartPosition = FormStartPosition.CenterScreen Me.gbAssistant.ResumeLayout(False) Me.tlpAssistant.ResumeLayout(False) Me.tlpAssistant.PerformLayout() Me.gbAudio.ResumeLayout(False) Me.tlpAudio.ResumeLayout(False) Me.tlpAudio.PerformLayout() Me.lgbTarget.ResumeLayout(False) Me.lgbTarget.PerformLayout() Me.tlpTarget.ResumeLayout(False) Me.lgbSource.ResumeLayout(False) Me.lgbSource.PerformLayout() Me.tlpSource.ResumeLayout(False) Me.tlpSourceValues.ResumeLayout(False) Me.tlpSourceValues.PerformLayout() Me.lgbResize.ResumeLayout(False) Me.lgbResize.PerformLayout() Me.tlpResize.ResumeLayout(False) Me.tlpResize.PerformLayout() Me.tlpResizeValues.ResumeLayout(False) Me.tlpResizeValues.PerformLayout() CType(Me.tbResize, System.ComponentModel.ISupportInitialize).EndInit() Me.lgbFilters.ResumeLayout(False) Me.lgbFilters.PerformLayout() Me.lgbEncoder.ResumeLayout(False) Me.lgbEncoder.PerformLayout() Me.tlpMain.ResumeLayout(False) Me.ResumeLayout(False) Me.ScaleSize(44, 44) End Sub #End Region Public WithEvents CustomMainMenu As CustomMenu Public WithEvents CustomSizeMenu As CustomMenu Public CurrentAssistantTipKey As String Public BlockSubtitlesItemCheck As Boolean Public AssistantPassed As Boolean Public CommandManager As New CommandManager Public Property LastTbTargetFileText As String = "" Public Property PreviewScript As VideoScript Private TargetAspectRatioMenu As ContextMenuStripEx Private SizeContextMenuStrip As ContextMenuStripEx Private EncoderMenu As ContextMenuStripEx Private ContainerMenu As ContextMenuStripEx Private SourceAspectRatioMenu As ContextMenuStripEx Private TargetFileMenu As ContextMenuStripEx Private SourceFileMenu As ContextMenuStripEx Private NextContextMenuStrip As ContextMenuStripEx Private CanIgnoreTip As Boolean = True Private IsLoading As Boolean = True Private BlockBitrate, BlockSize As Boolean Private SkipAssistant As Boolean Private BlockSourceTextBoxTextChanged As Boolean Private AssistantClickAction As Action Private ThemeRefresh As Boolean Private Const TrackBarInterval As Integer = 16 Private Const TrackBarTicks As Integer = 4 Sub New(loadSettings As Boolean) AddHandler Application.ThreadException, AddressOf g.OnUnhandledException g.MainForm = Me If loadSettings Then g.LoadSettings() g.LoadAudioProfiles() g.LoadVideoEncoderProfiles() g.LoadEvents() PowerShell.InitCode = "Using namespace StaxRip;" + BR + "Using namespace StaxRip.UI;" + BR + "[Reflection.Assembly]::LoadWithPartialName(""StaxRip"")" If s.WriteDebugLog Then Dim filePath = Path.Combine(Folder.Startup, "Debug.log") If File.Exists(filePath) Then File.Delete(filePath) End If Dim listener = New TextWriterTraceListener(filePath) With { .TraceOutputOptions = TraceOptions.ThreadId Or TraceOptions.DateTime } Trace.Listeners.Add(listener) Trace.AutoFlush = True End If MenuItemEx.UseTooltips = s.EnableTooltips Icon = g.Icon g.DPI = DeviceDpi InitializeComponent() RestoreClientSize(60, 36) SetStyle(ControlStyles.SupportsTransparentBackColor, True) If components Is Nothing Then components = New Container() End If SetTip() TargetAspectRatioMenu = New ContextMenuStripEx(components) SizeContextMenuStrip = New ContextMenuStripEx(components) EncoderMenu = New ContextMenuStripEx(components) AddHandler EncoderMenu.Opening, Sub(sender As Object, e As CancelEventArgs) MenuOpening(sender, lgbEncoder.Tag) ContainerMenu = New ContextMenuStripEx(components) AddHandler ContainerMenu.Opening, Sub(sender As Object, e As CancelEventArgs) MenuOpening(sender, llMuxer.Tag) SourceAspectRatioMenu = New ContextMenuStripEx(components) TargetFileMenu = New ContextMenuStripEx(components) SourceFileMenu = New ContextMenuStripEx(components) NextContextMenuStrip = New ContextMenuStripEx(components) tbTargetFile.TextBox.ContextMenuStrip = TargetFileMenu tbSourceFile.TextBox.ContextMenuStrip = SourceFileMenu Dim rc = "right-click" tbSourceFile.TextBox.SendMessageCue(rc, False) tbTargetFile.TextBox.SendMessageCue(rc, False) MenuStrip.SuspendLayout() MenuStrip.Font = FontManager.GetDefaultFont() CommandManager.AddCommandsFromObject(Me) CommandManager.AddCommandsFromObject(g.DefaultCommands) CustomMainMenu = New CustomMenu(AddressOf GetDefaultMainMenu, s.CustomMenuMainForm, CommandManager, MenuStrip) OpenProject(g.StartupTemplatePath) CustomMainMenu.AddKeyDownHandler(Me) CustomMainMenu.BuildMenu() UpdateAudioMenus() UpdateTargetSizeLabel() MenuStrip.ResumeLayout() SizeContextMenuStrip.SuspendLayout() CustomSizeMenu = New CustomMenu(AddressOf GetDefaultMenuSize, s.CustomMenuSize, CommandManager, SizeContextMenuStrip) CustomSizeMenu.AddKeyDownHandler(Me) CustomSizeMenu.BuildMenu() SizeContextMenuStrip.ResumeLayout() NextContextMenuStrip.Add("Add to top and open Jobs", Sub() AddJob(True, 0)) NextContextMenuStrip.Add("Add to bottom and open Jobs", Sub() AddJob(True, -1)) NextContextMenuStrip.Add("-") NextContextMenuStrip.Add("Add to top w/o opening Jobs", Sub() AddJob(False, 0)) NextContextMenuStrip.Add("Add to bottom w/o opening Jobs", Sub() AddJob(False, -1)) g.SetRenderer(MenuStrip) ThemeManager.SetCurrentTheme(s.ThemeName) ApplyTheme() AddHandler ThemeManager.CurrentThemeChanged, AddressOf OnThemeChanged AddHandler FiltersListView.Changed, AddressOf ApplyFilters End Sub Protected Overrides Sub Dispose(disposing As Boolean) RemoveHandler ThemeManager.CurrentThemeChanged, AddressOf OnThemeChanged components?.Dispose() MyBase.Dispose(disposing) End Sub Sub OnThemeChanged(theme As Theme) ApplyTheme() Assistant(False) End Sub Sub ApplyTheme() ApplyTheme(ThemeManager.CurrentTheme) End Sub Sub ApplyTheme(theme As Theme) ApplyTheme(GetAllControls(), theme) End Sub Sub ApplyTheme(controls As IEnumerable(Of Control)) ApplyTheme(controls, ThemeManager.CurrentTheme) End Sub Sub ApplyTheme(controls As IEnumerable(Of Control), theme As Theme) If DesignHelp.IsDesignMode Then Exit Sub End If BackColor = theme.General.BackColor For Each control In controls.OfType(Of Label) If control Is laTip Then If CanIgnoreTip Then control.BackColor = theme.MainForm.laTipBackColor control.ForeColor = theme.MainForm.laTipForeColor Else control.BackColor = theme.MainForm.laTipBackHighlightColor control.ForeColor = theme.MainForm.laTipForeHighlightColor End If Else control.BackColor = theme.General.Controls.Label.BackColor control.ForeColor = theme.General.Controls.Label.ForeColor End If Next For Each control In controls.OfType(Of ButtonLabel) control.ApplyTheme(theme) control.BackColor = If(TypeOf control.Parent Is UserControl, theme.General.Controls.ListView.BackColor, theme.General.Controls.ButtonLabel.BackColor) Next For Each control In controls.OfType(Of ToggleButtonLabel) control.ApplyTheme(theme) control.BackColor = If(TypeOf control.Parent Is UserControl, theme.General.Controls.ListView.BackColor, theme.General.Controls.ToggleButtonLabel.BackColor) Next For Each control In controls.OfType(Of ButtonEx) control.ApplyTheme(theme) Next For Each control In controls.OfType(Of GroupBox) control.BackColor = theme.General.Controls.GroupBox.BackColor control.ForeColor = theme.General.Controls.GroupBox.ForeColor Next For Each control In controls.OfType(Of Panel) control.BackColor = theme.General.Controls.Panel.BackColor control.ForeColor = theme.General.Controls.Panel.ForeColor Next For Each control In controls.OfType(Of TableLayoutPanel) control.BackColor = theme.General.Controls.TableLayoutPanel.BackColor control.ForeColor = theme.General.Controls.TableLayoutPanel.ForeColor Next For Each control In controls.OfType(Of TextBox) control.BackColor = theme.General.Controls.TextBox.BackColor control.ForeColor = theme.General.Controls.TextBox.ForeColor Next For Each control In controls.OfType(Of TextBoxEx) control.BorderColor = theme.General.Controls.TextBox.BorderColor control.BorderFocusedColor = theme.General.Controls.TextBox.BorderFocusedColor Next For Each control In controls.OfType(Of TextEdit) control.BackColor = theme.General.Controls.TextEdit.BackColor control.ForeColor = theme.General.Controls.TextEdit.ForeColor control.BorderColor = theme.General.Controls.TextEdit.BorderColor control.BorderFocusedColor = theme.General.Controls.TextEdit.BorderFocusedColor Next For Each control In controls.OfType(Of TrackBar) control.BackColor = theme.General.Controls.TrackBar.BackColor control.ForeColor = theme.General.Controls.TrackBar.ForeColor Next pnEncoder.BackColor = theme.General.Controls.ListView.BackColor End Sub Sub MenuOpening(sender As Object, tag As Object) Dim menu = TryCast(sender, ContextMenuStripEx) If menu Is Nothing Then Return If tag Is Nothing Then Return Dim allItems = menu.GetItems().OfType(Of MenuItemEx) Dim selectedItem = allItems.Where(Function(x) tag IsNot Nothing AndAlso tag.Equals(x.Tag)).OrderBy(Function(x) x.Path.Length).FirstOrDefault() If selectedItem Is Nothing Then Return Dim selectedSubPath = If(selectedItem IsNot Nothing, selectedItem.Path.LeftLast(" | "), "") Dim selectedSubSubPath = selectedSubPath.LeftLast(" | ") Dim selectedPathLevel = If(selectedItem IsNot Nothing, Regex.Matches(selectedItem.Path, " \| ").Count, 0) For Each item As MenuItemEx In allItems.Where(Function(x) Not String.IsNullOrEmpty(x.Path)) Dim sameLevel = Regex.Matches(item.Path, " \| ").Count = selectedPathLevel item.CheckState = CheckState.Unchecked item.CheckState = If(Not sameLevel AndAlso (selectedSubPath.Equals(item.Path) OrElse (selectedPathLevel > 1 AndAlso selectedSubSubPath.StartsWith(item.Path))), CheckState.Indeterminate, item.CheckState) item.CheckState = If(item.Path = selectedItem?.Path, CheckState.Checked, item.CheckState) Dim desiredFont = New Font(item.Font, If(item.CheckState = CheckState.Checked, FontStyle.Bold, FontStyle.Regular)) If Not item.Font.Equals(desiredFont) Then item.Font = desiredFont Next End Sub Function GetIfoFile() As String Dim ret = p.SourceFile.Dir If New DirectoryInfo(ret).Name.EndsWithEx("_temp") Then ret = ret.Parent End If ret = Path.Combine(ret, p.SourceFile.FileName.DeleteRight(5) + "0.ifo") If File.Exists(ret) Then Return ret End If End Function Sub RenameDVDTracks() Dim ifoPath = GetIfoFile() If Not File.Exists(ifoPath) Then Exit Sub End If For Each i In Directory.GetFiles(p.TempDir) If g.IsSourceSame(i) AndAlso i.Contains("VTS") Then Dim regex As New Regex(" T(\d\d) ") Dim match = regex.Match(i) If match.Success Then Dim dgID = CInt(match.Groups(1).Value) Using mi As New MediaInfo(ifoPath) 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 = i.Base base = regex.Replace(base, " ID" & x & " ") If base.Contains("2_0ch") Then base = base.Replace("2_0ch", "2ch") End If If base.Contains("3_2ch") Then base = base.Replace("3_2ch", "6ch") End If If base.Contains(" DELAY") Then base = base.Replace(" DELAY", "") End If If base.Contains(" 0ms") Then base = base.Replace(" 0ms", "") End If If stream.Language.TwoLetterCode <> "iv" Then base += " " + stream.Language.EnglishName End If If stream.Title <> "" Then base += " " + stream.Title End If FileHelp.Move(i, Path.Combine(i.Dir, base + i.ExtFull)) End If Next End Using End If End If Next End Sub Function IsSaveCanceled(Optional saveProject As Boolean = True) As Boolean SetLastModifiedTemplate() If s.ApplicationExitMode <> ApplicationExitMode.Regular Then Select Case s.ApplicationExitMode Case ApplicationExitMode.BypassProjectSaving Return False Case ApplicationExitMode.ForceProjectSaving If g.ProjectPath IsNot Nothing Then SaveProjectPath(g.ProjectPath) End If Return False Case Else Throw New NotImplementedException() End Select If g.ProjectPath Is Nothing Then If Not OpenSaveProjectDialog() Then Return True End If Else SaveProjectPath(g.ProjectPath) End If End If If ObjectHelp.GetCompareString(g.SavedProject) <> ObjectHelp.GetCompareString(p) Then 'If String.IsNullOrWhiteSpace(p.SourceFile) AndAlso Log.Length > 0 Then Return False If s.AutoSaveProject AndAlso p.SourceFile <> "" Then If g.ProjectPath Is Nothing Then g.ProjectPath = Path.Combine(p.TempDir, p.TargetFile.Base + ".srip") End If SaveProjectPath(g.ProjectPath) Return False End If Using td As New TaskDialog(Of DialogResult) td.Title = "Save changed project?" td.AddButton("Save", DialogResult.Yes) td.AddButton("Don't Save", DialogResult.No) td.AddButton("Cancel", DialogResult.Cancel) td.Show() Refresh() If td.SelectedValue = DialogResult.Yes Then If g.ProjectPath Is Nothing Then If Not OpenSaveProjectDialog() Then Return True End If Else SaveProjectPath(g.ProjectPath) End If ElseIf td.SelectedValue = DialogResult.Cancel Then Return True Else Return False End If End Using End If End Function Sub UpdateRecentProjectsMenu() If Disposing OrElse IsDisposed Then Exit Sub For Each mi In CustomMainMenu.MenuItems If mi.CustomMenuItem?.MethodName = "DynamicMenuItem" AndAlso mi.CustomMenuItem.Parameters(0).Equals(DynamicMenuItemID.RecentProjects) Then mi.DropDownItems.ClearAndDisplose SyncLock s.RecentProjects For Each recentProj In s.RecentProjects If File.Exists(recentProj) AndAlso Not recentProj.Base = "recover" Then Dim name = recentProj If recentProj.Length > 70 Then name = "..." + name.Remove(0, name.Length - 70) End If mi.DropDownItems.Add(New MenuItemEx(name, Sub() LoadProject(recentProj))) End If Next End SyncLock Exit For End If Next End Sub Sub UpdateDynamicMenuAsync() Task.Run(Sub() Thread.Sleep(500) Try Invoke(Sub() UpdateDynamicMenu()) Catch End Try End Sub) End Sub Sub UpdateDynamicMenu() PopulateProfileMenu(DynamicMenuItemID.EncoderProfiles) PopulateProfileMenu(DynamicMenuItemID.MuxerProfiles) PopulateProfileMenu(DynamicMenuItemID.AudioProfiles) PopulateProfileMenu(DynamicMenuItemID.FilterSetupProfiles) For Each iMenuItem In CustomMainMenu.MenuItems If iMenuItem.CustomMenuItem.MethodName = "DynamicMenuItem" Then If iMenuItem.CustomMenuItem.Parameters(0).Equals(DynamicMenuItemID.HelpApplications) Then iMenuItem.DropDownItems.ClearAndDisplose For Each pack In Package.Items.Values MenuItemEx.Add(iMenuItem.DropDownItems, pack.Name.Substring(0, 1).ToUpperInvariant + " | " + pack.ID, Sub() pack.ShowHelp()) Next End If End If Next Application.DoEvents() End Sub Async Sub UpdateScriptsMenuAsync() Dim files As String() = {} Dim events As String() = System.Enum.GetNames(GetType(ApplicationEvent)) Await Task.Run(Sub() If Folder.Scripts.DirExists Then files = Directory.GetFiles(Folder.Scripts) End If End Sub) If IsDisposed OrElse Native.GetForegroundWindow() <> Handle OrElse files.Count = 0 Then Exit Sub End If For Each menuItem In CustomMainMenu.MenuItems If menuItem.CustomMenuItem.MethodName = "DynamicMenuItem" Then If menuItem.CustomMenuItem.Parameters(0).Equals(DynamicMenuItemID.Scripts) Then menuItem.DropDownItems.ClearAndDisplose For Each path In files If Not events.Contains(path.FileName.Left(".")) AndAlso Not path.FileName.StartsWith("_") Then MenuItemEx.Add(menuItem.DropDownItems, path.FileName.Base, Sub() g.DefaultCommands.ExecutePowerShellFile(path)) End If Next menuItem.DropDownItems.Add(New ToolStripSeparator) MenuItemEx.Add(menuItem.DropDownItems, "Open Script Folder", Sub() g.ShellExecute(Folder.Scripts)) End If End If Next End Sub Async Sub UpdateTemplatesMenuAsync() If IsDisposed Then Exit Sub Dim templates As IEnumerable(Of String) = Nothing Await Task.Run(Sub() Thread.Sleep(500) For Each iFile In Directory.GetFiles(Folder.Template, "*.srip.backup") FileHelp.Move(iFile, Path.Combine(iFile.Dir, "Backup", iFile.Base)) Next templates = Directory.GetFiles(Folder.Template, "*.srip", SearchOption.AllDirectories).OrderBy(Function(x) x.Count(Function(c) c = Path.DirectorySeparatorChar)).ThenBy(Function(x) x) End Sub) For i = 0 To CustomMainMenu.MenuItems.Count - 1 Dim menuItem = CustomMainMenu.MenuItems(i) If IsDisposed Then Exit Sub If menuItem.CustomMenuItem.MethodName <> "DynamicMenuItem" OrElse Not menuItem.CustomMenuItem.Parameters(0).Equals(DynamicMenuItemID.TemplateProjects) Then Continue For menuItem.DropDownItems.ClearAndDisplose() Dim items As New List(Of MenuItemEx) For Each template In templates Dim text = template.Replace(Folder.Template, "").Trim(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, " | ") text = text.Substring(0, text.LastIndexOf(".srip")) text += If(template = g.StartupTemplatePath, " (Startup)", "") MenuItemEx.Add(menuItem.DropDownItems, text, AddressOf LoadProject, template, Nothing) Next menuItem.DropDownItems.Add("-") MenuItemEx.Add(menuItem.DropDownItems, "Explore", Sub() g.ShellExecute(Folder.Template), "Opens the directory containing the templates.") MenuItemEx.Add(menuItem.DropDownItems, "Restore", AddressOf ResetTemplates, "Restores the default templates.") Exit For Next If IsDisposed Then Exit Sub Application.DoEvents() End Sub Sub ResetTemplates() If MsgQuestion("Restore the default templates?") = DialogResult.OK Then Try FolderHelp.Delete(Folder.Template) Folder.Template.ToString() UpdateTemplatesMenuAsync() Catch ex As Exception g.ShowException(ex) End Try End If End Sub Sub LoadTemplate(name As String) Dim templates = Directory.GetFiles(Folder.Template, "*.srip", SearchOption.AllDirectories) For Each template In templates Dim temp = template.Replace(Folder.Template, "").Trim(Path.DirectorySeparatorChar) Dim text1 = temp.Substring(0, temp.LastIndexOf(".srip")) Dim text2 = text1.Replace(Path.DirectorySeparatorChar, " | ") If {text1.ToLowerEx(), text2.ToLowerEx()}.Contains(name.ToLowerEx()) Then LoadProject(template) Exit Sub End If Next End Sub Function LoadTemplateWithSelectionDialog(sources As IEnumerable(Of String), timeout As Integer, Optional templateFolder As String = "") As Boolean Return LoadTemplateWithSelectionDialog(sources?.Join("; "), timeout, templateFolder) End Function Function LoadTemplateWithSelectionDialog(sources As String(), timeout As Integer, Optional templateFolder As String = "") As Boolean Return LoadTemplateWithSelectionDialog(sources?.Join("; "), timeout, templateFolder) End Function Function LoadTemplateWithSelectionDialog(source As String, timeout As Integer, Optional templateFolder As String = "") As Boolean If Not templateFolder.DirExists Then templateFolder = Folder.Template If Not templateFolder.DirExists Then Return False Dim directories = Directory.GetDirectories(templateFolder, "*", SearchOption.TopDirectoryOnly).ToList() Dim templates = Directory.GetFiles(templateFolder, "*.srip", SearchOption.TopDirectoryOnly)?.Where(Function(x) x <> g.StartupTemplatePath)?.OrderBy(Function(x) x).ToList() If Not templates?.Any() Then Return True Using td As New TaskDialog(Of String) td.Timeout = If(s.ShowTemplateSelectionDefault = ShowTemplateSelectionDefaultMode.None, 0, timeout) td.Title = "Select a template" td.Content = If(String.IsNullOrWhiteSpace(source), "Please select a template you want to use:", $"Please select a template you want to use for:{BR}{source}") td.Icon = TaskIcon.Question Dim isModified = ObjectHelp.GetCompareString(g.SavedProject) <> ObjectHelp.GetCompareString(p) Dim isStartup = Not isModified AndAlso p.TemplateName = s.StartupTemplate If p.SourceFile = "" Then Dim postfix = If(isStartup, "(Startup and Current Template)", "(Current Template)") Dim name = If(isModified, "Current Template", $"{p.TemplateName} {postfix}") td.AddCommand(name, "CURRENT") Else td.AddCommand("Last set Template", "LAST") End If If isModified OrElse Not isStartup Then td.AddCommand(g.StartupTemplatePath.Base() + " (Startup)", g.StartupTemplatePath, ThemeManager.CurrentTheme.TaskDialog.Button.TimeoutBackColor.SetHue(ThemeManager.CurrentTheme.HighlightHue)) End If If templateFolder.Contains(Folder.Template + Path.DirectorySeparatorChar) Then td.AddCommand($". . {Path.DirectorySeparatorChar}", "UP") End If For i = 0 To templates.Count() - 1 Dim text = templates(i).Replace(Folder.Template, "").Trim(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, $" {Path.DirectorySeparatorChar} ") text = text.Substring(0, text.LastIndexOf(".srip")) If text <> p.TemplateName OrElse isModified Then td.AddCommand(text, templates(i)) End If Next For i = 0 To directories.Count() - 1 Dim text = directories(i).Replace(Folder.Template, "").Trim(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, $" {Path.DirectorySeparatorChar} ") text += $" {Path.DirectorySeparatorChar} . ." td.AddCommand(text, directories(i)) Next If s.ShowTemplateSelectionDefault = ShowTemplateSelectionDefaultMode.None Then td.AddButton("Abort", "", False) ElseIf s.ShowTemplateSelectionDefault = ShowTemplateSelectionDefaultMode.Abort Then td.AddButton("Abort", "", True) ElseIf s.ShowTemplateSelectionDefault = ShowTemplateSelectionDefaultMode.CurrentLast Then If p.SourceFile = "" Then td.AddButton("Current Template", "CURRENT", True) Else td.AddButton("Last set Template", "LAST", True) End If td.AddButton("Abort", "", False) ElseIf s.ShowTemplateSelectionDefault = ShowTemplateSelectionDefaultMode.Startup Then td.AddButton("Startup Template", g.StartupTemplatePath, True) td.AddButton("Abort", "", False) End If Dim selection = td.Show() If selection = "" Then Return False ElseIf selection = "CURRENT" Then Return True ElseIf selection = "LAST" Then Return OpenProject(g.LastModifiedTemplate) ElseIf selection = "UP" Then Return LoadTemplateWithSelectionDialog(source, timeout, templateFolder.Dir()) ElseIf selection.DirExists() Then Return LoadTemplateWithSelectionDialog(source, timeout, selection) Else Return OpenProject(td.SelectedValue, True) End If End Using End Function Sub AddBatchJobs(sourcefiles As String()) If sourcefiles Is Nothing Then Return For Each sourcefile In sourcefiles AddBatchJob(sourcefile) Next End Sub Sub AddBatchJob(sourcefile As String) Dim batchFolder = Path.Combine(Folder.Settings, "Batch Projects") If Not Directory.Exists(batchFolder) Then Directory.CreateDirectory(batchFolder) End If g.RaiseAppEvent(ApplicationEvent.BeforeJobAdding) sourcefile = sourcefile.TrimQuotes() Dim batchProject = ObjectHelp.GetCopy(Of Project)(p) batchProject.BatchMode = True batchProject.SourceFiles = {sourcefile}.ToList Dim splits = sourcefile.Dir.Split(Path.DirectorySeparatorChar) Dim joins = splits.Select(Function(x) x.Substring(0, Math.Min(x.Length, 128 \ splits.Length))).Join("-").Replace(":", "-") Dim jobPath = Path.Combine(batchFolder, joins + " " + p.TemplateName + " - " + sourcefile.FileName + ".srip") SafeSerialization.Serialize(batchProject, jobPath) JobManager.AddJob(sourcefile.Base, jobPath) End Sub Function LoadProject(path As String) As Boolean SetLastModifiedTemplate() Refresh() If Not File.Exists(path) Then MsgWarn("Project file not found.", $"{path}{BR}could not be found.") s.UpdateRecentProjects(path) UpdateRecentProjectsMenu() UpdateTemplatesMenuAsync() Return False Else Return OpenProject(path) End If End Function Function OpenSaveProjectDialog() As Boolean Using dialog As New SaveFileDialog dialog.SetInitDir(p.TempDir) dialog.FileName = If(p.SourceFile <> "", p.TargetFile.Base, "Untitled") dialog.Filter = $"StaxRip Project Files (*.srip)|*.srip" If dialog.ShowDialog() = DialogResult.OK Then If Not dialog.FileName.ToLowerInvariant.EndsWith(".srip") Then dialog.FileName += ".srip" End If SaveProjectPath(dialog.FileName) Return True End If End Using End Function Function OpenSaveTemplateDialog() As Boolean If p.SourceFile = "" Then Using dialog As New SaveFileDialog Dim tp As String Try Dim dirName = Path.GetDirectoryName(p.TemplatePath) If Directory.Exists(dirName) Then tp = dirName Catch ex As Exception tp = Folder.Template End Try dialog.SetInitDir(tp) dialog.FileName = If(p.TemplateName <> "", p.TemplateName, "Untitled") dialog.Filter = $"StaxRip Template Files (*.srip)|*.srip" If dialog.ShowDialog() = DialogResult.OK Then Dim fp = Path.GetFullPath(dialog.FileName) If Not fp.StartsWith(Folder.Template, StringComparison.OrdinalIgnoreCase) Then If MsgQuestion("Saving outside Template Folder", "You are going to save the template outside of the Template Folder, so this template won't be able to be used!", TaskButton.OkCancel) = DialogResult.Cancel Then Return False End If End If If Not fp.ToLower.EndsWith(".srip") Then fp += ".srip" End If SaveProjectPath(fp) UpdateTemplatesMenuAsync() Return True End If End Using Else MsgWarn("A template cannot be created after a source file was opened.") End If End Function Sub SetBindings(proj As Project, add As Boolean) SetTextBoxBinding(tbTargetFile, proj, NameOf(Project.TargetFile), add) RemoveHandler proj.PropertyChanged, AddressOf ProjectPropertyChanged If add Then AddHandler proj.PropertyChanged, AddressOf ProjectPropertyChanged End If End Sub Sub ProjectPropertyChanged(sender As Object, e As PropertyChangedEventArgs) Assistant() End Sub Sub SetTextBoxBinding(tb As TextBox, obj As Object, prop As String, add As Boolean) tb.DataBindings.Clear() If add Then tb.DataBindings.Add(New Binding(NameOf(TextBox.Text), obj, prop, False, DataSourceUpdateMode.OnPropertyChanged)) End If End Sub Sub SetTextBoxBinding(te As TextEdit, obj As Object, prop As String, add As Boolean) te.TextBox.DataBindings.Clear() If add Then te.TextBox.DataBindings.Add(New Binding(NameOf(TextBox.Text), obj, prop, False, DataSourceUpdateMode.OnPropertyChanged)) End If End Sub Function OpenProject(Optional path As String = Nothing) As Boolean Return OpenProject(path, True) End Function Function OpenProject(path As String, saveCurrentFirst As Boolean) As Boolean Try SetLastModifiedTemplate() If Not IsLoading AndAlso saveCurrentFirst AndAlso IsSaveCanceled() Then Return False If String.IsNullOrWhiteSpace(path) OrElse Not File.Exists(path) Then path = g.StartupTemplatePath Try p = SafeSerialization.Deserialize(New Project, path) Catch ex As Exception g.ShowException(ex, "Project file failed to load", "It will be reset to defaults." + BR2 + path) p = New Project() p.Init() End Try Return OpenProject(p, path) Catch ex As Exception OpenProject(g.StartupTemplatePath) End Try End Function Function OpenProject(proj As Project, Optional path As String = "", Optional markAsPChanged As Boolean = True) As Boolean Try SetLastModifiedTemplate() If proj IsNot Nothing AndAlso g.LastModifiedTemplate IsNot Nothing AndAlso ObjectHelp.GetCompareString(proj).Equals(ObjectHelp.GetCompareString(g.LastModifiedTemplate)) Then proj = ObjectHelp.GetCopy(g.LastModifiedTemplate) If String.IsNullOrWhiteSpace(path) Then path = proj.TemplatePath If path = "" Then Dim templates = Directory.GetFiles(Folder.Template, "*.srip", SearchOption.AllDirectories).Where(Function(x) x.Base() = proj.TemplateName).ToList() If templates.Count = 0 Then g.ShowException(New FileNotFoundException(), "Template not found", $"'{proj.TemplateName}' was not found") ElseIf templates.Count = 1 Then path = templates.First() Else g.ShowException(New Exception("Too many templates with the same name found and could not choose.")) End If End If ElseIf String.IsNullOrWhiteSpace(path) OrElse Not File.Exists(path) Then path = g.StartupTemplatePath End If p = If(proj IsNot Nothing, proj, SafeSerialization.Deserialize(New Project(), path)) Log = p.Log FileHelp.Delete(IO.Path.Combine(Folder.Temp, "staxrip.log")) SetBindings(p, True) Text = $"{path.Base} - {g.DefaultCommands.GetApplicationDetails()}" If Not Environment.Is64BitProcess Then Text += " (32 bit)" End If PreviewScript = Nothing SkipAssistant = True If path.StartsWith(Folder.Template) Then g.ProjectPath = Nothing p.TemplateName = path.Base p.TemplatePath = path p.BatchMode = False Dim nnm = TypeOf p.Videoencoder.Muxer IsNot NullMuxer If nnm AndAlso Not p.VideoEncoder.Muxer.CanEdit Then p.VideoEncoder.Muxer.CanEdit = nnm SaveProjectPath(path) End If Else g.ProjectPath = path End If g.SetTempDir() Dim width = p.TargetWidth Dim height = p.TargetHeight Dim size = p.TargetSize Dim bitrate = p.VideoBitrate FiltersListView.Load() FiltersListView.Items(0).Selected = True If p.SourceFile = "" AndAlso p.SourceFiles.Any() Then p.SourceFile = p.SourceFiles(0) If p.SourceFile <> "" Then s.LastSourceDir = p.SourceFile.Dir BlockSourceTextBoxTextChanged = True tbSourceFile.Text = p.SourceFile BlockSourceTextBoxTextChanged = False p.VideoEncoder.OnStateChange() If p.TargetFile = "" Then p.VideoEncoder.UpdateTargetFile(True) End If tbTargetFile.TextBox.SelectionStart = tbTargetFile.Text.Length SetAudioTracks(p) If p.BitrateIsFixed Then tbBitrate.Text = "" tbBitrate.Text = bitrate.ToString Else tbTargetSize.Text = "" tbTargetSize.Text = size.ToString() End If SetSlider() tbTargetWidth.Text = width.ToString tbTargetHeight.Text = height.ToString If markAsPChanged Then SetSavedProject() SkipAssistant = False Assistant(False) s.UpdateRecentProjects(path) UpdateRecentProjectsMenu() g.RaiseAppEvent(ApplicationEvent.AfterProjectLoaded) g.RaiseAppEvent(ApplicationEvent.AfterProjectOrSourceLoaded) FiltersListView.RebuildMenu() If p.SourceFile <> "" AndAlso Not g.VerifyRequirements Then Throw New AbortException End If Return True Catch ex As Exception OpenProject(g.StartupTemplatePath) Finally SkipAssistant = False End Try End Function Sub SetSlider() tbResize.Maximum = ((Calc.FixMod(p.SourceWidth, TrackBarInterval) \ 2) * 3) \ Math.Max(TrackBarInterval, p.ForcedOutputMod) tbResize.Maximum += If(tbResize.Maximum Mod 3 = 0, 0, 1) tbResize.Maximum += If(tbResize.Maximum Mod 3 = 0, 0, 1) End Sub Sub SetSavedProject() g.SavedProject = ObjectHelp.GetCopy(Of Project)(p) End Sub Sub SetLastModifiedTemplate() If p.SourceFile <> "" OrElse Not p.Log.IsEmpty Then Exit Sub g.LastModifiedTemplate = ObjectHelp.GetCopy(Of Project)(p) End Sub Sub SetAudioTracks(Optional proj As Project = Nothing) proj = If(proj, p) proj.AudioTracks = If(proj.AudioTracks, New List(Of AudioTrack)) Dim availableAudioTracks = Mathf.Clamp(proj.AudioTracksAvailable, 1, 25) Dim sourceFile = p.LastOriginalSourceFile Dim streams = If(sourceFile.FileExists(), MediaInfo.GetAudioStreams(sourceFile), New List(Of AudioStream)) Dim ateHeight = -1 'tlpAudio.SuspendLayout() Try tlpAudio.Controls.Clear() tlpAudio.RowStyles.Clear() If proj.AudioTracks.Count > availableAudioTracks Then For index = proj.AudioTracks.Count - 1 To availableAudioTracks - 1 Step -1 proj.AudioTracks(index).TextEdit.Dispose() proj.AudioTracks(index).LanguageLabel.Dispose() proj.AudioTracks(index).NameLabel.Dispose() proj.AudioTracks(index).EditLabel.Dispose() proj.AudioTracks.RemoveAt(index) Next End If For i = 0 To availableAudioTracks - 1 Dim index = i Dim textEditContextMenuStripEx = New ContextMenuStripEx(components) Dim audioTrack As AudioTrack Dim audioProfile As AudioProfile = If(index < proj.AudioTracks.Count AndAlso proj.AudioTracks(index)?.AudioProfile IsNot Nothing, proj.AudioTracks(index)?.AudioProfile, New MuxAudioProfile()) If audioProfile.Streams Is Nothing OrElse Not audioProfile.Streams.Any() Then audioProfile.Streams = streams Dim textEdit = New AudioTextEdit(index) Dim languageLabel = New AudioLanguageLabel(index) With { .Text = audioProfile.Language.Name } Dim nameLabel = New AudioNameButtonLabel(index) With { .ContextMenuStripEx = New ContextMenuStripEx(components), .ClickAction = Sub() .ContextMenuStripEx.Show(audioTrack.NameLabel, 0, 16) End Sub } Dim editLabel = New AudioEditButtonLabel(index) With { .ClickAction = Sub() audioTrack.AudioProfile.EditProject() UpdateAudioMenus() UpdateSizeOrBitrate() nameLabel.Text = g.ConvertPath(audioTrack.AudioProfile.Name) languageLabel.Text = audioTrack.AudioProfile.Language.Name ShowAudioTip(audioTrack.AudioProfile) End Sub } textEdit.TextBox.ContextMenuStrip = textEditContextMenuStripEx TipProvider.SetTip("Shows the assigned language", languageLabel) TipProvider.SetTip("Shows audio profiles", nameLabel) TipProvider.SetTip("Opens audio settings for the current project/template", editLabel) Dim textEditTextChanged = Sub(sender As Object, e As EventArgs) AudioTextEditChanged(audioTrack) End Sub Dim textEditDoubleClick = Sub(sender As Object, e As EventArgs) AudioTextEditDoubleClick(audioTrack) End Sub Dim textEditMouseDown = Sub(sender As Object, e As MouseEventArgs) If e.Button = MouseButtons.Right Then UpdateAudioFileMenu(audioTrack, index, Sub() textEditDoubleClick(Nothing, Nothing)) End If End Sub AddHandler textEdit.TextChanged, textEditTextChanged AddHandler textEdit.DoubleClick, textEditDoubleClick AddHandler textEdit.MouseDown, textEditMouseDown If proj.AudioTracks.ElementAtOrDefault(index) Is Nothing Then audioTrack = New AudioTrack(index) With {.AudioProfile = audioProfile, .EditLabel = editLabel, .LanguageLabel = languageLabel, .NameLabel = nameLabel, .TextEdit = textEdit} proj.AudioTracks.Add(audioTrack) Else audioTrack = New AudioTrack(index) With {.AudioProfile = proj.AudioTracks(index).AudioProfile, .EditLabel = editLabel, .LanguageLabel = languageLabel, .NameLabel = nameLabel, .TextEdit = textEdit} proj.AudioTracks(index) = audioTrack End If Next For index = 0 To proj.AudioTracks.Count - 1 tlpAudio.Controls.Add(proj.AudioTracks(index).RowLabel, 0, index) tlpAudio.Controls.Add(proj.AudioTracks(index).TextEdit, 1, index) tlpAudio.Controls.Add(proj.AudioTracks(index).LanguageLabel, 2, index) tlpAudio.Controls.Add(proj.AudioTracks(index).NameLabel, 3, index) tlpAudio.Controls.Add(proj.AudioTracks(index).EditLabel, 4, index) Next Catch ex As Exception Finally tlpAudio.RowCount = availableAudioTracks For Each ate In tlpAudio.Controls.OfType(Of AudioTextEdit) ateHeight = ate.Height + ate.Margin.Vertical ate.TextBox.SendMessageCue("right-click", False) tlpAudio.RowStyles.Add(New RowStyle(SizeType.AutoSize)) Next 'tlpAudio.ResumeLayout() SetFormBoundaries(ateHeight) UpdateAudioMenus() PopulateProfileMenu(DynamicMenuItemID.AudioProfiles) End Try End Sub Sub AddAudioTracks() If p.AudioTracks.Count = 0 Then Exit Sub Dim files = g.GetFilesInTempDirAndParent().AsEnumerable() files = files.Where(Function(x) FileTypes.Audio.Contains(x.Ext.ToLowerInvariant())) files = files.Where(Function(x) g.IsSourceSame(x)) files = files.Where(Function(x) x.Ext.ToLowerInvariant() <> "avs") files = files.Where(Function(x) Not x.ToLowerInvariant().Contains("_cut_")) files = files.Where(Function(x) Not x.ToLowerInvariant().Contains("_out")) files = files.Where(Function(x) Not x.ToLowerInvariant().Matches("_chunk\d+$")) files = files.OrderBy(Function(x) x, New StringLogicalComparer()).ToList() Dim hqAudioFiles = files.Where(Function(x) FileTypes.AudioHQ.Contains(x.Ext())) Dim normalAudioFiles = files.Where(Function(x) (FileTypes.Audio.Except(FileTypes.AudioHQ)).Contains(x.Ext())) Dim orderedAudioFiles = hqAudioFiles.Concat(normalAudioFiles).Distinct() Dim groupedAudioFiles = orderedAudioFiles.GroupBy(Function(x) g.ExtractLanguageFromPath(x)).ToList() Dim setLanguages = p.AudioTracks.Select(Function(x) x.AudioProfile.Language).Where(Function(x) x.IsDetermined).Select(Function(x) x.ThreeLetterCode) Dim preferredAudios = p.PreferredAudio.ToLowerInvariant().SplitNoEmptyAndWhiteSpace(",", ";", " ") Dim selectedAudios = preferredAudios.Concat(setLanguages.Distinct().Except(preferredAudios)).ToList() Dim audioTracks As New List(Of (FilePath As String, Language As Language, Stream As AudioStream)) Dim addAudioTrack = Sub(groupIndex As Integer, pathIndex As Integer) If groupedAudioFiles.Count <= groupIndex Then Exit Sub If groupedAudioFiles(groupIndex) Is Nothing Then Exit Sub If groupedAudioFiles(groupIndex).Count() <= pathIndex Then Exit Sub If groupedAudioFiles(groupIndex)(pathIndex) = "" Then Exit Sub Dim filePath = groupedAudioFiles(groupIndex)(pathIndex) Dim baseName = filePath.Base().UnescapeIllegalFileSysChars() audioTracks.Add((filePath, groupedAudioFiles(groupIndex).Key, Nothing)) End Sub Dim audioStreams = New MediaInfo(p.SourceFile)?.AudioStreams Dim addAudioStream = Sub(index As Integer) If index >= audioStreams.Count Then Exit Sub If audioStreams(index) Is Nothing Then Exit Sub If p.DemuxAudio = DemuxMode.Dialog Then Exit Sub If s.Demuxers.Any(Function(x) x.Active AndAlso TypeOf x Is eac3toDemuxer AndAlso x.InputExtensions.Contains(p.SourceFile.Ext())) Then Exit Sub audioTracks.Add((audioStreams(index).Name, audioStreams(index).Language, audioStreams(index))) End Sub For i = 0 To selectedAudios.Count() - 1 Dim selectedAudio = selectedAudios(i) Dim idMatch = Regex.Match(selectedAudio, "^(\d+)([^,; ]*)$", RegexOptions.IgnoreCase) Dim languageMatch = Regex.Match(selectedAudio, "^([a-z]{2,}|[a-z]{2,4}(?:-[a-z]{2,})-[a-z]{2,5})([^,; ]*)$", RegexOptions.IgnoreCase) If idMatch.Success Then Dim id = idMatch.Groups(1).Value Dim fileAdded = False For j = 0 To groupedAudioFiles.Count() - 1 Dim item = groupedAudioFiles(j) If item Is Nothing Then Continue For For k = 0 To item.Count() - 1 If Not Regex.IsMatch(item(k).Base(), $"ID{id}\D") Then Continue For addAudioTrack(j, k) Next fileAdded = True Next If Not fileAdded Then addAudioStream(id.ToInt() - 1) End If ElseIf languageMatch.Success Then Dim prefLangString = languageMatch.Groups(1).Value Dim prefLang = New Language(prefLangString) For j = 0 To groupedAudioFiles.Count() - 1 Dim item = groupedAudioFiles(j) If item IsNot Nothing Then If prefLangString.ToLowerInvariant() <> "all" AndAlso prefLang.ThreeLetterCode <> item.Key.ThreeLetterCode AndAlso prefLang.Name <> item.Key.Name Then Continue For If prefLangString.ToLowerInvariant() = "all" AndAlso selectedAudios.Contains(item.Key.ThreeLetterCode, StringComparer.OrdinalIgnoreCase) Then Continue For For k = 0 To item.Count() - 1 Dim index = k If prefLangString.ToLowerInvariant() = "all" AndAlso audioTracks?.Any(Function(x) x.FilePath = item(index)) Then Continue For addAudioTrack(j, k) Next End If Next For j = 0 To audioStreams.Count() - 1 Dim item = audioStreams(j) If item IsNot Nothing Then If prefLangString.ToLowerInvariant() <> "all" AndAlso prefLang.ThreeLetterCode <> item.Language.ThreeLetterCode AndAlso prefLang.Name <> item.Language.Name Then Continue For If prefLangString.ToLowerInvariant() = "all" AndAlso selectedAudios.Contains(item.Language.ThreeLetterCode, StringComparer.OrdinalIgnoreCase) Then Continue For If audioTracks?.Any(Function(x) x.FilePath.ContainsEx("ID" + (item.Index + 1).ToString()) AndAlso x.Language.ThreeLetterCode = item.Language.ThreeLetterCode) Then Continue For addAudioStream(j) End If Next End If Next Dim addTrack = Sub(source As (FilePath As String, Language As Language, Stream As AudioStream), dest As AudioTrack) If source.FilePath = "" Then Return If dest Is Nothing Then Return dest.AudioProfile.Reset(dest.Index) If source.Stream Is Nothing Then dest.TextEdit.Text = source.FilePath dest.AudioProfile.File = source.FilePath Else dest.AudioProfile.File = p.SourceFile dest.AudioProfile.Stream = source.Stream dest.TextEdit.Text = $"{source.Stream.Name} ({p.SourceFile?.Ext()})" End If dest.AudioProfile.Language = source.Language dest.LanguageLabel.Refresh() End Sub For index = 0 To audioTracks.Count - 1 Dim i = index If String.IsNullOrWhiteSpace(audioTracks(i).FilePath) Then Continue For Dim sameLanguages = p.AudioTracks.Where(Function(x) x.TextEdit.Text = "" AndAlso TypeOf x.AudioProfile IsNot NullAudioProfile AndAlso x.AudioProfile.Language.ThreeLetterCode = audioTracks(i).Language.ThreeLetterCode).ToList() If sameLanguages.Any() Then addTrack(audioTracks(i), sameLanguages.First()) Else For index2 = 0 To p.AudioTracks.Count - 1 Dim j = index2 If TypeOf p.AudioTracks(j).AudioProfile Is NullAudioProfile Then Continue For If p.AudioTracks(j).TextEdit.Text <> "" Then Continue For If p.AudioTracks(j).AudioProfile.Language.IsDetermined AndAlso p.AudioTracks(j).AudioProfile.Language.ThreeLetterCode <> audioTracks(i).Language.ThreeLetterCode Then Continue For addTrack(audioTracks(i), p.AudioTracks(j)) Exit For Next End If Next End Sub Function GetAudioTextBox(ap As AudioProfile) As TextEdit Return p.AudioTracks.FirstOrDefault(Function(x) x.AudioProfile Is ap)?.TextEdit End Function Dim BlockAudioTextChanged As Boolean Sub AudioTextEditChanged(audioTrack As AudioTrack) If audioTrack Is Nothing Then Exit Sub If BlockAudioTextChanged Then Exit Sub Dim te = audioTrack.TextEdit Dim ap = audioTrack.AudioProfile If te.Text.Contains(":\") OrElse te.Text.StartsWith("\\") Then If te.Text <> ap.File Then ap.Reset(audioTrack.Index) ap.File = te.Text If FileTypes.Audio.Contains(ap.File.Ext) Then If Not p.Script.GetFilter("Source").Script.Contains("DirectShowSource") Then ap.Delay += g.ExtractDelay(ap.File) End If If p.TakeOverAudioName Then If ap.StreamName = "" AndAlso ap.File.Contains("{") Then ap.StreamName = g.ExtractTrackNameFromFilename(ap.File) End If End If If p.TakeOverAudioDefault Then ap.Default = ( ap.Stream IsNot Nothing AndAlso ap.Stream.Default) OrElse g.ExtractDefaultFlagFromFilename(ap.File) If p.TakeOverAudioForced Then ap.Forced = ( ap.Stream IsNot Nothing AndAlso ap.Stream.Forced) OrElse g.ExtractForcedFlagFromFilename(ap.File) End If ap.SetStreamOrLanguage() End If UpdateSizeOrBitrate() BlockAudioTextChanged = True te.Text = ap.DisplayName BlockAudioTextChanged = False ElseIf te.Text = "" Then audioTrack.Remove() UpdateSizeOrBitrate() End If audioTrack.LanguageLabel?.Refresh() audioTrack.NameLabel.Text = g.ConvertPath(audioTrack.AudioProfile.Name) End Sub Sub AudioTextEditDoubleClick(audioTrack As AudioTrack) Using dialog As New OpenFileDialog Dim filter = FileTypes.Audio.ToList() filter.Insert(0, "avs") dialog.SetFilter(filter) dialog.SetInitDir(p.TempDir, s.LastSourceDir) If dialog.ShowDialog() = DialogResult.OK Then audioTrack.TextEdit.Text = dialog.FileName End If End Using End Sub Function GetPathFromIndexFile(sourcePath As String) As String For Each i In File.ReadAllLines(sourcePath) If i.Contains(":\") OrElse i.StartsWith("\\") Then If Regex.IsMatch(i, "^.+ \d+$") Then i = i.LeftLast(" ") End If If File.Exists(i) AndAlso FileTypes.Video.Contains(i.Ext) Then Return i End If End If Next End Function Function ShowSourceFilterSelectionDialog(inputFile As String) As VideoFilter Dim filters As New List(Of VideoFilter) If inputFile.Ext.EqualsAny("mp4", "m4v", "mov") Then AddSourceFilters({"LSMASHVideoSource", "LibavSMASHSource"}, filters) End If If FileTypes.Video.Contains(inputFile.Ext) AndAlso Not FileTypes.VideoText.Contains(inputFile.Ext) Then AddSourceFilters({"BestSource", "FFVideoSource", "LWLibavVideoSource", "ffms2", "LWLibavSource"}, filters) End If If g.IsCOMObjectRegistered(GUIDS.LAVSplitter) AndAlso g.IsCOMObjectRegistered(GUIDS.LAVVideoDecoder) Then AddSourceFilters({"DSS2"}, filters) End If If {"avi", "avs", "vdr"}.Contains(inputFile.Ext) Then AddSourceFilters({"AVISource"}, filters) End If If inputFile.Ext = "d2v" Then AddSourceFilters({"d2vsource"}, filters) End If If p.Script.IsAviSynth Then filters = filters.Where(Function(filter) Not filter.Script.Replace(" ", "").Contains("clip=core.")).ToList filters.Insert(0, New VideoFilter("Source", "Automatic", "#avs")) Else filters = filters.Where(Function(filter) filter.Script.Replace(" ", "").Contains("clip=core.")).ToList filters.Insert(0, New VideoFilter("Source", "Automatic", "#vs")) End If Dim td As New TaskDialog(Of VideoFilter) With { .Title = If(p.Script.IsAviSynth, "Select an AviSynth source filter:", "Select a VapourSynth source filter:") } For Each f In filters td.AddCommand(f.Name, f) Next Dim ret = td.Show td.Dispose() If ret Is Nothing Then Throw New AbortException End If ret.Script = Macro.ExpandGUI(ret.Script, True).Value Return ret End Function Sub AddSourceFilters(filterNames As String(), filters As List(Of VideoFilter)) Dim avsProfiles = s.AviSynthProfiles.Where(Function(cat) cat.Name = "Source").First.Filters Dim vsProfiles = s.VapourSynthProfiles.Where(Function(cat) cat.Name = "Source").First.Filters Dim allFilters = avsProfiles.Concat(vsProfiles) For Each f In allFilters For Each filterName In filterNames If f.Script.ToLowerInvariant.Contains(filterName.ToLowerInvariant + "(") OrElse f.Script.ToLowerInvariant.Contains(filterName.ToLowerInvariant + ".") Then If filters.Where(Function(val) val.Name = f.Name).Count = 0 Then filters.Add(f.GetCopy) End If End If Next Next End Sub Sub OpenAnyFile(files As IEnumerable(Of String), showTemplateSelection As Boolean, Optional errorTimeout As Integer = 0) If files Is Nothing Then Exit Sub If Not files.Any() Then Exit Sub SetLastModifiedTemplate() Dim showTemplateSelectionTimeout = If(s.ShowTemplateSelection <> ShowTemplateSelectionMode.Never, s.ShowTemplateSelectionTimeout, 0) files = files.Select(Function(filePath) New FileInfo(filePath.TrimQuotes()).FullName) If files(0).Ext = "srip" Then OpenProject(files(0)) ElseIf FileTypes.Video.Contains(files(0).Ext.ToLowerInvariant) Then files = files.OrderBy(Function(x) FileTypes.Video.Contains(x.Ext)).ThenBy(Function(x) FileTypes.Audio.Contains(x.Ext)) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(files, showTemplateSelectionTimeout) Then OpenVideoSourceFiles(files, True, errorTimeout) Else Exit Sub End If Else OpenVideoSourceFiles(files, True, errorTimeout) End If ElseIf FileTypes.IsoImage.ContainsAny(files.Select(Function(s) s.Ext.ToLowerInvariant)) Then files = files.Where(Function(x) FileTypes.IsoImage.Contains(x.Ext().ToLowerInvariant())).OrderBy(Function(x) x, New StringLogicalComparer()) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(files(0), showTemplateSelectionTimeout) Then OpenBlurayImage(files(0)) Else Exit Sub End If Else OpenBlurayImage(files(0)) End If ElseIf FileTypes.Audio.ContainsAny(files.Select(Function(s) s.Ext.ToLowerInvariant)) Then Dim audioFiles = files.Where(Function(x) FileTypes.Audio.Contains(x.Ext().ToLowerInvariant())).OrderBy(Function(x) x, New StringLogicalComparer()) Dim fileIndex = 0 Dim freeAudioTracks = p.AudioTracks.Where(Function(x) x.TextEdit.Text = "") If audioFiles?.Any() AndAlso freeAudioTracks?.Any() Then For Each track In freeAudioTracks If fileIndex >= audioFiles.Count() Then Exit For track.TextEdit.Text = audioFiles(fileIndex) fileIndex += 1 Next End If Else files = files.OrderBy(Function(x) FileTypes.Video.Contains(x.Ext)).ThenBy(Function(x) FileTypes.Audio.Contains(x.Ext)) Dim action = Sub() If files(0).DirExists() Then OpenBlurayFolder(files(0)) Else OpenVideoSourceFiles(files, True, errorTimeout) End If End Sub If showTemplateSelection Then If LoadTemplateWithSelectionDialog(files, showTemplateSelectionTimeout) Then action() Else Exit Sub End If Else action() End If End If End Sub Function OpenBlurayFolder(srcPath As String) As Boolean If String.IsNullOrWhiteSpace(srcPath) Then Return False If Not srcPath.DirExists() Then Return False If Directory.Exists(Path.Combine(srcPath, "BDMV")) Then srcPath = Path.Combine(srcPath, "BDMV") End If If Directory.Exists(Path.Combine(srcPath, "PLAYLIST")) Then srcPath = Path.Combine(srcPath, "PLAYLIST") End If If New DirectoryInfo(srcPath).Name <> "PLAYLIST" Then MsgWarn("No playlist directory found.") Return False End If Dim minDuration = If(p.MinBdmvPlaylistDuration >= 0, $" -minDuration={p.MinBdmvPlaylistDuration}", "") Log.WriteEnvironment() Log.Write("Process Blu-Ray folder using eac3to", """" + Package.eac3to.Path + """ """ + srcPath + """" + minDuration + BR2) Log.WriteLine("Source Drive Type: " + New DriveInfo(srcPath).DriveType.ToString + BR) Dim output = ProcessHelp.GetConsoleOutput(Package.eac3to.Path, srcPath.Escape & minDuration).Replace(VB6.vbBack, "") Log.WriteLine(output) Dim a = Regex.Split(output, "^\d+\)", RegexOptions.Multiline).ToList If a(0) = "" Then a.RemoveAt(0) Using td As New TaskDialog(Of Integer) td.Title = "Please select a playlist." For Each i In a If Not i.Contains(BR) Then Continue For Dim match = Regex.Match(i, "(\+\d+)\1{8,}", RegexOptions.Multiline) If match.Success AndAlso match.Groups.Count > 1 Then Continue For Dim value = a.IndexOf(i) + 1 Dim text = value & ") " & i.Left(BR).Trim() Dim description = i.Right(BR).TrimEnd() td.AddCommand(text, description, value) Next If td.Show() <> 0 Then OpenEac3toDemuxForm(srcPath, td.SelectedValue) End If End Using Return True End Function Function OpenBlurayImage(isoPath As String) As Boolean If String.IsNullOrWhiteSpace(isoPath) Then Return False If Not isoPath.FileExists() Then Return False Try Dim drive = IsoHelp.Mount(isoPath) Dim srcPath = drive & Path.VolumeSeparatorChar & Path.DirectorySeparatorChar If Directory.Exists(Path.Combine(srcPath, "BDMV")) Then srcPath = Path.Combine(srcPath, "BDMV") End If If Directory.Exists(Path.Combine(srcPath, "PLAYLIST")) Then srcPath = Path.Combine(srcPath, "PLAYLIST") End If If New DirectoryInfo(srcPath).Name <> "PLAYLIST" Then MsgWarn("No playlist directory found.") Return False End If Dim minDuration = If(p.MinBdmvPlaylistDuration >= 0, $" -minDuration={p.MinBdmvPlaylistDuration}", "") Log.WriteEnvironment() Log.Write("Process mounted Blu-Ray folder using eac3to", """" + Package.eac3to.Path + """ """ + srcPath + """" + minDuration + BR2) Log.WriteLine("Source Drive Type: " + New DriveInfo(srcPath).DriveType.ToString + BR) Log.WriteLine("Mounted ISO File: " + isoPath.Escape() + BR) Dim output = ProcessHelp.GetConsoleOutput(Package.eac3to.Path, srcPath.Escape & minDuration).Replace(VB6.vbBack, "") Log.WriteLine(output) Dim a = Regex.Split(output, "^\d+\)", RegexOptions.Multiline).ToList If a(0) = "" Then a.RemoveAt(0) Using td As New TaskDialog(Of Integer) td.Title = "Please select a playlist." For Each i In a If Not i.Contains(BR) Then Continue For Dim match = Regex.Match(i, "(\+\d+)\1{8,}", RegexOptions.Multiline) If match.Success AndAlso match.Groups.Count > 1 Then Continue For Dim value = a.IndexOf(i) + 1 Dim text = value & ") " & i.Left(BR).Trim() Dim description = i.Right(BR).TrimEnd() td.AddCommand(text, description, value) Next If td.Show() <> 0 Then OpenEac3toDemuxForm(srcPath, td.SelectedValue) End If End Using Return True Catch ex As Exception g.ShowException(ex) Return False Finally IsoHelp.Dismount(isoPath) End Try End Function Sub OpenVideoSourceFile(fp As String, Optional demux As Boolean = True, Optional errorTimeout As Integer = 0) OpenVideoSourceFiles({fp}, demux, errorTimeout) End Sub Sub OpenVideoSourceFiles(files As IEnumerable(Of String), Optional demux As Boolean = True, Optional errorTimeout As Integer = 0) OpenVideoSourceFiles(files, demux, False, errorTimeout) End Sub Sub OpenVideoSourceFiles(files As IEnumerable(Of String), demuxSource As Boolean, isEncoding As Boolean, Optional errorTimeout As Integer = 0) If p.SourceFile = "" Then SetLastModifiedTemplate() Dim recoverPath = g.ProjectPath Dim recoverProjectPath = Path.Combine(Folder.Temp, Guid.NewGuid.ToString + ".bin") Dim recoverText = Text Dim saveCurrent = p.SourceFile <> "" If saveCurrent AndAlso Not IsLoading Then If IsSaveCanceled() Then Return End If End If Try SafeSerialization.Serialize(p, recoverProjectPath) AddHandler Disposed, Sub() FileHelp.Delete(recoverProjectPath) Catch ex As Exception MsgWarn("Recovery not saved!", $"The recovery project could not be saved at:{BR}{recoverProjectPath}") End Try SkipAssistant = True Try files = files.Select(Function(filePath) New FileInfo(filePath.TrimQuotes()).FullName).OrderBy(Function(filePath) filePath, StringComparer.InvariantCultureIgnoreCase) If Not g.VerifySource(files) Then Throw New AbortException End If For Each i In files Dim name = i.FileName If name.ToUpperInvariant Like "VTS_0#_0.VOB" Then If MsgQuestion("Are you sure you want to open the file " + name + "," + BR + "the first VOB file usually contains a menu.") = DialogResult.Cancel Then Throw New AbortException End If End If If name.ToUpperInvariant = "VIDEO_TS.VOB" Then MsgWarn("The file VIDEO_TS.VOB can't be opened.") Throw New AbortException End If Next p.SourceFiles = files.ToList() p.SourceFile = files(0) Debug.WriteLine(isEncoding) Debug.WriteLine(p.SourceFile) If p.SourceFile.Ext.EqualsAny(FileTypes.Image) Then If p.SourceFile.Base(p.SourceFile.Base.Length - 1).IsDigit Then If p.Script.IsAviSynth Then Dim digitCount = 0 For i = p.SourceFile.Base.Length - 1 To 0 Step -1 If p.SourceFile.Base(i).IsDigit Then digitCount += 1 End If Next Dim startText = p.SourceFile.Base.Substring(0, p.SourceFile.Base.Length - digitCount) Dim images As New List(Of String) Dim allFiles = Directory.GetFiles(p.SourceFile.Dir) For Each file In allFiles If file.Base.Length = p.SourceFile.Base.Length AndAlso file.Ext = p.SourceFile.Ext AndAlso file.Base.StartsWith(startText) Then images.Add(file) End If Next images.Sort() Dim filter = p.Script.GetFilter("Source") filter.Path = "Image" filter.Script = "ImageSource(""" + Path.Combine(images(0).Dir, p.SourceFile.Base.Substring(0, p.SourceFile.Base.Length - digitCount) + "%0" & digitCount & "d." + p.SourceFile.Ext) + """, " & images(0).Base.Substring(p.SourceFile.Base.Length - digitCount).ToInt & ", " & images(images.Count - 1).Base.Substring(p.SourceFile.Base.Length - digitCount).ToInt & ", 25)" End If Else Dim filter = p.Script.GetFilter("Source") filter.Path = "Image" filter.Script = "ImageSource(""%source_file%"", 0, 1000, 25)" End If End If FiltersListView.IsLoading = True PreviewScript = Nothing Dim preferredSourceFilter As VideoFilter = Nothing If p.SourceFiles.Count = 1 AndAlso p.Script.Filters(0).Name = "Manual" AndAlso Not p.NoDialogs AndAlso Not p.BatchMode AndAlso Not p.SourceFile.Ext.EqualsAny("avs", "vpy") Then preferredSourceFilter = ShowSourceFilterSelectionDialog(files(0)) End If If preferredSourceFilter IsNot Nothing Then Dim isVapourSynth = preferredSourceFilter.Script.Replace(" ", "").Contains("clip=core.") OrElse preferredSourceFilter.Script = "#vs" If isVapourSynth Then If Not Package.Python.VerifyOK(True) OrElse Not Package.VapourSynth.VerifyOK(True) OrElse Not Package.vspipe.VerifyOK(True) Then Throw New AbortException End If If p.Script.IsAviSynth Then p.Script = VideoScript.GetDefaults()(1) End If Else If Not Package.AviSynth.VerifyOK(True) Then Throw New AbortException If p.Script.Engine = ScriptEngine.VapourSynth Then p.Script = VideoScript.GetDefaults()(0) End If End If p.Script.SetFilter(preferredSourceFilter.Category, preferredSourceFilter.Name, preferredSourceFilter.Script) End If If Not g.VerifyRequirements() Then Throw New AbortException End If p.LastOriginalSourceFile = p.SourceFile p.FirstOriginalSourceFile = p.SourceFile If FileTypes.VideoIndex.Contains(p.SourceFile.Ext) Then Dim path = GetPathFromIndexFile(p.SourceFile) If path <> "" Then p.LastOriginalSourceFile = path p.FirstOriginalSourceFile = path End If ElseIf p.SourceFile.Ext.EqualsAny({"avs", "vpy"}) Then Dim code = p.SourceFile.ReadAllText Dim matches = Regex.Matches(code, "('|"")(.+?)\1", RegexOptions.IgnoreCase) For Each match As Match In matches If match.Success Then Dim path = match.Groups(2).Value If File.Exists(path) AndAlso FileTypes.Video.Contains(path.Ext) Then If FileTypes.VideoIndex.Contains(path.Ext) Then path = GetPathFromIndexFile(path) If path <> "" Then p.LastOriginalSourceFile = path p.FirstOriginalSourceFile = path Exit For End If Else p.LastOriginalSourceFile = path p.FirstOriginalSourceFile = path Exit For End If End If End If Next End If g.SetTempDir() Dim sourcePAR = MediaInfo.GetVideo(p.LastOriginalSourceFile, "PixelAspectRatio") If sourcePAR <> "" Then p.SourcePAR.X = CInt(Convert.ToSingle(sourcePAR, CultureInfo.InvariantCulture) * 1000) p.SourcePAR.Y = 1000 End If p.SourceVideoHdrFormat = MediaInfo.GetVideo(p.LastOriginalSourceFile, "HDR_Format_Commercial") p.SourceVideoHdrFormat = If(String.IsNullOrWhiteSpace(p.SourceVideoHdrFormat), "SDR", p.SourceVideoHdrFormat) p.SourceVideoHdrFormat = If(p.SourceVideoHdrFormat = "Dolby Vision", "DV", p.SourceVideoHdrFormat) If p.SourceVideoHdrFormat.ContainsAny("SDR", "HDR10", "HDR10+", "Dolby Vision") Then Dim hdrFormat = MediaInfo.GetVideo(p.LastOriginalSourceFile, "HDR_Format/String") If hdrFormat.ContainsEx("Dolby Vision") Then p.SourceVideoHdrFormat = "DV" Dim profileMatch = Regex.Match(hdrFormat, "Profile (\d\.\d),") If profileMatch.Success Then p.SourceVideoHdrFormat += " " + profileMatch.Groups(1).Value End If If Regex.IsMatch(hdrFormat, "HDR10 compatible") Then p.SourceVideoHdrFormat += " / HDR10" ElseIf Regex.IsMatch(hdrFormat, "HDR10\+ Profile [AB] compatible") Then p.SourceVideoHdrFormat += " / HDR10+" End If End If End If p.SourceVideoFormat = MediaInfo.GetVideoFormat(p.LastOriginalSourceFile) p.SourceVideoFormatProfile = MediaInfo.GetVideo(p.LastOriginalSourceFile, "Format_Profile") p.SourceVideoBitDepth = MediaInfo.GetVideo(p.LastOriginalSourceFile, "BitDepth").ToInt p.SourceColorSpace = MediaInfo.GetVideo(p.LastOriginalSourceFile, "ColorSpace") p.SourceChromaSubsampling = MediaInfo.GetVideo(p.LastOriginalSourceFile, "ChromaSubsampling") p.SourceSize = If(p.LastOriginalSourceFile.FileExists(), p.LastOriginalSourceFile.FileSize, If(p.LastOriginalSourceFile.DirExists(), p.LastOriginalSourceFile.DirSize(), 0L)) p.SourceVideoSize = MediaInfo.GetVideo(p.LastOriginalSourceFile, "StreamSize").ToLong() p.SourceBitrate = CInt(MediaInfo.GetVideo(p.LastOriginalSourceFile, "BitRate").ToInt / 1000) p.SourceFrameRateMode = MediaInfo.GetVideo(p.LastOriginalSourceFile, "FrameRate_Mode") p.SourceScanType = MediaInfo.GetVideo(p.LastOriginalSourceFile, "ScanType") p.SourceScanOrder = MediaInfo.GetVideo(p.LastOriginalSourceFile, "ScanOrder") Dim mkvMuxer = TryCast(p.VideoEncoder.Muxer, MkvMuxer) If mkvMuxer IsNot Nothing Then If p.TakeOverVideoLanguage AndAlso Not mkvMuxer.VideoTrackLanguage?.IsDetermined Then mkvMuxer.VideoTrackLanguage = New Language(MediaInfo.GetVideo(p.LastOriginalSourceFile, "Language")) End If If p.TakeOverTitle Then If mkvMuxer.Title = "" Then mkvMuxer.Title = MediaInfo.GetGeneral(p.LastOriginalSourceFile, "Title") If mkvMuxer.Title = "" Then mkvMuxer.Title = MediaInfo.GetGeneral(p.LastOriginalSourceFile, "Movie") End If End If If Not isEncoding AndAlso p.BatchMode Then Assistant() Exit Sub End If Log.WriteEnvironment() Log.WriteHeader("Media Info Source File") For Each i In p.SourceFiles Log.WriteLine(i) Next Log.WriteLine(BR + MediaInfo.GetSummary(p.SourceFile)) For Each i In DriveInfo.GetDrives() If i.DriveType = DriveType.CDRom AndAlso p.TempDir.ToUpperInvariant.StartsWith(i.RootDirectory.ToString.ToUpperInvariant) Then MsgWarn("Opening files from an optical drive requires to set a temp files folder in the options.") Throw New AbortException End If Next If Not p.BatchMode Then p.VideoEncoder.UpdateTargetFile(True) If demuxSource Then Demux() If String.IsNullOrWhiteSpace(p.Hdr10PlusMetadataFile) OrElse String.IsNullOrWhiteSpace(p.HdrDolbyVisionMetadataFile?.Path) Then Dim metadatas = Task.Run(Async Function() Await FindHdrMetadataAsync(p)).Result p.Hdr10PlusMetadataFile = If(String.IsNullOrWhiteSpace(metadatas.jsonFile), Nothing, metadatas.jsonFile) p.HdrDolbyVisionMetadataFile = If(String.IsNullOrWhiteSpace(metadatas.rpuFile), Nothing, New DolbyVisionMetadataFile(metadatas.rpuFile)) End If If p.ExtractHdrmetadata <> HdrmetadataMode.None AndAlso Not p.SourceVideoHdrFormat?.EqualsAny("", "SDR") AndAlso (String.IsNullOrWhiteSpace(p.Hdr10PlusMetadataFile) OrElse String.IsNullOrWhiteSpace(p.HdrDolbyVisionMetadataFile?.Path)) Then Select Case p.ExtractHdrmetadata Case HdrmetadataMode.DolbyVision ExtractDolbyVisionMetadata(p) Case HdrmetadataMode.HDR10Plus ExtractHdr10PlusMetadata(p) Case Else ExtractHdrMetadata(p) End Select End If p.VideoEncoder.SetMetaData(p.LastOriginalSourceFile) If p.LastOriginalSourceFile <> p.SourceFile AndAlso Not FileTypes.VideoText.Contains(p.SourceFile.Ext) Then p.LastOriginalSourceFile = p.SourceFile End If s.LastSourceDir = p.SourceFile.Dir If p.SourceFile.Ext = "avs" AndAlso p.Script.IsAviSynth Then p.Script.Filters.Clear() p.Script.Filters.Add(New VideoFilter("Source", "AVS Script Import", "Import(""" + p.SourceFile + """)")) ElseIf p.SourceFile.Ext = "vpy" Then p.Script.Engine = ScriptEngine.VapourSynth p.Script.Filters.Clear() Dim code = "import vapoursynth as vs" + BR + "core = vs.core" + BR + "from importlib.machinery import SourceFileLoader" + BR + $"SourceFileLoader('clip', r""{p.SourceFile}"").load_module()" + BR + "clip = vs.get_output()" p.Script.Filters.Add(New VideoFilter("Source", "VS Script Import", code)) End If ModifyFilters(errorTimeout) FiltersListView.IsLoading = False FiltersListView.Load() RenameDVDTracks() If FileTypes.VideoAudio.Contains(p.LastOriginalSourceFile.Ext) Then Dim streams = MediaInfo.GetAudioStreams(p.LastOriginalSourceFile) For Each track In p.AudioTracks track.AudioProfile.Streams = streams Next End If If p.SourceFile.Ext = "d2v" Then Dim content = p.SourceFile.ReadAllText If content.Contains("Aspect_Ratio=16:9") Then p.SourceAnamorphic = True Else Dim ifoFile = GetIfoFile() If ifoFile <> "" Then Dim dar2 = MediaInfo.GetVideo(ifoFile, "DisplayAspectRatio") If dar2 = "1.778" Then p.SourceAnamorphic = True End If End If End If If content.Contains("Frame_Rate=29970") Then Dim m = Regex.Match(content, "FINISHED\s+(\d{1,2}(?:\.\d{1,2}))\s?%\s+FILM") If m.Success Then Dim film = m.Groups(1).Value.ToSingle() If film >= p.D2VAutoForceFilmThreshold Then content = content.Replace($"Field_Operation=0{BR}Frame_Rate=29970 (30000/1001)", $"Field_Operation=1{BR}Frame_Rate=23976 (24000/1001)") content.WriteFileSystemEncoding(p.SourceFile) End If End If End If End If UpdateSourceParameters() SetSlider() AddAudioTracks() If p.UseScriptAsAudioSource Then If p.AudioTracks.Any() Then p.AudioTracks(0).TextEdit.Text = p.Script.Path End If End If BlockSourceTextBoxTextChanged = True tbSourceFile.Text = p.SourceFile BlockSourceTextBoxTextChanged = False s.LastPosition = 0 UpdateTargetParameters(p) DemuxVobSubSubtitles() ConvertBluRaySubtitles() ExtractForcedVobSubSubtitles() p.VideoEncoder.UpdateTargetFile(True) g.RaiseAppEvent(ApplicationEvent.BeforeMuxingWhenSourceOpening) p.VideoEncoder.Muxer.Init() If p.HardcodedSubtitle Then g.AddHardcodedSubtitle() End If AutoCrop() AutoResize() If p.Script.IsFilterActive("Crop") AndAlso (p.CropLeft Or p.CropTop Or p.CropRight Or p.CropBottom) <> 0 Then g.OvercropWidth() If p.AutoSmartCrop Then g.SmartCrop() End If End If Dim nonDvdFiles = files.Where(Function(x) Not Regex.IsMatch(x, ".*VTS_\d\d_\d\.vob", RegexOptions.IgnoreCase)) If nonDvdFiles.Count() > 1 Then Dim psi = New ProcessStartInfo(Application.ExecutablePath, $"-NoFocus -LoadTemplate:""{p.TemplateName}"" -LoadSourceFiles:""{nonDvdFiles.Skip(1).Join(""";""", False)}""") With { .UseShellExecute = False, .CreateNoWindow = True } Process.Start(psi)?.Dispose() End If If p.AutoCompCheck AndAlso p.VideoEncoder.IsCompCheckEnabled Then p.VideoEncoder.RunCompCheck() End If g.RaiseAppEvent(ApplicationEvent.AfterSourceOpened) SkipAssistant = False Assistant() g.RaiseAppEvent(ApplicationEvent.AfterSourceLoaded) g.RaiseAppEvent(ApplicationEvent.AfterProjectOrSourceLoaded) Log.Save() Catch ex As AbortException Log.Save() SetSavedProject() OpenProject(recoverProjectPath) Text = recoverText g.ProjectPath = recoverPath If isEncoding Then Throw New AbortException End If Catch ex As Exception g.OnException(ex) OpenProject("", False) Finally SkipAssistant = False If Not isEncoding Then ProcController.Finished() End If End Try End Sub Sub ModifyFilters(Optional timeout As Integer = 0) If p.SourceFile = "" Then Exit Sub Dim profiles = If(p.Script.IsAviSynth, s.AviSynthProfiles, s.VapourSynthProfiles) Dim preferences = If(p.Script.IsAviSynth, s.AviSynthFilterPreferences, s.VapourSynthFilterPreferences) Dim editAVS = p.Script.IsAviSynth AndAlso p.SourceFile.Ext <> "avs" Dim editVS = p.Script.IsVapourSynth AndAlso p.SourceFile.Ext <> "vpy" If p.AutoRotation AndAlso (editAVS OrElse editVS) Then Dim rot = MediaInfo.GetVideo(p.SourceFile, "Rotation").ToDouble If rot <> 0 Then Dim name = "" Select Case rot Case 90 name = "Right" Case 180 name = "Upside Down" Case 270 name = "Left" Case Else End Select If name <> "" Then Dim filter = VideoFilter.GetDefault("Rotation", name, p.Script.Engine) If filter IsNot Nothing Then p.Script.SetFilter(filter.Category, filter.Name, filter.Script) End If End If End If End If Dim sourceFilter = p.Script.GetFilter("Source") SetSourceFilter(sourceFilter, preferences, profiles, True, True, False, False) SetSourceFilter(sourceFilter, preferences, profiles, False, True, True, False) SetSourceFilter(sourceFilter, preferences, profiles, True, False, False, True) SetSourceFilter(sourceFilter, preferences, profiles, False, False, False, False) If editAVS Then If Not sourceFilter.Script.Contains("(") Then Dim filter = VideoFilter.GetDefault("Source", "FFVideoSource") p.Script.SetFilter(filter.Category, filter.Name, filter.Script) End If ElseIf editVS Then If Not sourceFilter.Script.Contains("(") Then Dim filter = VideoFilter.GetDefault("Source", "ffms2", ScriptEngine.VapourSynth) p.Script.SetFilter(filter.Category, filter.Name, filter.Script) End If End If For Each iFilter In p.Script.Filters If iFilter.Script.Contains("$") Then iFilter.Script = Macro.ExpandGUI(iFilter.Script, True).Value End If Next Dim errorMsg As String Try errorMsg = p.SourceScript.GetError Catch ex As AbortException errorMsg = ex.Message timeout = -1 Catch ex As Exception errorMsg = ex.Message End Try If errorMsg <> "" Then Log.WriteHeader("Error opening source") Log.WriteLine(errorMsg + BR2) Log.WriteLine(p.SourceScript.GetFullScript) Log.Save() MsgError("Script Error", errorMsg, Handle, timeout) Throw New AbortException End If If Not editAVS AndAlso Not editVS Then Exit Sub End If Dim sourceInfo = p.SourceScript.Info If p.FixFrameRate Then Dim fixedFrameRate = FixFrameRate(sourceInfo.FrameRateNum, sourceInfo.FrameRateDen) If fixedFrameRate.num <> sourceInfo.FrameRateNum OrElse fixedFrameRate.den <> sourceInfo.FrameRateDen Then If editAVS Then p.Script.GetFilter("Source").Script += BR + "AssumeFPS(" & fixedFrameRate.num & ", " & fixedFrameRate.den & ")" Else p.Script.GetFilter("Source").Script += BR + "clip = core.std.AssumeFPS(clip, None, " & fixedFrameRate.num & ", " & fixedFrameRate.den & ")" End If p.SourceScript.Synchronize() End If End If If editAVS Then Dim miFPS = MediaInfo.GetFrameRate(p.FirstOriginalSourceFile, 25) Dim avsFPS = sourceInfo.FrameRate If (CInt(miFPS) * 2) = CInt(avsFPS) Then p.Script.GetFilter("Source").Script += BR + "SelectEven().AssumeFPS(" & miFPS.ToInvariantString + ")" p.SourceScript.Synchronize() End If End If Dim bitDepthAdjusted = False If p.SourceChromaSubsampling <> "4:2:0" AndAlso p.ConvertChromaSubsampling Then Dim interlaced = p.SourceScanType.EqualsAny("Interlaced", "MBAFF") If editVS Then Dim sourceHeight = MediaInfo.GetVideo(p.LastOriginalSourceFile, "Height").ToInt Dim matrix = If(sourceHeight = 0 OrElse sourceHeight > 576, "709", "470bg") Dim format = If(p.SourceVideoBitDepth = 10, "YUV420P10", "YUV420P8") If p.ConvertToBits <> ConvertTo420BitDepth.None AndAlso p.ConvertToBits <> p.SourceVideoBitDepth Then format = "YUV420P" & (p.ConvertToBits + 0) bitDepthAdjusted = True End If Dim category = "Color" Dim name = $"Convert To {format}" Dim script = $"clip = clip.resize.Bicubic(format = vs.{format})" If interlaced Then p.Script.Filters.Add(New VideoFilter(category, name, script, True)) Else p.Script.Filters.Insert(1, New VideoFilter(category, name, script, True)) End If ElseIf editAVS Then Dim category = "Color" Dim name = $"ConvertToYUV420()" Dim script = $"ConvertToYUV420()" If interlaced Then p.Script.Filters.Add(New VideoFilter(category, name, script, True)) Else p.Script.Filters.Insert(1, New VideoFilter(category, name, script, True)) End If End If End If If p.ConvertToBits <> ConvertTo420BitDepth.None AndAlso p.ConvertToBits <> p.SourceVideoBitDepth AndAlso Not bitDepthAdjusted Then Dim bits = (p.ConvertToBits + 0) Dim category = "BitDepth" Dim name = $"Convert To {bits}-bit" If editVS Then Dim script = $"clip = core.fmtc.bitdepth(clip, bits={bits})" p.Script.Filters.Add(New VideoFilter(category, name, script, True)) ElseIf editAVS Then Dim script = $"ConvertBits({bits})" p.Script.Filters.Add(New VideoFilter(category, name, script, True)) End If End If End Sub Function FixFrameRate(num As Integer, den As Integer) As (num As Integer, den As Integer) Dim rate = num / den Return If(rate < 50 AndAlso rate > 49, (50, 1), (num, den)) End Function Sub SetSourceFilter( sourceFilter As VideoFilter, preferences As StringPairList, profiles As List(Of FilterCategory), skipAnyExtension As Boolean, skipAnyFormat As Boolean, skipNonAnyExtension As Boolean, skipNonAnyFormat As Boolean) If Not sourceFilter.Script.Contains("(") Then For Each pref In preferences Dim extensions = pref.Name.SplitNoEmptyAndWhiteSpace({",", " ", ";"}) For Each extension In extensions extension = extension.ToLowerInvariant Dim format = "*" If extension.Contains(":") Then format = extension.Right(":").ToLowerInvariant extension = extension.Left(":").ToLowerInvariant End If If skipAnyExtension AndAlso extension = "*" Then Continue For If skipAnyFormat AndAlso format = "*" Then Continue For If skipNonAnyExtension AndAlso extension <> "*" Then Continue For If skipNonAnyFormat AndAlso format <> "*" Then Continue For If (extension = p.SourceFile.Ext OrElse extension = "*") AndAlso (format = "*" OrElse format = MediaInfo.GetVideo(p.SourceFile, "Format").ToLowerInvariant) Then Dim filters = profiles.Where( Function(cat) cat.Name = "Source").First.Filters.Where( Function(cat) cat.Name = pref.Value) If filters.Count > 0 Then p.Script.SetFilter("Source", filters(0).Name, filters(0).Script) Exit Sub End If End If Next Next End If End Sub Sub AutoCrop() g.CheckForModifiedDolbyVisionLevel5Data() If p.AutoCropMode = AutoCropMode.DolbyVisionOnly OrElse p.AutoCropMode = AutoCropMode.Always Then p.SourceScript.Synchronize(True, True, True) Dim useDvOnly = p.HdrDolbyVisionMetadataFile IsNot Nothing AndAlso p.VideoEncoder.IsDolbyVisionSet AndAlso p.HdrDolbyVisionMetadataFile.Crop <> Padding.Empty If useDvOnly Then Dim c = p.HdrDolbyVisionMetadataFile.Crop Dim sm = If(p.AutoCropDolbyVisionSideMode = AutoCropDolbyVisionSideMode.NoOverride, p.AutoCropSideMode, AutoCropSideMode.All) If p.AutoCropDolbyVisionSideMode = AutoCropDolbyVisionSideMode.Horizontal Then sm = AutoCropSideMode.Horizontal If p.AutoCropDolbyVisionSideMode = AutoCropDolbyVisionSideMode.Vertical Then sm = AutoCropSideMode.Vertical g.SetCrop(c.Left, c.Top, c.Right, c.Bottom, sm, p.ForcedOutputModDirection, True) ElseIf p.AutoCropMode <> AutoCropMode.Disabled Then Dim info = p.SourceScript.Info Dim selectionMode = Convert.ToInt32(p.AutoCropFrameSelectionMode) Dim selectionValue = If(p.AutoCropFrameSelectionMode = AutoCropFrameSelectionMode.FrameInterval, p.AutoCropFrameIntervalFrameSelection, p.AutoCropFixedFramesFrameSelection) selectionValue = If(p.AutoCropFrameSelectionMode = AutoCropFrameSelectionMode.TimeInterval, p.AutoCropTimeIntervalFrameSelection, selectionValue) Dim considerationMode = Convert.ToInt32(p.AutoCropFrameRangeMode) Dim considerationThresholdBegin = 0 Dim considerationThresholdEnd = 0 Dim luminanceThreshold = CInt(p.AutoCropLuminanceThreshold * 100) Dim vfw = If(FrameServerHelp.IsVfwUsed, 1, 0) If p.AutoCropFrameRangeMode = AutoCropFrameRangeMode.Automatic Then Dim threshold = CInt(Conversion.Fix(info.FrameCount * 0.05)) considerationThresholdBegin = threshold considerationThresholdEnd = threshold ElseIf p.AutoCropFrameRangeMode = AutoCropFrameRangeMode.ManualThreshold Then considerationThresholdBegin = p.AutoCropFrameRangeThresholdBegin considerationThresholdEnd = p.AutoCropFrameRangeThresholdEnd End If Dim parameters = $"{selectionMode} {selectionValue} {considerationThresholdBegin} {considerationThresholdEnd} {luminanceThreshold.ToInvariantString()} {vfw}" Dim savingFilePath = Path.Combine(p.TempDir, "autocrop.tmp") Dim fileLines = If(savingFilePath.FileExists(), File.ReadAllLines(savingFilePath), {""}) Dim fileParameters = If(fileLines.Length > 0, fileLines(0), "") Dim values = If(fileLines.Length > 1, fileLines(1), "") Dim valuesPattern = "(\d+),(\d+),(\d+),(\d+)" Dim redo = Not (Regex.IsMatch(values, valuesPattern) AndAlso parameters.Equals(fileParameters)) If redo Then Try g.AddToPath( Package.Python.Directory, Package.VapourSynth.Directory, Package.vspipe.Directory, Package.AviSynth.Directory, Package.FFTW.Directory, Path.Combine(Folder.Startup, "Apps", "Support", "VC")) Using proc As New Proc proc.Header = "Auto Crop" proc.SkipString = "%" proc.Package = Package.AutoCrop proc.Arguments = $"{p.SourceScript.Path.Escape} {parameters}" proc.Start() Dim m = Regex.Match(proc.Log.ToString(), valuesPattern) If m.Success Then Try values = m.Value Dim content = parameters & Environment.NewLine & values content.WriteFileUTF8(savingFilePath) Catch ex As Exception End Try End If End Using Catch ex As SkipException Log.WriteLine("AutoCrop skipped...") Log.Save() ProcController.Aborted = False Catch ex As AbortException Log.WriteLine("AutoCrop aborted...") Log.Save() ProcController.Aborted = False Catch ex As ErrorAbortException Log.WriteLine("AutoCrop aborted...") Log.Save() ProcController.Aborted = False Catch ex As Exception Throw ex End Try End If Dim match = Regex.Match(values, valuesPattern) If match.Success Then g.SetCrop(match.Groups(1).Value.ToInt, match.Groups(2).Value.ToInt, match.Groups(3).Value.ToInt, match.Groups(4).Value.ToInt, p.AutoCropSideMode, p.ForcedOutputModDirection, False) End If End If SetCropFilter() DisableCropFilter() End If End Sub Sub AutoResize() If p.Script.IsFilterActive("Resize") Then If p.AutoResizeImage <> 0 Then SetTargetImageSizeByPixel(p.AutoResizeImage) Else If p.AdjustHeight Then Dim h = Calc.FixMod(CInt(p.TargetWidth / Calc.GetTargetDAR()), p.ForcedOutputMod) tbTargetHeight.Text = h.ToString() End If End If Else Dim cropw = p.SourceWidth - p.CropLeft - p.CropRight tbTargetWidth.Text = cropw.ToString tbTargetHeight.Text = (p.SourceHeight - p.CropTop - p.CropBottom).ToString End If End Sub Sub ConvertBluRaySubtitles() If Not p.ConvertSup2Sub Then Exit Sub For Each i In g.GetFilesInTempDirAndParent If i.Ext = "sup" AndAlso g.IsSourceSameOrSimilar(i) AndAlso Not File.Exists(i.DirAndBase + ".idx") Then Using proc As New Proc proc.Header = "Convert sup to sub" proc.SkipStrings = {"#>", "#<", "Decoding frame"} proc.File = Package.BDSup2SubPP.Path proc.Arguments = "-o """ + i.DirAndBase + ".idx"" " + i.Escape proc.Start() End Using End If Next End Sub Sub ExtractForcedVobSubSubtitles() If Not p.ExtractForcedSubSubtitles Then Exit Sub For Each path In g.GetFilesInTempDirAndParent If path.ExtFull = ".idx" AndAlso g.IsSourceSameOrSimilar(path) AndAlso Not path.Contains("_forced") AndAlso Not File.Exists(path.DirAndBase + "_forced.idx") Then Dim idxContent = path.ReadAllTextDefault If idxContent.Contains(VB6.ChrW(&HA) + VB6.ChrW(&H0) + VB6.ChrW(&HD) + VB6.ChrW(&HA)) Then idxContent = idxContent.FixBreak idxContent = idxContent.Replace(BR + VB6.ChrW(&H0) + BR, BR + "langidx: 0" + BR) idxContent.WriteFileSystemEncoding(path) End If Using proc As New Proc proc.Header = "Extract forced subtitles if existing" proc.SkipString = "# " proc.WriteLog(path.FileName + BR2) proc.File = Package.BDSup2SubPP.Path proc.Arguments = "--forced-only -o " + (path.DirAndBase + "_forced.idx").Escape + " " + path.Escape proc.AllowedExitCodes = {0, 1, 4} proc.Start() End Using End If Next End Sub Sub DemuxVobSubSubtitles() If p.SubtitleMode = SubtitleMode.Disabled 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(Path.Combine(p.TempDir, p.SourceFile.Base + ".idx")) Then Exit Sub Dim subtitleCount = MediaInfo.GetSubtitleCount(ifoPath) If subtitleCount > 0 Then Dim pgcCount As Byte Dim sectorPointer As Integer Dim buffer = File.ReadAllBytes(ifoPath) sectorPointer = (((buffer(&HCC) * &H1000000) + (buffer(&HCD) * &H10000)) + (buffer(&HCE) * &H100)) + (buffer(&HCF) * 1) pgcCount = CByte((buffer(sectorPointer * &H800) * &H100) + buffer((sectorPointer * &H800) + 1)) If pgcCount <> 0 Then For i = 0 To pgcCount - 1 Dim a = ((sectorPointer * &H800) + (i * 8)) + 12 Dim b = (((buffer(a + 0) * &H1000000) + (buffer(a + 1) * &H10000)) + (buffer(a + 2) * &H100)) + (buffer(a + 3) * 1) + sectorPointer * &H800 Dim hour, min, sec As Integer hour = CByte((((buffer(b + 4) And 240) >> 4) * 10) + (buffer(b + 4) And 15)) min = CByte((((buffer(b + 5) And 240) >> 4) * 10) + (buffer(b + 5) And 15)) sec = CByte((((buffer(b + 6) And 240) >> 4) * 10) + (buffer(b + 6) And 15)) If Math.Abs(p.SourceSeconds - ((hour * 60 ^ 2) + (min * 60) + sec)) < 30 Then Dim args = ifoPath + BR + Path.Combine(p.TempDir, p.SourceFile.Base) + BR & (i + 1) & BR + "1" + BR + "ALL" + BR + "CLOSE" Dim fileContent = Path.Combine(p.TempDir, p.TargetFile.Base + "_vsrip.txt") args.WriteFileSystemEncoding(fileContent) Using proc As New Proc proc.Header = "Demux subtitles using VSRip" proc.WriteLog(args + BR2) proc.File = Package.VSRip.Path proc.Arguments = """" + fileContent + """" proc.AllowedExitCodes = {0, 1, 2} proc.Start() End Using Exit For End If Next End If End If End Sub Function ProcessTip(message As String) As Boolean If message.Contains(BR2) Then message = message.Replace(BR2, BR) End If If message.Contains(VB6.vbLf + VB6.vbLf) Then message = message.FixBreak.Replace(BR2, BR) End If CurrentAssistantTipKey = message.MD5Hash If Not p.SkippedAssistantTips.Contains(CurrentAssistantTipKey) Then If message <> "" Then If message.Length > 130 Then laTip.SetFontSize(8) Else laTip.SetFontSize(9) End If End If laTip.Text = message Return True End If End Function Function RemoveTip(message As String) As Boolean If message.Contains(BR2) Then message = message.Replace(BR2, BR) End If If message.Contains(VB6.vbLf + VB6.vbLf) Then message = message.FixBreak.Replace(BR2, BR) End If Return p.SkippedAssistantTips.Remove(message.MD5Hash) End Function Function Warn(msg As String, ParamArray controls As Control()) As Boolean Warn(msg, Nothing, controls) End Function Function Warn(msg As String, clickAction As Action, ParamArray controls As Control()) As Boolean AssistantClickAction = clickAction bnNext.Enabled = True If msg <> gbAssistant.Text Then gbAssistant.Text = msg End If Highlight(True, controls) UpdateNextButton() End Function Function Block(msg As String, ParamArray controls As Control()) As Boolean Block(msg, Nothing, controls) End Function Function Block(msg As String, clickAction As Action, ParamArray controls As Control()) As Boolean AssistantClickAction = clickAction gbAssistant.Text = msg bnNext.Enabled = False CanIgnoreTip = False ThemeRefresh = True Highlight(True, controls) UpdateNextButton() End Function Sub Highlight(ParamArray controls As Control()) Highlight(False, controls) End Sub Sub Highlight(highlight As Boolean, ParamArray controls As Control()) Dim theme = ThemeManager.CurrentTheme If highlight Then laTip.BackColor = theme.MainForm.laTipBackHighlightColor laTip.ForeColor = theme.MainForm.laTipForeHighlightColor Else laTip.BackColor = theme.MainForm.laTipBackColor laTip.ForeColor = theme.MainForm.laTipForeColor End If If controls Is Nothing Then Return If Not controls.NothingOrEmpty Then ThemeRefresh = True For Each control In controls.OfType(Of Label) control.BackColor = theme.General.Controls.Label.BackHighlightColor control.ForeColor = theme.General.Controls.Label.ForeHighlightColor Next For Each control In controls.OfType(Of ButtonLabel) control.BackColor = If(TypeOf control.Parent Is UserControl, theme.General.Controls.ListView.BackHighlightColor, theme.General.Controls.ButtonLabel.BackHighlightColor) control.ForeColor = theme.General.Controls.ButtonLabel.ForeHighlightColor control.LinkColor = theme.General.Controls.ButtonLabel.ForeHighlightColor control.LinkHoverColor = theme.General.Controls.ButtonLabel.ForeHighlightColor Next For Each control In controls.OfType(Of Button) control.BackColor = theme.General.Controls.Button.BackHighlightColor control.ForeColor = theme.General.Controls.Button.ForeHighlightColor Next For Each control In controls.OfType(Of GroupBox) control.BackColor = theme.General.Controls.GroupBox.BackHighlightColor control.ForeColor = theme.General.Controls.GroupBox.ForeHighlightColor Next For Each control In controls.OfType(Of Panel) control.BackColor = theme.General.Controls.Panel.BackHighlightColor control.ForeColor = theme.General.Controls.Panel.ForeHighlightColor Next For Each control In controls.OfType(Of TableLayoutPanel) control.BackColor = theme.General.Controls.TableLayoutPanel.BackHighlightColor control.ForeColor = theme.General.Controls.TableLayoutPanel.ForeHighlightColor Next For Each control In controls.OfType(Of TextBox) control.BackColor = theme.General.Controls.TextBox.BackHighlightColor control.ForeColor = theme.General.Controls.TextBox.ForeHighlightColor Next For Each control In controls.OfType(Of TextBoxEx) control.BorderColor = theme.General.Controls.TextBox.BackHighlightColor control.BorderFocusedColor = theme.General.Controls.TextBox.ForeHighlightColor Next For Each control In controls.OfType(Of TextEdit) control.TextBox.BackColor = theme.General.Controls.TextEdit.BackHighlightColor control.TextBox.ForeColor = theme.General.Controls.TextEdit.ForeHighlightColor Next For Each control In controls.OfType(Of TrackBar) control.BackColor = theme.General.Controls.TrackBar.BackHighlightColor control.ForeColor = theme.General.Controls.TrackBar.ForeHighlightColor Next End Sub Sub OpenTargetFolder() g.ShellExecute(p.TargetFile.Dir) End Sub Function AbortDueToLowDiskSpace() As Boolean Try 'crashes with network shares If p.TargetFile = "" OrElse p.TargetFile.StartsWith("\\") Then Exit Function End If Dim di As New DriveInfo(p.TargetFile.Dir) If di.AvailableFreeSpace / PrefixedSize(3).Factor < s.MinimumDiskSpace Then Using td As New TaskDialog(Of String) td.Title = "Low Disk Space" td.Content = $"The target drive {Path.GetPathRoot(p.TargetFile)} has only " + $"{(di.AvailableFreeSpace / PrefixedSize(3).Factor):f2} {PrefixedSize(3).Unit} free disk space." td.Icon = TaskIcon.Warning td.AddButton("Continue") td.AddButton("Abort") If td.Show <> "Continue" Then Return True End If End Using End If Catch End Try End Function Sub StartEncoding() AssistantPassed = True AddJob(False, "") g.ProcessJobs() End Sub Sub ExtractHdrMetadata(sourcePath As String) Dim proj = New Project() With { .SourceFile = sourcePath, .FirstOriginalSourceFile = sourcePath } ExtractHdrMetadata(proj) End Sub Sub ExtractHdrMetadata(proj As Project) ExtractHdr10PlusMetadata(proj) ExtractDolbyVisionMetadata(proj) End Sub Sub ExtractHdr10PlusMetadata(proj As Project) If proj Is Nothing Then Return If String.IsNullOrWhiteSpace(proj.SourceFile) Then Return If Not File.Exists(proj.SourceFile) Then Return Dim sourcePaths = {proj.SourceFile, proj.FirstOriginalSourceFile, proj.LastOriginalSourceFile} For Each sourcePath As String In sourcePaths Dim mi = New MediaInfo(sourcePath) If Not mi.GetVideo("HDR_Format_Commercial")?.ContainsAny("HDR10+") Then Continue For If mi.GetVideo("Format") <> "HEVC" Then Continue For Dim jsonPath = sourcePath.ChangeExt("json") If Not String.IsNullOrWhiteSpace(proj.TempDir) Then jsonPath = If(sourcePath.Contains(proj.TempDir) AndAlso Not proj.TempDir.EndsWithEx("_temp"), jsonPath, If(proj.TempDir.DirExists(), $"{Path.Combine({proj.TempDir, "HDR10PlusMetadata.json"})}", jsonPath)) End If If Not jsonPath.FileExists() Then Dim commandLine = $"{Package.ffmpeg.Path.Escape} -hide_banner -probesize 50M -i ""{sourcePath}"" -an -sn -dn -c:v copy -bsf:v hevc_mp4toannexb -f hevc - | {Package.HDR10PlusTool.Path.Escape} extract -o ""{jsonPath}"" -" Try Using proc As New Proc proc.Priority = s.ToolProcessPriority proc.Package = Package.HDR10PlusTool proc.Project = If(proj, p) proc.Header = "Extract HDR10+ metadata" proc.Encoding = Encoding.UTF8 proc.File = "cmd.exe" proc.Arguments = "/S /C """ + commandLine + """" proc.SkipStrings = Proc.GetSkipStrings(commandLine) proc.AllowedExitCodes = {0} proc.OutputFiles = {jsonPath} proc.Start() End Using If jsonPath?.FileExists() Then Try Dim fi = New FileInfo(jsonPath) If fi.Length < 100 Then File.Delete(jsonPath) End If Catch ex As Exception jsonPath = "" End Try End If Catch ex As AbortException Throw ex Catch ex As Exception g.ShowException(ex) Throw New AbortException Finally Log.Save() End Try End If If jsonPath.FileExists() Then proj.Hdr10PlusMetadataFile = jsonPath Exit For End If Next End Sub Sub ExtractDolbyVisionMetadata(proj As Project) If proj Is Nothing Then Return If String.IsNullOrWhiteSpace(proj.SourceFile) Then Return If Not File.Exists(proj.SourceFile) Then Return Dim sourcePaths = {proj.SourceFile, proj.FirstOriginalSourceFile, proj.LastOriginalSourceFile} For Each sourcePath As String In sourcePaths Dim isEL = False Dim files = Directory.GetFiles(sourcePath.Dir, sourcePath.Base + "*_EL*.*", SearchOption.TopDirectoryOnly).AsEnumerable() files = files?.Where(Function(x) {"h265", "hevc"}.Contains(x.Ext)) If files?.Any() Then sourcePath = files.First() isEL = True End If Dim format = MediaInfo.GetVideoFormat(sourcePath) If format <> "HEVC" Then Continue For Dim fileHdrFormat = MediaInfo.GetVideo(sourcePath, "HDR_Format/String") If isEL OrElse (Regex.IsMatch(fileHdrFormat, "Dolby Vision.*Profile|HDR10+ Profile B")) Then Dim rpuPath = sourcePath.ChangeExt("rpu") Dim doviFile = proj.HdrDolbyVisionMetadataFile If Not String.IsNullOrWhiteSpace(proj.TempDir) Then rpuPath = If(sourcePath.Contains(proj.TempDir), rpuPath, If(proj.TempDir.DirExists(), $"{Path.Combine({proj.TempDir, "HDRDVmetadata.rpu"})}", rpuPath)) End If Try If Not rpuPath.FileExists() Then Dim commandLine = $"{Package.ffmpeg.Path.Escape} -hide_banner -probesize 50M -i ""{sourcePath}"" -an -sn -dn -c:v copy -bsf:v hevc_mp4toannexb -f hevc - | {Package.DoViTool.Path.Escape} extract-rpu - -o ""{rpuPath}""" Dim throwError As (Title As String, Content As String) Using proc As New Proc Dim throwIf = Sub(value As String) If value?.Contains("Unexpected RPU NALU") Then throwError = ("Unexpected RPU NALU", "Unexpected RPU NALU found, extraction aborts...") proc.Kill() End If If value?.Contains("Discarding") Then throwError = ("Discarding", "Dovi_tool is discarding data, extraction aborts...") proc.Kill() End If End Sub proc.Priority = s.ToolProcessPriority proc.Package = Package.DoViTool proc.Project = If(proj, p) proc.Header = "Extract Dolby Vision metadata" proc.Encoding = Encoding.UTF8 proc.File = "cmd.exe" proc.Arguments = "/S /C """ + commandLine + """" proc.SkipStrings = Proc.GetSkipStrings(commandLine) proc.AllowedExitCodes = {0} proc.OutputFiles = {rpuPath} proc.ReadOutput = True AddHandler proc.OutputDataReceived, throwIf AddHandler proc.ErrorDataReceived, throwIf proc.Start() End Using If throwError.Title IsNot Nothing AndAlso throwError.Content IsNot Nothing Then Throw New ErrorAbortException(throwError.Title, throwError.Content) If rpuPath?.FileExists() Then Try Dim fi = New FileInfo(rpuPath) If fi.Length > 100 Then doviFile = New DolbyVisionMetadataFile(rpuPath) Else File.Delete(rpuPath) End If Catch ex As Exception doviFile = New DolbyVisionMetadataFile(rpuPath) End Try End If End If Catch ex As ErrorAbortException g.ShowException(ex, Nothing, Nothing, s.ErrorMessageTimeout) doviFile = Nothing Catch ex As AbortException g.ShowException(ex) doviFile = Nothing Throw ex Catch ex As Exception g.ShowException(ex) doviFile = Nothing Throw New AbortException Finally Log.Save() End Try proj.HdrDolbyVisionMetadataFile = doviFile Exit For End If Next End Sub Async Function FindHdrMetadataAsync(proj As Project) As Task(Of (jsonFile As String, rpuFile As String)) If proj Is Nothing Then Return Nothing If String.IsNullOrWhiteSpace(proj.SourceFile) Then Return Nothing Dim sourcePath = proj.SourceFile Dim jsonFile = "" Dim rpuFile = "" Dim files As IEnumerable(Of String) Dim searchTask = Task.Run(Sub() Try files = Directory.GetFiles(sourcePath.Dir(), $"{sourcePath.Base}*.*", SearchOption.TopDirectoryOnly) jsonFile = files.FirstOrDefault(Function(x) {"json"}.Contains(x.Ext) AndAlso Not x.Base.EndsWithAny("_L5", "_Config")) rpuFile = files.FirstOrDefault(Function(x) {"bin", "rpu"}.Contains(x.Ext) AndAlso Not x.Base.EndsWith("_Cropped")) If Not String.IsNullOrWhiteSpace(proj.TempDir) AndAlso String.IsNullOrWhiteSpace(jsonFile) AndAlso String.IsNullOrWhiteSpace(rpuFile) Then files = Directory.GetFiles(proj.TempDir, "*.*", SearchOption.TopDirectoryOnly) jsonFile = If(String.IsNullOrWhiteSpace(jsonFile), files.FirstOrDefault(Function(x) {"json"}.Contains(x.Ext) AndAlso Not x.Base.EndsWithAny("_L5", "_Config")), jsonFile) rpuFile = If(String.IsNullOrWhiteSpace(rpuFile), files.FirstOrDefault(Function(x) {"bin", "rpu"}.Contains(x.Ext) AndAlso Not x.Base.EndsWith("_Cropped")), rpuFile) End If Catch ex As Exception Log.WriteLine(ex.Message) Log.Save() End Try End Sub) Await searchTask Return (jsonFile, rpuFile) End Function Sub Demux() Dim getFormat = Function() As String Dim ret = MediaInfo.GetVideo(p.SourceFile, "Format") Select Case ret Case "MPEG Video" ret = "mpeg2" Case "VC-1" ret = "vc1" End Select Return ret.ToLowerInvariant End Function Dim srcScript = p.Script.GetFilter("Source").Script.ToLowerInvariant For Each i In s.Demuxers If Not i.Active AndAlso (i.SourceFilters.NothingOrEmpty OrElse Not srcScript.ContainsAny(i.SourceFilters.Select(Function(val) val.ToLowerInvariant + "(").ToArray)) Then Continue For End If If i.InputExtensions?.Length = 0 OrElse i.InputExtensions.Contains(p.SourceFile.Ext) Then If Not srcScript?.Contains("(") OrElse i.SourceFilters.NothingOrEmpty OrElse srcScript.ContainsAny(i.SourceFilters.Select(Function(val) val.ToLowerInvariant + "(").ToArray) Then Dim inputFormats = i.InputFormats.NothingOrEmpty OrElse i.InputFormats.Contains(getFormat()) If inputFormats Then i.Run(p) Refresh() For Each outExt In i.OutputExtensions Dim exitFor = False For Each iFile In Directory.GetFiles(p.TempDir, "*." + outExt) If g.IsSourceSame(iFile) AndAlso p.SourceFile <> iFile AndAlso Not iFile.Base.EndsWith("_CompCheck") AndAlso Not iFile.Base.EndsWith("_out") AndAlso Not iFile.Base.Matches("_chunk\d+$") AndAlso Not iFile.Base.ContainsEx("_cut_") Then p.SourceFile = iFile p.SourceFiles.Clear() p.SourceFiles.Add(p.SourceFile) BlockSourceTextBoxTextChanged = True tbSourceFile.Text = p.SourceFile BlockSourceTextBoxTextChanged = False exitFor = True Exit For End If Next If exitFor Then Exit For End If Next End If End If End If Next p.Script.Synchronize() End Sub Sub Indexing() If p.SourceFile.Ext.EqualsAny("avs", "vpy") Then Exit Sub If Not p.Script.Path.FileExists Then p.Script.Synchronize(False, False) Dim codeLower = p.Script.GetFilter("Source").Script.ToLowerInvariant If codeLower.Contains("ffvideosource(") OrElse codeLower.Contains("ffms2(") OrElse codeLower.Contains("ffms2.source") Then If FileTypes.VideoIndex.Contains(p.SourceFile.Ext) Then p.SourceFile = p.LastOriginalSourceFile BlockSourceTextBoxTextChanged = True tbSourceFile.Text = p.SourceFile BlockSourceTextBoxTextChanged = False End If Dim cachePath = If(codeLower.Contains("cachefile") AndAlso p.TempDir <> "", Path.Combine(p.TempDir, g.GetSourceBase + ".ffindex"), p.SourceFile + ".ffindex") If Not cachePath.FileExists() Then g.ffmsindex(p.SourceFile, cachePath) End If ElseIf codeLower.Contains("lwlibavvideosource(") OrElse codeLower.Contains("lwlibavsource(") Then If FileTypes.VideoIndex.Contains(p.SourceFile.Ext) Then p.SourceFile = p.LastOriginalSourceFile BlockSourceTextBoxTextChanged = True tbSourceFile.Text = p.SourceFile BlockSourceTextBoxTextChanged = False End If If Not File.Exists(p.SourceFile + ".lwi") AndAlso Not File.Exists(Path.Combine(p.TempDir, g.GetSourceBase + ".lwi")) AndAlso File.Exists(p.Script.Path) AndAlso Not FileTypes.VideoText.Contains(p.SourceFile.Ext) Then Using proc As New Proc proc.Header = "Index LWLibav" proc.Encoding = Encoding.UTF8 proc.SkipString = "Creating lwi" If p.Script.IsAviSynth Then proc.File = Package.ffmpeg.Path proc.Arguments = "-i " + p.Script.Path.LongPathPrefix.Escape + " -hide_banner" Else proc.File = Package.vspipe.Path proc.Arguments = p.Script.Path.Escape + " NUL -i" End If proc.AllowedExitCodes = {0, 1} proc.Start() End Using End If ElseIf codeLower.Contains("bsvideosource(") OrElse codeLower.Contains("bs.videosource(") Then If FileTypes.VideoIndex.Contains(p.SourceFile.Ext) Then p.SourceFile = p.LastOriginalSourceFile BlockSourceTextBoxTextChanged = True tbSourceFile.Text = p.SourceFile BlockSourceTextBoxTextChanged = False End If Dim cacheBase = If(codeLower.Contains("cachepath") AndAlso p.TempDir <> "", Path.Combine(p.TempDir, g.GetSourceBase), p.SourceFile) Dim cachePath = cacheBase + ".0.bsindex" If Not cachePath.FileExists() Then Using proc As New Proc proc.Header = "Index BestSource" proc.Encoding = Encoding.UTF8 proc.SkipStrings = {"Creating bsindex"} If p.Script.IsAviSynth Then proc.File = Package.ffmpeg.Path proc.Arguments = "-i " + p.Script.Path.LongPathPrefix.Escape + " -hide_banner" Else proc.File = Package.vspipe.Path proc.Arguments = p.Script.Path.Escape + " NUL -i" End If proc.AllowedExitCodes = {0, 1} proc.Start() End Using End If ElseIf codeLower.Contains("lsmashvideosource(") OrElse codeLower.Contains("libavsmashsource(") OrElse codeLower.Contains("directshowsource(") OrElse codeLower.Contains("dss2(") Then If FileTypes.VideoIndex.Contains(p.SourceFile.Ext) Then p.SourceFile = p.LastOriginalSourceFile BlockSourceTextBoxTextChanged = True tbSourceFile.Text = p.SourceFile BlockSourceTextBoxTextChanged = False End If End If End Sub Sub ShowFileBrowserToOpenProject() Using dialog As New OpenFileDialog dialog.Filter = "Project Files|*.srip" If dialog.ShowDialog() = DialogResult.OK Then Refresh() OpenProject(dialog.FileName) End If End Using End Sub Sub ShowEventCommandsDialog() Using form As New EventCommandsEditor(s.EventCommands) If form.ShowDialog() = DialogResult.OK Then s.EventCommands.Clear() For Each i As ListViewItem In form.lv.Items s.EventCommands.Add(DirectCast(i.Tag, EventCommand)) Next g.SaveSettings() g.SaveEvents() End If End Using End Sub Sub SaveProject() If g.ProjectPath Is Nothing Then OpenSaveProjectDialog() Else SaveProjectPath(g.ProjectPath) End If End Sub Sub SaveProjectPath( path As String) path = Macro.Expand(path) If path.StartsWith(Folder.Template) Then If p.SourceFile <> "" Then MsgWarn("A template cannot be created after a source file was opened.") Exit Sub End If p.Log.Clear() p.TemplateName = path.Base() p.TemplatePath = path Else g.ProjectPath = path End If Try SafeSerialization.Serialize(p, path) SetSavedProject() Text = $"{path.Base} - {g.DefaultCommands.GetApplicationDetails()}" s.UpdateRecentProjects(path) UpdateRecentProjectsMenu() Catch ex As Exception g.ShowException(ex) End Try End Sub Sub SaveProjectAs() OpenSaveProjectDialog() End Sub Sub SaveProjectAsTemplate() OpenSaveTemplateDialog() End Sub Sub CloseProject() OpenProject(g.StartupTemplatePath) End Sub Sub StartCompCheck() p.VideoEncoder.RunCompCheck() End Sub Sub StartNewInstance() Using p As New Process() p.StartInfo.FileName = Application.ExecutablePath p.Start() End Using End Sub Sub [Exit]() Close() End Sub Sub ExitWithoutSaving() s.ApplicationExitMode = ApplicationExitMode.BypassProjectSaving Close() End Sub Sub ShowAppsDialog() Using form As New AppsForm Dim found As Boolean If s.StringDictionary.ContainsKey("RecentExternalApplicationControl") Then For Each pack In Package.Items.Values If pack.Name + pack.Version = s.StringDictionary("RecentExternalApplicationControl") Then form.ShowPackage(pack) found = True Exit For End If Next End If If Not found Then form.ShowPackage(Package.x265) End If form.ShowDialog() g.SaveSettings() End Using End Sub Sub ShowEncoderProfilesDialog() g.LoadVideoEncoderProfiles() Using form As New ProfilesForm("Encoder Profiles", s.VideoEncoderProfiles, AddressOf g.LoadVideoEncoder, AddressOf GetNewVideoEncoderProfile, AddressOf VideoEncoder.GetDefaults) If form.ShowDialog() = DialogResult.OK Then g.SaveVideoEncoderProfiles() End If End Using PopulateProfileMenu(DynamicMenuItemID.EncoderProfiles) End Sub Sub ShowMuxerProfilesDialog() If p.VideoEncoder.OpenMuxerProfilesDialog() = DialogResult.OK Then PopulateProfileMenu(DynamicMenuItemID.MuxerProfiles) End If Assistant() End Sub Sub RecalcBitrate() UpdateSizeOrBitrate() End Sub Function GetNewVideoEncoderProfile() As Profile Dim sb As New SelectionBox(Of VideoEncoder) With { .Title = "Add New Profile", .Text = "Please select a profile from the defaults." } sb.AddItem("Current Project", p.VideoEncoder) For Each i In VideoEncoder.GetDefaults() sb.AddItem(i) Next If sb.Show = DialogResult.OK Then Return sb.SelectedValue End If End Function Sub PopulateProfileMenu(id As DynamicMenuItemID) For Each i In CustomMainMenu.MenuItems If i.CustomMenuItem.MethodName = "DynamicMenuItem" AndAlso i.CustomMenuItem.Parameters(0).Equals(id) Then i.DropDownItems.ClearAndDisplose Select Case id Case DynamicMenuItemID.EncoderProfiles g.PopulateProfileMenu(i.DropDownItems, s.VideoEncoderProfiles, AddressOf ShowEncoderProfilesDialog, AddressOf g.LoadVideoEncoder) Case DynamicMenuItemID.MuxerProfiles g.PopulateProfileMenu(i.DropDownItems, s.MuxerProfiles, AddressOf ShowMuxerProfilesDialog, AddressOf p.VideoEncoder.LoadMuxer) Case DynamicMenuItemID.AudioProfiles For j = 0 To p.AudioTracks.Count - 1 Dim index = j g.PopulateProfileMenu(i.DropDownItems, s.AudioProfiles, Sub() ShowAudioProfilesDialog(index), Sub(profile) g.LoadAudioProfile(profile, index)) Next Case DynamicMenuItemID.FilterSetupProfiles g.PopulateProfileMenu(i.DropDownItems, s.FilterSetupProfiles, AddressOf ShowFilterSetupProfilesDialog, AddressOf LoadFilterSetup) End Select Exit For End If Next End Sub Sub ShowCropDialog() If p.SourceFile = "" Then ShowOpenSourceDialog() Else If Not g.VerifyRequirements OrElse Not g.IsValidSource Then Exit Sub End If Using form As New CropForm form.ShowDialog() End Using SetCropFilter() DisableCropFilter() Assistant() End If End Sub ' Sub ApplyFilters(Optional filters As List(Of VideoFilter) = Nothing) If PreviewScript Is Nothing Then Exit Sub PreviewScript.Filters = If(filters, p.Script.Filters) End Sub Sub ShowPreviewDialog() ShowPreview(True) End Sub Sub ShowPreview() ShowPreview(False) End Sub Sub ShowPreview(modal As Boolean) If p.SourceFile = "" Then ShowOpenSourceDialog() Else If Not g.VerifyRequirements OrElse Not g.IsValidSource Then Exit Sub If PreviewScript Is Nothing Then PreviewScript = p.Script.GetNewScript() If PreviewScript Is Nothing Then Exit Sub End If PreviewScript.Path = Path.Combine(p.TempDir, p.TargetFile.Base + "_view." + PreviewScript.FileType) PreviewScript.RemoveFilter("Cutting") Else ApplyFilters() End If PreviewScript.RemoveFilter("Cutting") Dim err = PreviewScript.GetError() If err <> "" Then MsgError("Script Error", err) Exit Sub End If If modal Then Using form As New PreviewForm(PreviewScript) form.ShowDialog() End Using Else Dim form As New PreviewForm(PreviewScript) form.Show() End If End If End Sub Sub ShowMainMenuEditor() s.CustomMenuMainForm = CustomMainMenu.Edit() UpdateTemplatesMenuAsync() UpdateScriptsMenuAsync() UpdateRecentProjectsMenu() UpdateDynamicMenuAsync() g.SetRenderer(MenuStrip) Refresh() g.SaveSettings() End Sub Sub ShowJobsDialog() JobsForm.ShowForm() End Sub Sub ClearJobs() FileHelp.Delete(Path.Combine(Folder.Settings, "Jobs.dat")) End Sub Sub LoadProfile( videoProfile As String, audioProfile1 As String, audioProfile2 As String) videoProfile = videoProfile.TrimQuotes().Trim() audioProfile1 = audioProfile1.TrimQuotes().Trim() audioProfile2 = audioProfile2.TrimQuotes().Trim() If videoProfile <> "" Then For Each i In s.VideoEncoderProfiles If i.Name = videoProfile Then g.LoadVideoEncoder(i) End If Next End If If audioProfile1 <> "" Then For Each i In s.AudioProfiles If i.Name = audioProfile1 Then g.LoadAudioProfile(i, 0) End If Next End If If audioProfile2 <> "" Then For Each i In s.AudioProfiles If i.Name = audioProfile2 Then g.LoadAudioProfile(i, 1) End If Next End If End Sub Sub AddJob(Optional showJobsDialog As Boolean = True, Optional position As Integer = -1) If Not CanIgnoreTip Then MsgWarn("Assistant warning cannot be skipped.") Exit Sub End If If Not p.SkippedAssistantTips.Contains(CurrentAssistantTipKey) Then p.SkippedAssistantTips.Add(CurrentAssistantTipKey) End If If Not g.VerifyRequirements() Then Exit Sub End If For Each form In PreviewForm.Instances.ToArray form.Close() Next If AssistantPassed Then If AbortDueToLowDiskSpace() Then Exit Sub g.RaiseAppEvent(ApplicationEvent.BeforeJobAdding) Dim jobPath = JobManager.JobPath Dim jobs = JobManager.GetJobs()?.Where(Function(x) x.Active AndAlso x.Path = jobPath) If jobs.Any() Then If MsgQuestion($"An active job for this project already exists.{BR}If you continue, it will be overwritten.", TaskButton.OkCancel) = DialogResult.Cancel Then Exit Sub End If End If If TypeOf p.VideoEncoder IsNot NullEncoder Then Dim op = If(p.VideoEncoder.CanChunkEncode(), p.VideoEncoder.OutputPath.DirAndBase() + "_chunk1" + p.VideoEncoder.OutputPath.ExtFull(), p.VideoEncoder.OutputPath) If op.FileExists() Then Select Case p.FileExistVideo Case FileExistMode.Ask Using td As New TaskDialog(Of String) td.Title = "A video encoding output file already exists" td.Content = "Would you like to skip video encoding and reuse the existing video encoder output file or would you like to re-encode and overwrite it?" td.AddCommand("Reuse") td.AddCommand("Re-encode") Select Case td.Show Case "Reuse" p.SkipVideoEncoding = True Case "Re-encode" p.SkipVideoEncoding = False Case Else Exit Sub End Select End Using Case FileExistMode.Overwrite p.SkipVideoEncoding = False Case FileExistMode.Skip p.SkipVideoEncoding = True End Select End If End If If p.AudioTracks.Any(Function(track) track.AudioProfile.File <> "" AndAlso (TypeOf track.AudioProfile Is GUIAudioProfile OrElse TypeOf track.AudioProfile Is BatchAudioProfile) AndAlso File.Exists(track.AudioProfile.GetOutputFile())) Then Select Case p.FileExistAudio Case FileExistMode.Ask Using td As New TaskDialog(Of String) td.Title = "An audio encoding output file already exists" td.Content = "Would you like to skip audio encoding and reuse existing audio encoding output files or would you like to re-encode and overwrite?" td.AddCommand("Reuse") td.AddCommand("Re-encode") Select Case td.Show Case "Reuse" p.SkipAudioEncoding = True Case "Re-encode" p.SkipAudioEncoding = False Case Else Exit Sub End Select End Using Case FileExistMode.Overwrite p.SkipAudioEncoding = False Case FileExistMode.Skip p.SkipAudioEncoding = True End Select End If AddJob(False, Nothing, position) If showJobsDialog Then Me.ShowJobsDialog() Else bnNext.ShowBold() End If Else Assistant() End If End Sub Sub AddJob( showConfirmation As Boolean, templateName As String, Optional position As Integer = -1) AddJob(showConfirmation, templateName, True, position) End Sub Sub AddJob( showConfirmation As Boolean, templateName As String, showAssistant As Boolean, Optional position As Integer = -1) If Not g.VerifyRequirements() Then Exit Sub End If If showAssistant AndAlso Not IsLoading AndAlso Not AssistantPassed Then MsgWarn("Please follow the assistant.") Exit Sub End If Dim jobPath = JobManager.JobPath SaveProjectPath(jobPath) JobManager.AddJob(jobPath, jobPath, position) If showConfirmation Then MsgInfo("Job added") End If If templateName <> "" Then LoadProject(Path.Combine(Folder.Template, templateName + ".srip")) End If End Sub Sub ShowVideoComparison() Dim form As New VideoComparisonForm form.Show() End Sub Sub ShowFiltersEditor() FiltersListView.ShowCodeEditor() End Sub Sub ShowCodePreview() g.ShowCodePreview(p.Script.GetFullScript) End Sub Sub SetCropFilter() If CInt(p.CropLeft Or p.CropTop Or p.CropRight Or p.CropBottom) <> 0 Then If Not g.EnableFilter("Crop") Then If p.Script.IsAviSynth Then p.Script.InsertAfter("Source", New VideoFilter("Crop", "Crop", "Crop(%crop_left%, %crop_top%, -%crop_right%, -%crop_bottom%)")) Else p.Script.InsertAfter("Source", New VideoFilter("Crop", "Crop", "clip = core.std.Crop(clip, %crop_left%, %crop_right%, %crop_top%, %crop_bottom%)")) End If End If FiltersListView.Load() End If End Sub Sub DisableCropFilter() Dim f = p.Script.GetFilter("Crop") If f IsNot Nothing AndAlso CInt(p.CropLeft Or p.CropTop Or p.CropRight Or p.CropBottom) = 0 Then f.Active = False FiltersListView.Load() End If End Sub Sub ShowFilterSetupProfilesDialog() Using form As New ProfilesForm( "Filter Setup Profiles", s.FilterSetupProfiles, AddressOf LoadFilterSetup, AddressOf GetScriptAsProfile, AddressOf VideoScript.GetDefaults) If form.ShowDialog() = DialogResult.OK Then PopulateProfileMenu(DynamicMenuItemID.FilterSetupProfiles) FiltersListView.RebuildMenu() End If End Using End Sub Sub ShowFilterProfilesDialog() Dim filterProfiles = If(p.Script.IsAviSynth, s.AviSynthProfiles, s.VapourSynthProfiles) Dim getDefaults = If(p.Script.IsAviSynth, Function() FilterCategory.GetAviSynthDefaults, Function() FilterCategory.GetVapourSynthDefaults) Using dialog As New MacroEditorDialog dialog.SetScriptDefaults() dialog.Text = $"Filter Profiles - {g.DefaultCommands.GetApplicationDetails()}" dialog.MacroEditorControl.Value = g.GetFilterProfilesText(filterProfiles) dialog.bnContext.Text = " Restore Defaults... " dialog.bnContext.Visible = True dialog.MacroEditorControl.rtbDefaults.Text = g.GetFilterProfilesText(getDefaults()) dialog.bnContext.ClickAction = Sub() If Msg("Restore defaults?", Nothing, TaskIcon.Warning, TaskButton.OkCancel) = DialogResult.OK Then dialog.MacroEditorControl.Value = g.GetFilterProfilesText(getDefaults()) MsgInfo("Defaults were restored.") End If End Sub If dialog.ShowDialog() = DialogResult.OK Then Try filterProfiles = FilterCategory.ParseFilterProfilesIniContent(dialog.MacroEditorControl.Value) For Each i In getDefaults() Dim found As Boolean For Each i2 In filterProfiles If i.Name = i2.Name Then found = True End If Next If Not found AndAlso {"Source", "Crop", "Resize"}.Contains(i.Name) Then MsgWarn($"The category '{i.Name}' was recreated. A Source, Crop and Resize category is mandatory.") filterProfiles.Add(i) End If Next If p.Script.IsAviSynth Then s.AviSynthProfiles = filterProfiles Else s.VapourSynthProfiles = filterProfiles End If g.SaveSettings() g.MainForm.FiltersListView.RebuildMenu() Catch ex As Exception g.ShowException(ex) End Try End If End Using End Sub Shared Function GetDefaultMainMenu() As CustomMenuItem Dim ret As New CustomMenuItem("Root") ret.Add("File|Open Video Source File(s)...", NameOf(ShowOpenSourceDialog), Keys.O Or Keys.Control, Symbol.Preview) ret.Add("File|Open Video Source File(s)...|Single File", NameOf(ShowOpenSourceSingleFileDialog)) ret.Add("File|Open Video Source File(s)...|Multiple Files", NameOf(ShowOpenSourceMultipleFilesDialog)) ret.Add("File|Open Video Source File(s)...|Batch Multiple Files", NameOf(ShowOpenSourceBatchFilesDialog)) ret.Add("File|Open Video Source File(s)...|-") ret.Add("File|Open Video Source File(s)...|Merge Files", NameOf(ShowOpenSourceMergeFilesDialog)) ret.Add("File|Open Video Source File(s)...|-") ret.Add("File|Open Video Source File(s)...|Blu-ray Image File", NameOf(ShowOpenSourceBlurayImageDialog)) ret.Add("File|Open Video Source File(s)...|Blu-ray Folder", NameOf(ShowOpenSourceBlurayFolderDialog)) ret.Add("File|Demux...", NameOf(g.DefaultCommands.ShowDemuxTool), Symbol.fa_sitemap) ret.Add("File|-") ret.Add("File|Video Comparison...", NameOf(ShowVideoComparison), Keys.F5, Symbol.VideoLegacy) ret.Add("File|-") ret.Add("File|Open Project...", NameOf(ShowFileBrowserToOpenProject), Symbol.OpenFile) ret.Add("File|Save Project", NameOf(SaveProject), Keys.S Or Keys.Control, Symbol.Save) ret.Add("File|Save Project As...", NameOf(SaveProjectAs), Keys.S Or Keys.Control Or Keys.Shift, Symbol.SaveAs) ret.Add("File|Save Project As Template...", NameOf(SaveProjectAsTemplate)) ret.Add("File|Close Project", NameOf(CloseProject), Keys.W Or Keys.Control, Symbol.fa_close) ret.Add("File|-") ret.Add("File|Project Templates", NameOf(g.DefaultCommands.DynamicMenuItem), Symbol.Library, {DynamicMenuItemID.TemplateProjects}) ret.Add("File|Recent Projects", NameOf(g.DefaultCommands.DynamicMenuItem), Symbol.History, {DynamicMenuItemID.RecentProjects}) ret.Add("File|-") ret.Add("File|Launch New Instance", NameOf(StartNewInstance), Keys.N Or Keys.Control, Symbol.fa_clone) ret.Add("File|-") ret.Add("File|Exit", NameOf([Exit]), Keys.X Or Keys.Alt, Symbol.fa_window_close) ret.Add("Crop", NameOf(ShowCropDialog), Keys.F3, Symbol.fa_crop) ret.Add("Preview", NameOf(ShowPreview), Keys.F4, Symbol.fa_eye) ret.Add("Project|Add Hardcoded Subtitle...", NameOf(ShowHardcodedSubtitleDialogFromTempDir), Keys.Control Or Keys.H, Symbol.Subtitles) ret.Add("Project|Script Info...", NameOf(ShowScriptInfo), Keys.F2, Symbol.Info) ret.Add("Project|Advanced Script Info...", NameOf(ShowAdvancedScriptInfo), Keys.Control Or Keys.F2, Symbol.AddTo) ret.Add("Project|-") ret.Add("Project|Log File", NameOf(g.DefaultCommands.ShowLogFile), Keys.F8, Symbol.Page) ret.Add("Project|-") ret.Add("Project|Folders", Symbol.Library) ret.Add("Project|Folders|Source", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%source_dir%"""}) ret.Add("Project|Folders|Target", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%target_dir%"""}) ret.Add("Project|Folders|Temp", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%temp_dir%"""}) ret.Add("Project|Folders|Working", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%working_dir%"""}) ret.Add("Project|-") ret.Add("Project|Options", NameOf(ShowOptionsDialog), Keys.F9, Symbol.Project) ret.Add("Tools|Jobs...", NameOf(ShowJobsDialog), Keys.F6, Symbol.MultiSelectLegacy) ret.Add("Tools|Folders", Symbol.Library) ret.Add("Tools|Folders|Log Files", NameOf(g.DefaultCommands.ExecuteCommandLine), {$"""%settings_dir%{IO.Path.DirectorySeparatorChar}Log Files"""}) ret.Add("Tools|Folders|Plugins", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%plugin_dir%"""}) ret.Add("Tools|Folders|Programs", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%programs_dir%"""}) ret.Add("Tools|Folders|Scripts", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%script_dir%"""}) ret.Add("Tools|Folders|Settings", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%settings_dir%"""}) ret.Add("Tools|Folders|Startup", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%startup_dir%"""}) ret.Add("Tools|Folders|System", NameOf(g.DefaultCommands.ExecuteCommandLine), {"""%system_dir%"""}) ret.Add("Tools|Folders|Templates", NameOf(g.DefaultCommands.ExecuteCommandLine), {$"""%settings_dir%{IO.Path.DirectorySeparatorChar}Templates"""}) ret.Add("Tools|Scripts", NameOf(g.DefaultCommands.DynamicMenuItem), Symbol.Code, {DynamicMenuItemID.Scripts}) ret.Add("Tools|Advanced", Symbol.More) ret.Add("Tools|Advanced|Event Commands...", NameOf(ShowEventCommandsDialog), Keys.Control Or Keys.E, Symbol.LightningBolt) ret.Add("Tools|Advanced|Macros...", NameOf(g.DefaultCommands.ShowMacrosDialog), Keys.Control Or Keys.M, Symbol.CalculatorPercentage) ret.Add("Tools|Advanced|Reset Settings...", NameOf(g.DefaultCommands.ResetSettings)) ret.Add("Tools|Advanced|-") ret.Add("Tools|Advanced|Command Prompt", NameOf(g.DefaultCommands.ExecuteCommandLine), Symbol.fa_terminal, {"cmd.exe", False, False, False, "%working_dir%"}) ret.Add("Tools|Advanced|PowerShell Terminal", NameOf(g.DefaultCommands.ExecuteCommandLine), Symbol.fa_terminal, {"powershell.exe -nologo -executionpolicy bypass", False, False, False, "%working_dir%"}) If g.IsWindowsTerminalAvailable Then ret.Add("Tools|Advanced|Windows Terminal", NameOf(g.DefaultCommands.ExecuteCommandLine), Keys.Control Or Keys.T, Symbol.fa_terminal, {"wt.exe", False, False, False, "%working_dir%"}) End If ret.Add("Tools|Advanced|-") ret.Add("Tools|Advanced|Generate Wiki Content", NameOf(g.DefaultCommands.GenerateWikiContent)) ret.Add("Tools|Advanced|Ingest HDR", NameOf(g.DefaultCommands.SaveMKVHDR)) ret.Add("Tools|-") ret.Add("Tools|Edit Menu...", NameOf(ShowMainMenuEditor), Symbol.Settings) ret.Add("Tools|Settings...", NameOf(ShowSettingsDialog), Keys.F10, Symbol.fa_cogs, {""}) ret.Add("Apps|Subtitles|Subtitle Edit", NameOf(g.DefaultCommands.StartTool), {"Subtitle Edit"}) ret.Add("Apps|Subtitles|BDSup2Sub++", NameOf(g.DefaultCommands.StartTool), {"BDSup2Sub++"}) ret.Add("Apps|Subtitles|VSRip", NameOf(g.DefaultCommands.StartTool), {"VSRip"}) ret.Add("Apps|Media Info|mkvinfo", NameOf(g.DefaultCommands.ShowMkvInfo)) ret.Add("Apps|Media Info|MediaInfo File", NameOf(g.DefaultCommands.ShowMediaInfo)) ret.Add("Apps|Media Info|MediaInfo Folder", NameOf(g.DefaultCommands.ShowMediaInfoFolderViewDialog)) ret.Add("Apps|Players|mpv.net", NameOf(g.DefaultCommands.StartTool), {"mpv.net"}) ret.Add("Apps|Players|MPC", NameOf(g.DefaultCommands.StartTool), {"MPC"}) ret.Add("Apps|Indexing|D2V Witch", NameOf(g.DefaultCommands.StartTool), {"D2V Witch"}) ret.Add("Apps|Indexing|DGIndex", NameOf(g.DefaultCommands.StartTool), {"DGIndex"}) ret.Add("Apps|Thumbnails|StaxRip Thumbnailer (using project options)", NameOf(g.DefaultCommands.ShowThumbnailerDialogAsync)) ret.Add("Apps|Animation|Animated GIF", NameOf(g.DefaultCommands.SaveGIF)) ret.Add("Apps|Animation|Animated PNG", NameOf(g.DefaultCommands.SavePNG)) ret.Add("Apps|Other|MKVToolnix GUI", NameOf(g.DefaultCommands.StartTool), {"MKVToolnix GUI"}) ret.Add("Apps|Other|chapterEditor", NameOf(g.DefaultCommands.StartTool), {"chapterEditor"}) ret.Add("Apps|-") ret.Add("Apps|Manage...", NameOf(ShowAppsDialog), Keys.F11, Symbol.AllApps) If g.IsDevelopmentPC Then ret.Add("Apps|Test...", NameOf(g.DefaultCommands.Test), Keys.F12) End If ret.Add("Help|Apps", NameOf(g.DefaultCommands.DynamicMenuItem), Symbol.AllApps, {DynamicMenuItemID.HelpApplications}) ret.Add("Help|-") ret.Add("Help|Website", NameOf(g.DefaultCommands.ExecuteCommandLine), Symbol.fa_github, {"https://github.com/staxrip/staxrip"}) ret.Add("Help|Documentation", NameOf(g.DefaultCommands.ExecuteCommandLine), Keys.F1, Symbol.fa_book, {"https://github.com/staxrip/staxrip/tree/master/Docs/README.md"}) ret.Add("Help|Changelog", NameOf(g.DefaultCommands.ExecuteCommandLine), Symbol.Bookmarks, {"https://github.com/staxrip/staxrip/blob/master/CHANGELOG.md"}) ret.Add("Help|Support", NameOf(g.DefaultCommands.ExecuteCommandLine), Symbol.Heart, {"https://github.com/staxrip/staxrip?tab=readme-ov-file#contribution--support"}) ret.Add("Help|-") ret.Add("Help|Report an issue", NameOf(g.DefaultCommands.ExecuteCommandLine), Symbol.fa_bug, {"https://github.com/staxrip/staxrip/issues/new/choose"}) ret.Add("Help|-") ret.Add("Help|Discord Server", NameOf(g.DefaultCommands.ExecuteCommandLine), Symbol.People, {"https://discord.gg/uz8pVR79Bd"}) ret.Add("Help|-") ret.Add("Help|Check for Updates", NameOf(g.DefaultCommands.CheckForUpdate), Symbol.fa_recycle) ret.Add("Help|-") ret.Add("Help|What's new...", NameOf(ShowChangelog), Symbol.fa_shield, {True}) ret.Add("Help|Info...", NameOf(g.DefaultCommands.OpenHelpTopic), Symbol.Info, {"info"}) Return ret End Function Sub ShowHardcodedSubtitleDialogFromLastSourceDir() ShowHardcodedSubtitleDialog(s.LastSourceDir) End Sub Sub ShowHardcodedSubtitleDialogFromTempDir() ShowHardcodedSubtitleDialog(p.TempDir) End Sub Sub ShowHardcodedSubtitleDialog(initDir As String) Using dialog As New OpenFileDialog dialog.SetFilter(FileTypes.SubtitleExludingContainers) dialog.SetInitDir(initDir) If dialog.ShowDialog = DialogResult.OK Then If dialog.FileName.Ext = "idx" Then Dim subs = Subtitle.Create(dialog.FileName) If subs.Count = 0 Then MsgInfo("No subtitles found.") Exit Sub End If Dim sb As New SelectionBox(Of Subtitle) With { .Title = "Language", .Text = "Please select a subtitle." } For Each i In subs sb.AddItem(i.Language.EnglishName, i) Next If sb.Show = DialogResult.Cancel Then Exit Sub End If Regex.Replace(dialog.FileName.ReadAllText, "langidx: \d+", "langidx: " + sb.SelectedValue.IndexIDX.ToString).WriteFileSystemEncoding(dialog.FileName) End If p.AddHardcodedSubtitleFilter(dialog.FileName, True) End If End Using End Sub Sub tbResize_MouseUp(sender As Object, e As MouseEventArgs) Handles tbResize.MouseUp Assistant() End Sub Sub tbResize_Scroll() Handles tbResize.Scroll SkipAssistant = True g.AddResizeFilter() tbTargetWidth.Text = CInt(p.SourceWidth \ 2 + tbResize.Value * Math.Max(TrackBarInterval, p.ForcedOutputMod)).ToString SetImageHeight() SkipAssistant = False Assistant(False) End Sub Sub SetImageHeight() Try Dim modval = p.ForcedOutputMod Dim ar As Double If ModifierKeys = Keys.Control Then Dim cropw = p.SourceWidth - p.CropLeft - p.CropRight Dim croph = p.SourceHeight - p.CropTop - p.CropBottom ar = cropw / croph Else ar = Calc.GetTargetDAR End If tbTargetHeight.Text = (CInt(p.TargetWidth / ar / modval) * modval).ToString() If p.TargetWidth = 1920 AndAlso p.TargetHeight = 1088 Then tbTargetHeight.Text = CStr(1080) End If Catch End Try End Sub Sub SetImageWidth() Try Dim modval = p.ForcedOutputMod tbTargetWidth.Text = (CInt(p.TargetHeight * Calc.GetTargetDAR / modval) * modval).ToString() Catch End Try End Sub Sub tbBitrate_KeyDown(sender As Object, e As KeyEventArgs) Handles tbBitrate.KeyDown If tbBitrate.ReadOnly Then Exit Sub End If If e.KeyData = Keys.Up Then e.Handled = True tbBitrate.Text = Math.Max(0, Calc.GetNextMod(tbBitrate.Text.ToInt, 50)).ToString ElseIf e.KeyData = Keys.Down Then e.Handled = True tbBitrate.Text = Math.Max(0, Calc.GetPreviousMod(tbBitrate.Text.ToInt, 50)).ToString End If End Sub Sub tbTargetSize_KeyDown(sender As Object, e As KeyEventArgs) Handles tbTargetSize.KeyDown If tbTargetSize.ReadOnly Then Exit Sub End If Dim modValue As Integer Select Case p.TargetSeconds Case Is > 50 * 60 modValue = 50 Case Is > 10 * 60 modValue = 10 Case Is > 60 modValue = 5 Case Else modValue = 1 End Select If e.KeyData = Keys.Up Then e.Handled = True tbTargetSize.Text = Math.Max(0, Calc.GetNextMod(tbTargetSize.Text.ToInt, modValue)).ToString ElseIf e.KeyData = Keys.Down Then e.Handled = True tbTargetSize.Text = Math.Max(0, Calc.GetPreviousMod(tbTargetSize.Text.ToInt, modValue)).ToString End If End Sub Sub UpdateSizeOrBitrate() If p.VideoEncoder.QualityMode Then Return If p.BitrateIsFixed Then tbBitrate_TextChanged() Else tbSize_TextChanged() End If End Sub Sub tbSize_TextChanged() Handles tbTargetSize.TextChanged Try If tbTargetSize.TextBox.Focused Then p.BitrateIsFixed = False End If If Integer.TryParse(tbTargetSize.Text, Nothing) Then p.TargetSize = Math.Max(0, CInt(tbTargetSize.Text)) BlockSize = True If Not BlockBitrate Then tbBitrate.Text = CInt(Calc.GetVideoBitrate).ToString End If BlockSize = False Assistant() End If Catch End Try End Sub Sub tbBitrate_TextChanged() Handles tbBitrate.TextChanged Try If tbBitrate.TextBox.Focused Then p.BitrateIsFixed = True End If If Integer.TryParse(tbBitrate.Text, Nothing) Then p.VideoBitrate = Math.Max(0, CInt(tbBitrate.Text)) p.VideoEncoder.Bitrate = p.VideoBitrate BlockBitrate = True If Not BlockSize Then tbTargetSize.Text = $"{CInt(Calc.GetSizeInBytes \ PrefixedSize(2).Factor)}" End If p.VideoEncoder.UpdateTargetFile() BlockBitrate = False Assistant() End If Catch End Try End Sub Sub tbTargetWidth_TextChanged() Handles tbTargetWidth.TextChanged Try If Integer.TryParse(tbTargetWidth.Text, Nothing) Then p.TargetWidth = CInt(tbTargetWidth.Text) Assistant() End If Catch End Try End Sub Sub tbTargetHeight_TextChanged() Handles tbTargetHeight.TextChanged Try If Integer.TryParse(tbTargetHeight.Text, Nothing) Then p.TargetHeight = CInt(tbTargetHeight.Text) Assistant() End If Catch End Try End Sub Sub tbTargetWidth_KeyDown(sender As Object, e As KeyEventArgs) Handles tbTargetWidth.KeyDown If e.KeyData = Keys.Up Then e.Handled = True Dim modVal = p.ForcedOutputMod tbTargetWidth.Text = CInt(((p.TargetWidth + modVal) / modVal) * modVal).ToString() ElseIf e.KeyData = Keys.Down Then e.Handled = True Dim modVal = p.ForcedOutputMod tbTargetWidth.Text = CInt(((p.TargetWidth - modVal) / modVal) * modVal).ToString() End If End Sub Sub tbTargetHeight_KeyDown(sender As Object, e As KeyEventArgs) Handles tbTargetHeight.KeyDown If e.KeyData = Keys.Up Then e.Handled = True Dim modVal = p.ForcedOutputMod tbTargetHeight.Text = CInt(((p.TargetHeight + modVal) / modVal) * modVal).ToString() ElseIf e.KeyData = Keys.Down Then e.Handled = True Dim modVal = p.ForcedOutputMod tbTargetHeight.Text = CInt(((p.TargetHeight - modVal) / modVal) * modVal).ToString() End If End Sub Sub tbTargetWidth_MouseWheel(sender As Object, e As MouseEventArgs) Handles tbTargetWidth.MouseWheel If e.Delta < 0 Then Dim modVal = p.ForcedOutputMod tbTargetWidth.Text = CInt(((p.TargetWidth - modVal) / modVal) * modVal).ToString() Else Dim modVal = p.ForcedOutputMod tbTargetWidth.Text = CInt(((p.TargetWidth + modVal) / modVal) * modVal).ToString() End If End Sub Sub tbTargetHeight_MouseWheel(sender As Object, e As MouseEventArgs) Handles tbTargetHeight.MouseWheel If e.Delta < 0 Then Dim modVal = p.ForcedOutputMod tbTargetHeight.Text = CInt(((p.TargetHeight - modVal) / modVal) * modVal).ToString() Else Dim modVal = p.ForcedOutputMod tbTargetHeight.Text = CInt(((p.TargetHeight + modVal) / modVal) * modVal).ToString() End If End Sub Shared Function GetDefaultMenuSize() As CustomMenuItem Dim ret = New CustomMenuItem("Root") ret.Add("DVD/BD-5 (4482 MiB / 4700 MB)", NameOf(SetSize), {CInt(4700_000_000 \ PrefixedSize(2).Factor)}) ret.Add("DVD-DL/BD-9 (8145 MiB / 8540 MB)", NameOf(SetSize), {CInt(8540_000_000 \ PrefixedSize(2).Factor)}) ret.Add("-") ret.Add("BD (23842 MiB / 25000 MB)", NameOf(SetSize), {CInt(25000_000_000 \ PrefixedSize(2).Factor)}) ret.Add("BD-DL (47684 MiB / 50000 MB)", NameOf(SetSize), {CInt(50000_000_000 \ PrefixedSize(2).Factor)}) ret.Add("-") ret.Add("50%", NameOf(SetPercent), {50}) ret.Add("60%", NameOf(SetPercent), {60}) ret.Add("-") ret.Add("Edit Menu...", NameOf(ShowSizeMenuEditor)) Return ret End Function Sub SetTargetImageSize(width As Integer, height As Integer) g.AddResizeFilter() If height = 0 AndAlso width > 0 Then tbTargetWidth.Text = width.ToString SetImageHeight() ElseIf width = 0 AndAlso height > 0 Then tbTargetHeight.Text = height.ToString SetImageWidth() Else tbTargetWidth.Text = width.ToString tbTargetHeight.Text = height.ToString End If Assistant() End Sub Sub SetTargetImageSizeByPixel(pixel As Integer) g.AddResizeFilter() Dim cropw = p.SourceWidth - p.CropLeft - p.CropRight Dim ar = Calc.GetTargetDAR() Dim w = Calc.FixMod16(CInt(Math.Sqrt(pixel * ar))) If w > cropw Then w = (cropw \ 16) * 16 End If Dim h = Calc.FixMod16(CInt(w / ar)) tbTargetWidth.Text = w.ToString() tbTargetHeight.Text = h.ToString() Assistant() End Sub Sub SetSize( targetSize As Integer) tbTargetSize.Text = targetSize.ToString p.BitrateIsFixed = False End Sub Sub ShowScriptInfo() g.ShowScriptInfo(p.Script) End Sub Sub ShowAdvancedScriptInfo() g.ShowAdvancedScriptInfo(p.Script) End Sub Sub SetPercent( value As Integer) tbTargetSize.Text = g.GetAutoSize(value).ToString p.BitrateIsFixed = False End Sub Sub SetBitrate( bitrate As Integer) tbBitrate.Text = bitrate.ToString End Sub Sub StartAutoCrop() g.RunAutoCrop(Nothing) SetCropFilter() DisableCropFilter() Assistant() End Sub Sub StartSmartCrop() g.SmartCrop() SetCropFilter() DisableCropFilter() Assistant() End Sub Sub ShowSizeMenuEditor() s.CustomMenuSize = CustomSizeMenu.Edit() End Sub Sub UpdateSizeMenu() For Each i As MenuItemEx In CustomSizeMenu.MenuItems If i.CustomMenuItem.MethodName = "SetPercent" Then i.Enabled = p.Compressibility > 0 End If Next End Sub Function GetScriptAsProfile() As Profile Dim sb As New SelectionBox(Of TargetVideoScript) With { .Title = "New Profile", .Text = "Please select a profile." } sb.AddItem("Current Project", p.Script) For Each i In VideoScript.GetDefaults sb.AddItem(i) Next If sb.Show = DialogResult.OK Then Return sb.SelectedValue End If End Function Sub LoadFilterSetup(profileInterface As Profile) Dim profile = DirectCast(ObjectHelp.GetCopy(profileInterface), TargetVideoScript) If profile.Engine = ScriptEngine.AviSynth OrElse (Package.Python.VerifyOK(True) AndAlso Package.VapourSynth.VerifyOK(True) AndAlso Package.vspipe.VerifyOK(True)) Then Dim currentSetup = p.Script Try p.Script = profile SetCropFilter() PreviewScript = Nothing ModifyFilters() FiltersListView.OnChanged() Assistant() Catch ex As Exception p.Script = currentSetup PreviewScript = Nothing ModifyFilters() FiltersListView.OnChanged() Assistant() End Try End If FiltersListView.RebuildMenu() End Sub Function ParseCommandLine(commandLine As String, Optional delimiter As Char = " "c) As String() If String.IsNullOrWhiteSpace(commandLine) Then Return New List(Of String)().ToArray() Dim args = New List(Of String) Dim sb = New StringBuilder() Dim insideQuote = False Dim insideCurlyBracketsLevel = 0 Dim insideRoundBracketsLevel = 0 Dim insideSquareBracketsLevel = 0 For i = 0 To commandLine.Length - 1 Dim c = commandLine.Chars(i) If c = """" Then sb.Append(c) Dim lc = If(i > 0, commandLine.Chars(i - 1), "_"c) If lc <> "`" Then insideQuote = Not insideQuote End If ElseIf c = "{" Then sb.Append(c) insideCurlyBracketsLevel += 1 ElseIf c = "}" Then sb.Append(c) If insideCurlyBracketsLevel > 0 Then insideCurlyBracketsLevel -= 1 ElseIf c = "(" Then sb.Append(c) insideRoundBracketsLevel += 1 ElseIf c = ")" Then sb.Append(c) If insideRoundBracketsLevel > 0 Then insideRoundBracketsLevel -= 1 ElseIf c = "[" Then sb.Append(c) insideSquareBracketsLevel += 1 ElseIf c = "]" Then sb.Append(c) If insideSquareBracketsLevel > 0 Then insideSquareBracketsLevel -= 1 ElseIf c = delimiter Then If insideQuote Then sb.Append(c) ElseIf insideCurlyBracketsLevel > 0 Then sb.Append(c) ElseIf insideRoundBracketsLevel > 0 Then sb.Append(c) ElseIf insideSquareBracketsLevel > 0 Then sb.Append(c) Else Dim str = sb.ToString() If Not String.IsNullOrWhiteSpace(str) Then args.Add(str) End If sb = New StringBuilder() End If Else sb.Append(c) End If Next If sb.Length > 0 Then args.Add(sb.ToString()) Return args.ToArray() End Function Sub ProcessCommandLine(commandLine As String) If String.IsNullOrWhiteSpace(commandLine) Then Exit Sub Dim args = ParseCommandLine(commandLine) If args.Any() Then Package.LoadConfAll() Else Exit Sub End If Dim files As New List(Of String) Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.CommandLine)) <> 0 Dim forcedTemplateLoading = args.Where(Function(s) s.ToLowerInvariant().TrimQuotes().StartsWith("-" & NameOf(LoadTemplate).ToLowerInvariant())).Any() For Each arg In args.Skip(1) Try If Not arg.FileExists() AndAlso files.Count > 0 Then Dim files2 As New List(Of String)(files) Refresh() If Not showTemplateSelection AndAlso Not forcedTemplateLoading Then OpenProject(g.LastModifiedTemplate) OpenAnyFile(files2, showTemplateSelection AndAlso Not forcedTemplateLoading) files.Clear() End If If arg.FileExists() Then files.Add(arg) Else If Not CommandManager.ProcessCommandLineArgument(arg) Then Throw New Exception End If End If Catch ex As Exception MsgWarn("Error parsing argument:" + BR2 + arg + BR2 + ex.Message) End Try Next If files.Count > 0 Then Refresh() If Not showTemplateSelection AndAlso Not forcedTemplateLoading Then OpenProject(g.LastModifiedTemplate) OpenAnyFile(files, showTemplateSelection AndAlso Not forcedTemplateLoading) End If End Sub Sub SetHideDialogsOption(hide As Boolean) p.NoDialogs = hide End Sub Sub Standby() g.ShutdownPC(ShutdownMode.Standby) End Sub Sub Shutdown() g.ShutdownPC(ShutdownMode.Shutdown) End Sub Sub SetEncoderControl(c As Control) pnEncoder.Controls.Add(c) If pnEncoder.Controls.Count > 1 Then Dim old = pnEncoder.Controls(0) pnEncoder.Controls.Remove(old) old.Dispose() End If End Sub Sub UpdateEncoderStateRelatedControls() blFilesize.Visible = Not p.VideoEncoder.QualityMode tbTargetSize.Visible = Not p.VideoEncoder.QualityMode laBitrate.Visible = Not p.VideoEncoder.QualityMode tbBitrate.Visible = Not p.VideoEncoder.QualityMode End Sub Sub ShowOpenSourceSingleFileDialog() SetLastModifiedTemplate() If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub Using dialog As New OpenFileDialog dialog.SetFilter(FileTypes.Video.Concat(FileTypes.Image)) dialog.SetInitDir(s.LastSourceDir) If dialog.ShowDialog() = DialogResult.OK Then Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.OpeningMenu)) <> 0 Dim showTemplateSelectionTimeout = If(s.ShowTemplateSelection <> ShowTemplateSelectionMode.Never, s.ShowTemplateSelectionTimeout, 0) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(dialog.FileNames, showTemplateSelectionTimeout) Then OpenVideoSourceFiles(dialog.FileNames) Else Exit Sub End If Else OpenProject(g.LastModifiedTemplate) OpenVideoSourceFiles(dialog.FileNames) End If End If End Using End Sub Sub ShowOpenSourceMultipleFilesDialog() SetLastModifiedTemplate() If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub Using dialog As New OpenFileDialog dialog.SetFilter(FileTypes.Video) dialog.SetInitDir(s.LastSourceDir) dialog.Multiselect = True If dialog.ShowDialog() = DialogResult.OK Then Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.OpeningMenu)) <> 0 Dim showTemplateSelectionTimeout = If(s.ShowTemplateSelection <> ShowTemplateSelectionMode.Never, s.ShowTemplateSelectionTimeout, 0) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(dialog.FileNames, showTemplateSelectionTimeout) Then OpenVideoSourceFiles(dialog.FileNames) Else Exit Sub End If Else OpenProject(g.LastModifiedTemplate) OpenVideoSourceFiles(dialog.FileNames) End If End If End Using End Sub Sub ShowOpenSourceBlurayFolderDialog() SetLastModifiedTemplate() If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub Using dialog As New FolderBrowserDialog dialog.Description = "Please select a Blu-ray source folder." dialog.SetSelectedPath(s.Storage.GetString("last blu-ray source folder")) dialog.ShowNewFolderButton = False If dialog.ShowDialog = DialogResult.OK Then s.Storage.SetString("last blu-ray source folder", dialog.SelectedPath) Dim srcPath = dialog.SelectedPath.FixDir Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.OpeningMenu)) <> 0 Dim showTemplateSelectionTimeout = If(s.ShowTemplateSelection <> ShowTemplateSelectionMode.Never, s.ShowTemplateSelectionTimeout, 0) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(srcPath, showTemplateSelectionTimeout) Then OpenBlurayFolder(srcPath) Else Exit Sub End If Else OpenProject(g.LastModifiedTemplate) OpenBlurayFolder(srcPath) End If End If End Using End Sub Sub ShowOpenSourceBlurayImageDialog() SetLastModifiedTemplate() If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub Using dialog As New OpenFileDialog dialog.SetFilter(FileTypes.IsoImage) dialog.SetInitDir(s.LastSourceDir) If dialog.ShowDialog = DialogResult.OK Then Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.OpeningMenu)) <> 0 Dim showTemplateSelectionTimeout = If(s.ShowTemplateSelection <> ShowTemplateSelectionMode.Never, s.ShowTemplateSelectionTimeout, 0) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(dialog.FileName, showTemplateSelectionTimeout) Then OpenBlurayImage(dialog.FileName) Else Exit Sub End If Else OpenProject(g.LastModifiedTemplate) OpenBlurayImage(dialog.FileName) End If End If End Using End Sub Sub ShowOpenSourceMergeFilesDialog() SetLastModifiedTemplate() If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub Using form As New SourceFilesForm() form.Text = $"Merge - {g.DefaultCommands.GetApplicationDetails()}" form.IsMerge = True If form.ShowDialog() = DialogResult.OK AndAlso form.lb.Items.Count > 0 Then Dim files = form.GetFiles Select Case files(0).Ext Case "mpg", "vob" OpenVideoSourceFiles(files) Case Else Using proc As New Proc proc.Header = "Merge source files" For Each i In files Log.WriteLine(MediaInfo.GetSummary(i) + "---------------------------------------------------------" + BR2) Next proc.Encoding = Encoding.UTF8 proc.Package = Package.mkvmerge Dim outFile = files(0).DirAndBase + "_merged.mkv" proc.Arguments = "-o " + outFile.Escape + " """ + files.Join(""" + """) + """" Try proc.Start() Catch ex As Exception g.ShowException(ex) MsgInfo("Manual Merging", "Please merge the files manually with an appropriate tool or visit the support forum].") Throw New AbortException End Try If Not g.FileExists(outFile) Then Log.Write("Error merged output file is missing", outFile) Exit Sub Else Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.OpeningMenu)) <> 0 Dim showTemplateSelectionTimeout = If(s.ShowTemplateSelection <> ShowTemplateSelectionMode.Never, s.ShowTemplateSelectionTimeout, 0) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(outFile, showTemplateSelectionTimeout) Then OpenVideoSourceFile(outFile) Else Exit Sub End If Else OpenProject(g.LastModifiedTemplate) OpenVideoSourceFile(outFile) End If End If End Using End Select End If End Using End Sub Sub ShowOpenSourceBatchFilesDialog() SetLastModifiedTemplate() If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub If AbortDueToLowDiskSpace() Then Exit Sub Using form As New SourceFilesForm() form.Text = $"File Batch - {g.DefaultCommands.GetApplicationDetails()}" If p.DefaultTargetName = "%source_dir_name%" Then p.DefaultTargetName = "%source_name%" End If If form.ShowDialog() = DialogResult.OK AndAlso form.lb.Items.Count > 0 Then Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.OpeningMenu)) <> 0 Dim showTemplateSelectionTimeout = If(s.ShowTemplateSelection <> ShowTemplateSelectionMode.Never, s.ShowTemplateSelectionTimeout, 0) If showTemplateSelection Then If LoadTemplateWithSelectionDialog(form.GetFiles(), showTemplateSelectionTimeout) Then For Each filepath In form.GetFiles() AddBatchJob(filepath) Next Else Exit Sub End If Else OpenProject(g.LastModifiedTemplate, "", False) For Each filepath In form.GetFiles AddBatchJob(filepath) Next End If ShowJobsDialog() End If End Using End Sub Sub ShowOpenSourceDialog() Using td As New TaskDialog(Of String) td.Title = "Select a method for opening a source:" td.AddCommand("Single File") td.AddCommand("Multiple Files") td.AddCommand("Merge Files") td.AddCommand("File Batch") td.AddCommand("Blu-ray Folder") td.AddCommand("Blu-ray Image File") Select Case td.Show Case "Single File" ShowOpenSourceSingleFileDialog() Case "Multiple Files" ShowOpenSourceMultipleFilesDialog() Case "Merge Files" ShowOpenSourceMergeFilesDialog() Case "File Batch" ShowOpenSourceBatchFilesDialog() Case "Blu-ray Folder" ShowOpenSourceBlurayFolderDialog() Case "Blu-ray Image File" ShowOpenSourceBlurayImageDialog() End Select End Using End Sub Sub OpenEac3toDemuxForm(playlistFolder As String, playlistID As Integer) Using form As New eac3toForm(p) form.PlaylistFolder = playlistFolder form.PlaylistID = playlistID Dim workDir = playlistFolder.Parent.Parent Dim title = InputBox.Show("Enter a short title used as filename", playlistFolder.Parent.Parent.DirName) If title = "" Then Exit Sub If p.TempDir <> "" Then workDir = p.TempDir.Replace("%source_name%", title).FixDir Else workDir = Path.Combine(workDir, title) End If If Not g.IsFixedDrive(workDir) Then Using dialog As New FolderBrowserDialog dialog.Description = "Please select a folder for temporary files on a fixed local drive." dialog.SetSelectedPath(s.Storage.GetString("last blu-ray target folder").Parent) If dialog.ShowDialog = DialogResult.OK Then workDir = dialog.SelectedPath Else Exit Sub End If End Using End If form.teTempDir.Text = workDir If form.ShowDialog() = DialogResult.OK Then If Not Directory.Exists(form.OutputFolder) Then Try Directory.CreateDirectory(form.OutputFolder) Catch ex As Exception MsgError("The temp folder could not be created." + BR2 + form.OutputFolder) Exit Sub End Try End If If Not g.IsFixedDrive(form.OutputFolder) Then MsgError("Only fixed local drives are supported as temp dir.") Exit Sub End If Try Dim di As New DriveInfo(form.OutputFolder) If di.AvailableFreeSpace / PrefixedSize(3).Factor < s.MinimumDiskSpace Then Using td As New TaskDialog(Of String) td.Title = "Low Disk Space" td.Content = $"The target drive {Path.GetPathRoot(p.TargetFile)} has only " + $"{(di.AvailableFreeSpace / PrefixedSize(3).Factor):f2} {PrefixedSize(3).Unit} free disk space." td.Icon = TaskIcon.Warning td.AddButton("Continue") td.AddButton("Abort") If td.Show <> "Continue" Then Exit Sub End If End Using End If Using pr As New Proc pr.Header = "Demux M2TS" pr.TrimChars = {"-"c, " "c} pr.SkipStrings = {"analyze: ", "process: "} pr.Package = Package.eac3to Dim outFiles As New List(Of String) pr.Process.StartInfo.Arguments = form.GetArgs(playlistFolder.Escape + " " & playlistID & ")", title, outFiles) pr.OutputFiles = outFiles Try pr.Start() Catch ex As AbortException Exit Sub Catch ex As Exception g.ShowException(ex) Exit Sub End Try End Using s.Storage.SetString("last blu-ray target folder", form.OutputFolder) Dim fs = Path.Combine(form.OutputFolder, title + "." + form.cbVideoOutput.Text.ToLowerInvariant) If File.Exists(fs) Then p.TempDir = form.OutputFolder OpenVideoSourceFile(fs, False) End If Catch End Try End If End Using End Sub Function GetSourceFilesFromDir(path As String) As String() For Each i In FileTypes.Video Dim files = Directory.GetFiles(path, "*." + i) Array.Sort(files) If files.Length > 0 Then Return files End If Next End Function Protected Overrides Sub WndProc(ByRef m As Message) MyBase.WndProc(m) End Sub Sub tbSource_DoubleClick() Handles tbSourceFile.DoubleClick SetLastModifiedTemplate() Using dialog As New OpenFileDialog dialog.SetFilter(FileTypes.Video) dialog.Multiselect = True dialog.SetInitDir(s.LastSourceDir) If dialog.ShowDialog() = DialogResult.OK Then Refresh() Dim files = dialog.FileNames files.Sort() If Not files.NothingOrEmpty Then Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.OpeningMenu)) <> 0 If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub If Not showTemplateSelection Then OpenProject(g.LastModifiedTemplate) BeginInvoke(Sub() OpenAnyFile(files.ToList, showTemplateSelection)) End If End If End Using End Sub Function GetNewAudioProfile(currentProfile As AudioProfile) As AudioProfile Dim sb As New SelectionBox(Of AudioProfile) With { .Title = "New Profile", .Text = "Please select a profile." } If currentProfile IsNot Nothing Then sb.AddItem("Current Project", currentProfile) End If For Each i In AudioProfile.GetDefaults() sb.AddItem(i) Next If sb.Show = DialogResult.OK Then Return sb.SelectedValue End If End Function Sub lTip_Click() Handles laTip.Click If AssistantClickAction IsNot Nothing Then AssistantClickAction.Invoke() Assistant() End If End Sub Sub UpdateTargetParameters(proj As Project) If proj Is Nothing Then Exit Sub If proj.Script Is Nothing Then Exit Sub Dim info = proj.Script.GetInfo() Dim frameCount = 0 Dim frameRate = 0D Dim seconds = 0 If info.FrameRate > 0 Then frameCount = info.FrameCount frameRate = info.FrameRate seconds = CInt(frameCount / frameRate) Else End If UpdateTargetParameters(seconds, frameCount, frameRate) End Sub Sub UpdateTargetParameters(seconds As Integer, frames As Integer, frameRate As Double) p.TargetSeconds = seconds p.TargetFrames = frames p.TargetFrameRate = frameRate UpdateSizeOrBitrate() End Sub Sub pEncoder_MouseLeave() Handles pnEncoder.MouseLeave Assistant() End Sub Sub ShowAudioTip(ap As AudioProfile) If TypeOf ap Is GUIAudioProfile Then Dim gap = DirectCast(ap, GUIAudioProfile) If ap.Decoder = AudioDecoderMode.ffmpeg AndAlso gap.GetEncoder = GuiAudioEncoder.ffmpeg Then Documentation.ShowTip( "Please note that defining an audio decoder will always result in a separate " + "decoding step, which is usually not necessary if the decoder and encoder are identical, " + "it's a waste of time and disk space.") End If End If End Sub Sub ShowAudioProfilesDialog( number As Integer) g.LoadAudioProfiles() Dim form = New ProfilesForm("Audio Profiles", s.AudioProfiles, Sub(profile) g.LoadAudioProfile(profile, number), Function() GetNewAudioProfile(p.AudioTracks(number).AudioProfile), AddressOf AudioProfile.GetDefaults) If form.ShowDialog() = DialogResult.OK Then g.SaveAudioProfiles() End If form.Dispose() UpdateAudioMenus() PopulateProfileMenu(DynamicMenuItemID.AudioProfiles) End Sub Sub UpdateAudioMenus() If p.AudioTracksAvailable < 1 Then Exit Sub Dim nameControls = tlpAudio?.Controls?.OfType(Of AudioNameButtonLabel)?.Where(Function(x) x.GetType() Is GetType(AudioNameButtonLabel)) If nameControls Is Nothing Then Exit Sub If nameControls.Count < 1 Then Exit Sub For i = 0 To nameControls.Count - 1 Dim index = i Dim control = nameControls(index) control.ContextMenuStripEx = If(control.ContextMenuStripEx, New ContextMenuStripEx(components)) control.ContextMenuStripEx.Items.ClearAndDisplose() g.PopulateProfileMenu(control.ContextMenuStripEx.Items, s.AudioProfiles, Sub() ShowAudioProfilesDialog(index), Sub(profile) g.LoadAudioProfile(profile, index)) Next End Sub Sub AviSynthListView_ScriptChanged() Handles FiltersListView.Changed If Not IsLoading AndAlso Not FiltersListView.IsLoading Then If g.IsValidSource(False) Then UpdateSourceParameters() UpdateTargetParameters(p) p.VideoEncoder?.UpdateTargetFile() End If Assistant() End If End Sub Sub UpdateFilters() FiltersListView.Load() If g.IsValidSource(False) Then UpdateTargetParameters(p) End If End Sub Sub AviSynthListView_DoubleClick() Handles FiltersListView.DoubleClick FiltersListView.ShowCodeEditor() End Sub Sub gbFilters_MenuClick() Handles lgbFilters.LinkClick FiltersListView.ContextMenuStrip.Show(lgbFilters, 0, 16) End Sub Sub gbEncoder_LinkClick() Handles lgbEncoder.LinkClick EncoderMenu.Items.ClearAndDisplose g.PopulateProfileMenu(EncoderMenu.Items, s.VideoEncoderProfiles, AddressOf ShowEncoderProfilesDialog, AddressOf g.LoadVideoEncoder) EncoderMenu.Show(lgbEncoder, 0, 16) End Sub Sub llSize_Click() Handles blFilesize.Click UpdateSizeMenu() SizeContextMenuStrip.Show(blFilesize, 0, 16) End Sub Sub llContainer_Click() Handles llMuxer.Click ContainerMenu.Items.ClearAndDisplose g.PopulateProfileMenu(ContainerMenu.Items, s.MuxerProfiles, AddressOf ShowMuxerProfilesDialog, AddressOf p.VideoEncoder.LoadMuxer) ContainerMenu.Show(llMuxer, 0, 16) End Sub Sub gbResize_LinkClick() Handles lgbResize.LinkClick Dim cms = TextCustomMenu.GetMenu(s.TargetImageSizeMenu, lgbResize.Label, components, AddressOf TargetImageMenuClick) cms.Add("-") cms.Add("Image Options...", Sub() ShowOptionsDialog("Image")) cms.Add("Edit Menu...", Sub() s.TargetImageSizeMenu = TextCustomMenu.EditMenu(s.TargetImageSizeMenu, ApplicationSettings.GetDefaultTargetImageSizeMenu, Me)) cms.Show(lgbResize, 0, lgbResize.Label.Height) End Sub Sub blSourceParText_Click(sender As Object, e As EventArgs) Handles blSourceParText.Click Dim menu = TextCustomMenu.GetMenu(s.ParMenu, blSourceParText, components, AddressOf SourceParMenuClick) menu.Add("-") menu.Items.Add(New MenuItemEx("Edit Menu...", Sub() s.ParMenu = TextCustomMenu.EditMenu(s.ParMenu, ApplicationSettings.GetParMenu, Me))) menu.Show(blSourceParText, 0, blSourceParText.Height) End Sub Sub blSourceDarText_Click(sender As Object, e As EventArgs) Handles blSourceDarText.Click Dim menu = TextCustomMenu.GetMenu(s.DarMenu, blSourceDarText, components, AddressOf SourceDarMenuClick) menu.Add("-") menu.Items.Add(New MenuItemEx("Edit Menu...", Sub() s.DarMenu = TextCustomMenu.EditMenu(s.DarMenu, ApplicationSettings.GetDarMenu, Me))) menu.Show(blSourceDarText, 0, blSourceDarText.Height) End Sub Sub blTargetDarText_Click(sender As Object, e As EventArgs) Handles blTargetDarText.Click Dim menu = TextCustomMenu.GetMenu(s.DarMenu, blTargetDarText, components, AddressOf TargetDarMenuClick) menu.Add("-") menu.Items.Add(New MenuItemEx("Edit Menu...", Sub() s.DarMenu = TextCustomMenu.EditMenu(s.DarMenu, ApplicationSettings.GetDarMenu, Me))) menu.Show(blTargetDarText, 0, blTargetDarText.Height) End Sub Sub blTargetParText_Click(sender As Object, e As EventArgs) Handles blTargetParText.Click Dim menu = TextCustomMenu.GetMenu(s.ParMenu, blTargetParText, components, AddressOf TargetParMenuClick) menu.Add("-") menu.Items.Add(New MenuItemEx("Edit Menu...", Sub() s.ParMenu = TextCustomMenu.EditMenu(s.ParMenu, ApplicationSettings.GetParMenu, Me))) menu.Show(blTargetParText, 0, blTargetParText.Height) End Sub Sub SourceDarMenuClick(value As String) value = Macro.Expand(value) Dim tup = Macro.ExpandGUI(value) If tup.Cancel Then Exit Sub End If p.CustomSourcePAR = "" p.CustomSourceDAR = tup.Value If Calc.ParseCustomAR(tup.Value, 0, 0).X = 0 Then p.CustomSourceDAR = "" End If Assistant() End Sub Sub SourceParMenuClick(value As String) value = Macro.Expand(value) Dim tup = Macro.ExpandGUI(value) If tup.Cancel Then Exit Sub End If p.CustomSourcePAR = tup.Value p.CustomSourceDAR = "" If value <> "force" AndAlso Calc.ParseCustomAR(tup.Value, 0, 0).X = 0 Then p.CustomSourcePAR = "" End If Assistant() End Sub Sub TargetDarMenuClick(value As String) value = Macro.Expand(value) Dim tup = Macro.ExpandGUI(value) If tup.Cancel Then Exit Sub End If p.CustomTargetPAR = "" p.CustomTargetDAR = tup.Value If Calc.ParseCustomAR(tup.Value, 0, 0).X = 0 Then p.CustomTargetDAR = "" End If Assistant() End Sub Sub TargetParMenuClick(value As String) value = Macro.Expand(value) Dim tup = Macro.ExpandGUI(value) If tup.Cancel Then Exit Sub End If p.CustomTargetPAR = tup.Value p.CustomTargetDAR = "" If value <> "force" AndAlso Calc.ParseCustomAR(tup.Value, 0, 0).X = 0 Then p.CustomTargetPAR = "" End If Assistant() End Sub Sub TargetImageMenuClick(value As String) g.EnableFilter("Resize") value = Macro.Expand(value) Dim tup = Macro.ExpandGUI(value) If tup.Cancel Then Exit Sub End If value = tup.Value If value.IsInt Then SetTargetImageSizeByPixel(CInt(value)) Exit Sub End If If value?.Contains("x") Then Dim a = value.SplitNoEmptyAndWhiteSpace("x") If a.Length = 2 AndAlso a(0).IsInt AndAlso a(1).IsInt Then SetTargetImageSize(a(0).ToInt, a(1).ToInt) Exit Sub End If End If MsgWarn("Invalid format") End Sub Sub SetAutoAspectRatio(isAnamorphic As Boolean) p.SourceAnamorphic = isAnamorphic p.CustomSourcePAR = "" p.CustomSourceDAR = "" If p.Script.IsFilterActive("Resize)") Then SetTargetImageSize(p.TargetWidth, 0) End If Assistant() End Sub Sub SetTip() With TipProvider .SetTip("Target Display Aspect Ratio", lDAR, blTargetDarText) .SetTip("Target Pixel Aspect Ratio", lPAR, blTargetParText) .SetTip("Target Storage Aspect Ratio", lSAR, lSarText) .SetTip("Imagesize in pixel (width x height)", lPixel, lPixelText) .SetTip("Zoom factor between source and target image size", lZoom, lZoomText) .SetTip("Press Ctrl while using the slider to resize anamorphic.", tbResize) .SetTip("Aspect Ratio Error", lAspectRatioError, lAspectRatioErrorText) .SetTip("Cropped image size", lCrop, lCropText) .SetTip("Cropped sides in format: Left, Right / Top, Bottom", blCropText, lCrop2) .SetTip("Source Display Aspect Ratio", lSourceDar, blSourceDarText) .SetTip("Source Pixel Aspect Ratio", lSourcePAR, blSourceParText) .SetTip("Target Video Bitrate in Kbps (Up/Down key)", tbBitrate, laBitrate) .SetTip("Target Image Width in pixel (Up/Down key)", tbTargetWidth, lTargetWidth) .SetTip("Target Image Height in pixel (Up/Down key)", tbTargetHeight, lTargetHeight) .SetTip("Target File Size (Up/Down key)", tbTargetSize) .SetTip("Source file", tbSourceFile) .SetTip("Target file", tbTargetFile) .SetTip("Shows a menu with Container/Muxer profiles", llMuxer) .SetTip("Shows a menu with video encoder profiles", lgbEncoder.Label) .SetTip("Shows a menu with AviSynth filter options", lgbFilters.Label) End With End Sub Sub UpdateSourceParameters() If p.SourceScript Is Nothing Then Exit Sub Try Dim info = p.SourceScript.GetInfo p.SourceWidth = info.Width p.SourceHeight = info.Height p.SourceSeconds = CInt(info.FrameCount / info.FrameRate) p.SourceFrameRate = info.FrameRate p.SourceFrames = info.FrameCount Catch ex As Exception MsgError("Source filter returned invalid parameters", p.SourceScript.GetFullScript) Throw New AbortException() End Try End Sub Sub tbSource_TextChanged(sender As Object, e As EventArgs) Handles tbSourceFile.TextChanged If Not BlockSourceTextBoxTextChanged Then If File.Exists(tbSourceFile.Text) Then OpenVideoSourceFile(tbSourceFile.Text) End If End If End Sub Sub gbTarget_LinkClick() Handles lgbTarget.LinkClick UpdateTargetFileMenu() TargetFileMenu.Show(lgbTarget, 0, lgbTarget.Label.Height) End Sub Sub gbSource_MenuClick() Handles lgbSource.LinkClick UpdateSourceFileMenu() If File.Exists(p.SourceFile) Then SourceFileMenu.Show(lgbSource, 0, lgbSource.Label.Height) Else ShowOpenSourceDialog() End If End Sub Sub tbTargetFile_DoubleClick() Handles tbTargetFile.DoubleClick Using dialog As New SaveFileDialog dialog.FileName = p.TargetFile.Base dialog.SetInitDir(p.TargetFile.Dir) If dialog.ShowDialog() = DialogResult.OK Then Dim ext = p.VideoEncoder.Muxer.OutputExtFull p.TargetFile = If(dialog.FileName.Ext = ext, dialog.FileName, dialog.FileName + ext) End If End Using End Sub Sub tbTargetFile_TextChanged(sender As Object, e As EventArgs) Handles tbTargetFile.TextChanged If LastTbTargetFileText <> tbTargetFile.Text Then LastTbTargetFileText = tbTargetFile.Text If Not p.BatchMode AndAlso Not String.IsNullOrWhiteSpace(tbTargetFile.Text) Then p.VideoEncoder.OverridesTargetFileName = False End If End Sub Sub tbTargetFile_MouseDown(sender As Object, e As MouseEventArgs) Handles tbTargetFile.MouseDown If e.Button = MouseButtons.Right Then UpdateTargetFileMenu() End If End Sub Sub tbSourceFile_MouseDown(sender As Object, e As MouseEventArgs) Handles tbSourceFile.MouseDown If e.Button = MouseButtons.Right Then UpdateSourceFileMenu() End If End Sub Sub UpdateAudioFileMenu(audioTrack As AudioTrack, index As Integer, a As Action) Dim cms = DirectCast(audioTrack.TextEdit.TextBox.ContextMenuStrip, ContextMenuStripEx) Dim ap = audioTrack.AudioProfile Dim te = audioTrack.TextEdit Dim exist = File.Exists(ap.File) cms.Items.ClearAndDisplose() If ap.Streams IsNot Nothing AndAlso ap.Streams.Count > 0 Then For Each i In ap.Streams Dim temp = i Dim menuAction = Sub() If ap.File <> p.LastOriginalSourceFile Then te.Text = p.LastOriginalSourceFile End If te.Text = temp.Name + " (" + ap.File.Ext + ")" ap.Stream = temp audioTrack.LanguageLabel.Refresh() UpdateSizeOrBitrate() End Sub If ap.Streams.Count > 10 Then cms.Add("Streams | " + g.ConvertPath(i.Name), menuAction) Else cms.Add(g.ConvertPath(i.Name), menuAction) End If Next cms.Items.Add("-") End If If p.SourceFile.Ext = "avs" OrElse p.Script.GetScript.ToLowerInvariant.Contains("audiodub(") Then cms.Add(p.Script.Path.FileName, Sub() te.Text = p.Script.Path) End If If p.TempDir <> "" AndAlso Directory.Exists(p.TempDir) Then Dim audioFiles = Directory.GetFiles(p.TempDir).Where( Function(audioPath) FileTypes.Audio.Contains(audioPath.Ext)).ToList audioFiles.Sort(New StringLogicalComparer) If audioFiles.Count > 0 Then For Each i In audioFiles Dim temp = i Dim menuAction = Sub() audioTrack.Remove() te.Text = temp End Sub If audioFiles.Count > 10 Then cms.Add("Files | " + i.FileName, menuAction) Else cms.Add(i.FileName, menuAction) End If Next cms.Items.Add("-") End If End If Dim moreFilesAction = Sub() s.Storage.SetInt("last selected muxer tab", 1) p.VideoEncoder.OpenMuxerConfigDialog() End Sub cms.Add("Open File", a, "Change the audio source file.").SetImage(Symbol.OpenFile) cms.Add("Add more files...", moreFilesAction, exist) cms.Add("Play", Sub() g.PlayAudio(ap), exist, "Plays the audio source file with a media player.").SetImage(Symbol.Play) cms.Add("Media Info...", Sub() g.DefaultCommands.ShowMediaInfo(ap.File), exist, "Show MediaInfo for the audio source file.").SetImage(Symbol.Info) cms.Add("Explore", Sub() g.SelectFileWithExplorer(ap.File), exist, "Open the audio source file directory with File Explorer.").SetImage(Symbol.FileExplorer) cms.Add("-") cms.Add("Execute", Sub() ExecuteAudio(ap), exist, "Processes the audio profile.").SetImage(Symbol.LightningBolt) cms.Add("Execute All", Sub() ExecuteAllAudio(), p.AudioTracks.Any(Function(x) x.IsRelevant), "Processes all audio profiles.") cms.Add("-") cms.Add("Copy Path", Sub() Clipboard.SetText(ap.File), te.Text <> "") cms.Add("Copy Selection", Sub() Clipboard.SetText(te.TextBox.SelectedText), te.Text <> "").SetImage(Symbol.Copy) cms.Add("Paste", Sub() te.TextBox.Paste(), Clipboard.GetText.Trim <> "").SetImage(Symbol.Paste) cms.Add("-") cms.Add("Remove", Sub() audioTrack.Remove(), te.Text <> "", "Remove audio file").SetImage(Symbol.Remove) End Sub Sub ExecuteAudio(ap As AudioProfile) If MsgQuestion("Confirm to process the track.") = DialogResult.OK Then Dim cleanTemp = False Try If p.TempDir = "" Then p.TempDir = ap.File.Dir cleanTemp = True End If ap = ObjectHelp.GetCopy(ap) Audio.Process(ap) ap.Encode() Catch Finally If cleanTemp Then p.TempDir = "" End Try End If End Sub Sub ExecuteAllAudio() If MsgQuestion("Confirm to process ALL audio tracks.") = DialogResult.OK Then For Each track In p.AudioTracks Dim cleanTemp = False Try If track.TextEdit.Text = "" Then Continue For If TypeOf track.AudioProfile Is NullAudioProfile Then Continue For If p.TempDir = "" Then p.TempDir = track.AudioProfile.File.Dir() cleanTemp = True End If Dim ap = ObjectHelp.GetCopy(track.AudioProfile) Audio.Process(ap) ap.Encode() Catch Finally If cleanTemp Then p.TempDir = "" End Try Next End If End Sub Sub UpdateTargetFileMenu() TargetFileMenu.Items.ClearAndDisplose TargetFileMenu.Add("Browse File...", AddressOf tbTargetFile_DoubleClick, File.Exists(p.SourceFile), "Change the path of the target file.") TargetFileMenu.Add("Play", Sub() g.Play(p.TargetFile), File.Exists(p.TargetFile), "Play the target file.").SetImage(Symbol.Play) TargetFileMenu.Add("Media Info...", Sub() g.DefaultCommands.ShowMediaInfo(p.TargetFile), File.Exists(p.TargetFile), "Show MediaInfo for the target file.").SetImage(Symbol.Info) TargetFileMenu.Add("Explore...", Sub() g.SelectFileWithExplorer(p.TargetFile), Directory.Exists(p.TargetFile.Dir), "Open the target file directory with File Explorer.").SetImage(Symbol.FileExplorer) TargetFileMenu.Add("-") TargetFileMenu.Add("Copy", Sub() tbTargetFile.TextBox.Copy(), tbTargetFile.Text <> "").SetImage(Symbol.Copy) TargetFileMenu.Add("Paste", Sub() tbTargetFile.TextBox.Paste(), Clipboard.GetText.Trim <> "" AndAlso File.Exists(p.SourceFile)).SetImage(Symbol.Paste) End Sub Sub UpdateSourceFileMenu() SourceFileMenu.Items.ClearAndDisplose 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) SourceFileMenu.Add("Media Info...", Sub() g.DefaultCommands.ShowMediaInfo(p.LastOriginalSourceFile), File.Exists(p.LastOriginalSourceFile) AndAlso Not isIndex, "Show MediaInfo for the source file.").SetImage(Symbol.Info) SourceFileMenu.Add("Explore...", Sub() g.SelectFileWithExplorer(p.SourceFile), File.Exists(p.SourceFile), "Open the source file directory with File Explorer.").SetImage(Symbol.FileExplorer) SourceFileMenu.Items.Add("-") SourceFileMenu.Add("Copy", Sub() tbSourceFile.TextBox.Copy(), tbSourceFile.Text <> "", "Copies the selected text to the clipboard.").SetImage(Symbol.Copy) SourceFileMenu.Add("Paste", Sub() tbSourceFile.TextBox.Paste(), Clipboard.GetText.Trim <> "", "Copies the full source file path to the clipboard.").SetImage(Symbol.Paste) End Sub Protected Overrides Sub OnDragEnter(e As DragEventArgs) MyBase.OnDragEnter(e) Dim files = TryCast(e.Data.GetData(DataFormats.FileDrop), String()) If Not files.NothingOrEmpty Then e.Effect = DragDropEffects.Copy End If End Sub Protected Overrides Sub OnDragDrop(e As DragEventArgs) MyBase.OnDragDrop(e) SetLastModifiedTemplate() Dim files = TryCast(e.Data.GetData(DataFormats.FileDrop), String()) If Not files.NothingOrEmpty Then Dim showTemplateSelection = (s.ShowTemplateSelection And (ShowTemplateSelectionMode.Always Or ShowTemplateSelectionMode.DragDrop)) <> 0 If p.SourceFile <> "" AndAlso IsSaveCanceled() Then Exit Sub If Not showTemplateSelection Then OpenProject(g.LastModifiedTemplate) BeginInvoke(Sub() OpenAnyFile(files.ToList, showTemplateSelection)) End If End Sub Protected Overrides Sub OnActivated(e As EventArgs) MyBase.OnActivated(e) UpdateNextButton() If Not FrameServerHelp.IsAviSynthPortable AndAlso FrameServerHelp.GetAviSynthInstallPath = "" Then MsgError($"AviSynth installation not found,{BR}using portable mode instead.") s.AviSynthMode = FrameServerMode.Portable End If If Not FrameServerHelp.IsVapourSynthPortable AndAlso FrameServerHelp.GetVapourSynthInstallPath = "" Then MsgError($"VapourSynth installation not found,{BR}using portable mode instead.") s.VapourSynthMode = FrameServerMode.Portable End If ProcController.SetLastActivation() BeginInvoke(New Action(Sub() Application.DoEvents() Assistant() UpdateScriptsMenuAsync() End Sub)) End Sub Protected Overrides Sub OnLoad(args As EventArgs) MyBase.OnLoad(args) End Sub Protected Overrides Sub OnShown(e As EventArgs) MyBase.OnShown(e) UpdateDynamicMenuAsync() UpdateRecentProjectsMenu() UpdateTemplatesMenuAsync() IsLoading = False Refresh() CheckForWindows7() g.CheckForLongPathSupport() g.PreloadValuesAsync() ShowChangelog(False) ProcessCommandLine(Environment.CommandLine) StaxRipUpdate.SetFirstRunOnCurrentVersion() StaxRipUpdate.ShowUpdateQuestion() StaxRipUpdate.CheckForUpdateAsync(False, Environment.Is64BitProcess) g.RunTask(AddressOf g.LoadPowerShellScripts) 'Text = $"{Size.Width}x{Size.Height}" End Sub Protected Overrides Sub OnResize(e As EventArgs) MyBase.OnResize(e) 'Text = $"{Size.Width}x{Size.Height}" End Sub Protected Overrides Sub OnFormClosing(args As FormClosingEventArgs) MyBase.OnFormClosing(args) If IsSaveCanceled() Then args.Cancel = True End If End Sub Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs) MyBase.OnFormClosed(e) If g.ProcForm IsNot Nothing Then If g.ProcForm.InvokeRequired Then g.ProcForm.Invoke(Sub() g.ProcForm.Close()) Else g.ProcForm.Close() End If End If Try g.RaiseAppEvent(ApplicationEvent.ApplicationExit) Catch ex As Exception End Try g.SaveSettings() End Sub Protected Overrides Sub OnDeactivate(e As EventArgs) MyBase.OnDeactivate(e) UpdateNextButton() End Sub Protected Overrides Sub OnKeyDown(e As KeyEventArgs) MyBase.OnKeyDown(e) UpdateNextButton() End Sub Protected Overrides Sub OnKeyUp(e As KeyEventArgs) MyBase.OnKeyUp(e) UpdateNextButton() End Sub Protected Overrides ReadOnly Property ShowWithoutActivation As Boolean Get If g.IsAppStart Then g.IsAppStart = False If s.StartWithoutFocus OrElse ParseCommandLine(Environment.CommandLine)?.Contains("-" & NameOf(GlobalCommands.NoFocus), StringComparer.OrdinalIgnoreCase) Then ProcController.SetLastActivation(-s.PreventFocusStealAfter * 2) Return True End If End If If ProcController.BlockActivation Then ProcController.BlockActivation = False Return True End If Return MyBase.ShowWithoutActivation End Get End Property Sub UpdateTargetSizeLabel() Me.blFilesize.Text = $"Size in {PrefixedSize(2).Unit}:" End Sub Sub UpdateNextButton() If AssistantPassed AndAlso CanIgnoreTip Then Dim toTop = ModifierKeys.HasFlag(Keys.Shift) toTop = If(s.InvertShiftKeyOnNextButton, Not toTop, toTop) Dim hideList = ModifierKeys.HasFlag(Keys.Control) hideList = If(s.InvertCtrlKeyOnNextButton, Not hideList, hideList) Dim txt = "Add job" txt += If(toTop, " to top", "") txt += If(hideList, $"{BR}w/o showing list", "") bnNext.Text = txt Else bnNext.Text = "Accept / Next" End If End Sub Sub bnNext_Click(sender As Object, e As EventArgs) Handles bnNext.Click Dim toTop = ModifierKeys.HasFlag(Keys.Shift) toTop = If(s.InvertShiftKeyOnNextButton, Not toTop, toTop) Dim hideList = ModifierKeys.HasFlag(Keys.Control) hideList = If(s.InvertCtrlKeyOnNextButton, Not hideList, hideList) AddJob(Not hideList, If(toTop, 0, -1)) End Sub Sub bnNext_MouseDown(sender As Object, e As MouseEventArgs) Handles bnNext.MouseDown If e.Button = MouseButtons.Right AndAlso AssistantPassed AndAlso CanIgnoreTip Then NextContextMenuStrip.Show(bnNext, New Point(bnNext.Width, 0), ToolStripDropDownDirection.AboveLeft) End If End Sub Sub SetFormBoundaries(ateHeight As Integer) Dim assistantHeight = tlpMain.RowStyles.Item(4).Height Dim heights = tlpMain.GetRowHeights() Dim selectedHeights = heights.TakeWhile(Function(x, y) y < heights.Length - 1) Dim sum = CInt(selectedHeights.Sum(Function(s) s)) Dim h = sum + assistantHeight + (Size.Height - ClientSize.Height) MinimumSize = New Size(Font.Height * 48, CInt(h)) MaximumSize = New Size(Font.Height * 80, CInt(h)) End Sub Sub CheckForWindows7() If s.ShowWindows7Warning AndAlso OSVersion.VersionInfo.dwMajorVersion = 7 Then MsgWarn("Compatibility problem!", "Whereas Windows 7 is supported by StaxRip itself, some tools don't do it anymore. This can cause tools denying to work correctly or at whole. Currently those tools are 'MKVToolNix (mkvmerge)' and 'Python', which you have to downgrade or try to avoid. For further help join our Discord server.") End If s.ShowWindows7Warning = False End Sub Sub ShowChangelog(force As Boolean) Dim appDetails = g.DefaultCommands.GetApplicationDetails(True, True, False) If Not force AndAlso s.ShowChangelog = appDetails Then Exit Sub Dim ass = Assembly.GetExecutingAssembly() Dim currentVersion = ass.GetName().Version If Not force AndAlso currentVersion.Minor >= 99 Then Exit Sub Dim filepath = If(g.IsSupporterRelease, "StaxRip.CHANGELOG-SUPPORTER.md", "StaxRip.CHANGELOG.md") Using stream = ass.GetManifestResourceStream(filepath) Using reader As New StreamReader(stream) Dim lastChangelogVersionMatch = Regex.Match(s.ShowChangelog, "\d+\.\d+(?:\.\d+)*") Dim lastChangelogVersion = If(lastChangelogVersionMatch.Success, New Version(lastChangelogVersionMatch.Value), Nothing) Dim releases As New List(Of (Version As Version, VersionText As String, Changelog As String)) Dim readoutVersion As Version = Nothing Dim lastReadoutVersion As Version Dim lastReadoutVersionText As String Dim sb As New StringBuilder() Dim isComment = False Do While Not reader.EndOfStream Dim line = reader.ReadLine() If line = "" Then isComment = False Continue Do End If 'If String.IsNullOrWhiteSpace(line) Then Continue Do If line Like "========*" Then Continue Do Dim readoutVersionMatch = Regex.Match(line, "^(v(?\d+\.\d+(?:\.\d+)*(?:-(RC\d+))?))\W+\((?.*)\)") readoutVersion = If(readoutVersionMatch.Success, New Version(readoutVersionMatch.Groups("version").Value), readoutVersion) If readoutVersionMatch.Success Then If readoutVersion.Minor > currentVersion.Minor Then sb.Clear() Continue Do End If releases.Add((lastReadoutVersion, lastReadoutVersionText, sb.ToString().Trim())) lastReadoutVersion = readoutVersion lastReadoutVersionText = readoutVersionMatch.Groups("text").Value sb.Clear() Continue Do End If line = Regex.Replace(line, "(?<=\W\(?\[#\d+\])(\(/\.\./\.\./\w+/\d+\))(?=\)|(?>,|\)|$))", "", RegexOptions.CultureInvariant) line = Regex.Replace(line, "(?<=^| ) (?= |-)", " ", RegexOptions.CultureInvariant) sb.AppendLine(line) Loop Dim leftover = sb.ToString() If Not String.IsNullOrWhiteSpace(leftover) Then releases.Add((lastReadoutVersion, lastReadoutVersionText, leftover.Trim())) End If releases = releases.Where(Function(x) x.Version IsNot Nothing).ToList() Dim selectedReleases = releases.SkipWhile(Function(x) Not x.VersionText.IsDate AndAlso x.Version.Minor > currentVersion.Minor) selectedReleases = selectedReleases.Where(Function(x) x.Version.Minor = currentVersion.Minor AndAlso x.Version.Build <= Math.Max(currentVersion.Build, 0)) If lastChangelogVersion IsNot Nothing Then selectedReleases = selectedReleases.Where(Function(x) x.Version.Minor > lastChangelogVersion.Minor OrElse (x.Version.Minor = lastChangelogVersion.Minor AndAlso x.Version.Build > Math.Max(lastChangelogVersion.Build, 0))) End If selectedReleases = selectedReleases.ToList() Dim result = "" Dim versionLineBuilder = Function(version As Version, versionText As String) As String Dim versionLiner = New String("."c, 50) Return $"{versionLiner} v{version} [{versionText}] {versionLiner}" End Function If selectedReleases.Count() = 1 Then result = selectedReleases.Select(Function(x) x.Changelog).First() ElseIf selectedReleases.Count() > 1 Then result = selectedReleases.Select(Function(x) $"{versionLineBuilder(x.Version, x.VersionText)}{BR2}{x.Changelog}").Join(BR2) ElseIf force Then Dim currentRelease = releases.Where(Function(x) x.Version.Minor = currentVersion.Minor AndAlso x.Version.Build = Math.Max(currentVersion.Build, 0)).ToList() If currentRelease.Any() Then Dim release = currentRelease.FirstOrDefault() result = release.Changelog End If Else If force Then result = "Nothing to show..." End If End If If Not String.IsNullOrWhiteSpace(result) Then Using td As New TaskDialog(Of String)() td.Title = $"What's new in {appDetails}:" td.Icon = TaskIcon.Shield td.Content = result td.AddButton("OK") Dim answer = td.Show() s.ShowChangelog = appDetails If Not force Then g.SaveSettings() End Using End If End Using End Using End Sub End Class