This project has moved. For the latest updates, please go here.

Correct way of disposing the MediaElement

Apr 28, 2014 at 9:12 AM
Hi,


First of all thanks for the effort.


I am able to get everything work on WP 8.0 SDK. Now when user press the back button and my Page is navigating back, the media player is not destroyed properly, so I hooked my own OnBackKeyPress and used the following line of code to dispose Media Element.
this.mediaElement.Stop();
this.mediaElement.Dispose();
this works sometimes, and Most of the time it hangs.

Log
MediaElementWrapper.Stop()
MediaElementWrapper.Cleanup()
MediaElementWrapper.Close()
TsMediaStreamSource.CloseMedia()
Media CloseMediaCalled: Playing -> Draining at 4/28/2014 1:02:21 PM +04:00
TsMediaStreamSource.CloseMediaHandler()
TsMediaManager.CloseMedia()
TsMediaManager.CloseAsync()
MediaStreamFascadeBase.Stop()
MediaStreamFascadeBase.CloseAsync()
MediaStreamFascadeBase.CloseMediaAsync()
TsMediaManager.CloseAsync()
MediaStreamFascadeBase.MediaManagerOnStateChange() to Closing: 
The thread 0x9b4 has exited with code 259 (0x103).
The thread 0x1318 has exited with code 259 (0x103).
The thread 0xaac has exited with code 259 (0x103).
The thread 0xbf4 has exited with code 259 (0x103).
The thread 0x17b4 has exited with code 259 (0x103).
for better understanding the xaml looks like this
           <mmppf:MediaPlayer Name="mediaElement">
                <mmppf:MediaPlayer.Plugins>
                    <smmedia:StreamingMediaPlugin />
                </mmppf:MediaPlayer.Plugins>
            </mmppf:MediaPlayer>
and code behind to play the file is this
this.mediaElement.Source = new Uri(mediaURL, UriKind.Absolute);
Apr 28, 2014 at 9:13 AM
Device is Lumia 920
Coordinator
Apr 28, 2014 at 9:43 AM
Which download or version of the code are you using?

You might try setting mediaElement.Source to null instead of calling mediaElement.Stop(). The latter is like a pause together with a seek to the beginning.

When mucking with this manually (e.g., in HlsView), I used the OnNavigatedFrom event.
May 21, 2014 at 12:32 AM
Hi! I also encountered this on a Win 8.1 project on Visual Studio Express 2013. It hangs on the following line in the CleanupMediaStream() function:
 _mediaStreamFascade.DisposeSafe(); 
I commented it out and it didn't hang anymore though I'm not sure how significant this call is for destroying it properly. Any thoughts?
Coordinator
May 21, 2014 at 4:03 AM
Which version of phonesm are you using?

Do you have a way of getting it to hang that way reliably? I've seen sporadic hangs on shutdown since a1400cfefa74 ("Get rid of IMediaElementManager."), but they never seem to happen when I'm actually looking for them.

I'm planning on rearranging much of the back end code both to deal with the overcomplicated startup/shutdown stuff (which I think is the cause of your problem) and to propagate much needed information from the back end (e.g., "there is an #EXT-X-DISCONTINUTITY here"). That should also simplify implementing things like changing the bandwidth during playback.
Coordinator
May 21, 2014 at 4:15 AM
jinjereu wrote:
I commented it out and it didn't hang anymore though I'm not sure how significant this call is for destroying it properly. Any thoughts?
Not doing the dispose may cause network connections to hang around a bit longer. If playing a dynamic playlist, then the task that updates the playlist may keep running. Nothing that should be too damaging unless playing hundreds of separate streams. As a work around, you might want to consider using the DisposeBackground() extension method instead of commenting out the DisposeSafe() extension method. At worst, it will hang, more likely, it will clean up as much as it can. Come to think of it, you may want to use something like this (completely untested code) with a timeout of, say, one second:
public static async Task<bool> DisposeTimeout(this IDisposable disposable, TimeSpan timeout, CancellationToken cancellationToken, string description)
{
    var task = disposable.DisposeAsync();

    await Task.WhenAny(Task.Delay(timeout, cancellationToken), task).ConfigureAwait(false);

    if (task.IsCompleted)
        return true;

    TaskCollector.Default.Add(task, description);

    return true;
}