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# 多窗口委托通信的实现

    C# 多窗口委托通信的实现

    本文主要介绍了C# 多窗口委托通信的实现,窗口之间通信无非有两个方向,主窗口发送数据到副窗口,副窗口发送数据到主窗口,感兴趣的可以了解一下
    2022-03-03
  • C# 对象持久化详解

    C# 对象持久化详解

    本文介绍的是除数据库之外的几种对象持久化方式。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • c# 日历控件的实现

    c# 日历控件的实现

    这篇文章主要介绍了c# 实现日历的示例代码,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2020-12-12
  • C#编程调用Cards.dll实现图形化发牌功能示例

    C#编程调用Cards.dll实现图形化发牌功能示例

    这篇文章主要介绍了C#编程调用Cards.dll实现图形化发牌功能,结合实例形式分析了C#动态链接库调用及图形操作技巧,需要的朋友可以参考下
    2017-06-06
  • C#实现TIF图像转PDF文件的方法

    C#实现TIF图像转PDF文件的方法

    这篇文章主要介绍了C#实现TIF图像转PDF文件的方法,涉及C#使用TIFtoPDF工具实现pdf文件转换的技巧,需要的朋友可以参考下
    2015-07-07
  • 浅析wpf中datagrid显示列的问题

    浅析wpf中datagrid显示列的问题

    这篇文章主要为大家详细介绍了wpf中datagrid显示列问题的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以学习一下
    2024-04-04
  • C#程序中session值的保存方法以及转为字符串的方法总结

    C#程序中session值的保存方法以及转为字符串的方法总结

    这篇文章主要介绍了C#程序中session值的保存方法以及转为字符串的方法总结,经常被用于ASP.NET网络编程项目中,需要的朋友可以参考下
    2016-04-04
  • C#三种方法获取文件的Content-Type(MIME Type)

    C#三种方法获取文件的Content-Type(MIME Type)

    这篇文章介绍了C#获取文件Content-Type(MIME Type)的三种方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • C# 中的多态底层虚方法调用详情

    C# 中的多态底层虚方法调用详情

    这篇文章主要介绍了C# 中的多态底层虚方法调用详情,文章围绕主题展开详细的内容介绍,需要的小伙伴你可以参考一下
    2022-06-06
  • C#实现状态栏提示信息功能的示例

    C#实现状态栏提示信息功能的示例

    今天小编就为大家分享一篇C#实现状态栏提示信息功能的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06

最新评论