用WM Encoder编写的录屏程序,在双显示下的问题????求高手帮忙

xiaolang_zb 2011-07-10 09:08:56
本人用 VB 基于WM Encoder写了一段录屏程序。在单显示的情况下没有问题,CPU占用不高,用户没有什么感觉。但是在双显示器的情况下,程序把主副显示器的内容都录制了,导致CPU占用高达90%以上,客户程序无法正常运行。看了SDK ,想用指定录制区域的方法解决这个问题。但是SDK 只提供了C++的方法。有高手能帮我转为VB能用的程序吗?多谢。
VB 实现代码如下:

' Create a WMEncoder object.
Set Encoder = New WMEncoder

' Retrieve the source group collection and add a source group.
Dim SrcGrpColl As IWMEncSourceGroupCollection
Set SrcGrpColl = Encoder.SourceGroupCollection
Dim SrcGrp As IWMEncSourceGroup2
Set SrcGrp = SrcGrpColl.Add("SG_1")

' Add a video and audio source to the source group.
Dim SrcVid As IWMEncVideoSource
'Dim SrcAud As IWMEncAudioSource
Set SrcVid = SrcGrp.AddSource(WMENC_VIDEO)
' Set SrcAud = SrcGrp.AddSource(WMENC_AUDIO)

' Identify the source files to encode.
SrcVid.SetInput "ScreenCap://ScreenCapture1"

' Choose a profile from the collection.
Dim ProColl As IWMEncProfileCollection
Dim Pro As IWMEncProfile
Dim i As Integer
Dim lLength As Long

Set ProColl = Encoder.ProfileCollection
lLength = ProColl.Count

For i = 0 To lLength - 1
Set Pro = ProColl.Item(i)
Debug.Print Pro.Name
If Pro.Name = "屏幕视频 - 中(CBR)" Then
SrcGrp.Profile = Pro
Exit For
End If
Next

' Fill in the description object members.
Dim Descr As IWMEncDisplayInfo
Set Descr = Encoder.DisplayInfo
Descr.Author = "Author name"
Descr.Copyright = "Copyright information"
Descr.Description = "Text description of encoded content"
Descr.Rating = "Rating information"
Descr.Title = "Title of encoded content"

' Specify a file object in which to save encoded content.
Dim File As IWMEncFile
Set File = Encoder.File
File.LocalFileName = "C:\\OutputFile.wmv"

' Start the encoding process.
Encoder.Start

SDK中C++选择区域的方法为:
// Include libraries.
#include <windows.h>
#include <atlbase.h>
#include <comdef.h>
#include "C:\WMSDK\WMEncSDK9\include\wmencode.h"

// Define the screen capture properties.
#define WMSCRNCAP_CAPTUREWINDOW CComBSTR("CaptureWindow")
#define WMSCRNCAP_WINDOWLEFT CComBSTR("Left")
#define WMSCRNCAP_WINDOWTOP CComBSTR("Top")
#define WMSCRNCAP_WINDOWRIGHT CComBSTR("Right")
#define WMSCRNCAP_WINDOWBOTTOM CComBSTR("Bottom")
#define WMSCRNCAP_FLASHRECT CComBSTR("FlashRect")
#define WMSCRNCAP_ENTIRESCREEN CComBSTR("Screen")
#define WMSCRNCAP_WINDOWTITLE CComBSTR("WindowTitle")

// Declare variables.
HRESULT hr = S_OK;
IWMEncoder* pEncoder;
IWMEncSourceGroupCollection* pSrcGrpColl;
IWMEncSourceGroup* pSrcGrp;
IWMEncSource* pSrc;
IWMEncVideoSource2* pSrcVid;
IPropertyBag* pPropertyBag;
CComVariant varValue;

// Initialize the COM library and retrieve a pointer to an IWMEncoder interface.
hr = CoInitialize(NULL);
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance(CLSID_WMEncoder,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWMEncoder,
(void**) &pEncoder);
}

