MediaComposition.RenderToFileAsync 因许多静态图像而崩溃 [英] MediaComposition.RenderToFileAsync crashes with many static images

查看:20
本文介绍了MediaComposition.RenderToFileAsync 因许多静态图像而崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Windows Phone 8.1 Silverlight app that renders .gif files to .mp4, using the Windows.Media.Editing.MediaComposition class.

某些文件会随机使 RenderToFileAsync 方法崩溃.您至少会收到两种不同的错误消息,一种表示内存不足.

Certain files will randomly crash the RenderToFileAsync method. There are at least two different error messages you can receive, one stating insufficient memory.

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

Does anyone have any ideas for a workaround, or some insider knowledge on how this is supposed to work?

重现:

  • 在 VS2013 中创建新的 c# WP8.1 Silverlight 应用程序空白项目
  • 将 Usings 和 OnNavigatedTo 添加到 MainPage.xaml.cs,如下所示.
  • 在 512MB 模拟器中运行.观察崩溃(大部分时间).摆弄 i 的值以查看它是否正常工作.

  • Create new c# WP8.1 Silverlight app blank project in VS2013
  • Add Usings and OnNavigatedTo to MainPage.xaml.cs as below.
  • Run in 512MB emulator. Observe crash (most of the time). Fiddle with value of i to see it work properly.

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");

    }

推荐答案

我遇到了基本相同的问题,经过多次反复试验,我终于摆脱了导致许多或所有缺失的帧.

I had basically the same problem and after much trial and error I finally got rid of my "Value does not fall within the expected range" error which caused many or all missing frames.

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

I added GC.Collect(); right before every MediaClip.CreateFromImageFileAsync. It doesn't seem to effect performance or cause any problems and was the only way I could fix it. Hope this can help others.

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

Here is some of my code so you can see what I'm talking about:

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);
        }
}

这篇关于MediaComposition.RenderToFileAsync 因许多静态图像而崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