Do you have some library to capture a screen to be a compressed video file or some solution that can do it?
Win + Print Screen: Captures the entire screen. The difference here is that Windows saves the image as a file. By default, it's sent to C:Users Pictures>Screenshots or C:Users OneDrive>Pictures>Screenshots on your PC. Win + Shift + S: Captures a screenshot using the built-in screenshot tool called Snip & Sketch.
A capture card is a device that's used in conjunction with a computer to capture on-screen content and encode it for playback in either a livestream or a high-quality video file. Capture cards can be used with video game consoles new and old, as well as computers and cameras.
This code uses SharpAvi available on NuGet.
using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using SharpAvi; using SharpAvi.Codecs; using SharpAvi.Output; using System.Windows.Forms; namespace Captura { // Used to Configure the Recorder public class RecorderParams { public RecorderParams(string filename, int FrameRate, FourCC Encoder, int Quality) { FileName = filename; FramesPerSecond = FrameRate; Codec = Encoder; this.Quality = Quality; Height = Screen.PrimaryScreen.Bounds.Height; Width = Screen.PrimaryScreen.Bounds.Width; } string FileName; public int FramesPerSecond, Quality; FourCC Codec; public int Height { get; private set; } public int Width { get; private set; } public AviWriter CreateAviWriter() { return new AviWriter(FileName) { FramesPerSecond = FramesPerSecond, EmitIndex1 = true, }; } public IAviVideoStream CreateVideoStream(AviWriter writer) { // Select encoder type based on FOURCC of codec if (Codec == KnownFourCCs.Codecs.Uncompressed) return writer.AddUncompressedVideoStream(Width, Height); else if (Codec == KnownFourCCs.Codecs.MotionJpeg) return writer.AddMotionJpegVideoStream(Width, Height, Quality); else { return writer.AddMpeg4VideoStream(Width, Height, (double)writer.FramesPerSecond, // It seems that all tested MPEG-4 VfW codecs ignore the quality affecting parameters passed through VfW API // They only respect the settings from their own configuration dialogs, and Mpeg4VideoEncoder currently has no support for this quality: Quality, codec: Codec, // Most of VfW codecs expect single-threaded use, so we wrap this encoder to special wrapper // Thus all calls to the encoder (including its instantiation) will be invoked on a single thread although encoding (and writing) is performed asynchronously forceSingleThreadedAccess: true); } } } public class Recorder : IDisposable { #region Fields AviWriter writer; RecorderParams Params; IAviVideoStream videoStream; Thread screenThread; ManualResetEvent stopThread = new ManualResetEvent(false); #endregion public Recorder(RecorderParams Params) { this.Params = Params; // Create AVI writer and specify FPS writer = Params.CreateAviWriter(); // Create video stream videoStream = Params.CreateVideoStream(writer); // Set only name. Other properties were when creating stream, // either explicitly by arguments or implicitly by the encoder used videoStream.Name = "Captura"; screenThread = new Thread(RecordScreen) { Name = typeof(Recorder).Name + ".RecordScreen", IsBackground = true }; screenThread.Start(); } public void Dispose() { stopThread.Set(); screenThread.Join(); // Close writer: the remaining data is written to a file and file is closed writer.Close(); stopThread.Dispose(); } void RecordScreen() { var frameInterval = TimeSpan.FromSeconds(1 / (double)writer.FramesPerSecond); var buffer = new byte[Params.Width * Params.Height * 4]; Task videoWriteTask = null; var timeTillNextFrame = TimeSpan.Zero; while (!stopThread.WaitOne(timeTillNextFrame)) { var timestamp = DateTime.Now; Screenshot(buffer); // Wait for the previous frame is written videoWriteTask?.Wait(); // Start asynchronous (encoding and) writing of the new frame videoWriteTask = videoStream.WriteFrameAsync(true, buffer, 0, buffer.Length); timeTillNextFrame = timestamp + frameInterval - DateTime.Now; if (timeTillNextFrame < TimeSpan.Zero) timeTillNextFrame = TimeSpan.Zero; } // Wait for the last frame is written videoWriteTask?.Wait(); } public void Screenshot(byte[] Buffer) { using (var BMP = new Bitmap(Params.Width, Params.Height)) { using (var g = Graphics.FromImage(BMP)) { g.CopyFromScreen(Point.Empty, Point.Empty, new Size(Params.Width, Params.Height), CopyPixelOperation.SourceCopy); g.Flush(); var bits = BMP.LockBits(new Rectangle(0, 0, Params.Width, Params.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); Marshal.Copy(bits.Scan0, Buffer, 0, Buffer.Length); BMP.UnlockBits(bits); } } } } }
System.Drawing
and System.Windows.Forms
. (The usage of System.Windows.Forms
can be avoided if you modify the code).Code:
using Captura; using System; namespace ConsoleApp { class Program { static void Main(string[] args) { // Using MotionJpeg as Avi encoder, // output to 'out.avi' at 10 Frames per second, 70% quality var rec = new Recorder(new RecorderParams("out.avi", 10, SharpAvi.KnownFourCCs.Codecs.MotionJpeg, 70)); Console.WriteLine("Press any key to Stop..."); Console.ReadKey(); // Finish Writing rec.Dispose(); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With