基于C#实现的高性能实时MP4录屏方案

简介: 基于C#实现的高性能实时MP4录屏方案

一、技术选型对比

方案 优点 缺点 适用场景
GDI截图+FFmpeg 实现简单,兼容性强 CPU占用高(约30%-50%) 低分辨率/非实时场景
DXGI捕获+MediaFoundation 高性能(GPU加速),低CPU占用 开发复杂度高,需处理帧同步问题 高帧率(60fps)/4K录制
SharpDX/D3D11 支持DirectX加速,画质最佳 需要DirectX开发经验 游戏直播/专业视频制作

二、推荐实现方案(DXGI + MediaFoundation)

1. 核心代码结构

// 初始化捕获设备
var factory = new SharpDX.Direct3D11.DeviceFactory();
var adapter = factory.GetAdapter1(0);
var device = new SharpDX.Direct3D11.Device(adapter);

// 创建DXGI输出
var output = adapter.GetOutput(0);
var output1 = output.QueryInterface<SharpDX.DXGI.Output1>();
var duplication = output1.DuplicateOutput(device);

// 配置视频编码参数
var mediaType = new MediaFoundationEncoder.VideoMediaType(
    width: 1920,
    height: 1080,
    frameRate: 30,
    pixelFormat: SharpDX.WIC.PixelFormat.Format32bppBGRA,
    codec: MediaFoundationEncoder.Codec.H264,
    bitrate: 5000000 // 5Mbps
);

// 创建编码器
var encoder = new MediaFoundationEncoder(mediaType);
encoder.StartEncoding("output.mp4");

// 录制循环
while (isRecording)
{
   
    var frame = duplication.AcquireNextFrame(1000);
    var texture = frame.DesktopImage;

    // 转换为MediaFoundation可处理格式
    using (var stream = new MemoryStream())
    {
   
        texture.CopyTo(stream);
        encoder.EncodeFrame(stream.ToArray());
    }

    frame.Release();
}

2. 关键优化点

  • GPU加速编码:使用MediaFoundation的硬件编码(如NVIDIA NVENC),CPU占用可降低至5%以下

  • 内存映射文件:通过MemoryMappedFile实现零拷贝写入,提升IO性能

  • 帧率控制:动态调整捕获间隔,避免丢帧或卡顿

// 自适应帧率控制
var targetFrameTime = 1000 / targetFPS;
var lastFrameTime = Stopwatch.StartNew();

while (isRecording)
{
   
    var frameTime = lastFrameTime.ElapsedMilliseconds;
    if (frameTime >= targetFrameTime)
    {
   
        // 捕获并编码帧
        lastFrameTime.Restart();
    }
    else
    {
   
        Thread.Sleep(targetFrameTime - (int)frameTime);
    }
}

三、分段保存实现

// 自动分段保存逻辑
private void CheckSegment()
{
   
    if (encoder.TotalDuration >= _segmentDuration)
    {
   
        encoder.StopEncoding();
        string newPath = GenerateSegmentPath();
        encoder.StartEncoding(newPath);
    }
}

// 文件名生成策略
private string GenerateSegmentPath()
{
   
    var now = DateTime.Now;
    return $"recording_{now:yyyyMMdd_HHmmss}_{Guid.NewGuid():N}.mp4";
}

四、完整实现步骤

1. 环境配置

<!-- NuGet依赖 -->
<PackageReference Include="SharpDX" Version="4.3.0" />
<PackageReference Include="MediaFoundationEncoder" Version="1.2.0" />

2. 界面设计(WinForm)

<!-- 主窗体布局 -->
<DockPanel>
    <StatusBar DockPanel.Dock="Bottom">
        <TextBlock Text="{Binding Status}"/>
        <TextBlock Text="{Binding FPS} FPS"/>
    </StatusBar>

    <Button Content="开始录制" Command="{Binding StartCommand}"/>
    <Button Content="停止录制" Command="{Binding StopCommand}"/>

    <Slider Minimum="1" Maximum="60" Value="{Binding FrameRate}" Width="200"/>
</DockPanel>

3. ViewModel实现

public class MainViewModel : INotifyPropertyChanged
{
   
    private bool _isRecording;
    private int _frameRate = 30;
    private long _totalFrames;

    public ICommand StartCommand => new RelayCommand(StartRecording);
    public ICommand StopCommand => new RelayCommand(StopRecording);

    public string Status => _isRecording ? "录制中..." : "空闲";
    public int FPS => (int)(_totalFrames / (Stopwatch.GetTimestamp() / 1e7));

