예제 #1
0
        //called when data for any output pin is requested
        public async void Evaluate(int SpreadMax)
        {
            switch (FCaptureState)
            {
            case CaptureState.Idle:
            {
                if (FRecord[0])
                {
                    if (FFrameCount[0] < 0 || (FFrameCount[0] > 0 && FRecord.IsChanged))
                    {
                        int p = unchecked ((int)FInput[0]);
                        FHandleToCapture = new IntPtr(p);

                        if (FHandleToCapture != IntPtr.Zero)
                        {
                            FCaptureState       = CaptureState.Capturing;
                            FFramesToCapture    = FFrameCount[0];
                            FDelayTimeToCapture = FDelay[0];
                            FIsRecording[0]     = true;
                            FCurrentTime        = FHDEHost.FrameTime;

                            //initialize TimeProvider
                            FHDEHost.SetFrameTimeProvider(_ => FCurrentTime);
                        }
                    }
                }
                break;
            }

            case CaptureState.Capturing:
            {
                if (FFramesToCapture < 0)
                {
                    //write file when capture stops
                    if (!FRecord[0])
                    {
                        FCaptureState = CaptureState.Writing;
                    }
                }
                else if (FFrames.Count >= FFramesToCapture)
                {
                    FCaptureState = CaptureState.Writing;
                }
                break;
            }
            }

            if (FCaptureState == CaptureState.Capturing)
            {
                try
                {
                    var img   = FScreenCapture.CaptureWindow(FHandleToCapture, true, null, FShowCursor[0]);
                    var delay = FHDEHost.FrameTime - FLastFrameTime;

                    FFrames.Add(new Frame()
                    {
                        Image = img, Delay = (float)delay
                    });

                    //advance frame time (will be taken into account for next frame captured)
                    FCurrentTime += FDelayTimeToCapture;
                }
                catch (Exception e)
                {
                    //in case of exception assume out of memory (even if no OOM exception occurs)
                    //free some memory by removing the last recorded frames for Saving not to fail
                    var freeCount = Math.Min(FFrames.Count, 10);
                    for (int i = FFrames.Count - freeCount; i < FFrames.Count; i++)
                    {
                        FFrames[i].Image.Dispose();
                    }
                    FFrames = FFrames.SkipLast(freeCount).ToList();

                    //then try saving the captured stuff
                    if (FFrames.Count > 0)
                    {
                        FCaptureState = CaptureState.Writing;
                    }
                    else
                    {
                        FCaptureState = CaptureState.Idle;
                    }
                }
            }
            else if (FCaptureState == CaptureState.Writing)
            {
                if (!FIsWriting[0])
                {
                    //reset TimeProvider
                    FHDEHost.SetFrameTimeProvider((ITimeProvider)null);

                    //compute filename
                    FCurrentFilename = FFilename[0];
                    if (FAutoFilename[0])
                    {
                        FCurrentFilename += Path.HasExtension(FCurrentFilename) ? "" : "\\"; //add trailing slash if this is supposed to be a path
                        var path = Path.GetDirectoryName(FCurrentFilename);
                        FCurrentFilename = Path.GetFileNameWithoutExtension(FCurrentFilename);
                        var now = DateTime.Now;
                        FCurrentFilename += "_" + now.ToString("dd.MM.yyyy-HH.mm.ss");
                        FCurrentFilename  = Path.Combine(path, FCurrentFilename + ".gif");
                        //FLogger.Log(LogType.Debug, filename);
                    }

                    FIsRecording[0] = false;
                    FIsWriting[0]   = true;

                    //write the file
                    await Task.Run(() => SaveGIFAsync(FCurrentFilename));

                    FLastFile[0]  = FCurrentFilename;
                    FIsWriting[0] = false;

                    FCaptureState = CaptureState.Idle;
                    FProgressBar.Hide();
                }
            }

            if (FReportProgress[0])
            {
                ReportProgress();
            }

            FLastFrameTime    = FHDEHost.FrameTime;
            FFrameCountOut[0] = FFrames.Count;
        }