WPF mediaElement disappearing after some time - c#

I have a user control with a WPF MediaElement and an Image control. This user control is again used in a few more user control which uses this in two differnt layouts. The application is supposed to show a list of videos and images for a long period of time in loops. Each user control will be loaded for a particular time period and after that time, this will be unloaded and the next control will be loaded. When the videos are running every now and then the position of the video is changed to show a particular part of the video.
XAML Code. The MediaElement is inside a Grid with one column and one row.
<MediaElement Volume="0" Name="m1" Stretch="Fill" Visibility="Hidden" LoadedBehavior="Manual" UnloadedBehavior="Manual" />
C# Code, setting source
this.mediaElement.Source = item.Path;
this.mediaElement.Position = new TimeSpan(0, 0, 0);
this.mediaElement.Play();
C# Code changing position. This position change is done using a DispatcherTimer
t = TimeSpan.FromMilliseconds(Position);
mediaElement.Position = t;
C# Code disposing the MediaElement. I use this code to dispose the MediaElement because previously I found out after playing for a while the MediaElement was using too much memory and becomes frozen after a while.. The below code fixed that issue.
mediaElement.Close();
mediaElement = null;
GC.Collect();
GC.WaitForPendingFinalizers();
The application works fine, but the problem is after some time (like 20 mins) the WPF MediaElement disappears. The application works smoothly (It doesn't get frozen), the images are shown, but the MediaElement is gone.
When this problem occurred, I did some debugging and found these.
The WPF MediaElement visibility is Visible. The Source has correct filenames. The MediaElement is not hidden behind any other controls.
However the actual width and actual height are shown as 0.
I checked all the code to find out where the height and width becomes zero. But could not find any. So I decided to try and override the Height and Width evey millisecond using a DispatcherTimer (Just to check if it was possible). But even then the 0 in actual height and width remained the same.
Also, the application doesn't seem to use excessive memory and everything else seems to be fine.
Does anyone got a clue as to why this is happening? Any solutions or workarounds? Thanks

Related

WPF Effect prevent texture reloading

I currently have an application which displays Images in a grid. Each image has an effect. When the user moves the mouse while clicked, some input parameters for the effect are changed, leading to a different display of the image. However when I have about 8 or more images displayed, and each image is changed simultaneously, I experience a large drop in FPS.
Using the Perforator tool, I noticed that the HW IRTs get very large (32 per frame for 8 images). The amount of HW IRTs is proportional to the amount of images displayed. So it seems that for each frame change, the Image texture is loaded again and again to the GPU, although the actual texture never changes.
Is there a way to disable this behaviour? RenderOptions.CachingHint sounded like a candidate for this, but it does not have any effect when I set it on the Image.

UI Scaling/Settings

I've been working on a UWP application that will initially be deployed only to Surface Pro 4 (Maybe some SP3s) devices but I'm having a real difficult time getting my UI to fit on the screen.
Right now my Designer window is set to '12" Tablet (2160 x 1440) 150% Scale' with it locked in landscape mode (the only way this app will be used) so that the 'Effective: 1440 x 960' resolution is set.
I've got my MainPage page set to 960 x 1440 with a Frame for display content essentially filling the entire 960 x 1440 but when I run the app (either in full screen or windowed) it cuts off the content of my MainPage (not just the frame content but part of my app sidebar menu).
That all being said my question(s): How do I get my UWP to scale my content to fit inside what ever size window the app is displayed in when running (full screen or user adjusted window size), OR what settings do I need/How do I configure it to display my entire MainPage contents on my SP4 screen (2736 x 1824) in fullscreen without just trial/error adjusting elements manually until they fit.
I'm more concerned with the second question because I don't just want this app to do what I want (because I know I can figure it out myself by manually sizing elements) but I want to understand why it's doing what it's doing and the right way to go about doing what I want to do.
I did a lot of searching but could not find the answer to my question, if this is a duplicate please feel free to link the answer.
Thanks in advance.
The Designer just gives you a general guide on how things would look. The demensions are not for SP4 specifically.
At 150% DPI, try setting your MainPage to 1824, 1216.
You can call
ApplicationView.GetForCurrentView().VisibleBounds
at runtime to find how many pixels(epx) that your screen is currently set to.
Note that these are effective pixels. They are different from the physical pixels of the device. All UWP UI measurements are epx based. So when you see this -
<Button Width="24" />
You should know that the value 24 is measured in epx.
To find out what epx really is, give this a read.

Sound disabled after changing background image

I have an issue with sound being disabled after changing a background image.
Basically, what I have is a PanoramaItem. In that Item I have placed 1 big image as the background image (lets say a flag). On that flag I have several buttons that will change the button image on press (XAML Code created in Blend) and will also play a sound. (using Click Event Handler Sound.Play();)
All works fine, as long as the image is preloaded (. Layout-Image is in the back and buttons are on top/front.
However, I have now also added a button that enables the user to change the image to something from their own library, using the PhotoChooserTask. The problem now is that, yes the image gets replaced by the one the user selects but the buttons are not playing any sound anymore. The Button image still changes though, when pressed and released, which means the button is still active/enabled yet the sound is either disabled or the click even handler is no longer working.
Would you have an idea as to why that is? I played around with it all night last night and couldn't figure it out.
Any help is greatly appreciated :-)
EDIT:
Here is the code that I am using to load the picture:
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
BackGroundIMG.Source = bmp;
}
}
My XAML Code for the Picture is:
<Image Name="BackGroundIMG" Source="/Assets/Test.jpg" Grid.RowSpan ="3" Grid.ColumnSpan = "3"/>
XAML Code for MediaSound is:
<MediaElement x:Name="Theme" Source="/Assets/Theme.wav" Volume="1" Autoplay="False"/>
XAML Code for the Button is:
<Button Name="Button1" Click="Button1_Click" Grid.Row="1" Grid.Column ="1"/>
Image and Button are in the same Grid. under Layout I have set the BackGroundImage to "Sent to Back" and the Button is on top of it.
C# for playing Sound:
private void Button1_Click (object sender, RoutedEventargs e)
{Theme.Play();}
So again, the sound plays fine when I start the App and just press the button but no sound will be played once I change the background image.
So my guess is, that the picture is not loaded correctly, but I am not sure how to test/change that.
I think the issue is not exactly with changing the image but with the opening of the PhotoChooserTask. I suspect if you used any of the built-in launchers and choosers the audio would cut out as well. http://msdn.microsoft.com/en-us/library/windowsphone/develop/microsoft.phone.tasks(v=vs.105).aspx
For a MediaElement to work it has to be part of the visual tree, otherwise it will stop playing. When these chooser tasks open they are navigating away from the current page. I think if you use a global MediaElement in your App.Xaml instead you could get around this behaviour. This post has a method of creating a global media element: Global MediaElement that continues playing after navigating to other page

