Directshow捕获到文件,什么也没有发生 [英] Directshow capture to file, nothing happens

查看:150
本文介绍了Directshow捕获到文件,什么也没有发生的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过DirectShow的例子在Windows开发中心,使我自己的应用程序,可以捕获屏幕和音频到视频:将视频捕获到AVI文件

I am trying to follow through the DirectShow examples on the windows dev center to make my own application that can capture screen and audio to video: Capturing Video to an AVI File

去确定,但没有发生,avi文件不出现。网络摄像头连接我可以看到流与AMCap。在代码cam出现与正确的文件名。安装了Windows SDK,我的平台是win7 x64。

All code goes ok but nothing happens, the avi file is not appearing. The web cam is connected I can see stream with AMCap. In code cam is appearing with correct filename. The windows SDK is installed, my platform is win7 x64.

我的代码:

#include "stdafx.h"
#include <iostream>

#include <windows.h>
#include <dshow.h>

#pragma comment(lib, "strmiids")

HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
{
    // Create the System Device Enumerator.
    ICreateDevEnum *pDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

    if (SUCCEEDED(hr))
    {
        // Create an enumerator for the category.
        hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);
        if (hr == S_FALSE)
        {
            hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
        }
        pDevEnum->Release();
    }
    return hr;
}

HRESULT InitCaptureGraphBuilder(
    IGraphBuilder **ppGraph,  // Receives the pointer.
    ICaptureGraphBuilder2 **ppBuild  // Receives the pointer.
)
{
    if (!ppGraph || !ppBuild)
    {
        return E_POINTER;
    }
    IGraphBuilder *pGraph = NULL;
    ICaptureGraphBuilder2 *pBuild = NULL;

    // Create the Capture Graph Builder.
    HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
        CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
    if (SUCCEEDED(hr))
    {
        // Create the Filter Graph Manager.
        hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,
            IID_IGraphBuilder, (void**)&pGraph);
        if (SUCCEEDED(hr))
        {
            // Initialize the Capture Graph Builder.
            pBuild->SetFiltergraph(pGraph);

            // Return both interface pointers to the caller.
            *ppBuild = pBuild;
            *ppGraph = pGraph; // The caller must release both interfaces.
            return S_OK;
        }
        else
        {
            pBuild->Release();
        }
    }
    return hr; // Failed
}

void DisplayDeviceInformation(IEnumMoniker *pEnum)
{
    IMoniker *pMoniker = NULL;

    while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
    {
        IPropertyBag *pPropBag;
        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
        if (FAILED(hr))
        {
            pMoniker->Release();
            continue;
        }

        VARIANT var;
        VariantInit(&var);

        hr = pPropBag->Read(L"DevicePath", &var, 0);
        if (SUCCEEDED(hr))
        {
            // The device path is not intended for display.
            printf("Device path: %S\n", var.bstrVal);
            VariantClear(&var);
        }

        IGraphBuilder *ppGraph;
        ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder
        hr = InitCaptureGraphBuilder(&ppGraph, &pBuild);


        IBaseFilter *pCap; // Video capture filter.
        hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
        if (SUCCEEDED(hr))
        {
            hr = ppGraph->AddFilter(pCap, L"Capture Filter");
            if (SUCCEEDED(hr)) {
                IBaseFilter *pMux;
                hr = pBuild->SetOutputFileName(
                    &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
                    L"C:\\a\\Example.avi", // File name.
                    &pMux,              // Receives a pointer to the mux.
                    NULL);              // (Optional) Receives a pointer to the file sink.

                hr = pBuild->RenderStream(
                    &PIN_CATEGORY_CAPTURE, // Pin category.
                    &MEDIATYPE_Video,      // Media type.
                    pCap,                  // Capture filter.
                    NULL,                  // Intermediate filter (optional).
                    pMux);                 // Mux or file sink filter.

                                           // Release the mux filter.
                pMux->Release();

                IConfigAviMux *pConfigMux = NULL;
                hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
                if (SUCCEEDED(hr))
                {
                    pConfigMux->SetMasterStream(0);
                    pConfigMux->Release();
                }

                IConfigInterleaving *pInterleave = NULL;
                hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
                if (SUCCEEDED(hr))
                {
                    pInterleave->put_Mode(INTERLEAVE_CAPTURE);
                    pInterleave->Release();
                }

            }
        }

        pPropBag->Release();
        pMoniker->Release();
    }
}

int _tmain(int argc, _TCHAR* argv[])
{

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (SUCCEEDED(hr))
    {
        IEnumMoniker *pEnum;

        hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
        if (SUCCEEDED(hr))
        {
            DisplayDeviceInformation(pEnum);
            pEnum->Release();
        }
        CoUninitialize();
    }

    int i;
    std::cin >> i;
    return 0;
}


推荐答案

您的代码枚举设备),建立一个文件记录管道,然后丢弃所有内容并进入下一个设备。

Your code enumerates devices (sources), build a file recording pipeline, then drops everything and advances to next device.

该代码不应该做实际记录。

The code is not supposed to do actual recording.

一个最小的缺失是这个( DisplayDeviceInformation 的底部):

A minimal missing piece is this (bottom of your DisplayDeviceInformation):

    IConfigInterleaving *pInterleave = NULL;
    hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
    if (SUCCEEDED(hr))
    {
        pInterleave->put_Mode(INTERLEAVE_CAPTURE);
        pInterleave->Release();
    }

    ///////////////////////////////////////////////////
    // Added
    IMediaControl* pMediaControl;
    ppGraph->QueryInterface(&pMediaControl);
    pMediaControl->Run();
    Sleep(5000);
    pMediaControl->Stop();
    ///////////////////////////////////////////////////

    pPropBag->Release();
    pMoniker->Release();

这篇关于Directshow捕获到文件,什么也没有发生的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