0

我用一个MainPage创建了一个简单的测试 UWP 应用程序,它有MediaPlayer

public sealed partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
        Loaded += MainPage_Loaded;
    }

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var mediaPlayer = new MediaPlayer
        {
            Source = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/preview.mp4")),
            AutoPlay = true
        };
        mediaPlayer.AddVideoEffect(typeof(VideoEffect).FullName, true, null);
    }
}

和带有IBasicVideoEffect继承类的WinRT 组件,它通知我处理了多少帧:

public sealed class VideoEffect : IBasicVideoEffect
{
    public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties => new List<VideoEncodingProperties>();

    public bool IsReadOnly => false;

    public MediaMemoryTypes SupportedMemoryTypes => MediaMemoryTypes.Gpu;

    public void SetProperties(IPropertySet configuration) { }

    public bool TimeIndependent => false;

    public void Close(MediaEffectClosedReason reason) { }

    public void DiscardQueuedFrames() { }

    private int _frameCounter;

    public void ProcessFrame(ProcessVideoFrameContext context)
    {
        _frameCounter++;
        Debug.WriteLine("Frame #" + _frameCounter);
    }

    public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
    {
        Debug.WriteLine("SetEncodingProperties");
    }
}

如果我运行它 - 无论视频文件是什么,都只会处理 3 帧。

如果我在_frameCounter递增的位置设置断点,我将设法击中 F5 8 帧。

为什么以及如何处理所有帧?

正如许多示例所说,我可以使用MediaClipMediaComposition来解决它,但在这种情况下,帧是由 CPU 而不是 GPU 视频引擎处理的,这不是我的目标。

4

2 回答 2

1

这里的问题是您正在播放MediaPlayer而没有在 XAML 中显示它。所以只处理了前几帧,因为媒体没有在 UI 上渲染,不需要处理其他帧。

为了使您的VideoEffect工作,您可以使用带有MediaPlayerElement.SetMediaPlayer方法的MediaPlayerElement控件来呈现媒体。

XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <MediaPlayerElement x:Name="mediaPlayerElement" />
</Grid>

代码隐藏:

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var mediaPlayer = new MediaPlayer
    {
        Source = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/preview.mp4")),
        AutoPlay = true
    };
    mediaPlayer.AddVideoEffect(typeof(VideoEffect).FullName, true, null);

    mediaPlayerElement.SetMediaPlayer(mediaPlayer);
}

在此之后,您将_frameCounter在媒体播放时看到增加。

于 2017-01-16T14:56:42.867 回答
0

使用 MediaPlayer,您必须在设置源之前添加效果。

effect.AddVideoEffect(_player);
_player.Source = MediaSource.CreateFromMediaStreamSource(source);
于 2020-05-21T08:18:47.920 回答