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(); }
bool CKTVDlg::buildMixGraph(int filterIndex, int pinIndex) { int index = -1; if (filterIndex != -1) { index = findFilter(&m_mixDevice, NULL, filterIndex); } else { if (GetWinVersion() >= WINVERSION_VISTA) index = findFilter(&m_mixDevice, L"混音"); else index = findFilter(&m_mixDevice); } if (index == -1) return false; if (pinIndex != -1) { activePin(m_mixDevice, index, NULL, pinIndex); } else { if (GetWinVersion() >= WINVERSION_VISTA) activePin(m_mixDevice, index); else activePin(m_mixDevice, index, L"麦克风"); } SetAudioProperties(m_mixDevice); HRESULT r = m_mixGraphBuilder->AddFilter(m_mixDevice, L"mix Capture"); if (FAILED(r)) return false; intrusive_ptr<IPin> sourceOutPin1; r = GetPinByDirection(m_mixDevice, reinterpret_cast<IPin**>(&sourceOutPin1), PINDIR_OUTPUT); if (FAILED(r)) return false; // {3C78B8E2-6C4D-11d1-ADE2-0000F8754B99} static const GUID CLSID_WavDest = { 0x3c78b8e2, 0x6c4d, 0x11d1, { 0xad, 0xe2, 0x0, 0x0, 0xf8, 0x75, 0x4b, 0x99 } }; HMODULE m = LoadLibrary(L"wavdest.ax"); if (!m) return false; typedef HRESULT (__stdcall* dllGetClassObjectProc)(const IID&, const IID&, void**); typedef HRESULT (__stdcall* dllCanUnloadNowProc)(); do { dllGetClassObjectProc getObjProc = reinterpret_cast<dllGetClassObjectProc>(GetProcAddress( m, "DllGetClassObject")); dllCanUnloadNowProc canUnloadProc = reinterpret_cast<dllCanUnloadNowProc>(GetProcAddress( m, "DllCanUnloadNow")); if (!getObjProc || !canUnloadProc) break; intrusive_ptr<IClassFactory> factory; r = getObjProc(CLSID_WavDest, IID_IClassFactory, reinterpret_cast<void**>(&factory)); if (SUCCEEDED(r)) r = factory->CreateInstance(NULL, IID_IBaseFilter, (void**)&m_aviMuxer); if (FAILED(r)) { return false; } } while (0); // r = CoCreateInstance(CLSID_WavDest, NULL, CLSCTX_INPROC, // IID_IBaseFilter, (void **)&m_aviMuxer); if (FAILED(r)) return false; r = m_mixGraphBuilder->AddFilter(m_aviMuxer, L"wav MUX"); if (FAILED(r)) return false; intrusive_ptr<IPin> muxerInPin; r = GetPinByDirection(m_aviMuxer, reinterpret_cast<IPin**>(&muxerInPin), PINDIR_INPUT); if (FAILED(r)) return false; r = m_mixGraphBuilder->ConnectDirect(sourceOutPin1.get(), muxerInPin.get(), NULL); if (FAILED(r)) return false; intrusive_ptr<IFileSinkFilter2> pFileSink; r = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC, IID_IFileSinkFilter, (void**)&pFileSink); if (FAILED(r)) return false; // Get the file sink interface from the File Writer r = pFileSink->QueryInterface(IID_IBaseFilter, (void **)&m_pFileWriter); if (FAILED(r)) return false; // Add the FileWriter filter to the graph r = m_mixGraphBuilder->AddFilter((IBaseFilter *)m_pFileWriter, L"File Writer"); if (FAILED(r)) return false; intrusive_ptr<IPin> writerInPin; r = GetPinByDirection(m_pFileWriter, reinterpret_cast<IPin**>(&writerInPin), PINDIR_INPUT); if (FAILED(r)) return false; IFileSinkFilter* fileSinkFilter; r = m_pFileWriter->QueryInterface( IID_IFileSinkFilter, reinterpret_cast<void**>(&fileSinkFilter)); if (FAILED(r)) return false; r = fileSinkFilter->SetFileName(L"D:\\1111.wav", NULL); if (FAILED(r)) return false; intrusive_ptr<IPin> muxerOutPin; r = GetPinByDirection(m_aviMuxer, reinterpret_cast<IPin**>(&muxerOutPin), PINDIR_OUTPUT); if (FAILED(r)) return false; r = m_mixGraphBuilder->ConnectDirect(muxerOutPin.get(), writerInPin.get(), NULL); if (FAILED(r)) return false; return true; }