如何从UWP中的MediaPlayer获取SoftwareBitmap

时间:2018-04-13 19:43:12

标签: c# video uwp

我目前正在开展一个项目,我正在接收来自IP摄像机的实时视频流作为MediaPlayer对象。最终目标是能够使用Windows.Media.OCR每隔一秒左右从帧中提取文本,为此我需要一个SoftwareBitmap。

从Microsoft UWP文档中,可以使用CopyFrameToVideoSurface(CanvasBitmap)方法从MediaPlayer对象中获取帧。我可以从一个SoftwareBitmap创建一个CanvasBitmap ,但我还没有找到一种方法从CanvasBitmap创建一个SoftwareBitmap而不必保存文件(我试图避免,我不需要保留图像)。我希望我遗漏一些简单的东西,有没有办法从MediaPlayer对象获取SoftwareBitmap?

我一直在引用this example以在帧服务器模式下使用MediaPlayer。我不需要显示图像,所以如果可能的话,如果可以的话,最好避免使用CanvasBitmap。

的MediaPlayer

private async Task GetStream()
{
    mediaPlayer = new MediaPlayer()
    {
        Source = MediaSource.CreateFromStream(placeholder, "video")
    };

    mediaPlayer.VideoFrameAvailable += VideoFrameAvailable;
    mediaPlayer.IsVideoFrameServerEnabled = true;
    mediaPlayer.Play();
}

private async void VideoFrameAvailable(MediaPlayer sender, object args)
{
    // Get frame from media player, create SoftwareBitmap
    await ExtractText(softwareBitmapImg);
}

我的OCR部分的代码相对简单,当我有一个SoftwareBitmap提供时,它就像一个魅力。

OCR

private async Task ExtractText()
{
    Language ocrLanguage = new Language("en-us");
    OcrEngine ocrEngine = OcrEngine.TryCreateFromLanguage(ocrLanguage);

    var ocrResult = await ocrEngine.RecognizeAsync(bitmap);
    String text = ocrResult.Text;
}

1 个答案:

答案 0 :(得分:2)

CanvasBitmap 实现IDirect3DSurface界面,每当调用 VideoFrameAvailable 处理程序时,CopyFrameToVideoSurface方法用于复制内容框架为IDirect3DSurface。当调用 CopyFrameToVideoSurface 时,我们需要 CanvasBitmap 对象将当前帧从MediaPlayer复制到 CanvasBitmap ,但是您不需要显示图像。

private async void mediaPlayer_VideoFrameAvailable(MediaPlayer sender, object args)
{
    CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice();
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
        SoftwareBitmap softwareBitmapImg;
        SoftwareBitmap frameServerDest = new SoftwareBitmap(BitmapPixelFormat.Rgba8, 100, 100, BitmapAlphaMode.Premultiplied);

        using (CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(canvasDevice, frameServerDest))
        {
            sender.CopyFrameToVideoSurface(canvasBitmap);

            softwareBitmapImg = await SoftwareBitmap.CreateCopyFromSurfaceAsync(canvasBitmap);

        }
        await ExtractText(softwareBitmapImg);
    });
}