Screen recorder producing huge AVI files











up vote
3
down vote

favorite












I'm currently trying to make a screen recorder in C#, and so far it works but the problem is that something as simple as a 20second video will take about 1GB of space. I have it setup so a timer continuously takes screenshots with this method:



void takeScreenshot()
{
Rectangle bounds = Screen.FromControl(this).Bounds;
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);
}
//Create and save screenshot:
string name = path + "//screenshot-" + fileCount + ".jpeg";
bitmap.Save(name, ImageFormat.Jpeg);
inputImageSequence.Add(name);
fileCount++;

//Dispose of bitmap:
bitmap.Dispose();
}
}


And then it stores those pictures in a temporary folder in the D:// drive, and then when it's done it takes all the pictures and creates an AVI video out of them like this:



//Set bounds of video to screen size:
Rectangle bounds = Screen.FromControl(this).Bounds;
int width = bounds.Width;
int height = bounds.Height;

var framRate = 5;

using (var vFWriter = new VideoFileWriter())
{
//Create new video file:
vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

//Make each screenshot into a video frame:
foreach (var imageLocation in inputImageSequence)
{
Bitmap imageFrame = System.Drawing.Image.FromFile(imageLocation) as Bitmap;
vFWriter.WriteVideoFrame(imageFrame);
imageFrame.Dispose();
}
vFWriter.Close();
}
//Delete the screenshots and temporary folder:
DeletePath(path);


Any help on reducing the inefficiency of this is appreciated, I'm fairly new to this kind of programming.










share|improve this question









New contributor




BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    3
    down vote

    favorite












    I'm currently trying to make a screen recorder in C#, and so far it works but the problem is that something as simple as a 20second video will take about 1GB of space. I have it setup so a timer continuously takes screenshots with this method:



    void takeScreenshot()
    {
    Rectangle bounds = Screen.FromControl(this).Bounds;
    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);
    }
    //Create and save screenshot:
    string name = path + "//screenshot-" + fileCount + ".jpeg";
    bitmap.Save(name, ImageFormat.Jpeg);
    inputImageSequence.Add(name);
    fileCount++;

    //Dispose of bitmap:
    bitmap.Dispose();
    }
    }


    And then it stores those pictures in a temporary folder in the D:// drive, and then when it's done it takes all the pictures and creates an AVI video out of them like this:



    //Set bounds of video to screen size:
    Rectangle bounds = Screen.FromControl(this).Bounds;
    int width = bounds.Width;
    int height = bounds.Height;

    var framRate = 5;

    using (var vFWriter = new VideoFileWriter())
    {
    //Create new video file:
    vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

    //Make each screenshot into a video frame:
    foreach (var imageLocation in inputImageSequence)
    {
    Bitmap imageFrame = System.Drawing.Image.FromFile(imageLocation) as Bitmap;
    vFWriter.WriteVideoFrame(imageFrame);
    imageFrame.Dispose();
    }
    vFWriter.Close();
    }
    //Delete the screenshots and temporary folder:
    DeletePath(path);


    Any help on reducing the inefficiency of this is appreciated, I'm fairly new to this kind of programming.










    share|improve this question









    New contributor




    BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I'm currently trying to make a screen recorder in C#, and so far it works but the problem is that something as simple as a 20second video will take about 1GB of space. I have it setup so a timer continuously takes screenshots with this method:



      void takeScreenshot()
      {
      Rectangle bounds = Screen.FromControl(this).Bounds;
      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);
      }
      //Create and save screenshot:
      string name = path + "//screenshot-" + fileCount + ".jpeg";
      bitmap.Save(name, ImageFormat.Jpeg);
      inputImageSequence.Add(name);
      fileCount++;

      //Dispose of bitmap:
      bitmap.Dispose();
      }
      }


      And then it stores those pictures in a temporary folder in the D:// drive, and then when it's done it takes all the pictures and creates an AVI video out of them like this:



      //Set bounds of video to screen size:
      Rectangle bounds = Screen.FromControl(this).Bounds;
      int width = bounds.Width;
      int height = bounds.Height;

      var framRate = 5;

      using (var vFWriter = new VideoFileWriter())
      {
      //Create new video file:
      vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

      //Make each screenshot into a video frame:
      foreach (var imageLocation in inputImageSequence)
      {
      Bitmap imageFrame = System.Drawing.Image.FromFile(imageLocation) as Bitmap;
      vFWriter.WriteVideoFrame(imageFrame);
      imageFrame.Dispose();
      }
      vFWriter.Close();
      }
      //Delete the screenshots and temporary folder:
      DeletePath(path);


      Any help on reducing the inefficiency of this is appreciated, I'm fairly new to this kind of programming.










      share|improve this question









      New contributor




      BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I'm currently trying to make a screen recorder in C#, and so far it works but the problem is that something as simple as a 20second video will take about 1GB of space. I have it setup so a timer continuously takes screenshots with this method:



      void takeScreenshot()
      {
      Rectangle bounds = Screen.FromControl(this).Bounds;
      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);
      }
      //Create and save screenshot:
      string name = path + "//screenshot-" + fileCount + ".jpeg";
      bitmap.Save(name, ImageFormat.Jpeg);
      inputImageSequence.Add(name);
      fileCount++;

      //Dispose of bitmap:
      bitmap.Dispose();
      }
      }


      And then it stores those pictures in a temporary folder in the D:// drive, and then when it's done it takes all the pictures and creates an AVI video out of them like this:



      //Set bounds of video to screen size:
      Rectangle bounds = Screen.FromControl(this).Bounds;
      int width = bounds.Width;
      int height = bounds.Height;

      var framRate = 5;

      using (var vFWriter = new VideoFileWriter())
      {
      //Create new video file:
      vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

      //Make each screenshot into a video frame:
      foreach (var imageLocation in inputImageSequence)
      {
      Bitmap imageFrame = System.Drawing.Image.FromFile(imageLocation) as Bitmap;
      vFWriter.WriteVideoFrame(imageFrame);
      imageFrame.Dispose();
      }
      vFWriter.Close();
      }
      //Delete the screenshots and temporary folder:
      DeletePath(path);


      Any help on reducing the inefficiency of this is appreciated, I'm fairly new to this kind of programming.







      c# compression video






      share|improve this question









      New contributor




      BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 17 mins ago









      t3chb0t

      33.7k745108




      33.7k745108






      New contributor




      BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 4 hours ago









      BenCompSci

      162




      162




      New contributor




      BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      BenCompSci is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote













          takeScreenshot()




          • Based on the .NET Naming Guidelines methods should be named using PascalCase casing takeScreenshot() => TakeScreenshot()

          • You are enclosing the usage of the Bitmap inside a using statement which is the way to go but calling Dispose() on that Bitmap is superflous because that is what a using statement is doing.


          • If you have two using statements without any code between you can stack them which saves one level of indentation like so (already removed the Dispose())



            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);

            //Create and save screenshot:
            string name = path + "//screenshot-" + fileCount + ".jpeg";
            bitmap.Save(name, ImageFormat.Jpeg);
            inputImageSequence.Add(name);
            fileCount++;
            }


          • Comments should explain why something is done in the way it is done. Let the code itself tell what is done by using meaningful named things. In this way your comments won't lie like e.g //Create and save screenshot: which isn't what that code does. Saving yes but no creating of a screenshot is taking place.




          Creating the video




          • Try to be consitent. Here you create a Bitmap and call Dispose() instead of using a using statement. In addition, sometime you use var and sometimes you use the concrete type althought the type is seen at first glance.

          • If you are using the as operator you should always add a null check for that object because an as operator won't throw an exception but the resulting object may be null which will trigger an exception soewhere else.


          Implementing these points will look like so



          Rectangle bounds = Screen.FromControl(this).Bounds;
          var width = bounds.Width;
          var height = bounds.Height;

          var framRate = 5;

          using (var vFWriter = new VideoFileWriter())
          {
          vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

          foreach (var imageLocation in inputImageSequence)
          {
          using(var imageFrame = (Bitmap)System.Drawing.Image.FromFile(imageLocation))
          {
          vFWriter.WriteVideoFrame(imageFrame);
          }
          }
          vFWriter.Close();
          }
          DeletePath(path);




          My guess about the big file size is that you are using the VideoCodec.Raw. Try to change it to some other codec and see if this helps.






          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });






            BenCompSci is a new contributor. Be nice, and check out our Code of Conduct.










             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208582%2fscreen-recorder-producing-huge-avi-files%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote













            takeScreenshot()




            • Based on the .NET Naming Guidelines methods should be named using PascalCase casing takeScreenshot() => TakeScreenshot()

            • You are enclosing the usage of the Bitmap inside a using statement which is the way to go but calling Dispose() on that Bitmap is superflous because that is what a using statement is doing.


            • If you have two using statements without any code between you can stack them which saves one level of indentation like so (already removed the Dispose())



              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);

              //Create and save screenshot:
              string name = path + "//screenshot-" + fileCount + ".jpeg";
              bitmap.Save(name, ImageFormat.Jpeg);
              inputImageSequence.Add(name);
              fileCount++;
              }


            • Comments should explain why something is done in the way it is done. Let the code itself tell what is done by using meaningful named things. In this way your comments won't lie like e.g //Create and save screenshot: which isn't what that code does. Saving yes but no creating of a screenshot is taking place.




            Creating the video




            • Try to be consitent. Here you create a Bitmap and call Dispose() instead of using a using statement. In addition, sometime you use var and sometimes you use the concrete type althought the type is seen at first glance.

            • If you are using the as operator you should always add a null check for that object because an as operator won't throw an exception but the resulting object may be null which will trigger an exception soewhere else.


            Implementing these points will look like so



            Rectangle bounds = Screen.FromControl(this).Bounds;
            var width = bounds.Width;
            var height = bounds.Height;

            var framRate = 5;

            using (var vFWriter = new VideoFileWriter())
            {
            vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

            foreach (var imageLocation in inputImageSequence)
            {
            using(var imageFrame = (Bitmap)System.Drawing.Image.FromFile(imageLocation))
            {
            vFWriter.WriteVideoFrame(imageFrame);
            }
            }
            vFWriter.Close();
            }
            DeletePath(path);




            My guess about the big file size is that you are using the VideoCodec.Raw. Try to change it to some other codec and see if this helps.






            share|improve this answer

























              up vote
              2
              down vote













              takeScreenshot()




              • Based on the .NET Naming Guidelines methods should be named using PascalCase casing takeScreenshot() => TakeScreenshot()

              • You are enclosing the usage of the Bitmap inside a using statement which is the way to go but calling Dispose() on that Bitmap is superflous because that is what a using statement is doing.


              • If you have two using statements without any code between you can stack them which saves one level of indentation like so (already removed the Dispose())



                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);

                //Create and save screenshot:
                string name = path + "//screenshot-" + fileCount + ".jpeg";
                bitmap.Save(name, ImageFormat.Jpeg);
                inputImageSequence.Add(name);
                fileCount++;
                }


              • Comments should explain why something is done in the way it is done. Let the code itself tell what is done by using meaningful named things. In this way your comments won't lie like e.g //Create and save screenshot: which isn't what that code does. Saving yes but no creating of a screenshot is taking place.




              Creating the video




              • Try to be consitent. Here you create a Bitmap and call Dispose() instead of using a using statement. In addition, sometime you use var and sometimes you use the concrete type althought the type is seen at first glance.

              • If you are using the as operator you should always add a null check for that object because an as operator won't throw an exception but the resulting object may be null which will trigger an exception soewhere else.


              Implementing these points will look like so



              Rectangle bounds = Screen.FromControl(this).Bounds;
              var width = bounds.Width;
              var height = bounds.Height;

              var framRate = 5;

              using (var vFWriter = new VideoFileWriter())
              {
              vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

              foreach (var imageLocation in inputImageSequence)
              {
              using(var imageFrame = (Bitmap)System.Drawing.Image.FromFile(imageLocation))
              {
              vFWriter.WriteVideoFrame(imageFrame);
              }
              }
              vFWriter.Close();
              }
              DeletePath(path);




              My guess about the big file size is that you are using the VideoCodec.Raw. Try to change it to some other codec and see if this helps.






              share|improve this answer























                up vote
                2
                down vote










                up vote
                2
                down vote









                takeScreenshot()




                • Based on the .NET Naming Guidelines methods should be named using PascalCase casing takeScreenshot() => TakeScreenshot()

                • You are enclosing the usage of the Bitmap inside a using statement which is the way to go but calling Dispose() on that Bitmap is superflous because that is what a using statement is doing.


                • If you have two using statements without any code between you can stack them which saves one level of indentation like so (already removed the Dispose())



                  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);

                  //Create and save screenshot:
                  string name = path + "//screenshot-" + fileCount + ".jpeg";
                  bitmap.Save(name, ImageFormat.Jpeg);
                  inputImageSequence.Add(name);
                  fileCount++;
                  }


                • Comments should explain why something is done in the way it is done. Let the code itself tell what is done by using meaningful named things. In this way your comments won't lie like e.g //Create and save screenshot: which isn't what that code does. Saving yes but no creating of a screenshot is taking place.




                Creating the video




                • Try to be consitent. Here you create a Bitmap and call Dispose() instead of using a using statement. In addition, sometime you use var and sometimes you use the concrete type althought the type is seen at first glance.

                • If you are using the as operator you should always add a null check for that object because an as operator won't throw an exception but the resulting object may be null which will trigger an exception soewhere else.


                Implementing these points will look like so



                Rectangle bounds = Screen.FromControl(this).Bounds;
                var width = bounds.Width;
                var height = bounds.Height;

                var framRate = 5;

                using (var vFWriter = new VideoFileWriter())
                {
                vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

                foreach (var imageLocation in inputImageSequence)
                {
                using(var imageFrame = (Bitmap)System.Drawing.Image.FromFile(imageLocation))
                {
                vFWriter.WriteVideoFrame(imageFrame);
                }
                }
                vFWriter.Close();
                }
                DeletePath(path);




                My guess about the big file size is that you are using the VideoCodec.Raw. Try to change it to some other codec and see if this helps.






                share|improve this answer












                takeScreenshot()




                • Based on the .NET Naming Guidelines methods should be named using PascalCase casing takeScreenshot() => TakeScreenshot()

                • You are enclosing the usage of the Bitmap inside a using statement which is the way to go but calling Dispose() on that Bitmap is superflous because that is what a using statement is doing.


                • If you have two using statements without any code between you can stack them which saves one level of indentation like so (already removed the Dispose())



                  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);

                  //Create and save screenshot:
                  string name = path + "//screenshot-" + fileCount + ".jpeg";
                  bitmap.Save(name, ImageFormat.Jpeg);
                  inputImageSequence.Add(name);
                  fileCount++;
                  }


                • Comments should explain why something is done in the way it is done. Let the code itself tell what is done by using meaningful named things. In this way your comments won't lie like e.g //Create and save screenshot: which isn't what that code does. Saving yes but no creating of a screenshot is taking place.




                Creating the video




                • Try to be consitent. Here you create a Bitmap and call Dispose() instead of using a using statement. In addition, sometime you use var and sometimes you use the concrete type althought the type is seen at first glance.

                • If you are using the as operator you should always add a null check for that object because an as operator won't throw an exception but the resulting object may be null which will trigger an exception soewhere else.


                Implementing these points will look like so



                Rectangle bounds = Screen.FromControl(this).Bounds;
                var width = bounds.Width;
                var height = bounds.Height;

                var framRate = 5;

                using (var vFWriter = new VideoFileWriter())
                {
                vFWriter.Open(outputPath+"//video.avi", width, height, framRate, VideoCodec.Raw);

                foreach (var imageLocation in inputImageSequence)
                {
                using(var imageFrame = (Bitmap)System.Drawing.Image.FromFile(imageLocation))
                {
                vFWriter.WriteVideoFrame(imageFrame);
                }
                }
                vFWriter.Close();
                }
                DeletePath(path);




                My guess about the big file size is that you are using the VideoCodec.Raw. Try to change it to some other codec and see if this helps.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 1 hour ago









                Heslacher

                44.6k460154




                44.6k460154






















                    BenCompSci is a new contributor. Be nice, and check out our Code of Conduct.










                     

                    draft saved


                    draft discarded


















                    BenCompSci is a new contributor. Be nice, and check out our Code of Conduct.













                    BenCompSci is a new contributor. Be nice, and check out our Code of Conduct.












                    BenCompSci is a new contributor. Be nice, and check out our Code of Conduct.















                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208582%2fscreen-recorder-producing-huge-avi-files%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    404 Error Contact Form 7 ajax form submitting

                    How to know if a Active Directory user can login interactively

                    Refactoring coordinates for Minecraft Pi buildings written in Python