MediaComposition.RenderToFileAsync与许多静态图像崩溃

我有一个Windows Phone 8.1 Silverlight应用程序,使用Windows.Media.Editing.MediaComposition类将.gif文件呈现为.mp4。

某些文件将随机崩溃RenderToFileAsync方法。 您可以收到至少两个不同的错误消息,一个表明内存不足。

有没有人有任何关于变通方法的想法,或者一些关于这应该如何工作的内幕知识?

摄制:

  • 在VS2013中创建新的c#WP8.1 Silverlight app空白项目
  • 将Usings和OnNavigatedTo添加到MainPage.xaml.cs,如下所示。
  • 运行512MB仿真器。 观察崩溃(大部分时间)。 摆弄i的价值,看它运作正常。

    using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Navigation; using Microsoft.Phone.Controls; using Microsoft.Phone.Shell; using System.Windows.Media.Imaging; using System.IO; using Windows.Media.Editing; using System.Diagnostics; 

  protected async override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); SystemTray.ProgressIndicator = new ProgressIndicator(); SystemTray.ProgressIndicator.IsVisible = true; SystemTray.ProgressIndicator.IsIndeterminate= true; var comp = new MediaComposition(); var r = new Random(); for (int i = 0; i < 190; i++) { var wb = new WriteableBitmap(576, 300); for (int iPix = 0; iPix < wb.Pixels.Length; iPix++) { wb.Pixels[iPix] = r.Next(); } string filename = "file" + i.ToString() + ".jpg"; var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.ReplaceExisting); using (var curr = await file.OpenStreamForWriteAsync()) { wb.SaveJpeg(curr, wb.PixelWidth, wb.PixelHeight, 0, 95); } var clip = await MediaClip.CreateFromImageFileAsync(file, TimeSpan.FromMilliseconds(60)); comp.Clips.Add(clip); } // Ensure add capability to write to video library AND ID_CAP_MEDIALIB_PHOTO and change below to // Windows.Storage.KnownFolders.VideosLibrary to see output in Videos app var destFolder = Windows.Storage.ApplicationData.Current.LocalFolder; var destFile = await destFolder.CreateFileAsync("test.mp4", Windows.Storage.CreationCollisionOption.ReplaceExisting); Debug.WriteLine("Mem use before render to disk: " + Windows.System.MemoryManager.AppMemoryUsage.ToString("N0")); await comp.RenderToFileAsync(destFile); Debug.WriteLine("Mem use after render to disk: " + Windows.System.MemoryManager.AppMemoryUsage.ToString("N0")); SystemTray.ProgressIndicator.IsVisible = false; MessageBox.Show("Done OK"); } 

我通过Windows Phone应用程序分析内存分析器运行代码。 我可以确认您的应用程序运行到大约150 MB的系统内存限制。 MediaComposition引擎可能需要大量内存,具体取决于输入和输出格式的大小。 在您的情况下,您正在添加大量剪辑。 可添加的剪辑数量受可用于解码的内存的限制。

老实说,MediaComposition不是为处理如此大量的剪辑而设计的。 预期的平均剪辑数量徘徊在五个左右。

不幸的是,我无法获得我能想到的唯一可行的解​​决方法。 我认为这个解决方案可能是可行的,但遗憾的是我不能再花时间了:你可能会使用较少数量的剪辑来创建多个输出文件。 例如,您可以创建一个包含图像一到二十的输出文件。 然后,您可以使用二十一到四十的图像创建第二个文件。 然后,您可以将这两个文件连接在一起。

我希望这有帮助,

詹姆士

我有基本相同的问题,经过多次试验和错误,我终于摆脱了我的“价值不落在预期的范围内”错误导致许多或所有丢失的帧。

我添加了GC.Collect(); 就在每个MediaClip.CreateFromImageFileAsync之前。 它似乎不会影响性能或导致任何问题,是我能解决它的唯一方法。 希望这可以帮助别人。

这是我的一些代码,所以你可以看到我在说什么:

 foreach (var thisFrame in frames) { GC.Collect(); try { MediaClip clip = await MediaClip.CreateFromImageFileAsync(thisFrame, TimeSpan.FromMilliseconds(36 * speed)); app.mediaComposition.Clips.Add(clip); } catch (Exception ex) { Debug.WriteLine(ex.Message + ex.StackTrace); } }