如何在C#应用程序中暂停/恢复Windows中的ffmpeg视频捕获

时间:2017-07-20 05:59:26

标签: c# video ffmpeg

我使用ffmpeg使用C#应用程序捕获屏幕和音频。我用来执行ffmpeg的命令如下:

ffmpeg -f gdigrab -i desktop -f dshow -i audio="Microphone (Realtek High Definition Audio)" -v
codec libx264 output.mp4

现在我想暂停/恢复录制,并希望从C#应用程序控制它。无论如何我能做到吗?

1 个答案:

答案 0 :(得分:1)

将Helper类添加到项目中作为打击:

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
    }

开始ffmpeg作为打击:

process =new Process();

process.StartInfo.FileName = "ffmpeg";
process.StartInfo.Arguments = "-i foo.VOB blabla.mp4";

process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;

process.Start();

暂停使用process.Suspend();,恢复使用process.Resume();注意 ffmpeg必须从您的应用程序开始。我在Windows应用程序中测试它,它工作正常。