2012-06-26 54 views
3

我正在使用WMEncoder进行屏幕录制。
在第一时间一切正常,
但在第二次Start()方法抛出我OutOfMemoryExceptionWMEncoder在一次迭代后抛出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; 
} 

帮助我!

UPDATE

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; 
     } 
+0

您是否有机会检查它是否确实内存不足?比如在'Win32'进程中打虚拟地址限制。作为一种猜测 - 编码器可能具有内部引用,并且不会立即销毁以保持资源。性能监视器应该告诉你这一点。 –

+0

谢谢@RomanR。我跑了性能监视器,我没有看到任何问题或失败,我该怎么办? –

+0

您可以使用'SetRecordingParams'和其他相关代码来显示,以便我们可以复制它并自行重现问题,ta。 –

回答

0

WMEncoder不再受微软显然支持。我会建议寻找表达式编码器,这使得屏幕捕获非常容易 - http://www.microsoft.com/expression/products/Encoder4_Overview.aspx。它可以为您节省编组和处理COM的麻烦。

+0

但它减缓了我的过程,因为它的输出不能被Silverlight(或任何其他非Windows媒体播放器的播放器)读取,所以我需要转换并且需要时间 –

+0

从来没有尝试过但编码器页面先前明确提到了silverlight支持。 – zeFrenchy

+0

我可以告诉你,在ee4屏幕捕捉输出上没有SL支持 –

相关问题