我正在使用 WMEncoder 进行屏幕录制。
第一次一切正常,
但第二次Start()
方法抛出我OutOfMemoryException
:
System.OutOfMemoryException was caught
HResult=-2147024882
Message=Not enough storage is available to complete this operation.
我的代码看起来像这样,它在 .Net4 上:
// Initialize encoder and set recording parameters
mEncoder = new WMEncoder();
SetRecordingParams(); // If it's relevant I can attach this function
// Set the output file.
mEncoder.EnableAutoArchive = true;
mEncoder.AutoIndex = true;
mEncoder.File.LocalFileName = tempRecFile;
// Start the encoding process.
mEncoder.PrepareToEncode(true);
mEncoder.Start();
// If currently recording, stop recording
if (mEncoder != null &&
mEncoder.RunState != WMENC_ENCODER_STATE.WMENC_ENCODER_STOPPED)
{
// Stop recording
mEncoder.Stop();
}
// Releasing Com object
if (mEncoder != null)
{
Marshal.FinalReleaseComObject(mEncoder);
mEncoder = null;
}
帮我!
更新
private void SetRecordingParams()
{
// Create a source group collection object from the WMEncoder object.
srcGrpColl = mEncoder.SourceGroupCollection;
// Add a source group named SG1 to the collection.
// Create a source object for each type of multimedia content
// in the source group.
srcGrp = (IWMEncSourceGroup2)srcGrpColl.Add("SG_1");
srcVideo = (IWMEncVideoSource2)srcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_VIDEO);
srcVideo.SetInput("ScreenCap://ScreenCapture1", "", "");
// Create a profile collection object from the WMEncoder object.
mEncoder.ProfileCollection.ProfileDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
mEncoder.ProfileCollection.Refresh();
proColl = mEncoder.ProfileCollection;
// Create a profile object
IEnumerator profEnum = proColl.GetEnumerator();
while (profEnum.MoveNext())
{
profile = (IWMEncProfile)profEnum.Current;
if (profile.Name == "Screen Recording")
{
// Load profile
newProfile = new WMEncProfile2();
newProfile.LoadFromIWMProfile(profile);
audience = newProfile.get_Audience(0);
audience.set_VideoFPS(0, paramMaps.fpsMapping[fpsKey] * 1000);
audience.set_VideoKeyFrameDistance(0, keyFrameInt * 1000);
audience.set_VideoWidth(0, Screen.PrimaryScreen.Bounds.Width * paramMaps.imageQualityMapping[qualityRatioKey] / 100);
audience.set_VideoHeight(0, Screen.PrimaryScreen.Bounds.Height * paramMaps.imageQualityMapping[qualityRatioKey] / 100);
// Set profile language to client machine's locale.
// When recording is done this way, it will assume server's locale when extracted from the DB.
// This enables us to know which locale should be used for the file merge.
// We have found that when profile is set to the same language as user's locale, the recording
// has a "flexible" language definition.
int langCount = newProfile.get_LanguageCount(WMENC_SOURCE_TYPE.WMENC_VIDEO, 0);
// Remove all existing language definitions from profile
for (int i = 0; i < langCount; i++)
{
newProfile.RemoveLanguage(WMENC_SOURCE_TYPE.WMENC_VIDEO, 0, newProfile.get_Language(WMENC_SOURCE_TYPE.WMENC_VIDEO, 0, i));
}
// Add current locale as profile language.
int lcid = Thread.CurrentThread.CurrentCulture.LCID;
newProfile.AddLanguage(WMENC_SOURCE_TYPE.WMENC_VIDEO, 0, lcid);
// Specify this profile object as the profile to use in source group.
srcGrp.set_Profile(newProfile);
}
}
mEncoder.VideoComplexity = WMENC_VIDEOCOMPLEXITY.WMENC_COMPLEXITY_LEVEL20;
}