(Note: All code has been severely simplified.)
Problem
MediaElement source not being set after Suspend/Resume. The CurrentState quickly changes to "Closed" after the source is set.
I am handling the MediaFailed event — it doesn't fire. I am also handling the MediaOpened event, which doesn't fire either.
Details
I have the following method which updates the MediaElement's Source. It works really well as long as the app is not trying to resume after having been Suspended.
private async void UpdateMediaElementSource(object sender, EventArgs e)
{
var videoSource = this.DefaultViewModel.CurrentSource; // a string
var file = await StorageFile.GetFileFromPathAsync(videoSource);
var videoStream = await file.OpenAsync(FileAccessMode.Read);
this.videoMediaElement.SetSource(videoStream, file.ContentType);
// The above line works many times as long as the app is not trying to Resume.
}
When the app is Suspended it calls the SaveState method:
protected async override void SaveState(Dictionary<String, Object> pageState)
{
pageState["MediaElementSource"] = this.DefaultViewModel.CurrentSource;
// I also made the videoStream global so I can dispose it — but no dice.
this.videoStream.Dispose();
this.videoStream = null;
}
When the app Resumes, it calls the LoadState method:
protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
string source = string.Empty;
if (pageState != null)
{
if (pageState.ContainsKey("MediaElementSource"))
{
source = (string)pageState["MediaElementSource"];
}
}
var document = PublicationService.GetDocument(this.currentDocumentIdNumber);
this.DefaultViewModel = new DocumentViewModel(document);
this.DefaultViewModel.CurrentMarkerSourceChanged += UpdateMediaElementSource;
if (!string.IsNullOrEmpty(source))
{
// This causes the UpdateMediaElementSource() method to run.
this.DefaultViewModel.CurrentSource = source;
}
}
I appreciate any help on this issue. Please let me know if you need more details.
So, it turns out that the mediaElement's Source was being set before it was added to the visual tree.
Usually, this is not an issue when doing this:
but it IS an issue when you do this:
Conclusion
Make sure that your MediaElement is part of the VisualTree when you call SetSource(...).
A simple way to get my above code to work is by adding a global bool that is set to true once the
mediaElement.Loaded
event has fired. Then, inside the code that callsSetSource()
, wrap that in anif(_mediaElementLoaded)
block.