C# 如何在SharpAvi中保存录制的视频

C# 如何在SharpAvi中保存录制的视频,c#,C#,我想录制屏幕视频,然后另存为Mp4、Webm或任何视频格式。 我正在使用SharpAvi录制视频,下面的代码正在录制视频,但停止后我无法保存,请帮助这里是我的代码 namespace RecordScreenvideo { // Used to Configure the Recorder public class RecorderParams { public RecorderParams(string filename, int FrameRate, FourCC Encoder

我想录制屏幕视频,然后另存为Mp4、Webm或任何视频格式。 我正在使用SharpAvi录制视频,下面的代码正在录制视频,但停止后我无法保存,请帮助这里是我的代码

 namespace RecordScreenvideo
 {
// 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 = (int)SystemParameters.PrimaryScreenHeight;
        Width = (int)SystemParameters.PrimaryScreenWidth;
    }

    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);
            }
        }
    }
}
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        FourCC selectedCodec = KnownFourCCs.Codecs.MotionJpeg;


        RecorderParams recparams = new RecorderParams("recordvideo",49,selectedCodec,100);

        Recorder record = new Recorder(recparams);


    }
}

}

您只需要调用dispose方法 因此,在开始录制后,您需要硬编码您希望录制的时间,或者在您按任意键后录制,这里是一个main示例,当您按任意键时,它将开始录制,然后在您按任意键后停止录制

private void button1_Click(object sender, EventArgs e)
{
    FourCC selectedCodec = KnownFourCCs.Codecs.MotionJpeg;
    RecorderParams recparams = new RecorderParams("recordvideo",49,selectedCodec,100);

    Console.WriteLine("Press any key to start recording ");
    Console.ReadKey();
    Recorder record = new Recorder(recparams);

    Console.WriteLine("Press any key to stop recording ");
    Console.ReadKey();
    record.Dispose();

}

这非常容易将输出保存为mp4或任何格式,因为您可以看到方法`接收文件名作为第一个参数

 RecorderParams recparams = new RecorderParams("recordvideo",49,selectedCodec,100);`
因此,只需将输出文件路径作为

   RecorderParams recparams = new RecorderParams("D:\\recordvideo.mp4",49,selectedCodec,100);`

好,但这不会保存输出文件如何保存录制的文件?这会保存文件。如果转到项目目录,请确保使用受支持的编解码器。Exmp:`var rec=new Recordernew recorderparamsrecorded video,10,SharpAvi.KnownFourCCs.Codecs.MotionJpeg,100`