无法使用 Windows Media Encoder 设置默认音频设备

发布于 2024-07-19 13:14:14 字数 6921 浏览 7 评论 0原文

我参考以下文档部分“用于捕获屏幕的Windows Media API”来捕获屏幕,原始代码工作正常。 当我添加附加功能时(我刚刚添加了几行以使其从默认音频设备进行录制),它在以下行处失败(我调试过,看起来它在 COM 层失败?),有任何提示吗? 我发布了原始源代码和我修改后的源代码。

“if(FAILED(hr=pSrcGrp->put_Profile(variant_t(pProfile))))”

http ://www.geocities.com/krishnapg/screencap.html

原始源代码:

http://www.geocities.com/krishnapg/WMEncScrnCap.zip

我修改的源代码(我只修改了函数InitEncoder)

HRESULT InitEncoder(LPCTSTR szOutputFileName)
{
    HRESULT hr = E_FAIL;
    CComVariant varValue;
    IWMEncSourceGroupCollection*    pSrcGrpCollection=NULL;
    IWMEncSourceGroup*  pSrcGrp=NULL;
    IWMEncSource*   pSrc=NULL;
    IWMEncSource*   paSrc=NULL;
    IPropertyBag*   pPropertyBag=NULL;
    IWMEncVideoSource2* pSrcVid=NULL;
    IWMEncAudioSource*  pSrcAud=NULL;
    IWMEncFile* pOutFile=NULL;
    IWMEncProfile*  pProfile=NULL;

    if(FAILED(CoCreateInstance(CLSID_WMEncoder,NULL,CLSCTX_INPROC_SERVER,IID_IWMEncoder2,(void**)&g_pEncoder)))
    {
        ErrorMessage("Unable to Create Encoder Object");
        return E_FAIL;
    }
    if(FAILED(g_pEncoder->get_SourceGroupCollection(&pSrcGrpCollection)))       //Retrieve the Source Group Collection  - One Application can Have many Source Groups - We need to add as many as we want
    {
        ErrorMessage("Unable to Get Source Group Collection");
        return E_FAIL;
    }

    do
    {
        if(FAILED(hr=pSrcGrpCollection->Add(CComBSTR("SourceGroup1"),&pSrcGrp)))//Add a Source Group to the Collection - Each Source can have one video one audio source input
        {
            ErrorMessage("Unable to Add A Source Group to the Collection");
            break;
        }
        if(FAILED(hr=pSrcGrp->AddSource(WMENC_VIDEO,&pSrc)))                    //Add a Video Source to the Group
        {
            ErrorMessage("Unable to Add A Source to the Source Group");
            break;
        }
        if(FAILED(hr=pSrcGrp->AddSource(WMENC_AUDIO,&paSrc)))                   //Add an Audio Source to the Group
        {
            ErrorMessage("Unable to Add A Source to the Source Group");
            break;
        }
        if(FAILED(hr=pSrc->QueryInterface(IID_IWMEncVideoSource2,(void**)&pSrcVid)))
        {
            ErrorMessage("Unable to Query interface for Video Source");
            break;
        }
        if(FAILED(hr=paSrc->QueryInterface(IID_IWMEncAudioSource,(void**)&pSrcAud)))
        {
            ErrorMessage("Unable to Query interface for Audio Source");
            break;
        }
        if(FAILED(hr=pSrcVid->SetInput(CComBSTR("ScreenCap://ScreenCapture1"))))//The Video Input Source Device - Should be "ScreenCap" Device
        {
            ErrorMessage("Unable to Set Video Input Source");
            break;
        }
        if(FAILED(hr=pSrcAud->SetInput(CComBSTR("Device://Default_Audio_Device"))))//The Video Input Source Device - Should be "Default_Audio_Device" Device
        {
            ErrorMessage("Unable to Set Audio Input Source");
            break;
        }
        if(FAILED(hr=pSrcVid->QueryInterface(IID_IPropertyBag,(void**)&pPropertyBag)))
        {
            ErrorMessage("Unable to Query Interface for Propery bag");
            break;
        }

        varValue = CAPTURE_FULLSCREEN;
        if(FAILED(hr=pPropertyBag->Write(WMSCRNCAP_ENTIRESCREEN,&varValue)))    //Set Full Screen Property true/false
        {
            ErrorMessage("Unable to Set Capture Screen Property");
            break;
        }
        //int nLeft, nRight, nTop, nBottom;                                 //Set Capture Area - when not in full screen mode
        //                                                                  // Initialize the capture area. The size must be even.
        //  varValue = false;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_ENTIRESCREEN, &varValue );
        //  }
        //  varValue = nLeft;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWLEFT, &varValue );
        //  }
        //  varValue = nRight;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWRIGHT, &varValue );
        //  }
        //  varValue = nTop;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWTOP, &varValue );
        //  }
        //  varValue = nBottom;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWBOTTOM, &varValue );
        //  }
        //  varValue = true;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_FLASHRECT, &varValue );
        //  }

        if(FAILED(hr=SetupScreenCaptureProfile()))                                  //Setup the Custom Profile
        {
            break;
        }
        if(FAILED(hr=g_pProfile->QueryInterface(IID_IWMEncProfile,(void**)&pProfile)))
        {
            ErrorMessage("Unable to Query Interface For Profile");
            break;
        }
        if(FAILED(hr=pSrcGrp->put_Profile(variant_t(pProfile))))                    //Select the Custom Profile into the Encoder    
        {
            ErrorMessage("Unable to Set Profile For Source Group");
            break;
        }
        if(FAILED(hr=g_pEncoder->get_File(&pOutFile)))
        {
            ErrorMessage("Unable to Get Encoder Output File Object");
            break;
        }
        if(FAILED(hr=pOutFile->put_LocalFileName(CComBSTR(szOutputFileName))))      //Set the Target Output Filename
        {
            ErrorMessage("Unable to Set Output File Name");
            break;
        }
        if(FAILED(hr=g_pEncoder->PrepareToEncode(VARIANT_TRUE)))                    //Using Prepare optimizes startig latency
        {
            ErrorMessage("Unable to Prepare for Encoding");
            break;
        }
    }while(false);

    if(pProfile)
    {
        pProfile->Release();
        pProfile=NULL;
    }
    if(pOutFile)
    {
        pOutFile->Release();
        pOutFile = NULL;
    }
    if(pPropertyBag)
    {
        pPropertyBag->Release();
        pPropertyBag = NULL;
    }
    if(pSrcVid)
    {
        pSrcVid->Release();
        pSrcVid = NULL;
    }
    if(pSrc)
    {
        pSrc->Release();
        pSrc = NULL;
    }
    if(pSrcGrp)
    {
        pSrcGrp->Release();
        pSrcGrp = NULL;
    }
    if(pSrcGrpCollection)
    {
        pSrcGrpCollection->Release();
        pSrcGrpCollection = NULL;
    }
    return hr;
}

