//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; }