直接显示捕获视频到 AVI

Directshow capturing video to AVI

本文关键字:视频 AVI 显示      更新时间:2023-10-16

我正在尝试按照Windows开发人员中心上的DirectShow示例进行操作,以创建自己的应用程序,该应用程序可以将屏幕和音频捕获到视频中。https://msdn.microsoft.com/en-us/library/windows/desktop/dd318627(v=vs.85).aspx

当我运行RenderStream方法失败时,HRESULT_CODE是 16387。

这是我的代码。我读过很多例子,但不能完全理解。我很想得到一些非常基本的工作,这样我就可以自己扩展它。

我意识到这不是最佳实践等。我对C++非常生疏,并且是 DirectShow 的新手,所以请不要太挑剔,请随时解释,就像我有点简单一样!

这是我的代码:

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(空)。它必须是一个捕获设备。 RenderStream 需要捕获设备或呈现器,而不是 NULL。如果搜索错误代码,请使用十六进制。16387 0x4003这是输入引脚的问题。难怪,它是零。

看这里

https://msdn.microsoft.com/en-us/library/windows/desktop/dd377566(v=vs.85).aspx

了解如何获取捕获设备。

这里的问题与您的新问题相同:Directshow RenderStream"参数不正确",它是无意中第二次创建CLSID_CaptureGraphBuilder2实例(详细信息)。

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