无法使用 Windows Media Encoder 设置默认音频设备
我参考以下文档部分“用于捕获屏幕的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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能需要重置音频:
打开控制面板 -> 打开声音
在播放中,您将看到扬声器作为默认播放。
右键单击它-> 转到属性 -> 转到高级选项卡-> 单击恢复默认值
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
您的代码可能没有任何问题。 Windows Vista 因无法以编程方式设置输出/输入而臭名昭著。
There is probably nothing wrong with your code. Windows Vista is notorious for not being able to programatically set the output / input.