为啥 MediaElement 有时会默默地失败,我该如何纠正它?

Posted

技术标签:

【中文标题】为啥 MediaElement 有时会默默地失败,我该如何纠正它?【英文标题】:Why does MediaElement sometimes silently fail and how can I correct it?为什么 MediaElement 有时会默默地失败,我该如何纠正它? 【发布时间】:2014-08-11 17:31:13 【问题描述】:

在我的 WPF 项目中,我创建了一个视图,其中包含多个播放视频的 MediaElement。有时,一个或所有 MediaElement 之间的任何位置都无法播放分配给它们的视频,而是显示一个黑色矩形,或者根本不出现。发生这种情况时不会发生 MediaFailed 事件。 MediaOpened 事件确实会在所有 MediaElement 上引发,即使它们不播放视频也是如此。

我已为我的显卡安装了最新的驱动程序,但对这个问题没有任何影响。

是否有我可以使用的程序来确保每个 MediaElement 始终如一地播放?

示例源代码如下。包含视频文件的完整示例项目位于 github 上 https://github.com/duggulous/MediaElementIssueExample

MainWindow.xaml

<Window x:Class="VideoDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="1920" Width="1080">
<Grid Name="rootContainer" Background="Pink">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="404" />
            <ColumnDefinition Width="136" />
            <ColumnDefinition Width="136" />
            <ColumnDefinition Width="134" />
            <ColumnDefinition Width="270" />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="270" />
            <RowDefinition Height="30" />
            <RowDefinition Height="412" />
            <RowDefinition Height="416"/>
            <RowDefinition Height="526"/>
            <RowDefinition Height="264"/>
        </Grid.RowDefinitions>

    <MediaElement x:Name="panel1" Margin="-1" 
                Grid.Column="0" Grid.Row="0"
                Grid.ColumnSpan="2" Grid.RowSpan="2" 
                Source="media/1-ekg.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel2" Margin="-1"
                Grid.Column="2" Grid.Row="0" 
                Grid.ColumnSpan="3" Grid.RowSpan="1"
                Source="media/2-star.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel3" Margin="-1"
                Grid.Column="0" Grid.Row="2" 
                Grid.ColumnSpan="2" Grid.RowSpan="1"
                Source="media/3-verticalLines.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel4"  Margin="-1"
                Grid.Column="2" Grid.Row="1" 
                Grid.ColumnSpan="2" Grid.RowSpan="2"
                Source="media/4-horizLines.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel5"  Margin="-1"
                Grid.Column="4" Grid.Row="1" 
                Grid.ColumnSpan="1" Grid.RowSpan="2"
                Source="media/5-curvedLines.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel6" Margin="-1"
                Grid.Column="0" Grid.Row="3" 
                Grid.ColumnSpan="1" Grid.RowSpan="1"
                Source="media/6-glassCircles.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel7" Margin="-1"
                Grid.Column="1" Grid.Row="3" 
                Grid.ColumnSpan="2" Grid.RowSpan="1" 
                Source="media/7-diagZigZag.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel8"  Margin="-1"
                Grid.Column="3" Grid.Row="3" 
                Grid.ColumnSpan="2" Grid.RowSpan="1"
                Source="media/8-glassBurst.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel9"  Margin="-1"
                Grid.Column="0" Grid.Row="4" 
                Grid.ColumnSpan="1" Grid.RowSpan="2"
                Source="media/9-wavyLines.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel10"  Margin="-1"
                Grid.Column="1" Grid.Row="4" 
                Grid.ColumnSpan="4" Grid.RowSpan="1"
                Source="media/10-circle.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>

    <MediaElement x:Name="panel11"  Margin="-1"
                Grid.Column="1" Grid.Row="5" 
                Grid.ColumnSpan="4" Grid.RowSpan="1"
                Source="media/11-wavyShape.mp4"
                MediaOpened="panel1_MediaOpened"
                MediaFailed="panel1_MediaFailed"
                MediaEnded="panel1_MediaEnded"/>
</Grid>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace VideoDemo

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    
        public MainWindow()
        
            InitializeComponent();
        

        private void panel1_MediaOpened(object sender, RoutedEventArgs e)
        
            Console.WriteLine("Opened: "+((MediaElement)sender).Source);
        

        private void panel1_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        
            Console.WriteLine("Failed:"+((MediaElement)sender).Source);
        

        private void panel1_MediaEnded(object sender, RoutedEventArgs e)
        
            Console.WriteLine("Ended:"+((MediaElement)sender).Source);
        
    

【问题讨论】:

您的代码在我的 I3、4GB、intel 4600 显卡上运行良好。没有失败的理由。 这并不能完全回答问题,但供将来参考:当我从使用 H.264 mp4 切换到 wmv 格式的视频时,我不再遇到此问题。 【参考方案1】:

MediaElement 使用EVR,而后者又使用 Direct3D。 EVR 是一种有限资源,您在每个 MediaElement 中使用一个实例,并且偶尔播放会达到限制。不幸的是,该问题在 API 内部的某处被抑制,并且没有发生合理的错误报告。

您可以使用此答案中引用的工具估计播放实例的数量:Black video using multiple instances VMR 9(那里也有 EVR 选项)。

【讨论】:

附言。也许不是您所期望的,但我们拥有我们所拥有的。当您启动多个演示应用程序时,该问题很容易重现。尽管前几个实例可能有效,但偶尔下一个实例会停止,而您所描述的症状没有任何原因。 我不知道,我无法在引用的答案中使用该工具重现黑屏,即使我创建了更多在我的应用程序中使用的实例。 使用您需要使用 EVR 选项的工具。您将很快以高分辨率达到极限,尤其是。具有多显示器配置。该工具很可能会显示错误代码,而 MediaElelement 将静默失败并且不显示视频。无论如何,这很可能是后端的相同问题,并且硬件资源不足。

以上是关于为啥 MediaElement 有时会默默地失败,我该如何纠正它?的主要内容,如果未能解决你的问题,请参考以下文章

为啥网站需要引用标头(并且默默地失败)?

为啥有时小吃店会失败

为啥有时 Directory.CreateDirectory 会失败?

为啥`git stash -p`有时会失败?

为啥我的下载有时会使用 flutter_downloader 失败?

为啥在方法中使用 require_once 有时会失败?