C++ Directshow将视频捕获到AVI

C++ Directshow将视频捕获到AVI,c++,directshow,video-capture,audio-recording,C++,Directshow,Video Capture,Audio Recording,我正试图通过windows开发中心上的DirectShow示例来制作我自己的应用程序,该应用程序可以捕获屏幕和音频到视频。 当我运行RenderStream方法失败时,HRESULT\u code为16387 这是我的密码。我已经读了很多例子,但不能完全理解。我想让一些真正基本的东西工作起来,这样我就可以自己扩展它了 我意识到这不是最好的练习。我对C++和新的DirectShow非常生疏,所以请不要太苛刻,请随意解释我有点简单。p> 以下是我的代码: void AudioVideoBuilde

我正试图通过windows开发中心上的DirectShow示例来制作我自己的应用程序,该应用程序可以捕获屏幕和音频到视频。

当我运行
RenderStream
方法失败时,
HRESULT\u code
为16387

这是我的密码。我已经读了很多例子,但不能完全理解。我想让一些真正基本的东西工作起来,这样我就可以自己扩展它了

我意识到这不是最好的练习。我对C++和新的DirectShow非常生疏,所以请不要太苛刻,请随意解释我有点简单。p> 以下是我的代码:

void AudioVideoBuilder::AVBuilder::MakeVideo()
{

    IGraphBuilder *pGraph = NULL;
    ICaptureGraphBuilder2 *pBuild = NULL;

    // Create the Filter Graph Manager.
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
        CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

    if (SUCCEEDED(hr))
    {
        // Create the Capture Graph Builder.
        hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
            CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
            (void **)&pBuild);
        if (SUCCEEDED(hr))
        {
            pBuild->SetFiltergraph(pGraph);
        }
    };
    IBaseFilter *pCap = 0;
    if (SUCCEEDED(hr))
    {
        // Create the Capture Graph Builder.
        hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_ICaptureGraphBuilder2,
            (void**)&pBuild);
        IBaseFilter *pMux;
        if (SUCCEEDED(hr))
        {
            hr = pBuild->SetOutputFileName(
                &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
                L"C:\\Example.avi", // File name.
                &pMux,              // Receives a pointer to the mux.
                NULL);              // (Optional) Receives a pointer to the file sink.

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

                if (SUCCEEDED(hr))
                {
                    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();
                    }
                }
                else
                {
                    DWORD error = HRESULT_CODE(hr);
                }
            }
            else
            {
                DWORD error = HRESULT_CODE(hr);
            }
        }
    }
    else
    {
        DWORD error = HRESULT_CODE(hr);
    }
}

正如安德鲁·科米亚金(Andrew Komiagin)在评论中所说的那样。不要将“c:\Example.avi”用作目标文件。如果您没有root用户的访问权限,可能会导致不必要的问题

此外,在代码中,您不需要定义捕获设备(输入设备)。中的变量pCap

pBuild->RenderStream
在代码中设置为0(NULL)。它必须是一个捕获设备
RenderStream
需要一个捕获设备或渲染器,从不为NULL。 如果搜索错误代码,请使用十六进制。16387是0x4003,这是输入引脚的问题。难怪是零

看这里


学习如何获取捕获设备。

这里的问题与您较新的问题相同:这是无意中第二次创建
CLSID\u CaptureGraphBuilder2
实例()


还要注意,错误代码是
HRESULT
值。这就是解释操作状态的原因。一旦尝试获取字符串并获取指向字符的指针,指针(
0x055…
0x099…
)就不是错误代码,它只是一些没有特殊意义的随机地址。代码是键。

您无法写入C:\root文件夹。请使用更好的错误处理:
\u com\u error err(hr);LPCTSTR errMsg=err.ErrorMessage()这样我们就可以知道这里发生了什么。谢谢大家的反馈。我已将AVI位置更改为temp文件夹,改进的错误处理返回-“+errMsg 0x0556FEB0”无效指针“wchar\u t*”。。我认为这似乎与下面Martin的建议相符,因此,我将努力找出添加捕获设备和枚举的方法。从管理员或调整文件夹权限开始,它应该仍能工作。@deW1我更改了文本。因此,我实现了设备枚举,并选择了第一个找到的音频和视频设备,以便继续运行。不幸的是,现在我得到了错误+errMsg 0x09910DB8“参数不正确。”wchar\u t*@JustinC 0x09910DB8看起来更像一个指针。它不是有效的HRESULT。如果没有看到新代码,就不可能给出答案。我想已经发生了很大的变化,所以最好还是提出一个新问题。如果只有一小部分发生了变化,请更新您的问题。确保您将更改标记为更新,否则我和其他人直到现在所做的回答将不再匹配(这可能导致否决票)。如果您不确定,请打开一个新问题,将代码缩减为仅显示错误的小示例,而不是整个renderpipe。谢谢Martin,我在这两个问题之间更改了不少代码,因此发布了一个新问题,包括更新的代码。。