WPF调用ffmpeg实现屏幕录制

 更新时间:2023年05月24日 15:21:25   作者:WPF开发者  
这篇文章主要为大家详细介绍了WPF如何调用ffmpeg实现屏幕录制,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下

WPF 实现调用 ffmpeg 实现屏幕录制

框架使用.NET4

Visual Studio 2022

需要去 ffmpeg[2] 官网下载 Windows 解压进入 ffmpeg-4.1.1-win32-static\bin\ 或者 下载 ffmpeg.exe[3] 拷贝到运行目录下的ffmpeg 文件夹下 DesktopRecord.exe 就可以进行录屏,结束录屏后视频保存在运行程序根目录下。

使用参数命令进行录屏 "-f gdigrab -framerate 30 -offset_x 0 -offset_y 0 -video_size 1920x1080 -i desktop -c:v libx264 -preset ultrafast -crf 0 " + DateTime.Now.ToString("yyyyMMddHHmmss") + "_DesktopRecord.mp4"

  • -f gdigrab: 设定视频输入来源为 Windows 桌面画面捕获;
  • -framerate 30: 设置帧率为 30fps
  • -offset_x 0 -offset_y 0: 设置捕获起始坐标为 (0, 0)
  • -video_size 1920x1080: 设置视频分辨率为 1920x1080
  • -i desktop: 指示从桌面捕获视频流;
  • -c:v libx264: 使用 libx264 编码器进行视频压缩;
  • -preset ultrafast: 设定视频压缩速度为最快;
  • -crf 0: 设置视频压缩质量无限制(CRF 为 0 表示最高质量);
  • " + DateTime.Now.ToString("yyyyMMddHHmmss") + "_DesktopRecord.mp4": 指定视频输出文件名为 yyyyMMddHHmmss_DesktopRecord.mp4

实现代码

1)创建 FFmpegHelper.cs 代码如下:

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace DesktopRecord.Helper
{
    public class FFmpegHelper
    {
        #region 模拟控制台信号需要使用的api
        [DllImport("kernel32.dll")]
        static extern bool GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId);
        [DllImport("kernel32.dll")]
        static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add);
        [DllImport("kernel32.dll")]
        static extern bool AttachConsole(int dwProcessId);
        [DllImport("kernel32.dll")]
        static extern bool FreeConsole();
        #endregion
        // ffmpeg进程
        static Process _process;
        // ffmpeg.exe实体文件路径
        static string ffmpegPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ffmpeg.exe");
        /// <summary>
        /// 功能: 开始录制
        /// </summary>
        public static bool Start()
        {
            if(!File.Exists(ffmpegPath))
                return false;
            var processInfo = new ProcessStartInfo
            {
                FileName = ffmpegPath,
                Arguments = "-f gdigrab -framerate 30 -offset_x 0 -offset_y 0 -video_size 1920x1080 -i desktop -c:v libx264 -preset ultrafast -crf 0 " + DateTime.Now.ToString("yyyyMMddHHmmss") + "_DesktopRecord.mp4",
                UseShellExecute = false,
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            };
            _process = new Process { StartInfo = processInfo };
            _process.Start();
            return true;
        }
        /// <summary>
        /// 功能: 停止录制
        /// </summary>
        public static void Stop()
        {
            if (_process == null) return;
            AttachConsole(_process.Id);
            SetConsoleCtrlHandler(IntPtr.Zero, true);
            GenerateConsoleCtrlEvent(0, 0);
            FreeConsole();
            _process.StandardInput.Write("q");
            if (!_process.WaitForExit(10000))
            {
                _process.Kill();
            }
        }
    }
}

2)创建 MainWindow.xaml 代码如下:

<wd:Window
    x:Class="DesktopRecord.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:DesktopRecord.ViewModel"
    xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
    Title="屏幕录制"
    Width="525"
    Height="200"
    Icon="/screen.ico"
    ResizeMode="CanMinimize"
    WindowStartupLocation="CenterScreen"
    mc:Ignorable="d">
    <wd:Window.DataContext>
        <vm:MainVM />
    </wd:Window.DataContext>
    <Grid>
        <TabControl>
            <TabItem Header="ffmpeg 录制">
                <StackPanel
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Orientation="Horizontal">
                    <Button
                        Margin="0,0,5,0"
                        Command="{Binding MyStart}"
                        Content="{Binding MyTime}"
                        Style="{StaticResource WD.SuccessPrimaryButton}" />
                    <Button
                        Margin="5,0,0,0"
                        Command="{Binding MyStop}"
                        Content="停止录制"
                        Style="{StaticResource WD.DangerPrimaryButton}" />
                </StackPanel>
            </TabItem>
        </TabControl>
    </Grid>
</wd:Window>

3)创建 MainVM.cs 代码如下:

