Beispiel #1
0
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;
}
Beispiel #2
0
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;
}