// Retrieve the source group collection.
if ( SUCCEEDED( hr ) )
{
hr = pEncoder->get_SourceGroupCollection(&pSrcGrpColl);
}

// Add a source group to the collection.
if ( SUCCEEDED( hr ) )
{
hr = pSrcGrpColl->Add(CComBSTR("SG_1"), &pSrcGrp);
}
if ( SUCCEEDED( hr ) )
{
hr = pSrcGrp->AddSource(WMENC_VIDEO, &pSrc);
}

// Retrieve an IWMEncVideoSource2 pointer.
if ( SUCCEEDED( hr ) )
{
hr = pSrc->QueryInterface(IID_IWMEncVideoSource2, (void**)&pSrcVid);
}

// Add a video source to the source group.
if ( SUCCEEDED( hr ) )
{
hr = pSrcVid->SetInput(CComBSTR("ScreenCap://ScreenCapture1"));
}

// Retrieve a pointer to the property bag.
if ( SUCCEEDED( hr ) )
{
hr = pSrcVid->QueryInterface(IID_IPropertyBag, (void**)&pPropertyBag);
}

// Set full screen capture.
{
varValue = true;
if ( SUCCEEDED( hr ) )
{
hr = pPropertyBag->Write( WMSCRNCAP_ENTIRESCREEN, &varValue );
}
}

// Set the capture area.
{
// nLeft, nRight, nTop, and nBottom are the dimensions to capture
int nLeft, nRight, nTop, nBottom;

// 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 );
}

自己试着写了点VB转换的代码,总是实现不了,希望高人帮帮忙。。。。急啊!!!!
万分感谢!!!!
...全文
258 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaolang_zb 2011-08-05
  • 打赏
  • 举报
回复
Srcvid没有IPropertybag
而且在VB里面设置一个IPropertybag后。只能用写属性和读属性给属性页赋值。
Dim Ipor As PropertyBag
Ipor.ReadProperty
Ipor.WriteProperty
我按照C++的赋值方法对相应属性赋值
#define WMSCRNCAP_CAPTUREWINDOW CComBSTR("CaptureWindow")
#define WMSCRNCAP_WINDOWLEFT CComBSTR("Left")
#define WMSCRNCAP_WINDOWTOP CComBSTR("Top")
#define WMSCRNCAP_WINDOWRIGHT CComBSTR("Right")
#define WMSCRNCAP_WINDOWBOTTOM CComBSTR("Bottom")
#define WMSCRNCAP_FLASHRECT CComBSTR("FlashRect")
#define WMSCRNCAP_ENTIRESCREEN CComBSTR("Screen")
#define WMSCRNCAP_WINDOWTITLE CComBSTR("WindowTitle")
比如
Ipor.WriteProperty "Left", 20
但是设置完以后没有什么反应。。。。。。呵呵。求解!
zfl2k 2011-07-29
  • 打赏
  • 举报
回复
大致看了一下,估计是这样
SrcVid.SetInput "ScreenCap://ScreenCapture1"
srcvid.IPropertyBag
IPropertyBag.WMSCRNCAP_ENTIRESCREEN=false
IPropertyBag.left=
IPropertyBag.top=
IPropertyBag.right=
IPropertyBag.bottom=
xiaolang_zb 2011-07-29
  • 打赏
  • 举报
回复
1.将显卡的硬件加速设为0
2.使用单独的进程实现录屏
3.将录制屏幕的切割参数left设定为整个屏幕的一半。
目前使用这种方法程序可以使用了。。。。。
虽然没有得到想要的方法。但是还是感谢Veron_04
贝隆 2011-07-13
  • 打赏
  • 举报
回复
对我而言,难度很高。
xiaolang_zb 2011-07-13
  • 打赏
  • 举报
回复
没有朋友帮忙吗?简单点说就是只录制主屏幕。

807

社区成员

发帖
与我相关
我的任务
社区描述
VB 多媒体
社区管理员
  • 多媒体
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