2012-06-26 65 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支持 –