HRESULT RecordGraph::BuildGraph(CString recordFileName) { HRESULT hr; ICreateDevEnum *pSysAudioCaptureEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysAudioCaptureEnum); if (FAILED(hr)) { return hr; } IBaseFilter *pAudioCapture = NULL; IEnumMoniker *pEnumMoniker = NULL; hr = pSysAudioCaptureEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumMoniker, 0); if (hr == S_OK) { IMoniker *pMoniker = NULL; ULONG fetched; BOOL findMicrophone = FALSE; while(pEnumMoniker->Next(1, &pMoniker, &fetched) == S_OK && !findMicrophone) { IPropertyBag *pPropBag; hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); if(SUCCEEDED(hr)) { VARIANT varName; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, 0); if(SUCCEEDED(hr)) { ASSERT(varName.vt == VT_BSTR); CString friendlyName(varName.bstrVal); if(friendlyName.Find(L"Microphone") >= 0) { hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void **)&pAudioCapture); findMicrophone = TRUE; } VariantClear(&varName); pPropBag->Release(); } } } pEnumMoniker->Release(); } pSysAudioCaptureEnum->Release(); if(pAudioCapture == NULL) { return S_FALSE; } pBuilder->AddFilter(pAudioCapture, L"Audio Capture"); IBaseFilter *pWaveDest = NULL; hr = CoCreateInstance(CLSID_WavDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pWaveDest); if(FAILED(hr)) { return hr; } pBuilder->AddFilter(pWaveDest, L"Wave Dest"); IBaseFilter *pFileWriter = NULL; hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pFileWriter); if(FAILED(hr)) { return hr; } pBuilder->AddFilter(pFileWriter, L"File Writer"); IFileSinkFilter *pFileSetter = NULL; hr = pFileWriter->QueryInterface(IID_IFileSinkFilter, (void **)&pFileSetter); if(FAILED(hr)) { return hr; } AM_MEDIA_TYPE pmt; pmt.majortype = MEDIATYPE_Stream; pmt.subtype = MEDIASUBTYPE_WAVE; pmt.formattype = FORMAT_WaveFormatEx; hr = pFileSetter->SetFileName(recordFileName, &pmt); hr = ConnectFilters(pBuilder, pAudioCapture, pWaveDest, MEDIATYPE_NULL);if(FAILED(hr)) return hr; hr = ConnectFilters(pBuilder, pWaveDest, pFileWriter, MEDIATYPE_NULL);//if(FAILED(hr)) return hr; SaveGraphFile(pBuilder, L"D:\\Record.grf"); pFileSetter->Release(); pFileWriter->Release(); pWaveDest->Release(); pAudioCapture->Release(); }
// A very simple program to capture a webcam & audio to a file using DirectShow // int main(int argc, char* argv[]) { ICaptureGraphBuilder2 *pCaptureGraph = NULL; // Capture graph builder object IGraphBuilder *pGraph = NULL; // Graph builder object IMediaControl *pControl = NULL; // Media control object IFileSinkFilter *pSink = NULL; // File sink object IBaseFilter *pAudioInputFilter = NULL; // Audio Capture filter IBaseFilter *pVideoInputFilter = NULL; // Video Capture filter IBaseFilter *pASFWriter = NULL; // WM ASF File config interface // Initialize the COM library. HRESULT hr = CoInitialize(NULL); if (FAILED(hr)) { // We’ll send our error messages to the console. printf("ERROR - Could not initialize COM library"); return hr; } // Create the filter graph manager and query for interfaces. hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&pCaptureGraph); if (FAILED(hr)) // FAILED is a macro that tests the return value { printf("ERROR - Could not create the Filter Graph Manager."); return hr; } // Use a method of the capture graph builder // To create an output path for the stream hr = pCaptureGraph->SetOutputFileName(&MEDIASUBTYPE_Asf, L"C:\\MyWebcam.ASF", &pASFWriter, &pSink); // Now configure the ASF Writer // Present the property pages for this filter hr = ShowFilterPropertyPages(pASFWriter); // Now get the filter graph manager // That's part of the capture graph builder hr = pCaptureGraph->GetFiltergraph(&pGraph); // Using QueryInterface on the graph builder, // Get the Media Control object. hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); if (FAILED(hr)) { printf("ERROR - Could not create the Media Control object."); pGraph->Release(); // Clean up after ourselves. CoUninitialize(); // And uninitalize COM return hr; } // Get an AudioCapture filter. // But there are several to choose from // So we need to enumerate them, and pick one. // Then add the audio capture filter to the filter graph. hr = GetAudioInputFilter(&pAudioInputFilter, L"Logitech"); if (SUCCEEDED(hr)) { hr = pGraph->AddFilter(pAudioInputFilter, L"Webcam Audio Capture"); } // Now create the video input filter from the webcam hr = GetVideoInputFilter(&pVideoInputFilter, L"Logitech"); if (SUCCEEDED(hr)) { hr = pGraph->AddFilter(pVideoInputFilter, L"Webcam Video Capture"); } // Add a video renderer //IBaseFilter *pVideoRenderer = NULL; //hr = AddFilterByCLSID(pGraph, CLSID_VideoRenderer, L"Video Renderer", &pVideoRenderer); // Use another method of the capture graph builder // To provide a render path for video preview IBaseFilter *pIntermediate = NULL; hr = pCaptureGraph->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVideoInputFilter, NULL, NULL); // Now add the video capture to the output file hr = pCaptureGraph->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVideoInputFilter, NULL, pASFWriter); // And do the same for the audio hr = pCaptureGraph->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pAudioInputFilter, NULL, pASFWriter); if (SUCCEEDED(hr)) { // Run the graph. hr = pControl->Run(); if (SUCCEEDED(hr)) { // Wait patiently for completion of the recording wprintf(L"Started recording...press Enter to stop recording.\n"); // Wait for completion. char ch; ch = getchar(); // We wait for keyboard input } // And let's stop the filter graph hr = pControl->Stop(); wprintf(L"Stopped recording.\n"); // To the console // Before we finish up, save the filter graph to a file. SaveGraphFile(pGraph, L"C:\\MyGraph.GRF"); } // Now release everything, and clean up. pSink->Release(); pASFWriter->Release(); pVideoInputFilter->Release(); pAudioInputFilter->Release(); pControl->Release(); pGraph->Release(); pCaptureGraph->Release(); CoUninitialize(); return 0; }