Fisheye lens correction?

DDDyson wrote on 9/3/2016, 2:43 PM

Does anyone know a good solution for turning action cam fisheye footage rectilinear? I would prefer a plugin solution rather that a stand-alone as the latter requires an intermediate pass (loss of time, disk space and quality).

This seems to have been missing from Vegas for quite a while. Vegas Pro 13 comes with the NewBlue FX trial versions, but the NewBlue lens correction works wrong: if the video aspect is non square like 16:9, the plugin's lens correction becomes elliptical, giving wrong results.

Sony Deform has been suggested, but it does not give correct results. You can get fairly close, but there is warping (it's not possible to get true spherical distortion with Deform)

ProDAD has a plugin version of Defishr for Magix Movie Edit Pro. Now that Sony Vegas and Magix have merged, any hopes that Defishr will be available for Vegas as a plugin too?

I've gotten the best results with AVISynth and a plugin called "Defish". But this is a stand-alone solution and as mentioned would prefer a plugin.

Comments

NickHope wrote on 9/3/2016, 11:48 PM

I can't answer the question directly but I can show you how to automate the Defish process so that AviSynth and VirtualDub run in the background and a defished event is put back on your timeline without you ever leaving Vegas. Paste this text into a text editor and save it as AviSynth-VirtualDub.js and put it in your C:\Program Files\Sony\Vegas Pro 13.0\Script Menu\ folder. You will need to manually edit file names, paths, templates etc.. Mine is currently set up to run an AviSynth script to deinterlace footage with QTGMC. But you can modify that line to run any AviSynth script including one that defishes. The render templates section is important and highly personalised. You have to have set up the render templates in Vegas before running the script, but that section of the script could just contain 1 template if that's all you need.

When this is set up and running correctly it's a wonderful timesaver. Quicker than a plugin. The Deshaker automation script this is based on was originally written by David Arendt and it has since been developed by WillemT, johnmeyer, wwaag and possibly others. See here to understand the origins. There are a few scripts kicking around that use some of this functionality, such as RenderEventAsTake from wwaag.

import System;
import System.IO;
import System.Text;
import system.Drawing;
import System.Collections;
import System.Diagnostics;
import System.Windows.Forms;
import Sony.Vegas;

//********************************************* User Modification Area ************************************************************************

var VIRTUALDUB : String = "C:\\Program Files (x86)\\VirtualDub\\VirtualDub.exe";   // 32-bit VirtualDub
//var VIRTUALDUB : String = "C:\\Program Files\\VirtualDub\\Veedub64.exe";   // 64-bit VirtualDub. 15/3/16 NH getting AVI filter error

//var SOURCE : String ="/p\"D:\\Videos\\720p\\720p-QTGMC-for-upscaling-from-576i-CURRENT.avs\"";   // Path to Avisynth script
var SOURCE : String ="/p\"D:\\Videos\\1080-1920p\\1920x1080-QTGMC-CURRENT.avs\"";   // Path to Avisynth script

var SETTINGS : String ="/s\"D:\\Documents\\MagicYUV-no-audio-progressive.vdscript\"";   // Virtualdub project render settings for output
//var SETTINGS : String ="/s\"D:\\Documents\\Deshaker-MagicYUV-progressive-allow-black-borders-for-later-cropping-zoom-0.vdscript\"";  // Error - puts result of 1st pass only back on timeline

var TMPFILE : String  = "D:\\fs.avi";   //Set temporary Vegas render out path.  Must be same in Avisynth script.

//var subDir : String = "AutoRender";   //Name of output sub-directory for rendered take files

var outputDir : String = "E:\\0-intermediates\\0-AviSynth-VirtualDub\\";   //Name of static output directory for rendered take files

//var suffix :  String = "-AR";   //Identifier in take name. Can be empty
var suffix :  String = "";   //Identifier in take name. Can be empty

//**********************************************************************************************************************************************

try {
// Variable declarations

//  var outputDir   :String  
//  var MyDir   :String;	
//  var MyPath    :String;
  var TemplateName : String;
  var VegasRenderTemplate : RenderTemplate;
  var NEWDEST : String;
  var projectPath : String;
  var fileName : String;
  var newName : String;
  var RendererName : String;
  var Extension : String;
  var addFrames : int
  var eventLength : int
  var newLength : Timecode
  var renderOpt : int
  var z : String
  var newTrack : int
  
  newTrack = 0;
 
// Remember project settings, so they can be restored at end of script
  var ProjectWidth = Vegas.Project.Video.Width;
  var ProjectHeight = Vegas.Project.Video.Height;
  var ProjectFrameRate = Vegas.Project.Video.FrameRate;
  var ProjectFieldOrder = Vegas.Project.Video.FieldOrder;
  var ProjectPixelAspectRatio = Vegas.Project.Video.PixelAspectRatio;
  var ProjectFieldOrder = Vegas.Project.Video.FieldOrder;

// Create render options GUI
	var dlog = new BatchRenderDialog();
		
	if (DialogResult.OK == dlog.ShowDialog()) {
          var selectedTemplates = dlog.GetCheckedTemplates();
	  if (dlog.addTake.Checked) {
		renderOpt=1;
	  }
	  if (dlog.addBoth.Checked) {
		renderOpt=3;
	  }
	  if (dlog.addTrack.Checked) {
		renderOpt=2;
	  }
	  var keepFX = dlog.keepEffects.Checked;
	}
	
	if (renderOpt == 0)
	  throw "user cancelled";
	
	if (renderOpt==2 || renderOpt==3) {
	  for (var newRenderVideoTrack : Track in Vegas.Project.Tracks) {		
		if (newRenderVideoTrack.Name =="Rendered") {
			newTrack=1;			
		}
	  break;
	  }
	  if (newTrack==0) {
		var RenderVideoTrack : VideoTrack = new VideoTrack();
		Vegas.Project.Tracks.Add(RenderVideoTrack);   // Add new track for rendered output.
		RenderVideoTrack.Name = "Rendered"; 
	  }
	}

  var TempVideoTrack : VideoTrack = new VideoTrack();
  Vegas.Project.Tracks.Add(TempVideoTrack);   // Add temporary track for render.
  TempVideoTrack.Name = "zzTempVideoTrack";
  // "true" copies the event to a new track and solos the track. 
  // However, if you need to render the result of say several tracks, then this line should be commented out.
  TempVideoTrack.Solo = true;

  // NoEventsSelected is used to exit if no event selected
  var NoEventsSelected : boolean = true;

  // Finally ready to go. Look through all selected events on all tracks ...
  for (var track : Track in Vegas.Project.Tracks) {
    if (track.IsAudio())
      continue;
    for (var ve : VideoEvent in track.Events) {
      if (!ve.Selected)   // Only process selected events.
        continue;

      // Selected video event found
      NoEventsSelected = false;

      TempVideoTrack.Events.Clear();
      var pve = ve.Copy(TempVideoTrack, ve.Start);   // Temporarily put copy of this event on clean, new track

      // Find media file path for selected event and then create output directory
      // NH - Commented out 4 lines because I prefer static directory outputDir defined in User Modification Area above
      //var MyTake=ve.ActiveTake;
      //MyPath=MyTake.MediaPath;
      //MyDir=MyPath.Substring(0, MyPath.LastIndexOf("\\"));
      //var outputDir = MyDir + "\\" + subDir;

      if (!Directory.Exists(outputDir)) {
        Directory.CreateDirectory(outputDir);
      }

      var thismedia = GetActiveMediaStream(pve);   // Find event's media file

      // Set project properties (temporarily) to media properties so that 
      // an  AVI is created without any changes from the original media.
      Vegas.Project.Video.Width = thismedia.Width;
      Vegas.Project.Video.Height = thismedia.Height;
      Vegas.Project.Video.FrameRate = thismedia.FrameRate;
      Vegas.Project.Video.FieldOrder = thismedia.FieldOrder;
      Vegas.Project.Video.PixelAspectRatio = thismedia.PixelAspectRatio;
      Vegas.Project.Video.FieldOrder = thismedia.FieldOrder;

// MessageBox.Show ("Frame Rate", ProjectFrameRate);
	     
      // Assign a render template matching the current event - These templates have to be already created and available--code by WillemT
      TemplateName = "Not Found";
      switch (thismedia.Width) {

        case 720: // PAL DV
	  TemplateName="NH MagicYUV 720x576 PAL DV 50i";
	  break;

        case 988: // Deinterlaced, upscaled DV for 
	     switch (thismedia.FrameRate) {
	        case 25:
	           TemplateName = "NH MagicYUV 988x720 25p";
	           break;
	        case 29.97002997002997:
	           TemplateName = "NH MagicYUV 988x720 30p";
	           break;
		case 50:
	           TemplateName = "NH MagicYUV 988x720 50p";
	           break;
	        case 59.94005994005994:
	           TemplateName = "NH MagicYUV 988x720 60p";
	           break;
	        default:
	           MessageBox.Show ("Oops! The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
		   continue;
            }
	  break;

        case 1280:
	     switch (thismedia.FrameRate) {
	        case 25:
	           TemplateName = "NH MagicYUV 1280x720 HD 25p";
	           break;
	        case 29.97002997002997:
	           TemplateName = "NH MagicYUV 1280x720 HD 30p";
	           break;
		case 50:
	           TemplateName = "NH MagicYUV 1280x720 HD 50p";
	           break;
	        case 59.94005994005994:
	           TemplateName = "NH MagicYUV 1280x720 HD 60p";
	           break;
	        default:
	           MessageBox.Show ("Oops! The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
		   continue;
            }
	  break;

	case 1440: // HDV, 1440x1080
	     switch (thismedia.FrameRate) {		     
	        case 25:
	           TemplateName="NH MagicYUV 1440x1080 HDV 50i";
	           break;
	        case 29.97002997002997:
	           TemplateName="NH MagicYUV 1440x1080 HDV 60i";
	           break;
	        default:
	           MessageBox.Show ("Oops! The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
		   continue;
            }
	  break;

	case 1920: // Full HD
	     switch (thismedia.FrameRate) {		     
	        case 25:
	           TemplateName = "NH MagicYUV 1920x1080 HD 25p";
	           break;
	        case 29.97002997002997:
	           TemplateName = "NH MagicYUV 1920x1080 HD 30p";
	           break;
		case 50:
	           TemplateName = "NH MagicYUV 1920x1080 HD 50p";
	           break;
	        case 59.94005994005994:
	           TemplateName = "NH MagicYUV 1920x1080 HD 60p";
	           break;
	        default:
	           MessageBox.Show ("Oops! The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
		   continue;
            }
	  break;

	case 2048: // For HD that's been upscaled to 2048 x 1152 in advance ready for cropping after deshaking
	  switch (thismedia.FrameRate) {		
	        case 25:
	           TemplateName = "NH MagicYUV 2048x1152 25p";
	           break;
	        case 29.97002997002997:
	           TemplateName = "NH MagicYUV 2048x1152 30p";
	           break;
		case 50:
	           TemplateName = "NH MagicYUV 2048x1152 50p";
	           break;
	        case 59.94005994005994:
	           TemplateName = "NH MagicYUV 2048x1152 60p";
	           break;
	        default:
	           MessageBox.Show ("Oops! The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
		   continue;
          }
	  break;

	case 3840: // UHD
	  switch (thismedia.FrameRate) {
		case 23.976023976023976:
	           TemplateName = "NH MagicYUV 3840x2160 UHD 23.976p";
	           break;
		case 24:
	           TemplateName = "NH MagicYUV 3840x2160 UHD 24p";
	           break;
	        case 25:
	           TemplateName = "NH MagicYUV 3840x2160 UHD 25p";
	           break;
	        case 29.97002997002997:
	           TemplateName = "NH MagicYUV 3840x2160 UHD 30p";
	           break;
		case 50:
	           TemplateName = "NH MagicYUV 3840x2160 UHD 50p";
	           break;
	        case 59.94005994005994:
	           TemplateName = "NH MagicYUV 3840x2160 UHD 60p";
	           break;
	        default:
	           MessageBox.Show ("Oops! The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
		   continue;
          }
	  break;

	case 4096: // C4K
	  switch (thismedia.FrameRate) {
		case 23.976023976023976:
	           TemplateName = "NH MagicYUV 4096x2160 C4K 23.976p";   // e.g. DJI OSMO C4K
	           break;
		case 24:
	           TemplateName = "NH MagicYUV 4096x2160 C4K 24p";   // e.g. GH4 C4K
	           break;
	        default:
	           MessageBox.Show ("Oops! The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
		   continue;
	  }
	  break;

// NH - I kept the below template as an example of conditional code that tests whether media is progressive or interlaced
//        case 1920: // HD, 1920x1080
//          if (thismedia.FieldOrder == "ProgressiveScan") {  // HD, 1080p, Progressive
//	     switch (thismedia.FrameRate) {	
//	        case 29.97002997002997: // HD, 1080p, 30fps Progressive
//	           TemplateName = "Cineform HD-1920-30P-No Audio";
//	           break;
//	        case 59.94005994005994: // HD, 1080p, 60fps Progressive
//	           TemplateName = "Cineform HD-1920-60P-No Audio";
//	           break;
//	        default:
//	           MessageBox.Show ("The framerate for event \"" + ve.ActiveTake.Name + "\" is not catered for.")
//		   continue;
//	     }
//          }
//	  else {  // HD, 1080i interlaced
//	     TemplateName = "Cineform HD-1920";
//	  }
//          break;

        default:  // Only the top options are catered for
	  MessageBox.Show ("The properties for event \"" + ve.ActiveTake.Name + "\" are not catered for.")
	  continue;
      }
      if (TemplateName == "Not Found") {
	MessageBox.Show ("Could not find the required template. (" + thismedia.Width + "x" + thismedia.height + " " + thismedia.FrameRate + "fps)")
	continue;
      }
      // END Automatic Render Template Selection

      // OK, it's time to render the event's video to a file so Avisynth/VirtualDub can do its magic.
      if (!keepFX) {
      RemovePanCrop(pve);   // Remove all pan/crop keyframes prior to rendering copied event.
      RemoveAllEffects (pve);   // Remove all fX keyframes prior to rendering copied event.
      }

      pve.FadeIn.Length = Timecode.FromFrames(0);   // Get rid of any fades, so we get actual video.
      pve.FadeOut.Length = Timecode.FromFrames(0);

      // Assign a filename for the denoised event, same as event then add an increment
      var file : String = outputDir + "\\" + ve.ActiveTake.Name + suffix;

      // Next check for duplicate file names and increments the counter
      // until an unused file name is found.
      var eventNum : int = 1; 
      //while (File.Exists(file + "-" + String.Format("{0:D3}", eventNum) + ".avi")) {   // 3 digits
      while (File.Exists(file + "-" + String.Format(eventNum) + ".avi")) {   // 1 digit	      
        eventNum++;
      }
      //file = file + "-" + String.Format("{0:D3}", eventNum) + ".avi";   // 3 digits
      file = file + "-" + String.Format(eventNum) + ".avi";   // 1 digit
      
      NEWDEST="\"" + file + "\"";
	
      // Render the file so VirtualDub can process it.
      // Use the above assigend render template to render the video to the tempavi file
      VegasRenderTemplate = Vegas.Renderers.FindByName("Video for Windows").Templates.FindByName(TemplateName);

      // Check if the Template was actually found
      if ( VegasRenderTemplate == null) {
	MessageBox.Show ("Could not find the required template (\"" + TemplateName + "\").")
	continue;
      }

      // Start the actual Vegas render to the temp track
      Vegas.Render(TMPFILE, VegasRenderTemplate, ve.Start, pve.Length)

      // Start VirtualDub and feed it the "command line" parameters.
      var CommandLine : String = SETTINGS + " " + SOURCE + " " + NEWDEST +" /r /x /c";
                             
      //MessageBox.Show (CommandLine);
 
      // This is where VirtualDub gets started and the parameters get passed to it
      var psi : ProcessStartInfo = new ProcessStartInfo(VIRTUALDUB, CommandLine);
      psi.UseShellExecute = false;
      psi.WindowStyle = ProcessWindowStyle.Normal

      var p : Process = Process.Start(psi);

      p.WaitForExit();   // Wait until VirtualDub is finished ... get a cup of coffee ...

      //MessageBox.Show ("Vdub completed");

      File.Delete(TMPFILE);   // Clean up
      //if (p.ExitCode != 0) {
      //  throw "QTGMC failed for take " + ve.ActiveTake.Name;
      //}

      // Add the rendered video to the media pool
      var media : Media = new Media(file);

      // VirtualDub doesn't set PAR,  so must reset here. 
      // NH - No! All my intermediates are progressive, PAR 1. I don't want to reset to interlaced or anamorphic
      //var mediaStream = media.Streams.GetItemByMediaType(MediaType.Video, 0);

      //mediaStream.PixelAspectRatio = thismedia.PixelAspectRatio;
      //mediaStream.FieldOrder = thismedia.FieldOrder;

	var take : Take = new Take(media.Streams.GetItemByMediaType(MediaType.Video, 0));
	var take1 : Take = new Take(media.Streams.GetItemByMediaType(MediaType.Video, 0));

	if (renderOpt==1 || renderOpt==3) {
	  // Add the new video as a take.
	  ve.Takes.Add(take);
	  ve.ActiveTake = take;
	}

	if (renderOpt==2 || renderOpt==3) {
/*
	  // Add the new video on a new track	
	  var nve : VideoEvent = RenderVideoTrack.AddVideoEvent (ve.Start, ve.Length);
	  nve.Takes.Add(take1);
	  nve.ActiveTake = take1;
*/
	  var track = FindTrack("Rendered");
	  var newEvent = new VideoEvent(ve.Start, ve.Length);
  	  track.Events.Add(newEvent);
 	  newEvent.Takes.Add(take1);  
	  newEvent.ActiveTake = take1;
	}

      eventNum++;   // Do it all again on the next selected event

    }
  }

  // All finished so clean up 
Vegas.Project.Tracks.Remove(TempVideoTrack);

  if (NoEventsSelected == true) {
    Vegas.UpdateUI();
    MessageBox.Show("No video events were selected.");
  }

  // Restore project settings 
  Vegas.Project.Video.Width = ProjectWidth;
  Vegas.Project.Video.Height = ProjectHeight;
  Vegas.Project.Video.FrameRate = ProjectFrameRate;
  Vegas.Project.Video.FieldOrder = ProjectFieldOrder;
  Vegas.Project.Video.PixelAspectRatio = ProjectPixelAspectRatio;
  Vegas.Project.Video.FieldOrder = ProjectFieldOrder;

} catch (e) {
  MessageBox.Show("Despite planning for all possible contingencies\nthe script had the following error: \n\n"+e);

  // In case of error, restore project settings.
  Vegas.Project.Video.Width = ProjectWidth;
  Vegas.Project.Video.Height = ProjectHeight;
  Vegas.Project.Video.FrameRate = ProjectFrameRate;
  Vegas.Project.Video.FieldOrder = ProjectFieldOrder;
  Vegas.Project.Video.PixelAspectRatio = ProjectPixelAspectRatio;
  Vegas.Project.Video.FieldOrder = ProjectFieldOrder;
} // End try/catch, and end of main program

// ***************************************
//                                       *
//            FUNCTIONS                  *
//                                       *
// ***************************************

// Remove all pan/crop keyframes from the copied event, prior to rendering.
function RemovePanCrop (evnt) {
    var keyframes = evnt.VideoMotion.Keyframes;
    var cKeyframes = keyframes.Count;
    var jj;
    for (jj = cKeyframes - 1; jj >= 0 ; jj-- ) {
      keyframes.Remove(keyframes[jj]);
    }
    var AddKey = new VideoMotionKeyframe(new Timecode(0));
    keyframes.Add(AddKey);
return;
}

// Remove all fX keyframes from the copied event, prior to rendering.
function RemoveAllEffects (evnt) {
    var videoEvent = VideoEvent(evnt);
    var i;
    for (i=videoEvent.Effects.Count - 1; i >= 0; i--) {
      var effect = videoEvent.Effects[i];
      videoEvent.Effects.Remove(effect);
    }
return;
}

// Find Media associated with event
function GetActiveMediaStream (trackEvent : TrackEvent)
{
    try
    {
        if ( ! trackEvent.ActiveTake.IsValid())
        {
            throw "empty or invalid take";
        }                
        
        var media = Vegas.Project.MediaPool.Find (trackEvent.ActiveTake.MediaPath);
        
        if (null == media)
        {
            throw "missing media";
        }
        
        var mediaStream = media.Streams.GetItemByMediaType (MediaType.Video, trackEvent.ActiveTake.StreamIndex);        
        
        return mediaStream;
    }
    catch (e)
    {
        //MessageBox.Show(e);
        return null;
    }    
}

function FindTrack(WhichTrack) : Track {
  var trackEnum = new Enumerator(Vegas.Project.Tracks);
  var PrevTrack : Track = Track(trackEnum.item());
  while (!trackEnum.atEnd()) {
    var track : Track = Track(trackEnum.item());
    if (WhichTrack == "Current") {
        if (track.Selected) {
            return track;
        }
    }
    if (WhichTrack == "Previous") {
        if (track.Selected) {
            return PrevTrack;
        }
    }
    if (track.Name == WhichTrack) {
        return track;
    }
    trackEnum.moveNext();
  }
  return null;
}

class BatchRenderDialog extends Form {
    var browseButton : BrowseButton;
    var fileNameBox : TextBox;
    var templateTree : TemplateTreeView;
    var addTake : RadioButton;
    var addTrack : RadioButton;
    var addBoth : RadioButton;
    var keepEffects : CheckBox;

    function BatchRenderDialog() {
        this.Text = "Render Options";
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
        this.MaximizeBox = false;
        this.StartPosition = FormStartPosition.CenterScreen;
        this.Width = 600;

        var titleBarHeight = this.Height - this.ClientSize.Height;
        var buttonWidth = 80;

	keepEffects = addCheckbox("Render FX and Pan/Crop Settings",1 , 25, 10);
//----------------------Set Default Effects--un comment to Keep FX as default; otherwise default is to remove effects
	keepEffects.Checked = true;
//------------------------------------------------------       
	fileNameBox = addTextControl("", titleBarHeight + 6, 460, 10, "");

        browseButton = new BrowseButton(fileNameBox);
        browseButton.Left = fileNameBox.Right + 4;
        browseButton.Top = fileNameBox.Top - 2;
        browseButton.Width = buttonWidth;
        browseButton.Height = browseButton.Font.Height + 12;
        browseButton.Text = "Browse...";
//        Controls.Add(browseButton);

        templateTree = new TemplateTreeView();
        templateTree.Left = 10;
        templateTree.Width = this.Width - 20;
        templateTree.Top = browseButton.Bottom + 10;
        templateTree.Height = 0;
        templateTree.CheckBoxes = true;
        Controls.Add(templateTree);
//        FillTemplateTree();

        var buttonTop = templateTree.Bottom + 16;
        var buttonsLeft = this.Width - (2*(buttonWidth+10));

        addTake = addRadioControl("Add as Take", 6, buttonTop);
        addTrack = addRadioControl("Add to New Track", addTake.Right, buttonTop);
        addBoth = addRadioControl("Add to Both", addTrack.Right, buttonTop);
	
        // New code added here to correctly identify whether to render selection, project, or region
//        var dSelStart = Vegas.SelectionStart.ToMilliseconds();
//        var dSelEnd = Vegas.SelectionStart.ToMilliseconds() + Vegas.SelectionLength.ToMilliseconds();
//        var dCursor = Vegas.Cursor.ToMilliseconds();
        
//        if (dSelStart == dCursor || dSelEnd == dCursor) {
//            renderSelection.Checked = true;
//        } else {
//            renderProject.Checked = true;
//        }

//----------------Set Default Radiobuttons--un-comment Button to be the default or uncomment all for no default---------------------------------------
	//addTake.Checked = true;
	addTrack.Checked = true;
	//addBoth.Checked = true;
//-------------------------------------------------------------------------------

        var okButton = new Button();
        okButton.Text = "OK";
        okButton.Left = this.Width - (2*(buttonWidth+10));
        okButton.Top = buttonTop;
        okButton.Width = buttonWidth;
        okButton.Height = okButton.Font.Height + 12;
        okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
        AcceptButton = okButton;
        Controls.Add(okButton);

        var cancelButton = new Button();
        cancelButton.Text = "Cancel";
        cancelButton.Left = this.Width - (1*(buttonWidth+10));
        cancelButton.Top = buttonTop;
        cancelButton.Height = cancelButton.Font.Height + 12;
        cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
        CancelButton = cancelButton;
        Controls.Add(cancelButton);

        this.Height = titleBarHeight + okButton.Bottom + 8;

    }

  function addTextControl(labelName, left, width, top, defaultValue) {
        var label = new Label();
        label.AutoSize = true;
        label.Text = labelName + ":";
        label.Left = left;
        label.Top = top + 4;
        Controls.Add(label);

        var textbox = new TextBox();
        textbox.Multiline = false;
        textbox.Left = label.Right;
        textbox.Top = top;
        textbox.Width = width - (label.Width);
        textbox.Text = defaultValue;
//        Controls.Add(textbox);

        return textbox;
    }

function addCheckbox(labelName, checkbox, left, top) {
        var label = new Label();
        label.AutoSize = true;
        label.Text = labelName;
        label.Left = left + 18;
        label.Top = top + 4;
        Controls.Add(label);

        if (checkbox == 1) {
           var checkbox = new CheckBox();
           checkbox.Left = left;
           checkbox.Width = 36;
           checkbox.Top = top;
           Controls.Add(checkbox);
           return checkbox;
        }
    }

    function addRadioControl(labelName, left, top) {
        var label = new Label();
        label.AutoSize = true;
        label.Text = labelName;
        label.Left = left;
        label.Top = top + 4;
        Controls.Add(label);

        var radiobutton = new RadioButton();
        radiobutton.Left = label.Right;
        radiobutton.Width = 36;
        radiobutton.Top = top;
        Controls.Add(radiobutton);

        return radiobutton;
    }

    function FillTemplateTree() {
        var renderers = new Enumerator(Vegas.Renderers);
        while (!renderers.atEnd()) {
            var renderer = renderers.item();

	    z = renderer.FileTypeName;
//		if (z != "Video for Windows") {
		if (z == "MP3 Audio"|z == "FLAC Audio"|z == "DebugMode FrameServer"|z == "Dolby Digital AC-3 Pro"|z == "Dolby Digital AC-3 Studio"|z == "ATRAC Audio"|z == "Audio Interchange File Format (AIFF)"|z == "OggVorbis"|
z == "Sony Wave64"|z == "Scott Studios Wave"|z == "Sony Perfect Clarity Audio"|z == "Wave (Microsoft)"|z == "Windows Media Audio V11"|z == "Image Sequence") {
			 renderers.moveNext();
			continue;
		}

            var rendererNode = new TreeNode(renderer.FileTypeName);
            rendererNode.Tag = renderer;
            templateTree.Nodes.Add(rendererNode);
            var templates = new Enumerator(renderer.Templates);
            while (!templates.atEnd()) {
                try {
                  var template = templates.item();
/*
			if (template.AudioStreamCount > 0) {
			templates.moveNext();
			continue;
			}
*/
                  var templateNode = new TreeNode(template.Name);
                  var tag = new Object();
                  tag.renderer = renderer;
                  tag.template = template;
                  templateNode.Tag = tag;
                  rendererNode.Nodes.Add(templateNode);
                  templates.moveNext();
              } catch (e) {
                templates.moveNext();
                }
            }
            renderers.moveNext();
        }
    }

    function GetCheckedTemplates() {
        var checkedTemplates = new ArrayList();
        var rendererNodes = new Enumerator(templateTree.Nodes);
        while (!rendererNodes.atEnd()) {
            var rendererNode = rendererNodes.item();
            GetCheckedTemplatesHelper(checkedTemplates, new Enumerator(rendererNode.Nodes));
            rendererNodes.moveNext();
        }
        return checkedTemplates;
    }

    function GetCheckedTemplatesHelper(checkedTemplates, templateNodes) {
        if (templateNodes.atEnd()) return;
        var templateNode = templateNodes.item();

        if (templateNode.Checked) {
            checkedTemplates.Add(templateNode.Tag);
        }
        templateNodes.moveNext();
        GetCheckedTemplatesHelper(checkedTemplates, templateNodes);
    }
}

// Button subclass that shows a save file dialog when clicked
class BrowseButton extends Button {
    var myResultBox = null;

    function BrowseButton(resultBox) {
        myResultBox = resultBox;
    }

    protected override function OnClick(e : EventArgs) {
        var saveFileDialog = new SaveFileDialog();
        saveFileDialog.Filter = "All Files (*.*)|*.*";
        saveFileDialog.CheckPathExists = true;
        saveFileDialog.AddExtension = false;
        if (null != myResultBox) {
            var filename = myResultBox.Text;
            var initialDir = Path.GetDirectoryName(filename);
            if (Directory.Exists(initialDir)) {
                saveFileDialog.InitialDirectory = initialDir;
            }
            saveFileDialog.DefaultExt = Path.GetExtension(filename);
            saveFileDialog.FileName = Path.GetFileNameWithoutExtension(filename);
        }
        if (System.Windows.Forms.DialogResult.OK == saveFileDialog.ShowDialog()) {
            if (null != myResultBox) {
                myResultBox.Text = Path.GetFullPath(saveFileDialog.FileName);
            }
        }
    }
}

class TemplateTreeView extends TreeView {

    protected function OnAfterCheck(e : TreeViewEventArgs) {
        super.OnAfterCheck(e);
        if (e.Node.Checked) {
            if (0 != e.Node.Nodes.Count) {
                if ((e.Action == TreeViewAction.ByKeyboard) || (e.Action == TreeViewAction.ByMouse)) {
                    SetChildrenChecked(new Enumerator(e.Node.Nodes), true);
                }
            } else if (!e.Node.Parent.Checked) {
                e.Node.Parent.Checked = true;
            }
        } else {
            if (0 != e.Node.Nodes.Count) {
                if ((e.Action == TreeViewAction.ByKeyboard) || (e.Action == TreeViewAction.ByMouse)) {
                    SetChildrenChecked(new Enumerator(e.Node.Nodes), false);
                }
            } else if (e.Node.Parent.Checked) {
                if (!AnyChildrenChecked(new Enumerator(e.Node.Parent.Nodes))) {
                    e.Node.Parent.Checked = false;
                }
            }
        }
    }

    protected function SetChildrenChecked(kidz, checked) {
        if (kidz.atEnd()) return;
        var kid = kidz.item();
        if (kid.Checked != checked)
            kid.Checked = checked;
        kidz.moveNext();
        SetChildrenChecked(kidz, checked);
    }

    protected function AnyChildrenChecked(kidz) : boolean {
        if (kidz.atEnd()) return false;
        var kid = kidz.item();
        if (kid.Checked)
            return true;
        kidz.moveNext();
        return AnyChildrenChecked(kidz);
    }
}

 

DDDyson wrote on 9/4/2016, 12:00 AM

Amazing, thanks! I had read earlier rumors that it's possible to import AviSynth scripts to Vegas directly as video clips, but never looked deeper into it. Now here's something for me to try out.

NickHope wrote on 9/4/2016, 12:08 AM

Good luck! Let us know if you need help. Coffee and a clear head needed before editing that script.

GJeffrey wrote on 12/11/2016, 3:02 AM

I've been trying to use the above script to deinterlace some footage but it fails.

All the path, render template and avs script are correctly set up.

When I start the script, the temp file rendered but Virtualdub never open and I end up with an error windows saying that "The system cannot find the specified file"

How to solve this?