c#在winfrom里面怎么设置按键录制视频全屏
时间: 2024-03-01 20:53:53 浏览: 179
要在 C# WinForms 应用程序中录制全屏视频,可以使用 Windows API 中的 GDI+ 和 DirectShow 库。下面是一个简单的示例代码,演示如何使用 GDI+ 和 DirectShow 来录制全屏视频:
```csharp
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using DirectShowLib;
namespace ScreenRecorder
{
public partial class MainForm : Form
{
private IFilterGraph2 filterGraph;
private ISampleGrabber sampleGrabber;
private IMediaControl mediaControl;
private IBaseFilter grabberFilter;
private int stride;
public MainForm()
{
InitializeComponent();
stride = 4 * ((Screen.PrimaryScreen.Bounds.Width * 32 + 31) / 32);
}
private void button_start_Click(object sender, EventArgs e)
{
// 创建 FilterGraph 对象
filterGraph = (IFilterGraph2)new FilterGraph();
// 创建 SampleGrabber 对象
sampleGrabber = (ISampleGrabber)new SampleGrabber();
// 设置 SampleGrabber 参数
AMMediaType mediaType = new AMMediaType();
mediaType.majorType = MediaType.Video;
mediaType.subType = MediaSubType.RGB32;
mediaType.formatType = FormatType.VideoInfo;
sampleGrabber.SetMediaType(mediaType);
sampleGrabber.SetBufferSamples(true);
// 添加 SampleGrabber 到 FilterGraph 中
grabberFilter = (IBaseFilter)sampleGrabber;
filterGraph.AddFilter(grabberFilter, "Grabber");
// 枚举视频输入设备,选择第一个全屏设备
DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
for (int i = 0; i < devices.Length; i++)
{
if (devices[i].Name.ToLower().Contains("screen capture"))
{
// 创建 VideoCapture 对象,并将其添加到 FilterGraph 中
IBaseFilter videoCapture = (IBaseFilter)new VideoCapture();
filterGraph.AddFilter(videoCapture, "Video Capture");
// 连接 VideoCapture 和 SampleGrabber
IPin captureOut = DsFindPin.ByDirection(videoCapture, PinDirection.Output, 0);
IPin grabberIn = DsFindPin.ByDirection(grabberFilter, PinDirection.Input, 0);
filterGraph.Connect(captureOut, grabberIn);
// 设置采集视频的大小和位置
VideoInfoHeader videoInfo = new VideoInfoHeader();
videoInfo.BmiHeader.Width = Screen.PrimaryScreen.Bounds.Width;
videoInfo.BmiHeader.Height = Screen.PrimaryScreen.Bounds.Height;
videoInfo.BmiHeader.BitCount = 32;
videoInfo.BmiHeader.Compression = 0;
videoInfo.BmiHeader.ImageSize = videoInfo.BmiHeader.Width * videoInfo.BmiHeader.Height * videoInfo.BmiHeader.BitCount / 8;
videoInfo.BmiHeader.Planes = 1;
videoInfo.AvgTimePerFrame = 333333;
sampleGrabber.SetMediaType(mediaType);
sampleGrabber.GetConnectedMediaType(mediaType);
Marshal.PtrToStructure(mediaType.formatPtr, videoInfo);
videoInfo.SrcRect.Right = videoInfo.SrcRect.Left + Screen.PrimaryScreen.Bounds.Width;
videoInfo.SrcRect.Bottom = videoInfo.SrcRect.Top + Screen.PrimaryScreen.Bounds.Height;
videoInfo.TargetRect.Right = videoInfo.TargetRect.Left + Screen.PrimaryScreen.Bounds.Width;
videoInfo.TargetRect.Bottom = videoInfo.TargetRect.Top + Screen.PrimaryScreen.Bounds.Height;
sampleGrabber.SetMediaType(mediaType);
sampleGrabber.SetOneShot(false);
sampleGrabber.SetBufferSamples(true);
sampleGrabber.SetCallback(new SampleGrabberCallback(this));
sampleGrabber.SetMediaType(mediaType);
sampleGrabber.GetConnectedMediaType(mediaType);
Marshal.StructureToPtr(videoInfo, mediaType.formatPtr, false);
sampleGrabber.SetMediaType(mediaType);
// 创建 MediaControl 对象,并开始录制
mediaControl = (IMediaControl)filterGraph;
mediaControl.Run();
break;
}
}
}
private void button_stop_Click(object sender, EventArgs e)
{
// 停止录制
if (mediaControl != null)
mediaControl.Stop();
// 释放资源
if (mediaControl != null) Marshal.ReleaseComObject(mediaControl);
if (grabberFilter != null) Marshal.ReleaseComObject(grabberFilter);
if (sampleGrabber != null) Marshal.ReleaseComObject(sampleGrabber);
if (filterGraph != null) Marshal.ReleaseComObject(filterGraph);
}
private class SampleGrabberCallback : ISampleGrabberCB
{
private MainForm parent;
private Bitmap bitmap;
public SampleGrabberCallback(MainForm parent)
{
this.parent = parent;
}
public int SampleCB(double sampleTime, IMediaSample sample)
{
return 0;
}
public int BufferCB(double sampleTime, IntPtr buffer, int bufferLength)
{
// 将采集到的视频数据转换为位图
if (bitmap == null)
bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, parent.stride, System.Drawing.Imaging.PixelFormat.Format32bppRgb, buffer);
else
bitmap = new Bitmap(bitmap.Width, bitmap.Height, parent.stride, System.Drawing.Imaging.PixelFormat.Format32bppRgb, buffer);
// 在窗口中显示录制的视频
parent.pictureBox.Image = bitmap;
return 0;
}
}
}
}
```
在上面的示例代码中,我们创建了一个 MainForm 窗口,并在窗口中添加了两个按钮和一个 PictureBox 控件。单击“开始”按钮时,程序会枚举视频输入设备,并选择第一个全屏设备。然后,程序会创建 FilterGraph 对象,并将 VideoCapture 和 SampleGrabber 添加到其中。最后,程序会创建 MediaControl 对象,并开始录制视频。单击“停止”按钮时,程序会停止录制,并释放所有资源。
需要注意的是,上面的代码只是一个简单的示例,可能存在一些问题。例如,程序可能无法正确识别视频输入设备,或者无法正确处理某些视频格式。如果您想要实现更高级的功能,可以参考 MSDN 上的相关文档,或者使用开源的视频录制库(如 FFmpeg)。
阅读全文