I am using Image and MediaElement in wpf project, where I show Images and Videos from file system. I have few timers, which load files to Image/MediaElement controls. Everything works for 4-5 hours, but then MediaElement Video file freezes and MediaEnded event does not occur. I restart the application, it runs without any problem, but after some hours this problem occurs again.
My WPF XAML code:
<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# code:
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: {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 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;
}
I googled it and found that this was WPF graphic issue related to software rendering. The issue is solved by adding this piece of code into the ViewPageLoaded method.
try
{
var hwndSource = PresentationSource.FromVisual(this) as HwndSource;
var hwndTarget = hwndSource.CompositionTarget;
hwndTarget.RenderMode = RenderMode.SoftwareOnly;
}
catch (Exception ex)
{
Log.ErrorException(ex.Message, ex);
}
It helped me to solve the problem. Hope it will help you too.
Got the answer from here. Thanks to @detale for the solution
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With