    private void StartRecording()
    {
   
        _isRecording = true;
        _totalFrames = 0;

        Task.Run(() => 
        {
   
            using (var recorder = new MediaRecorder())
            {
   
                recorder.Start(_frameRate);
                while (_isRecording)
                {
   
                    var frame = CaptureFrame();
                    recorder.Encode(frame);
                    _totalFrames++;
                }
                recorder.Stop();
            }
        });
    }

    private void StopRecording()
    {
   
        _isRecording = false;
    }
}

五、性能优化方案

1. 内存管理

  • 对象池:重用Texture2DMemoryStream对象
public class FramePool
{
   
    private readonly Queue<Texture2D> _pool = new();

    public Texture2D GetFrame(int width, int height)
    {
   
        return _pool.Count > 0 ? _pool.Dequeue() : new Texture2D(device, width, height);
    }

    public void ReturnFrame(Texture2D frame)
    {
   
        frame.Dispose();
    }
}

2. 多线程处理

// 生产者-消费者模型
BlockingCollection<Bitmap> _frameQueue = new();
Task.Run(() => EncodeWorker());

void EncodeWorker()
{
   
    foreach (var frame in _frameQueue.GetConsumingEnumerable())
    {
   
        // 编码处理
    }
}

3. GPU内存优化

// 使用DX12的显存直接访问
var commandAllocator = new CommandAllocator(device, CommandListType.Copy);
var commandList = new CommandList(device, commandAllocator);
commandList.CopyBufferRegion(stagingBuffer, 0, gpuBuffer, 0, dataSize);
commandAllocator.Reset();
commandList.Reset(commandAllocator, null);

六、扩展功能实现

1. 鼠标点击高亮

// 在捕获帧时叠加点击标记
void DrawClickMarker(Graphics g, Point position)
{
   
    using (var pen = new Pen(Color.Red, 2))
    {
   
        g.DrawEllipse(pen, position.X - 5, position.Y - 5, 10, 10);
    }
}

2. 音频同步录制

// 使用NAudio捕获系统音频
using (var waveIn = new WaveInEvent())
{
   
    waveIn.DataAvailable += (s, e) => 
    {
   
        audioBuffer.Write(e.Buffer, 0, e.BytesRecorded);
    };
    waveIn.StartRecording();
}

七、测试与调试

1. 性能监控

// 实时显示资源占用
public class PerformanceMonitor
{
   
    private readonly PerformanceCounter _cpuCounter = new("Processor", "% Processor Time", "_Total");
    private readonly PerformanceCounter _ramCounter = new("Memory", "Available MBytes");

    public string GetStatus()
    {
   
        return $"CPU: {_cpuCounter.NextValue()}%  内存: {_ramCounter.NextValue()}MB";
    }
}

2. 日志系统

public static class Logger
{
   
    private static readonly RollingFileAppender _appender = new();

    static Logger()
    {
   
        _appender.File = "log.txt";
        _appender.Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline");
        _appender.ActivateOptions();
    }

    public static void Log(string message)
    {
   
        _appender.DoAppend(new LoggingEvent(new LoggingEventData {
   
            Message = message,
            TimeStamp = DateTime.Now
        }));
    }
}

八、部署建议

  1. 安装依赖

    • 安装Microsoft Visual C++ 2015-2022 Redistributable

    • 部署FFmpeg动态库(ffmpeg.dll, avcodec-58.dll等)

  2. 代码签名

    # 使用signtool进行数字签名
    signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 MyApp.exe
    
  3. 安装包制作

    <!-- WiX安装配置 -->
    <Component Id="MainComponent" Guid="*">
        <File Id="MainExe" Name="MyApp.exe" Source="..\bin\Release\MyApp.exe"/>
        <RegistryValue Root="HKLM" Key="Software\MyCompany\MyApp" 
                       Name="InstallDir" Value="[INSTALLDIR]" Type="string"/>
    </Component>
    

参考代码 C#实时录屏软件 MP4格式 www.youwenfan.com/contentali/93565.html

九、方案对比与选择

场景 推荐方案 理由
企业级会议录制 MediaFoundation+DXGI 低延迟,支持多路流输入
游戏直播 SharpDX+NVENC硬件编码 最高支持8K 60fps,极致性能
简单录屏工具 GDI+FFmpeg命令行 开发周期短,维护成本低
跨平台录制 AValon+FFmpeg.AutoGen 支持Windows/macOS/Linux

