WMEncoder在一次迭代后抛出OutOfMemoryException

时间:2012-06-26 08:00:52

标签: c# .net out-of-memory encoder windows-media-encoder

我正在使用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;
        }

1 个答案:

答案 0 :(得分:0)

显然,微软不再支持WMEncoder。我建议查看Expression Encoder,它可以非常轻松地捕获屏幕 - http://www.microsoft.com/expression/products/Encoder4_Overview.aspx。它为您节省了编组和处理COM的麻烦。