c# – WPF MediaElement视频冻结

我在wpf项目中使用 Image和MediaElement,我在文件系统中显示图像和视频.我有几个定时器,它们将文件加载到Image / MediaElement控件.一切都工作4-5小时,但MediaElement视频文件冻结,MediaEnded事件不会发生.我重新启动应用程序,它运行没有任何问题,但几个小时后,这个问题再次出现.

我的WPF XAML代码

<Grid Name="MainGrid">
    <Image HorizontalAlignment="Center" VerticalAlignment="Center" Name="MainImage" Stretch="Fill" />
    <MediaElement MediaEnded="MediaEnded" MediaOpened="MediaOpened" LoadedBehavior="Manual" HorizontalAlignment="Center" Name="VideoControl" VerticalAlignment="Center"  
                   Stretch="Fill" UnloadedBehavior="Manual"/>
</Grid>

C#代码

public partial class ImageView
{
    private static readonly Logger Log = LogManager.GetCurrentClassLogger();
    private static String _advCheckGuid;
    private List<String> _FolderNames;
    private int _FolderIndex = 0;
    private MainWindow _MainWindow;
    private List<String> _PathList;
    private List<String> _CheckPathList; 
    private int _Index;
    private BitmapImage _BitmapImage;
    private volatile bool _Running = true;
    private Backend _Backend;
    private ApplicationDeployment _UpdateCheck;

    // Threads
    private Timer _ImageTimer;
    private Timer _UpdateTimer;
    private Timer _FolderClearTimer;
    private Timer _CheckApplicationUpdateTimer;
    private Thread _TerminationThread;


    public ImageView()
    {
        InitializeComponent();
        _PathList = new List<string>();
        _CheckPathList = new List<string>();
        _Index = 0;

    }

    private void ViewPageLoaded(Object sender,EventArgs e)
    {

        _FolderNames = new List<string> { Constants.AdsFolderFirst,Constants.AdsFolderSecond };

        _Backend = new Backend();



        _MainWindow = (MainWindow)Window.Getwindow(this);


        _ImageTimer = new Timer(Constants.DefaultimageTimer);
        _ImageTimer.Elapsed += ChangeImageSource;
        _ImageTimer.Start();


    }


    private void ChangeImageSource(object sender,System.Timers.ElapsedEventArgs e)
    {
        Application.Current.dispatcher.Invoke(
            dispatcherPriority.normal,new Action(
                  delegate()
                  {
                      try
                      {
                          if (MainImage != null && MainImage.source != null)
                          {
                              MainImage.source = null;
                          }

                          if (VideoControl != null && VideoControl.source != null)
                          {
                              VideoControl.Stop();
                              VideoControl.source = null;
                          }

                          if (_Index >= _PathList.Count)
                          {
                              _Index = 0;
                          }

                          if (_PathList.ElementAt(_Index) != null)
                          {

                              Log.Info(String.Format("Start [ChangeImageSource]. Element: {0},Index: {1}",_PathList.ElementAt(_Index),_Index));

                              try
                              {
                                  _ImageTimer.Stop();

                                  String[] checkExt = _PathList.ElementAt(_Index).Split('.');
                                  String ext = checkExt[checkExt.Length - 1];

                                  if (ext.Equals("jpg",StringComparison.CurrentCultureIgnoreCase) ||
                                      ext.Equals("jpeg",StringComparison.CurrentCultureIgnoreCase) ||
                                      ext.Equals("png",StringComparison.CurrentCultureIgnoreCase))
                                  {
                                      _ImageTimer.Interval = Constants.normalImageTimer;
                                      ShowImage(_PathList.ElementAt(_Index));
                                  }

                                  else if (ext.Equals("mp4",StringComparison.CurrentCultureIgnoreCase) ||
                                           ext.Equals("3gp",StringComparison.CurrentCultureIgnoreCase))
                                  {
                                      _ImageTimer.Interval = Constants.VideoDefaultTimer;
                                      PlayQueue(_PathList.ElementAt(_Index));
                                  }

                                  _ImageTimer.Start();
                                  _Index++;
                              }
                              catch (Exception exception)
                              {
                                  Log.ErrorException(exception.Message,exception);
                              }
                          }
                      }
                      catch (Exception exception)
                      {
                          Log.ErrorException(exception.Message,exception);
                      }
                  }));
    }