using DesktopRecord.Helper;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Threading;
using WPFDevelopers.Controls;
using WPFDevelopers.Helpers;
namespace DesktopRecord.ViewModel
{
    public class MainVM : ViewModelBase
    {
        private DispatcherTimer tm = new DispatcherTimer();
        public int currentCount = 0;
        private string myTime = "开始录制";
        public string MyTime
        {
            get { return myTime; }
            set
            {
                myTime = value;
                NotifyPropertyChange("MyTime");
            }
        }
        private bool isStart = true;
        public bool IsStart
        {
            get { return isStart; }
            set
            {
                isStart = value;
                NotifyPropertyChange("IsStart");
            }
        }
        private bool _isShow;
        public bool IsShow
        {
            get { return _isShow; }
            set
            {
                _isShow = value;
                NotifyPropertyChange("IsShow");
            }
        }
        private ICommand myStart;
        public ICommand MyStart
        {
            get
            {
                return myStart ?? (myStart = new RelayCommand(p =>
                {
                    App.Current.MainWindow.WindowState = System.Windows.WindowState.Minimized;
                    if (!FFmpegHelper.Start())
                    {
                        App.Current.MainWindow.WindowState = System.Windows.WindowState.Normal;
                        MessageBox.Show("未找到 【ffmpeg.exe】,请下载", "错误", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                        return;
                    }
                    tm.Tick += tm_Tick;
                    tm.Interval = TimeSpan.FromSeconds(1);
                    tm.Start();
                    IsStart = false;
               }, a =>
                {
                return IsStart;
                }));
            }
        }
        private void tm_Tick(object sender, EventArgs e)
        {
            currentCount++;
            MyTime = "录制中(" + currentCount + "s)";
        }
        /// <summary>
        /// 获取或设置
        /// </summary>
        private ICommand myStop;
        /// <summary>
        /// 获取或设置
        /// </summary>
        public ICommand MyStop
        {
            get
            {
                return myStop ?? (myStop = new RelayCommand(p =>
                           {
                               var task = new Task(() =>
                               {
                                   FFmpegHelper.Stop();
                                   MyTime = "开始录制";
                                   tm.Stop();
                                   currentCount = 0;
                                   IsShow = true;
                               });
                               task.ContinueWith(previousTask =>
                               {
                                   IsShow = false;
                                   IsStart = true;
                                   Process.Start(AppDomain.CurrentDomain.BaseDirectory);
                               }, TaskScheduler.FromCurrentSynchronizationContext());
                               task.Start();
                           }, a =>
            {
                return !IsStart;
            }));
            }
        }

效果图

以上就是WPF调用ffmpeg实现屏幕录制的详细内容,更多关于WPF屏幕录制的资料请关注脚本之家其它相关文章!

相关文章

  • C#应用ToolStrip控件使用方法

    C#应用ToolStrip控件使用方法

    在本篇文章里小编给大家分享了关于C#应用ToolStrip控件使用方法和技巧,对此有兴趣的朋友们学习下。
    2019-01-01
  • 快速解决owin返回json字符串多带了双引号

    快速解决owin返回json字符串多带了双引号"多了重string转义字符串

    下面小编就为大家带来一篇快速解决owin返回json字符串多带了双引号"多了重string转义字符串。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • Unity实现物体弧线运动到规定的坐标

    Unity实现物体弧线运动到规定的坐标

    这篇文章主要为大家详细介绍了Unity实现物体以弧线的形式运动到规定的坐标,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • C# 引用类型参数ref详解

    C# 引用类型参数ref详解

    C#中ref和out关键字允许按引用传递参数,以修改实参的值,本文给大家介绍C#引用类型参数ref的相关知识,感兴趣的朋友一起看看吧
    2025-06-06
  • WinForm中异步TCP通信的正确打开方式

    WinForm中异步TCP通信的正确打开方式

    软件开发中,网络通信是实现分布式系统、远程控制和实时数据交换的核心技术之一,TCP 作为传输层中最常用的协议,以其面向连接、可靠传输、字节流通信的特点,本文将结合一个完整的WinForm 应用程序实例,给大家介绍WinForm中异步TCP通信的正确打开方式
    2025-08-08
  • C# 读写ini文件操作实现

    C# 读写ini文件操作实现

    本文主要介绍了C# 读写ini文件操作实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • C#利用时间和随即字符串创建唯一的订单编号

    C#利用时间和随即字符串创建唯一的订单编号

    本文介绍了利用时间和随机字符串组合生成唯一订单号的示例,从而保证订单号不会重复,希望能够对大家有所帮助。
    2016-03-03
  • 基于WPF实现简单的文件夹比较工具

    基于WPF实现简单的文件夹比较工具

    文件比较平常都是用Beyond Compare,可以说离不开的神器,不过Beyond Compare平常拿它主要是用来做代码比较,用来做一些大批量的二进制文件比较,其实有点不是很方便,所以本文来用WPF做一个简单的文件夹比较的小工具
    2023-05-05
  • C#实现拆分合并Word表格中的单元格

    C#实现拆分合并Word表格中的单元格

    我们在使用Word制作表格时,由于表格较为复杂,只是简单的插入行、列并不能满足我们的需要。要做一个完整的表格,很多时候需要将单元格进行拆分或者合并。本文将详细为您介绍在Word表格中拆分或合并单元格的思路及方法,希望对大家有所帮助
    2022-12-12
  • C# 操作Windows注册表的实现方法

    C# 操作Windows注册表的实现方法

    本文主要介绍了C# 操作Windows注册表的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-03-03

最新评论