代码之家  ›  专栏  ›  技术社区  ›  luvieere

捕获每个WPF MediaElement帧

  •  1
  • luvieere  · 技术社区  · 16 年前

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

    2 回复  |  直到 16 年前
        1
  •  3
  •   Jeremiah Morrill    16 年前

    试试我的 WPF MediaKit 项目。允许您在WPF中使用媒体执行几乎所有操作。试试mediadector.cs,它允许您从媒体中的任何时间提取帧。这是一个小马车,因为我从来没有把很多时间在它,但应该为你需要的工作。

        2
  •  1
  •   Ray Burns    16 年前

    没有内置的WPF方式:

    • MediaElement没有此功能。
    • BitmapDecoder有API来请求这一点,但是使用BitmapDecoder从任意媒体提取帧并没有实现:它只能从一些动画位图格式(如.gif)中提取帧。

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

    DirectShow解决方案执行得相当好,托管到非托管的转换也没什么大不了的,但是花了一段时间才弄清楚DirectShow图形构建的细节。

        3
  •  0
  •   Clive Miller    7 年前

    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));
    }
    
        4
  •  0
  •   SandiaDeDia    5 年前

    您可以尝试此方法输出任何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);
                    }
                }
            }