我制作了一台录像机,它可以拍摄每一帧的截图,并将其保存在一个临时文件夹中.当我按下停止录制按钮时,它将所有内容放在一个视频中.我现在需要让我的程序判断最新的2个截图,并进行比较,以找到变化,如果没有找到变化的最后一个图像应该删除.另一方面,如果两个图像有任何差异,两个图像都会保持不变.
谢谢你帮我!
下面是我的屏幕录制脚本
ScreenRecorder.cs
using System.IO;
using System.Drawing;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Accord.Video;
using Accord.Video.FFMPEG;
using GroupDocs.Comparison.Options;
using GroupDocs.Comparison;
namespace Timelapser_version_1._2
{
class ScreenRecorder
{
//Video variables:
private Rectangle bounds;
private string outputPath = "";
private string tempPath = "";
private int fileCount = 1;
private List<string> inputImageSequence = new List<string>();
//File variables:
private string audioName = "mic.wav";
private string videoName = "video.mp4";
private string finalName = "FinalVideo.mp4";
//Time variable:
Stopwatch watch = new Stopwatch();
//Audio variables:
public static class NativeMethods
{
[DllImport("winmm.dll", EntryPoint = "mciSendStringA", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int record(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);
}
//ScreenRecorder Object:
public ScreenRecorder(Rectangle b, string outPath)
{
//Create temporary folder for screenshots:
CreateTempFolder("tempScreenCaps");
//Set variables:
bounds = b;
outputPath = outPath;
}
//Create temporary folder:
private void CreateTempFolder(string name)
{
//Check if a C or D drive exists:
if (Directory.Exists("D://"))
{
string pathName = $"D://{name}";
Directory.CreateDirectory(pathName);
tempPath = pathName;
}
else
{
string pathName = $"C://Documents//{name}";
Directory.CreateDirectory(pathName);
tempPath = pathName;
}
}
//Change final video name:
public void setVideoName(string name)
{
finalName = name;
}
//Delete all files and directory:
private void DeletePath(string targetDir)
{
string[] files = Directory.GetFiles(targetDir);
string[] dirs = Directory.GetDirectories(targetDir);
//Delete each file:
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
//Delete the path:
foreach (string dir in dirs)
{
DeletePath(dir);
}
Directory.Delete(targetDir, false);
}
//Delete all files except the one specified:
private void DeleteFilesExcept(string targetDir, string excDir)
{
string[] files = Directory.GetFiles(targetDir);
//Delete each file except specified:
foreach (string file in files)
{
if (file != excDir)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
}
}
//Clean up program on crash:
public void cleanUp()
{
if (Directory.Exists(tempPath))
{
DeletePath(tempPath);
}
}
//Return elapsed time:
public string getElapsed()
{
return string.Format("{0:D2}:{1:D2}:{2:D2}", watch.Elapsed.Hours, watch.Elapsed.Minutes, watch.Elapsed.Seconds);
}
//Record video:
public void RecordVideo()
{
//Keep track of time:
watch.Start();
int blac=0;
string a ="screenshot-1+%d";
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
//Add screen to bitmap:
g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}
//Save screenshot:
string name = tempPath + "//screenshot-" + fileCount + ".png";
bitmap.Save(name, ImageFormat.Png);
inputImageSequence.Add(name);
fileCount++;
//Dispose of bitmap:
bitmap.Dispose();
}
}
//Record audio:
public void RecordAudio()
{
NativeMethods.record("open new Type waveaudio Alias recsound", "", 0, 0);
NativeMethods.record("record recsound", "", 0, 0);
}
//Save audio file:
private void SaveAudio()
{
string audioPath = "save recsound " + outputPath + "//" + audioName;
NativeMethods.record(audioPath, "", 0, 0);
NativeMethods.record("close recsound", "", 0, 0);
}
//Save video file:
public void SaveVideo(int width, int height, int frameRate)
{
using (VideoFileWriter vFWriter = new VideoFileWriter())
{
vFWriter.Open(outputPath + "//"+ videoName, width, height, frameRate, VideoCodec.MPEG4);
//Make each screenshot into a video frame:
foreach (string imageLocation in inputImageSequence)
{
Bitmap imageFrame = System.Drawing.Image.FromFile(imageLocation) as Bitmap;
vFWriter.WriteVideoFrame(imageFrame);
imageFrame.Dispose();
}
//Close:
vFWriter.Close();
}
}
//Combine video and audio files:
private void CombineVideoAndAudio(string video, string audio)
{
//FFMPEG command to combine video and audio:
string args = $"/c ffmpeg -i \"{video}\" -i \"{audio}\" -shortest {finalName}";
ProcessStartInfo startInfo = new ProcessStartInfo
{
CreateNoWindow = false,
FileName = "cmd.exe",
WorkingDirectory = outputPath,
Arguments = args
};
//Execute command:
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
public void Stop()
{
//Stop watch:
watch.Stop();
//Video variables:
int width = bounds.Width;
int height = bounds.Height;
int frameRate = 10;
//Save audio:
SaveAudio();
//Save video:
SaveVideo(width, height, frameRate);
//Combine audio and video files:
CombineVideoAndAudio(videoName, audioName);
//Delete the screenshots and temporary folder:
DeletePath(tempPath);
//Delete separated video and audio files:
DeleteFilesExcept(outputPath, outputPath + "\\" + finalName);
}
}
}
forms1.cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Timelapser_version_1._2
{
public partial class Timelapser : Form
{
string outputPath = "";
bool folderSelected = false;
string finalVidName = "FinalVideo.mp4";
// Screen recorder object:
ScreenRecorder screenRec = new ScreenRecorder(new Rectangle(), " ");
public Timelapser()
{
InitializeComponent();
}
private void Start_Click(object sender, EventArgs e)
{
bool containsMP4 = finalVidName.Contains(".mp4");
if (folderSelected && containsMP4)
{
screenRec.setVideoName(finalVidName);
timer1.Start();
}
else if(!folderSelected && containsMP4)
{
MessageBox.Show("You must select an output Folder before recording","Error");
}
else if (folderSelected && !containsMP4)
{
MessageBox.Show("You must select video name that ends in '.mp4'", "Error");
finalVidName = "FinalVideo.mp4";
}
}
private void Stop_Click(object sender, EventArgs e)
{
timer1.Stop();
screenRec.Stop();
Application.Restart();
}
private void timer1_Tick(object sender, EventArgs e)
{
screenRec.RecordVideo();
screenRec.RecordAudio();
Timelabel.Text = screenRec.getElapsed();
}
private void SelectFolder_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
folderBrowser.Description = "Select an Output Folder";
if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
outputPath = @folderBrowser.SelectedPath;
folderSelected = true;
Rectangle bounds = Screen.FromControl(this).Bounds;
screenRec = new ScreenRecorder(bounds,outputPath);
}
else
{
MessageBox.Show("Please select a folder");
}
}