问题
Is there a way to capture each WPF MediaElement frame? Like an event that fires at each rendered frame and allows me to access it. If MediaElement does not provide such functionality, how could it be implemented or what other control could I use? On a side note, is there such a control or method that would allow for off-screen fast rendering of media clips with frame capture? (so I could process frames as fast as possible)
回答1:
Try out my WPF MediaKit project. Allows you to do pretty much anything in WPF with Media. Try out the MediaDetector.cs, it allows you to extract out frames from any time in the media. It's a little buggy as I've never put a lot of time in it, but should work for what you need.
回答2:
There is no built-in WPF way:
- MediaElement does not have this ability.
- BitmapDecoder has the API to request this but using BitmapDecoder to extract frames from arbitrary media is not implemented: It can only extract frames from a few animated bitmap formats like .gif.
I was able to get frame images from .mpg, .wmv, .mov, .flv, .avi and other movie formats using DirectShow. I constructed a filter graph using DirectShow's COM graph builder interfaces. The resulting filter graph decoded the movie and connected it to a custom renderer filter written in C#. My custom filter received the frame data and converted it into BitmapSource objects for display using BitmapSource.Create.
The DirectShow solution performed quite well, and the managed to unmanaged transition was no big deal, but it took a while to figure out the details of the DirectShow graph building.
回答3:
If you use your imagination perhaps this snippet can give you some ideas:
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));
}
来源:https://stackoverflow.com/questions/3024169/capture-each-wpf-mediaelement-frame