十、常见问题解决方案

  1. 黑屏问题

    • 检查DXGI输出是否正确初始化

    • 确保以管理员权限运行程序

  2. 音频不同步

    • 设置AVSyncMode.AudioMaster同步模式

    • 添加音频缓冲队列(建议500ms)

  3. 文件损坏

    • 启用moov atom前置(快速启动)
    mediaType.FFmpegOptions.Add("movflags", "faststart");
    
相关文章
|
5天前
|
机器学习/深度学习 人工智能 API
5款靠谱的IP归属地查询服务深度测评:准确率、性能、离线库谁更强?
本文实测5款IP归属地查询工具,直击城市级定位不准痛点:广告投放偏差、风控失效。建议:先通过服务商提供的的免费测试额度验证区县级定位效果,用真实业务样本对比竞品差异,再决定是否接入离线库。高精度不是概念,而是可落地的工程能力。
345 2
|
5天前
|
人工智能 Oracle 机器人
推理 → 行动 → 观察:用 LangChain + Python 实现一个智能体循环
智能体循环(Agentic Loop)突破单次问答局限,通过“推理→行动→观察”迭代闭环,让AI能自主分解任务、调用工具、持续优化直至目标完成,是构建真正自动化智能体的核心架构。
203 9
推理 → 行动 → 观察:用 LangChain + Python 实现一个智能体循环
|
5天前
|
人工智能 监控 前端开发
学习AI Agent编程-第二天-LangGraph ReAct模式实现
本文介绍了LangChain中ReAct(推理-行动)模式的实践应用:通过“会议室申请”流程,演示LLM如何循环执行“决策→调用工具→评估结果→调整策略”,实现多步任务自动化。代码涵盖流程定义、工具函数与多轮会话测试,验证了其在空闲检查、报备审批、异常处理等场景的可靠性。(239字)
212 7
学习AI Agent编程-第二天-LangGraph ReAct模式实现
|
5天前
|
弹性计算 人工智能 网络安全
阿里云官方镜像一键部署OpenClaw保姆级教程:从实例创建到服务上线全流程
OpenClaw(原Clawdbot/Moltbot)是一款开源的本地优先AI代理与自动化平台,能通过自然语言调用浏览器、文件系统、邮件等工具,完成文档整理、邮件处理、日程安排等实际任务,堪称“能替你干活的AI数字员工”。2026年,阿里云官方推出OpenClaw专属应用镜像,依托轻量应用服务器与ECS云服务器,提供一键部署能力,无需手动配置复杂运行环境,零基础用户也能快速搭建专属AI助理,实现7×24小时稳定运行。
215 2
|
5天前
|
存储 人工智能 弹性计算
基于阿里Qoder的实训案例荣获2026全国高校程序设计教育大会特等奖
复旦大学赵卫东老师主持的“基于阿里Qoder开发个人博客系统”实训案例,获2026全国高校程序设计教育大会特等奖。案例融合通义灵码与千问API,覆盖AI写作、分析、部署全流程, exemplifies AI时代产教融合新范式。(239字)
194 3
|
5天前
|
人工智能 机器人 Shell
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
龙虾本地化AI(Lobster AI)是一款完全离线、零成本、零隐私泄露的开源机器人系统,支持文本推理(Gemma4)、多模态视觉理解(桌面/摄像头)、语音识别与合成(Sherpa-ONNX),纯本地运行,不依赖任何云服务。
250 2
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
|
5天前
|
机器学习/深度学习 人工智能 监控
人体姿态检测数据集分享(适用于YOLO系列深度学习检测任务)
本数据集含6000张高质量标注图像,覆盖站着、摔倒、坐、深蹲、跑5类人体姿态,按5:1划分训练集与验证集,采用YOLO格式标注,结构清晰,开箱即用,适用于YOLOv8等目标检测模型训练,助力跌倒监测、智能健身、安防监控等应用。
224 3
|
5天前
Trae关闭后,自动重新安装问题解决
本方案指导用户将Trae更新模式设为手动:进入设置→Editor设置→应用程序→更新,选择Manual模式。配图清晰展示各操作步骤界面,助您轻松完成配置
389 3
|
5天前
|
IDE 网络安全 开发工具
【全网最详细】TortoiseGit安装汉化和配置保姆级教程(附安装包+汉化包)
TortoiseGit是Windows平台开源免费的Git图形化客户端,集成于资源管理器右键菜单,零命令操作。支持图标覆盖层直观显示文件状态,无需记忆git命令,兼容所有IDE,学习成本低,适合个人及团队版本管理。(239字)
|
5天前
|
JSON Java fastjson
java工具:《json字符串转JavaBean对象》
java工具:《json字符串转JavaBean对象》
157 6