WPF之录制桌面视频(FFMPeg)

FFmpeg的视频录制,本身代码就是一个工具类,直接复制即可用,RecordHelper是基础的视频开始录制和视频停止录制

  public class RecordHelper
    {

        public static RecordHelper Instance = new RecordHelper();
        // ffmpeg进程
        static Process process;
        /// <summary>
        /// 开始录制
        /// </summary>
        /// <param name="FileName">文件名称.mp4</param>
        /// <param name="Framerate">帧数</param>
        /// <param name="ffmpegPath">ffmpeg.exe的路径</param>
        /// <param name="Path">输出文件路径</param>
        public  void Start(string FileName, int Framerate, string ffmpegPath, string Path)
        {
            try
            {
                process = new Process();
                string curDir = System.Environment.CurrentDirectory;
                process.StartInfo.FileName = ffmpegPath;
                process.StartInfo.Arguments = @"-f gdigrab -framerate " + Framerate + " -i desktop -preset ultrafast -pix_fmt yuv420p  -vf \"scale = 1280:720\" " + FileName;//parameters
               // ffmpeg - f avfoundation - i 1 - r 30 out.yuv
                process.StartInfo.UseShellExecute = false;//是否使用操作系统shell启动
                process.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
                process.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
                process.StartInfo.RedirectStandardError = true;//重定向标准错误输出
                process.StartInfo.CreateNoWindow = true;//不显示程序窗口
                process.ErrorDataReceived += ErrorDataReceived;
                process.OutputDataReceived += OutputDataReceived;
                process.StartInfo.WorkingDirectory = Path; // The output directory  
                process.Start();//Start
                process.BeginErrorReadLine();
                process.BeginOutputReadLine();
                // AudioRecorderProcess_ID = p.Id;
                //p.BeginErrorReadLine();//Start asynchronous reading
            }
            catch (Exception ex)
            {


            }
        }
        private static void ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            Log.Debug($"pdf 操作 错误信息: {e.Data}");
            //Process process = sender as Process;
         
        }

        private static void OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            Log.Debug($"pdf 操作 命令行输出: {e.Data}");
        }
        private const int ProcessTimeOut = 1000;
        /// <summary>
        /// 功能: 停止录制
        /// </summary>
        public  void Stop()
        {
            try
            {
                process.StandardInput.WriteLine("q");//In the console of this process, the analog input q is used to pause recording.
                process.StandardInput.AutoFlush = true;
                process.WaitForExit(ProcessTimeOut);//等待程序执行完退出进程  
                process.Close();
                process.Dispose();
            }
            catch (Exception ex)
            {
                Log.Error("视频录制停止时异常:" + ex.Message);
            }
        }


        public void MianSuspend()
        {
            //process.Suspend();
        }

        public  void Play()
        {
            //process.Resume();
        }
    }

接下来需要暂停和继续视频的录制,这里只是一个扩展方法,用来暂停和继续视频录制

 static class Helper
    {
        public static T[] ToArray<T>(this ICollection collection)
        {
            var items = new T[collection.Count];
            collection.CopyTo(items, 0);

            return items;
        }
    }

    public static class ProcessExtensions
    {
        #region Methods

        public static void Suspend(this Process process)
        {
            Action<ProcessThread> suspend = pt =>
            {
                var threadHandle = NativeMethods.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pt.Id);

                if (threadHandle != IntPtr.Zero)
                {
                    try
                    {
                        NativeMethods.SuspendThread(threadHandle);
                    }
                    finally
                    {
                        NativeMethods.CloseHandle(threadHandle);
                    }
                };
            };

            var threads = process.Threads.ToArray<ProcessThread>();

            if (threads.Length > 1)
            {
                Parallel.ForEach(threads, new ParallelOptions { MaxDegreeOfParallelism = threads.Length }, pt =>
                {
                    suspend(pt);
                });
            }
            else
            {
                suspend(threads[0]);
            }
        }

        public static void Resume(this Process process)
        {
            Action<ProcessThread> resume = pt =>
            {
                var threadHandle = NativeMethods.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pt.Id);
                if (threadHandle != IntPtr.Zero)
                {
                    try
                    {
                        NativeMethods.ResumeThread(threadHandle);
                    }
                    finally
                    {
                        NativeMethods.CloseHandle(threadHandle);
                    }
                }
            };

            var threads = process.Threads.ToArray<ProcessThread>();

            if (threads.Length > 1)
            {
                Parallel.ForEach(threads, new ParallelOptions { MaxDegreeOfParallelism = threads.Length }, pt =>
                {
                    resume(pt);
                });
            }
            else
            {
                resume(threads[0]);
            }
        }


        #endregion

        #region Interop

        static class NativeMethods
        {
            [DllImport("kernel32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool CloseHandle(IntPtr hObject);

            [DllImport("kernel32.dll")]
            public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);

            [DllImport("kernel32.dll")]
            public static extern uint SuspendThread(IntPtr hThread);

            [DllImport("kernel32.dll")]
            public static extern uint ResumeThread(IntPtr hThread);
        }

        [Flags]
        enum ThreadAccess : int
        {
            TERMINATE = (0x0001),
            SUSPEND_RESUME = (0x0002),
            GET_CONTEXT = (0x0008),
            SET_CONTEXT = (0x0010),
            SET_INFORMATION = (0x0020),
            QUERY_INFORMATION = (0x0040),
            SET_THREAD_TOKEN = (0x0080),
            IMPERSONATE = (0x0100),
            DIRECT_IMPERSONATION = (0x0200)
        }

        #endregion
    }

 

WPF之录制桌面视频(FFMPeg)

上一篇:php.curl详解


下一篇:Jmail组件实现php邮件发送(支持转码)