Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does MediaElement sometimes silently fail and how can I correct it?

In my WPF project I have created a view that includes several MediaElements playing videos. Sometimes, anywhere between one or all of the MediaElements will fail to play the video assigned to them, and will instead show a black rectangle, or not appear at all. The MediaFailed event does not occur when this happens. The MediaOpened event DOES get raised on all the MediaElements, even when they do not play the video.

I have installed the latest drivers for my graphics card and that has had no effect on this issue.

Is there a procedure I can use to ensure that every MediaElement consistently plays?

Example source code is below. A full example project including video files is on github at 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);
        }
    }
}
like image 987
duggulous Avatar asked Oct 01 '22 02:10

duggulous


1 Answers

MediaElement uses EVR, which in turn uses Direct3D. EVR is a limited resource, which you are using an instance per MediaElement, and once in a while the playback hits the limit. Unfortunately, the problem is suppressed somewhere inside the API and no reasonable error reporting takes place.

You can estimate the number of playback instances using a tool referenced in this answer: Black video using multiple instances VMR 9 (there is EVR option there as well).

like image 80
Roman R. Avatar answered Oct 25 '22 08:10

Roman R.