Search code examples
c#winui-3mediaplayerelement

WinUI 3 MediaPlayerElement capture image


I have a MediaPlayerElement playing a random video file and a "Capture" button. When I click a button, I want to get a screenshot of the video as a SoftwareBitmap object. I was able to do it from the Camera using MediaCapture and deviceId but I can't find how to handle it from the playing video file.

I found this code but it doesn't work for me

var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(mediaPlayerElement);
var pixelBuffer = await bitmap.GetPixelsAsync();
var videoCapture = SoftwareBitmap.CreateCopyFromBuffer(pixelBuffer, BitmapPixelFormat.Bgra8,
bitmap.PixelWidth, bitmap.PixelHeight);

Solution

  • I was able to handle this issue. I wasn't quite correct in my description instead of capturing I needed to extract playback video frame. Thanks to this question. I had to download this NuGet package Microsoft.Graphics.Win2D which has classes to work with 2D graphics. In the code below media is MediaPlayerElement.

    SoftwareBitmap softwareBitmap;
    var frame = new SoftwareBitmap(BitmapPixelFormat.Rgba8, 
    (int)media.ActualWidth, (int)media.ActualHeight, BitmapAlphaMode.Ignore);
    var canvasDevice = CanvasDevice.GetSharedDevice();
    using (var inputBitmap = CanvasBitmap.CreateFromSoftwareBitmap(canvasDevice, frame))
    {
        media.MediaPlayer.CopyFrameToVideoSurface(inputBitmap);
    
        using (var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
        {
            await inputBitmap.SaveAsync(stream, CanvasBitmapFileFormat.Png);
            var decoder = await BitmapDecoder.CreateAsync(stream);
            softwareBitmap = await decoder.GetSoftwareBitmapAsync();
        }
    }