Beispiel #1
0
    void ExportVideoMotionBounds(XmlElement parent, VideoMotionBounds bounds, String boundsName)
    {
        XmlElement elt = AddChild(parent, boundsName);

        ExportVideoMotionVertex(elt, bounds.TopLeft, "TopLeft");
        ExportVideoMotionVertex(elt, bounds.TopRight, "TopRight");
        ExportVideoMotionVertex(elt, bounds.BottomRight, "BottomRight");
        ExportVideoMotionVertex(elt, bounds.BottomLeft, "BottomLeft");
    }
    void MatchOutputAspect(VideoMotionKeyframe keyframe, double dMediaPixelAspect, double dAspectOut)
    {
        VideoMotionKeyframe keyframeSave = keyframe;

        try
        {
            double rotation = keyframe.Rotation;

            // undo rotation so that we can get at correct aspect ratio.
            //
            keyframe.RotateBy(-rotation);

            double dWidth         = Math.Abs(keyframe.TopRight.X - keyframe.TopLeft.X);
            double dHeight        = Math.Abs(keyframe.BottomLeft.Y - keyframe.TopLeft.Y);
            double dCurrentAspect = dMediaPixelAspect * dWidth / dHeight;
            double centerY        = keyframe.Center.Y;
            double centerX        = keyframe.Center.X;

            double dFactor;

            VideoMotionBounds bounds = new VideoMotionBounds(keyframe.TopLeft, keyframe.TopRight, keyframe.BottomRight, keyframe.BottomLeft);

            if (dCurrentAspect < dAspectOut)
            {
                // alter y coords
                dFactor = dCurrentAspect / dAspectOut;

                bounds.TopLeft.Y     = (float)((bounds.TopLeft.Y - centerY) * dFactor + centerY);
                bounds.TopRight.Y    = (float)((bounds.TopRight.Y - centerY) * dFactor + centerY);
                bounds.BottomLeft.Y  = (float)((bounds.BottomLeft.Y - centerY) * dFactor + centerY);
                bounds.BottomRight.Y = (float)((bounds.BottomRight.Y - centerY) * dFactor + centerY);
            }
            else
            {
                // alter x coords
                dFactor = dAspectOut / dCurrentAspect;

                bounds.TopLeft.X     = (float)((bounds.TopLeft.X - centerX) * dFactor + centerX);
                bounds.TopRight.X    = (float)((bounds.TopRight.X - centerX) * dFactor + centerX);
                bounds.BottomLeft.X  = (float)((bounds.BottomLeft.X - centerX) * dFactor + centerX);
                bounds.BottomRight.X = (float)((bounds.BottomRight.X - centerX) * dFactor + centerX);
            }

            // set it to new bounds
            keyframe.Bounds = bounds;

            // restore rotation.
            keyframe.RotateBy(rotation);
        }
        catch (Exception e)
        {
            // restore original settings on error
            keyframe = keyframeSave;
        }
    }
    public class EntryPoint {   //The usual stuff for a Vegas script, I'll explain it later (no)
        public void FromVegas(Vegas myVegas)
        {
            PlugInNode pipeffect = myVegas.VideoFX.GetChildByName("VEGAS Picture In Picture"); //Getting the PiP effetc

            if (pipeffect == null)                                                             //if the effect doesn't exists we exit the script with an error message
            {
                MessageBox.Show("You don't have the VEGAS Picture In Picture effect. \n Please install it and try again!");
                return;
            }
            List <VideoEvent> videvents = new List <VideoEvent>();         //A list for the selected events

            foreach (Track myTrack in myVegas.Project.Tracks)              //going through every track and every event, adding the selected video events to the list
            {
                foreach (TrackEvent myEvent in myTrack.Events)
                {
                    if ((myEvent.MediaType == MediaType.Video) && (myEvent.Selected == true))
                    {
                        videvents.Add((VideoEvent)myEvent);
                    }
                }
            }
            double            proWidth  = myVegas.Project.Video.Width;                           //the project's width
            double            proHeight = myVegas.Project.Video.Height;                          //the project's height
            VideoMotionBounds newBound;                                                          //variable for the crop's size
            VideoMotionBounds newerBound;                                                        //variable for crop size if the first one doesn't fit the whole picture

            foreach (VideoEvent pipevent in videvents)                                           // for each video event in the list
            {
                Take                piptake   = pipevent.ActiveTake;                             //getting the width and height of the event's source
                VideoStream         pipstream = piptake.MediaStream as VideoStream;
                int                 myWidth   = pipstream.Width;                                 //the event's width
                int                 myHeight  = pipstream.Height;                                //the event"s height
                double              proAspect = myWidth / (myHeight * (proWidth / proHeight));   //calculating the correct number to multiply later the width/height later
                VideoMotionKeyframe reframe   = new VideoMotionKeyframe(Timecode.FromFrames(0)); //creating a new Pan/Crop keyframe at the beginning of the event
                pipevent.VideoMotion.Keyframes.Add(reframe);
                if (myWidth > myHeight)                                                          //calculating the size of the pan/crop keyframe with the help of the previously calculated value (proAspect) (EXTREMLY COMPLEX AND DANGEROUS, handle with care)
                {
                    newBound = new VideoMotionBounds(new VideoMotionVertex((float)(reframe.Center.X - (double)(myWidth / 2)), (float)(reframe.Center.Y - (double)(myHeight / 2) * proAspect)), new VideoMotionVertex((float)(reframe.Center.X + (double)(myWidth / 2)), (float)(reframe.Center.Y - (double)(myHeight / 2) * proAspect)), new VideoMotionVertex((float)(reframe.Center.X + (double)(myWidth / 2)), (float)(reframe.Center.Y + (double)(myHeight / 2) * proAspect)), new VideoMotionVertex((float)(reframe.Center.X - (double)(myWidth / 2)), (float)(reframe.Center.Y + (double)(myHeight / 2) * proAspect)));
                    if (Math.Abs(newBound.TopLeft.Y - newBound.BottomLeft.Y) < myHeight)                   //if the crop is the correct aspect ration, but it still cuts out part of the image, this code will run and make a cropize, which covers the whole picture with the correct ratio (MORE MATH)
                    {
                        float multiply = myHeight / Math.Abs(newBound.TopLeft.Y - newBound.BottomLeft.Y);
                        float actWidth = Math.Abs(newBound.TopRight.X - newBound.TopLeft.X) / 2;
                        float toHeight = myHeight / 2;
                        newerBound = new VideoMotionBounds(new VideoMotionVertex(reframe.Center.X - actWidth * multiply, reframe.Center.Y - toHeight), new VideoMotionVertex(reframe.Center.X + actWidth * multiply, reframe.Center.Y - toHeight), new VideoMotionVertex(reframe.Center.X + actWidth * multiply, reframe.Center.Y + toHeight), new VideoMotionVertex(reframe.Center.X - actWidth * multiply, reframe.Center.Y + toHeight));
                        newBound   = newerBound;
                    }
                }
                else                 //almost same as above, casual math
                {
                    newBound = new VideoMotionBounds(new VideoMotionVertex((float)(reframe.Center.X - (double)(myWidth / 2) / proAspect), (float)(reframe.Center.Y - (double)(myHeight / 2))), new VideoMotionVertex((float)(reframe.Center.X + (double)(myWidth / 2) / proAspect), (float)(reframe.Center.Y - (double)(myHeight / 2))), new VideoMotionVertex((float)(reframe.Center.X + (double)(myWidth / 2) / proAspect), (float)(reframe.Center.Y + (double)(myHeight / 2))), new VideoMotionVertex((float)(reframe.Center.X - (double)(myWidth / 2) / proAspect), (float)(reframe.Center.Y + (double)(myHeight / 2))));
                    if (Math.Abs(newBound.TopRight.X - newBound.TopLeft.X) < myWidth)
                    {
                        float multiply  = myHeight / Math.Abs(newBound.TopRight.X - newBound.TopLeft.X);
                        float toWidth   = myWidth / 2;
                        float actHeight = Math.Abs(newBound.TopLeft.Y - newBound.BottomLeft.Y / 2);
                        newerBound = new VideoMotionBounds(new VideoMotionVertex(reframe.Center.X - toWidth, reframe.Center.Y - actHeight * multiply), new VideoMotionVertex(reframe.Center.X + toWidth, reframe.Center.Y - actHeight * multiply), new VideoMotionVertex(reframe.Center.X + toWidth, reframe.Center.Y + actHeight * multiply), new VideoMotionVertex(reframe.Center.X - toWidth, reframe.Center.Y + actHeight * multiply));
                        newBound   = newerBound;
                    }
                }
                reframe.Bounds = newBound;                //setting the keyframe's size
                pipevent.Effects.AddEffect(pipeffect);    //adding the PiP effect to the event
            }
        }
    public void FromVegas(Vegas vegas)
    {
        Project currProject = vegas.Project;
        Int32   videoWidth  = currProject.Video.Width;
        Int32   videoHeight = currProject.Video.Height;

        TrackEvent[] tes = FindSelectedEvents(currProject);
        VideoEvent[] ves = GetVideoEvents(tes);

        if (ves.Length != 1)
        {
            MessageBox.Show("You have to select exactly 1 video events in order for this script to work.\nThe events must contain the \"" + MOTION_TRACKING_FX_NAME + "\" effect with at least one mask enabled. You then zoom in, using pan and crop options. Then after clicking on this script, the pan and crop option will be reset and the point moved, so that it stays on the pixel you selected.\n\nTerminating...", "Wrong selection", MessageBoxButtons.OK, MessageBoxIcon.Information);
            return;
        }

        // foreach (VideoEvent ev in ves)
        // {
        //     foreach (Effect ef in ev.Effects)
        //     {
        //         MessageBox.Show(ef.Description);
        //     }
        // }

        VideoEvent ve = GetEventContainingEffect(ves, MOTION_TRACKING_FX_NAME);

        if (ve == null)
        {
            MessageBox.Show("No selected event with the \"" + MOTION_TRACKING_FX_NAME + "\" plugin found which holds the motion tracking data!\n\nTerminating...", "Wrong selection", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        OFXEffect fx = GetOFXFromEvent(ve, MOTION_TRACKING_FX_NAME);

        if (fx == null)
        {
            MessageBox.Show("Can't seem to grab the \"" + MOTION_TRACKING_FX_NAME + "\" effect!\n\nTerminating...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            return;
        }

        PopulateMaskBitmask(fx);

        // show_fx_parameters(fx);

        int mask_to_use = PromptForMaskNumber();

        if (mask_to_use == -1)
        {
            return;
        }

        Timecode cursorTime = null;

        Double motionStart = ve.Start.ToMilliseconds();
        Double motionEnd   = ve.End.ToMilliseconds();

        Double cursorStart = vegas.Transport.CursorPosition.ToMilliseconds();

        Double max = Math.Max(motionStart, cursorStart);
        Double min = Math.Min(motionEnd, cursorStart);

        if (max != cursorStart || min != cursorStart)
        {
            MessageBox.Show("The cursor must be placed within the event borders!\n\nTerminating...", "Invalid cursor position", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        cursorTime = new Timecode(cursorStart);

        OFXDouble2DParameter motionParam = fx.FindParameterByName("Location_" + mask_to_use.ToString()) as OFXDouble2DParameter;

        if (cursorTime == null)
        {
            MessageBox.Show("Something went wrong as the script tried to determine the cursor position...\n\nTerminating...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            return;
        }

        VideoMotion vevm = ve.VideoMotion;

        VideoMotionKeyframe currKeyframe = new VideoMotionKeyframe(currProject, (cursorTime - ve.Start));

        vevm.Keyframes.Add(currKeyframe);

        Single cutoutWidth  = currKeyframe.TopRight.X - currKeyframe.TopLeft.X;
        Single cutoutHeight = currKeyframe.BottomLeft.Y - currKeyframe.TopLeft.Y;
        Single originX      = currKeyframe.TopLeft.X;
        Single originY      = currKeyframe.BottomLeft.Y;

        OFXDouble2D cursorValue = motionParam.GetValueAtTime(cursorTime - ve.Start);

        Double newCoordX = originX + (cutoutWidth * cursorValue.X);
        Double newCoordY = originY - (cutoutHeight * cursorValue.Y);

        cursorValue.X = newCoordX / videoWidth;
        cursorValue.Y = 1 - (newCoordY / videoHeight);
        motionParam.SetValueAtTime((cursorTime - ve.Start), cursorValue);

        DialogResult dialogResult = MessageBox.Show("If you choose to also adapt the mask scale, this would mean that the mask will be shrunk together with the video frame.\nIf you have zoomed in alot, it sometimes makes sense to not do this as the control handles would get so small that you can't grab them.\nIf you choose to also adjust the size, you can also later on change the width/height from the mask settings.\n\nWould you like to also adapt the mask scale?", "Also adjust mask scale?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

        if (dialogResult == DialogResult.Yes)
        {
            OFXDoubleParameter widthParam     = fx.FindParameterByName("Width_" + mask_to_use.ToString()) as OFXDoubleParameter;
            OFXDoubleParameter heightParam    = fx.FindParameterByName("Height_" + mask_to_use.ToString()) as OFXDoubleParameter;
            Double             maskWidth      = widthParam.GetValueAtTime(cursorTime - ve.Start);
            Double             maskHeight     = heightParam.GetValueAtTime(cursorTime - ve.Start);
            Double             widthRelation  = videoWidth / cutoutWidth;
            Double             heightRelation = videoHeight / cutoutHeight;

            widthParam.SetValueAtTime((cursorTime - ve.Start), (maskWidth / widthRelation));
            heightParam.SetValueAtTime((cursorTime - ve.Start), (maskHeight / heightRelation));
        }

        VideoMotionBounds restoreBounds = new VideoMotionBounds(
            new VideoMotionVertex(0, 0),
            new VideoMotionVertex(videoWidth, 0),
            new VideoMotionVertex(videoWidth, videoHeight),
            new VideoMotionVertex(0, videoHeight)
            );

        currKeyframe.Bounds = restoreBounds;
        currKeyframe.Center = new VideoMotionVertex((videoWidth / 2), (videoHeight / 2));

        MessageBox.Show("Please select a different effect, or move the cursor to a differen event, in order to update the control handles of the mask", "Refresh control handles", MessageBoxButtons.OK, MessageBoxIcon.Information);

        fx.AllParametersChanged();
    }