私は Directshow.NET を使用するアプリケーションに取り組んでおり、GraphEd.exeをいじって、必要な正確なルートを把握することにしました。
私が欲しいものの最も単純なバージョンは、上の画像にあります(「test.mpeg」は「ファイルライター」フィルターです)。
確かに、GraphEd で簡単に見えることは、コーディングほど簡単ではありません。数秒後、私は directshow が理解できないものであることに気付きました。これが私のC#コードの試みです:
int hr;
IBaseFilter cameraStream = null;
IBaseFilter mpegEncoder = null;
IBaseFilter fileWriter = null;
ICaptureGraphBuilder2 capGraph = null;
filterGraph = (IFilterGraph2)new FilterGraph();
try
{
capGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
hr = capGraph.SetFiltergraph(filterGraph);
Marshal.ThrowExceptionForHR(hr);
hr = filterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out cameraStream);
Marshal.ThrowExceptionForHR(hr);
IPin cameraData = null;
hr = capGraph.FindPin(cameraStream, PinDirection.Output, PinCategory.Capture, MediaType.Video, true, 0, out cameraData );
//hr = cameraStream.FindPin("Capture", out cameraData);
Marshal.ThrowExceptionForHR(hr);
mpegEncoder = (IBaseFilter)new MJPGEnc();
hr = filterGraph.AddFilter(mpegEncoder, "mpeg encoder");
//hr = filterGraph.FindFilterByName("Microsoft MPEG-2 Video Encoder", out mpegEncoder);
Marshal.ThrowExceptionForHR(hr);
IPin mpegInput = null;
//hr = mpegEncoder.FindPin("Input0", out mpegInput);
hr = capGraph.FindPin(mpegEncoder, PinDirection.Input, null, null, true, 0, out mpegInput);
Marshal.ThrowExceptionForHR(hr);
filterGraph.Connect(cameraData, mpegInput);
IPin mpegOutput = null;
//hr = mpegEncoder.FindPin("Output", out mpegOutput);
hr = capGraph.FindPin(mpegEncoder, PinDirection.Output, null, null, true, 0, out mpegOutput);
Marshal.ThrowExceptionForHR(hr);
//hr = filterGraph.FindFilterByName("File writer", out fileWriter);
fileWriter = (IBaseFilter)new FileWriter();
IFileSinkFilter test = fileWriter as IFileSinkFilter2;
AMMediaType mtype = new AMMediaType();
mtype.majorType = MediaType.Video;
mtype.subType = MediaSubType.RGB24;
mtype.formatPtr = IntPtr.Zero;
test.SetFileName(videoPath, mtype );
IPin fwriterIn = null;
//hr = fileWriter.FindPin("in", out fwriterIn);
hr = capGraph.FindPin(fileWriter, PinDirection.Input, null, null, true, 0, out fwriterIn);
Marshal.ThrowExceptionForHR(hr);
filterGraph.Connect(mpegOutput, fwriterIn);
hr = capGraph.RenderStream(null, null, cameraStream, null, fileWriter); // *** Breaks on this line! ***
Marshal.ThrowExceptionForHR(hr);
mediaControl = filterGraph as IMediaControl;
}
finally
{
if (cameraStream != null)
{
Marshal.ReleaseComObject(cameraStream);
cameraStream = null;
}
if (mpegEncoder != null)
{
Marshal.ReleaseComObject(mpegEncoder);
mpegEncoder = null;
}
if (fileWriter != null)
{
Marshal.ReleaseComObject(fileWriter);
fileWriter = null;
}
if (capGraph != null)
{
Marshal.ReleaseComObject(capGraph);
capGraph = null;
}
}
(プログラミング ロジックに関する限り) 自分のコードがいかにばかげているかを書いて見た後、助けが必要だと気づきました。
どなたか、私が巨大な初心者であるかのように説明してくれる構造化された directshow チュートリアルに誘導してもらえますか、またはウェブカメラからファイルへの記録を処理する何らかの C# ライブラリにリンクしてもらえますか? 私は一般的にwin32プログラマーではないので、痛みを和らげるものは何でも良いはずです:)
また、機能しているように見えるカメラ デバイスの列挙コードがあります。
private void rescan_camera()
{
comboBox1.Items.Clear();
DsDevice[] cameraDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
for(int i=0; i < cameraDevices.Length; i++) {
comboBox1.Items.Add(cameraDevices[i].Name);
}
if (comboBox1.Items.Count > 0) comboBox1.SelectedIndex = 0;
}
DsDevice からモニカー データを取得できます。これは、記録する場所を directshow フィルター グラフに伝える重要な部分であることはわかっていますが、それは私の知識の範囲です。
編集:コードを更新し、改行の正確な場所を示します。