    private void ShowImage(String fileName)
    {
        try
        {
            if (!String.IsNullOrEmpty(fileName))
            {

                _BitmapImage = LoadImage(fileName);
                MainImage.source = _BitmapImage;

            }
        }
        catch (Exception e)
        {
            Log.ErrorException(e.Message,e);
        }
    }


    private void PlayQueue(String fileName)
    {

        try
        {
            if (!String.IsNullOrEmpty(fileName))
            {
                VideoControl.LoadedBehavior = MediaState.Play;
                VideoControl.source = new Uri(fileName,UriKind.Absolute);
            }
        }
        catch (Exception e)
        {
            Log.ErrorException(e.Message,e);
        }

    }



    private void MediaEnded(object sender,EventArgs e)
    {
        try
        {
            if (MainImage != null && MainImage.source != null)
            {
                MainImage.source = null;
            }

            if (VideoControl != null && VideoControl.source != null)
            {
                VideoControl.Stop();
                VideoControl.source = null;
            }

            if (_Index >= _PathList.Count)
            {
                _Index = 0;
            }

            if (_PathList.ElementAt(_Index) != null)
            {

                Log.Info(String.Format("Start [MediaEnded oper]. Element: {0},_Index));

                try
                {
                    _ImageTimer.Stop();

                    String[] checkExt = _PathList.ElementAt(_Index).Split('.');
                    String ext = checkExt[checkExt.Length - 1];

                    if (ext.Equals("jpg",StringComparison.CurrentCultureIgnoreCase) ||
                        ext.Equals("jpeg",StringComparison.CurrentCultureIgnoreCase) ||
                        ext.Equals("png",StringComparison.CurrentCultureIgnoreCase))
                    {
                        _ImageTimer.Interval = Constants.normalImageTimer;
                        ShowImage(_PathList.ElementAt(_Index));
                    }

                    else if (ext.Equals("mp4",StringComparison.CurrentCultureIgnoreCase) ||
                             ext.Equals("3gp",StringComparison.CurrentCultureIgnoreCase))
                    {
                        _ImageTimer.Interval = Constants.VideoDefaultTimer;
                        PlayQueue(_PathList.ElementAt(_Index));
                    }

                    _ImageTimer.Start();
                    _Index++;
                }
                catch (Exception exception)
                {
                    Log.ErrorException(exception.Message,exception);
                }
            }
        }
        catch (Exception exception)
        {
            Log.ErrorException(exception.Message,exception);
        }

    }



    private void MediaOpened(object sender,EventArgs e)
    {

    }



    private BitmapImage LoadImage(string myImageFile)
    {
        BitmapImage myRetVal = null;

        if (!String.IsNullOrEmpty(myImageFile))
        {
            var image = new BitmapImage();
            try
            {
                using (FileStream stream = File.OpenRead(myImageFile))
                {
                    image.BeginInit();
                    image.CacheOption = BitmapCacheOption.OnLoad;
                    image.StreamSource = stream;
                    image.EndInit();
                }
            }
            catch (Exception exception)
            {
                Log.ErrorException(exception.Message,exception);
            }

            myRetVal = image;
        }

        return myRetVal;
    }

解决方法

我用Google搜索,发现这是与软件渲染相关的WPF图形问题.通过将这段代码添加到ViewPageLoaded方法中来解决该问题.
try
        {
            var hwndSource = PresentationSource.FromVisual(this) as HwndSource;
            var hwndTarget = hwndSource.CompositionTarget;
            hwndTarget.RenderMode = RenderMode.softwareOnly;
        }
        catch (Exception ex)
        {
            Log.ErrorException(ex.Message,ex);
        }

它帮助我解决了这个问题.希望它也会对你有所帮助.

得到了here的答案.感谢@detale的解决方

相关文章

原文地址:http://msdn.microsoft.com/en-us/magazine/cc163...
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采...
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下...
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Mic...
c语言输入成绩怎么判断等级
字符型数据在内存中的存储形式是什么