C#调用FFmpeg实现桌面录制(视频+音频+生成本地文件)的实战指南

1次阅读
没有评论

共计 1859 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

背景痛点

在 C# 开发中实现桌面录制功能时,开发者常遇到以下问题:

C# 调用 FFmpeg 实现桌面录制(视频 + 音频 + 生成本地文件)的实战指南

  • 音视频同步困难:手动管理音频和视频的时间戳容易导致不同步
  • 性能瓶颈:高分辨率录制时 CPU 占用率飙升
  • 兼容性问题:不同硬件和系统版本的编解码器支持差异大
  • 文件格式限制:难以直接生成主流视频格式

技术选型

对比几种常见方案:

  1. DirectX:性能好但开发复杂度高,需要处理大量底层 API
  2. Windows API:依赖系统版本,功能有限
  3. FFmpeg:
  4. 开源且跨平台
  5. 支持几乎所有音视频格式
  6. 命令行调用简单
  7. 成熟的编解码解决方案

核心实现

环境准备

  1. 下载 FFmpeg 静态编译版本
  2. 解压到项目目录或系统 PATH 路径

关键代码实现

public class ScreenRecorder
{
    private Process ffmpegProcess;

    public void StartRecording(string outputPath)
    {
        var screenBounds = Screen.PrimaryScreen.Bounds;

        var args = $"-y -f gdigrab -framerate 30 -offset_x {screenBounds.X} -offset_y {screenBounds.Y}" +
                   $"-video_size {screenBounds.Width}x{screenBounds.Height} -i desktop -f dshow -i audio=\" 麦克风 \" " +
                   $"-c:v libx264 -preset ultrafast -pix_fmt yuv420p -c:a aac" +
                   $"-map 0:v -map 1:a {outputPath}";

        ffmpegProcess = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "ffmpeg.exe",
                Arguments = args,
                UseShellExecute = false,
                CreateNoWindow = true,
                RedirectStandardError = true
            }
        };

        ffmpegProcess.ErrorDataReceived += (sender, e) => 
        {if(!string.IsNullOrEmpty(e.Data))
                Console.WriteLine($"FFmpeg: {e.Data}");
        };

        ffmpegProcess.Start();
        ffmpegProcess.BeginErrorReadLine();}

    public void StopRecording()
    {if(ffmpegProcess != null && !ffmpegProcess.HasExited)
        {
            // 发送 q 命令正常退出
            ffmpegProcess.StandardInput.WriteLine("q");
            ffmpegProcess.WaitForExit(2000);

            if(!ffmpegProcess.HasExited)
                ffmpegProcess.Kill();

            ffmpegProcess.Dispose();}
    }
}

参数详解

  1. 视频采集:
  2. -f gdigrab:使用 Windows GDI 抓屏
  3. -framerate 30:设置帧率为 30fps
  4. -video_size:指定录制区域大小

  5. 音频采集:

  6. -f dshow:使用 DirectShow 采集音频
  7. audio="麦克风":指定音频输入设备

  8. 编码参数:

  9. -c:v libx264:使用 H.264 视频编码
  10. -preset ultrafast:最快编码预设
  11. -c:a aac:使用 AAC 音频编码

性能优化

  1. 降低分辨率:适当减少视频尺寸
  2. 调整帧率:根据需求降低帧率
  3. 使用硬件加速 :添加-hwaccel 参数
  4. 优化编码参数:
  5. -crf 28:平衡质量和文件大小
  6. -threads 4:使用多线程编码

避坑指南

  1. FFmpeg 路径问题:
  2. 将 ffmpeg.exe 放在程序目录
  3. 或指定完整路径

  4. 权限问题:

  5. 确保对输出目录有写入权限
  6. 管理员权限运行程序

  7. 音频设备不可用:

  8. 先通过 ffmpeg -list_devices true -f dshow -i dummy 列出设备
  9. 确保设备名称正确

  10. 文件锁定:

  11. 确保录制完成后再操作文件
  12. 使用 .mp4 等支持流式写入的格式

总结与扩展

基础功能实现后,可以考虑:

  1. 添加水印:通过-vf "movie=watermark.png [wm]; [in][wm] overlay=10:10 [out]"
  2. 直播推流:修改输出为 RTMP 地址
  3. 多显示器支持 :通过-i desktop:n 选择显示器
  4. 录制区域选择:添加 GUI 让用户选择区域

完整项目示例已上传 GitHub,包含更多高级功能和错误处理。

正文完
 0
评论(没有评论)