捕获每个WPF MediaElement框架

时间:2010-06-11 15:40:37

标签: c# wpf frames mediaelement

有没有办法捕获每个WPF MediaElement框架?就像在每个渲染帧中触发的事件一样,允许我访问它。如果MediaElement没有提供这样的功能,它可以如何实现或者我可以使用什么其他控件?另外,是否有这样的控件或方法可以通过帧捕获实现媒体剪辑的屏幕外快速渲染? (所以我可以尽快处理帧)

4 个答案:

答案 0 :(得分:3)

试用我的WPF MediaKit项目。允许您使用Media在WPF中执行几乎任何操作。试用MediaDetector.cs,它允许您随时从媒体中提取帧。这是一个小小的车,因为我从来没有花太多时间在它上面,但应该为你需要的东西工作。

答案 1 :(得分:0)

没有内置的WPF方式:

  • MediaElement没有此功能。
  • BitmapDecoder具有请求此功能的API,但是没有实现使用BitmapDecoder从任意媒体中提取帧:它只能从几个动画位图格式中提取帧,如.gif。

我能够使用DirectShow从.mpg,.wmv,.mov,.flv,.avi和其他电影格式中获取帧图像。我使用DirectShow的COM图形构建器接口构建了一个过滤器图形。生成的过滤器图形解码了电影并将其连接到用C#编写的自定义渲染器过滤器。我的自定义过滤器接收到帧数据并将其转换为BitmapSource对象,以便使用BitmapSource.Create进行显示。

DirectShow解决方案表现相当不错,管理到非托管转换并不是什么大不了的事,但需要一段时间才能弄清楚DirectShow图形构建的细节。

答案 2 :(得分:0)

如果您发挥自己的想象力,则此片段可能会给您一些想法:

MediaPlayer player = new MediaPlayer();
player.Open(new Uri(_inputFilename));
player.ScrubbingEnabled = true;
DrawingVisual dv = new DrawingVisual();
for (int i = 0; i < session.FramesList.Count; i++)
{
    Frame f = session.FramesList[i];
    player.Position = new TimeSpan((long)(f.Time * 10000000));
    using (DrawingContext dc = dv.RenderOpen())
    {
        dc.DrawVideo(player, new Rect(0, 0, 1024, 576));
    }
    RenderTargetBitmap bmp = new RenderTargetBitmap(1024, 576, 96, 96, PixelFormats.Pbgra32);
    bmp.Render(dv);
    f.Thumbnail = bmp.GetAsFrozen() as ImageSource;
    framesListView.Dispatcher.Invoke(() => FramesList.Add(f));
}

答案 3 :(得分:0)

您可以尝试使用此方法输出任何 UI 元素,包括 WPF 中的 MediaElement

 public static void ConvertUiElementToBitmap(UIElement elt, string path)
        {
            double h = elt.RenderSize.Height;
            double w = elt.RenderSize.Width;
            if (h > 0)
            {
                PresentationSource source = PresentationSource.FromVisual(elt);
                RenderTargetBitmap rtb = new RenderTargetBitmap((int)w, (int)h, 96, 96, PixelFormats.Default);

                VisualBrush sourceBrush = new VisualBrush(elt);
                DrawingVisual drawingVisual = new DrawingVisual();
                DrawingContext drawingContext = drawingVisual.RenderOpen();
                using (drawingContext)
                {
                    drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0),
                          new Point(w, h)));
                }
                rtb.Render(drawingVisual);

                // return rtb;
                var encoder = new PngBitmapEncoder();
                var outputFrame = BitmapFrame.Create(rtb);
                encoder.Frames.Add(outputFrame);

                using (var file = System.IO.File.OpenWrite(path))
                {
                    encoder.Save(file);
                }
            }
        }