I am refering the following document section "Windows Media API for Capturing the Screen" to capture screen and the original code works ok. When I am adding additional feature (I just added several lines to make it record from default audio device), it fails at thew following line (I debugged and looks like it fails at COM layer?), any hints? I posted both the original source codes and my modified source codes.

"if(FAILED(hr=pSrcGrp->put_Profile(variant_t(pProfile))))"

http://www.geocities.com/krishnapg/screencap.html

Original Source Code:

http://www.geocities.com/krishnapg/WMEncScrnCap.zip

My modified source code (I only modified function InitEncoder)

HRESULT InitEncoder(LPCTSTR szOutputFileName)
{
    HRESULT hr = E_FAIL;
    CComVariant varValue;
    IWMEncSourceGroupCollection*    pSrcGrpCollection=NULL;
    IWMEncSourceGroup*  pSrcGrp=NULL;
    IWMEncSource*   pSrc=NULL;
    IWMEncSource*   paSrc=NULL;
    IPropertyBag*   pPropertyBag=NULL;
    IWMEncVideoSource2* pSrcVid=NULL;
    IWMEncAudioSource*  pSrcAud=NULL;
    IWMEncFile* pOutFile=NULL;
    IWMEncProfile*  pProfile=NULL;

    if(FAILED(CoCreateInstance(CLSID_WMEncoder,NULL,CLSCTX_INPROC_SERVER,IID_IWMEncoder2,(void**)&g_pEncoder)))
    {
        ErrorMessage("Unable to Create Encoder Object");
        return E_FAIL;
    }
    if(FAILED(g_pEncoder->get_SourceGroupCollection(&pSrcGrpCollection)))       //Retrieve the Source Group Collection  - One Application can Have many Source Groups - We need to add as many as we want
    {
        ErrorMessage("Unable to Get Source Group Collection");
        return E_FAIL;
    }

    do
    {
        if(FAILED(hr=pSrcGrpCollection->Add(CComBSTR("SourceGroup1"),&pSrcGrp)))//Add a Source Group to the Collection - Each Source can have one video one audio source input
        {
            ErrorMessage("Unable to Add A Source Group to the Collection");
            break;
        }
        if(FAILED(hr=pSrcGrp->AddSource(WMENC_VIDEO,&pSrc)))                    //Add a Video Source to the Group
        {
            ErrorMessage("Unable to Add A Source to the Source Group");
            break;
        }
        if(FAILED(hr=pSrcGrp->AddSource(WMENC_AUDIO,&paSrc)))                   //Add an Audio Source to the Group
        {
            ErrorMessage("Unable to Add A Source to the Source Group");
            break;
        }
        if(FAILED(hr=pSrc->QueryInterface(IID_IWMEncVideoSource2,(void**)&pSrcVid)))
        {
            ErrorMessage("Unable to Query interface for Video Source");
            break;
        }
        if(FAILED(hr=paSrc->QueryInterface(IID_IWMEncAudioSource,(void**)&pSrcAud)))
        {
            ErrorMessage("Unable to Query interface for Audio Source");
            break;
        }
        if(FAILED(hr=pSrcVid->SetInput(CComBSTR("ScreenCap://ScreenCapture1"))))//The Video Input Source Device - Should be "ScreenCap" Device
        {
            ErrorMessage("Unable to Set Video Input Source");
            break;
        }
        if(FAILED(hr=pSrcAud->SetInput(CComBSTR("Device://Default_Audio_Device"))))//The Video Input Source Device - Should be "Default_Audio_Device" Device
        {
            ErrorMessage("Unable to Set Audio Input Source");
            break;
        }
        if(FAILED(hr=pSrcVid->QueryInterface(IID_IPropertyBag,(void**)&pPropertyBag)))
        {
            ErrorMessage("Unable to Query Interface for Propery bag");
            break;
        }

        varValue = CAPTURE_FULLSCREEN;
        if(FAILED(hr=pPropertyBag->Write(WMSCRNCAP_ENTIRESCREEN,&varValue)))    //Set Full Screen Property true/false
        {
            ErrorMessage("Unable to Set Capture Screen Property");
            break;
        }
        //int nLeft, nRight, nTop, nBottom;                                 //Set Capture Area - when not in full screen mode
        //                                                                  // Initialize the capture area. The size must be even.
        //  varValue = false;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_ENTIRESCREEN, &varValue );
        //  }
        //  varValue = nLeft;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWLEFT, &varValue );
        //  }
        //  varValue = nRight;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWRIGHT, &varValue );
        //  }
        //  varValue = nTop;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWTOP, &varValue );
        //  }
        //  varValue = nBottom;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_WINDOWBOTTOM, &varValue );
        //  }
        //  varValue = true;
        //  if ( SUCCEEDED( hr ) )
        //  {
        //      hr = pPropertyBag->Write( WMSCRNCAP_FLASHRECT, &varValue );
        //  }

        if(FAILED(hr=SetupScreenCaptureProfile()))                                  //Setup the Custom Profile
        {
            break;
        }
        if(FAILED(hr=g_pProfile->QueryInterface(IID_IWMEncProfile,(void**)&pProfile)))
        {
            ErrorMessage("Unable to Query Interface For Profile");
            break;
        }
        if(FAILED(hr=pSrcGrp->put_Profile(variant_t(pProfile))))                    //Select the Custom Profile into the Encoder    
        {
            ErrorMessage("Unable to Set Profile For Source Group");
            break;
        }
        if(FAILED(hr=g_pEncoder->get_File(&pOutFile)))
        {
            ErrorMessage("Unable to Get Encoder Output File Object");
            break;
        }
        if(FAILED(hr=pOutFile->put_LocalFileName(CComBSTR(szOutputFileName))))      //Set the Target Output Filename
        {
            ErrorMessage("Unable to Set Output File Name");
            break;
        }
        if(FAILED(hr=g_pEncoder->PrepareToEncode(VARIANT_TRUE)))                    //Using Prepare optimizes startig latency
        {
            ErrorMessage("Unable to Prepare for Encoding");
            break;
        }
    }while(false);

    if(pProfile)
    {
        pProfile->Release();
        pProfile=NULL;
    }
    if(pOutFile)
    {
        pOutFile->Release();
        pOutFile = NULL;
    }
    if(pPropertyBag)
    {
        pPropertyBag->Release();
        pPropertyBag = NULL;
    }
    if(pSrcVid)
    {
        pSrcVid->Release();
        pSrcVid = NULL;
    }
    if(pSrc)
    {
        pSrc->Release();
        pSrc = NULL;
    }
    if(pSrcGrp)
    {
        pSrcGrp->Release();
        pSrcGrp = NULL;
    }
    if(pSrcGrpCollection)
    {
        pSrcGrpCollection->Release();
        pSrcGrpCollection = NULL;
    }
    return hr;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的痛♀有谁懂 2024-07-26 13:14:16

您可能需要重置音频:

打开控制面板 -> 打开声音

播放中,您将看到扬声器作为默认播放。

右键单击它-> 转到属性 -> 转到高级选项卡-> 单击恢复默认值

You may need to reset the audio:

Open Control Panel -> open Sound

In Playback, you'll see your speaker as default playback.

Right-click on it -> go to Properties -> go to the Advanced tab-> click on Restore Default

水染的天色ゝ 2024-07-26 13:14:16

您的代码可能没有任何问题。 Windows Vista 因无法以编程方式设置输出/输入而臭名昭著。

There is probably nothing wrong with your code. Windows Vista is notorious for not being able to programatically set the output / input.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文