C# WMEncoder在一次迭代后抛出OutOfMemoryException

C# WMEncoder在一次迭代后抛出OutOfMemoryException,c#,.net,out-of-memory,encoder,windows-media-encoder,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

我正在使用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()
{
//从WMEncoder对象创建源组集合对象。
srcGrpColl=mEncoder.SourceGroupCollection;
//将名为SG1的源组添加到集合中。
//为每种类型的多媒体内容创建源对象
//在源组中。
srcGrp=(IWMEncSourceGroup2)srcGrpColl.Add(“SG_1”);
srcVideo=(IWMEncVideoSource2)srcGrp.AddSource(WMENC\u SOURCE\u TYPE.WMENC\u VIDEO);
SetInput(“ScreenCap://ScreenCapture1”,“”,“”);
//从WMEncoder对象创建配置文件集合对象。
mEncoder.ProfileCollection.ProfileDirectory=Path.GetDirectoryName(Assembly.getExecutionGassembly().Location);
mEncoder.ProfileCollection.Refresh();
proColl=mEncoder.ProfileCollection;
//创建纵断面对象
IEnumerator profEnum=proColl.GetEnumerator();
while(profEnum.MoveNext())
{
profile=(IWMEncProfile)profEnum.Current;
如果(profile.Name==“屏幕录制”)
{
//负荷剖面
newProfile=新的WMEncProfile2();
newProfile.LoadFromIWMProfile(配置文件);
受众=新建配置文件。获取受众(0);
受众.set_VideoFPS(0,paramMaps.fpsMapping[fpsKey]*1000);
受众。设置视频关键帧位置(0,关键帧长度*1000);
设置视频宽度(0,Screen.PrimaryScreen.Bounds.Width*paramMaps.imageQualityMapping[qualityRatioKey]/100);
受众.设置视频高度(0,Screen.PrimaryScreen.Bounds.Height*paramMaps.imageQualityMapping[qualityRatioKey]/100);
//将配置文件语言设置为客户端计算机的区域设置。
//当以这种方式进行记录时,从数据库中提取时,它将采用服务器的区域设置。
//这使我们能够知道文件合并应该使用哪种语言环境。
//我们发现,当配置文件设置为与用户的区域设置相同的语言时,录制
//具有“灵活”的语言定义。
int langCount=newProfile.get_LanguageCount(WMENC_SOURCE_TYPE.WMENC_VIDEO,0);
//从配置文件中删除所有现有的语言定义
对于(int i=0;i
微软显然不再支持WMEncoder。我建议研究一下表达式编码器,它使屏幕截图变得非常容易。而且它还为您省去了整理和处理COM的麻烦。

您是否有机会检查它是否真的内存不足?例如在
Win32
进程中达到虚拟地址限制。作为猜测,编码器可能有内部引用,并且不会立即被破坏,从而保持资源的稳定。性能监视器应该向您展示这个。谢谢@RomanR。我运行了Performance Monitor,但没有发现任何问题或故障,我能做什么?请您演示如何使用
SetRecordingParams
和其他相关代码,以便我们可以复制它并自己重新处理问题,ta。@Jeremythonpson我添加了它,但它会减慢我的进程,因为Silverlight无法读取它的输出(或任何其他非windows media player的播放器)所以我需要转换,这需要时间。我自己从未尝试过,但之前提供的编码器页面明确提到了silverlight支持。我可以告诉你,ee4屏幕捕获输出上没有SL支持。很抱歉,这对你没有帮助。反正我明天会快速查看,因为我刚刚完成了一个屏幕捕获项目使用表达式。我对SL的了解是0,所以我测试输出兼容性的能力不是很强。这个链接似乎暗示在表达式中使用VC1预设将产生可用的内容。我有一个很小的测试文件(256K)可供测试。
 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;
        }