Scrolling marquee control fails to scroll with MediaClock set on another control

I am creating an application which shows full screen videos with a scrolling text ticker at the bottom.
I'm using the MediaElement control to display the videos and playlisting several together, setting a play duration.
I'm setting each media duration as follows:
var timeline = new MediaTimeline(_playlist.PlaylistItems[_playlistPlayPosition].LocalMediaFile);
timeline.Duration = _playlist.PlaylistItems[_playlistPlayPosition].Duration;
MediaViewPort.Clock = timeline.CreateClock(false) as MediaClock; //THIS CAUSES AN ISSUE!
if (MediaViewPort.Clock != null)
{
MediaViewPort.Clock.Completed += Clock_Completed;
MediaViewPort.Clock.CurrentTimeInvalidated += Clock_CurrentTimeInvalidated;
}
This all works perfectly fine.
I found an excellent scrolling marquee control (http://koderhack.blogspot.co.uk/2011/05/content-ticker-control-in-wpf.html) which I dropped in as is. The control does not scroll.
I commented out the line
MediaViewPort.Clock = timeline.CreateClock(false) as MediaClock;
and the control started to scroll, however now my media doesn't have a duration set any more.
The control code itself is too big to post on here, I anyone would like to help it is on the URL above.
I fail to see what the Clock on my MediaElement control would have this effect on a separate control. Can anyone advise? I would prefer not to start setting timers to monitor media duration...
got around the issue by launching the control in a separate chromeless window on a new thread.

WPF ProgressBar loses its glow when it updates too quickly - bug?

Ok, so I found some rather weird behaviour while messing around with the WPF ProgressBar control. This control is located in a column of a ListView control and the general situation differs little from this question & answer in its essence.
I bind Progressbar to a class by means of several properties (Min, Max, Value), all OneWay Bindings obviously. This other class is updated from another thread and regularly uses the INotifyPropertyChanged interface to let the ProgressBar know the status is progressing. And this all works just great!
But here is where it gets odd. My ProgressBar loses its glow.. right upto the moment it reaches the Max (=100%) value. Then it suddenly starts pulsing its white glowy stuff all over the green bar, and this is very annoying. I am showing progress with a reason, and the lack of a pulse is actually pretty distracting once you start to notice it not being there.
Thus, I set off to debug. I found that with Thread.Sleep(1000) in my threads processing, it still hid the glow, but if I bump it to Thread.Sleep(1500) the glow comes back at all times with a crazy vigour. After that, I tried translating my progress units to smaller numbers so the integer values would take longer to change. Min 0, Max 100 still has the lack of the glow. Min 0, Max 10 had the glow come back in its full vigor. In all cases, it is the same amount of work and time spent to reach 100%, but it is a very visible binary YES/NO effect with regards to the glow showing. The only thing I have not tested is whether it also happens when the ProgressBar is not placed inside of this ListView control.
I know myself well enough that I can't make sense of the deep WPF innards of the (XAML involved with the) ProgressBar control. So I was hoping anyone here knows whether this is a known bug, something they stumbled into, or something they might even know how to work around/fix.
My machine runs Windows 7, and I'm developing in VS2010 targeting .NET Framework 4 Client Profile.
I would take a guess and say that you lose the glow because you are updating your progress bar to often. Every time you set a new value the progress bar restarts its glowing animation (I think - I haven't tested this, I'm writing off the top of my head).
It seems that you have perhaps thought of the same thing and tried to work around it, but I'm not sure you have fully exhausted all possibilities:
Try creating a check that if (progressbar.Value == newValue) don't do progressbar.Value = newValue;
Progressbar should be using Decimals for Min, Max, Value. Make sure you don't do updates for every decimal point, eg. - 10,1; 10,2; 10,3; etc... (use progressbar.Value = (int)newValue;)
Try setting the progressbar value in bigger increments, instead of increment = 1, use increment = 10;
You could try taking a progressbar outside of ListView, maybe there is a rendering bug with progressbar being inside it.
PS! If you update your progressbar very rapidly, then it is OK for the glow animation not to run. Remember that the glow animiation's purpose is only to show that the application is still running (machine hasn't frozen), despite the fact that the progress(bar) hasn't moved.
If the progress is moving quickly, then that on its own is a visual effect for the user, so there is no need to have the glow animation at that moment...

Categories