2017-07-20 8 views
1

ffmpegを使用して、C#アプリケーションを使用して画面とオーディオをキャプチャしています。私は次のようにffmpegのを実行するために使用していますコマンド:C#アプリケーションからWindowsでffmpegビデオキャプチャを一時停止/再開する方法

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

は、今私は/再開録音を一時停止し、C#アプリケーションからそれを制御したいしたいと思います。とにかく私はそれを達成することができますか?

答えて

1

ブローとして投影するヘルパークラスを追加します。

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アプリケーションでそれをテストし、正常に動作します。

+0

私は中断/再開の方法を試みました。しかし、通常はうまくいきません。サスペンド/レジュームには時間がかかりますが、キャプチャ時間は多少短くなります。なぜffmpegユーティリティがそのような基本的な機能を提供しないのか分かりません。 – jcyrss

+0

@jcyrssもう一度アプリケーションをテストすると正常に動作します...アプリケーションをasminとして実行してください。 –

関連する問題