Stream switching

Nov 18, 2013 at 2:57 AM
Are there plans to implement safe stream switching? I've seem to run into issues with trying to change the stream with out recreating the entire page again.
Coordinator
Nov 18, 2013 at 10:47 AM
It sounds like the cleanup isn't happening properly when you switch streams. That should (hopefully) be happening without needing to clobber the page.

Are you using code from HlsView or SamplePlayer?
Nov 18, 2013 at 1:13 PM
I've attempted using both.

With the SamplePlayer, I can get a stream to play. But, when I try to switch to a new stream (MediaPlayer.Close() => MediaPlayer.Source = new stream => MediaPlayer.Play()), the new stream does not play and I see errors in the output that appear to be the result of possibly a failed close?

With the HlsView, I can get a stream to play and switch streams once. But, when I try to switch the stream again, I run into the same issues as listed above. I'm being sure to close down the necessary objects like you do in the example but something isn't seeming to close properly.

Below is the juicy parts of the SamplePlayer method when trying to switch streams like described above.
BufferingManager.UpdateBuffering done buffering: 00:00:16.2252556 duration, 358494 size, 3976064 memory
PlaylistSegmentManager.CheckReload (11/18/2013 9:03:41 AM -05:00)
PlaylistSegmentManager.CheckReload (11/18/2013 9:03:41 AM -05:00)
'TaskHost.exe' (CLR C:\windows\system32\coreclr.dll: Silverlight AppDomain): Loaded 'C:\windows\system32\en-US\mscorlib.debug.resources.dll'. Module was built without symbols.
MediaElementWrapper.StartPlaybackAsync
An exception of type 'System.ObjectDisposedException' occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
PlaylistSegmentManager.CheckReload (11/18/2013 9:03:44 AM -05:00)
An exception of type 'System.ObjectDisposedException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
Command failed: Cannot access a disposed object.
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
An exception of type 'System.ObjectDisposedException' occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary
An exception of type 'System.ObjectDisposedException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
Command failed: Cannot access a disposed object.
TsMediaStreamSource.CloseMedia()
Media CloseMediaCalled: Playing -> Draining at 11/18/2013 9:03:46 AM -05:00
An exception of type 'System.InvalidOperationException' occurred in System.Windows.ni.dll and wasn't handled before a managed/native boundary
PlaylistSegmentManager.CheckReload (11/18/2013 9:03:46 AM -05:00)
An exception of type 'System.ArgumentException' occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary
TsMediaManager.CloseAsync: The tasks argument included a null value.
Parameter name: tasks
MediaElementWrapper.TsMediaManagerOnOnStateChange to Error: Close failed: The tasks argument included a null value.
Parameter name: tasks
PlaylistSegmentManager.CheckReload (11/18/2013 9:03:48 AM -05:00)
PlaylistSegmentManager.CheckReload (11/18/2013 9:03:50 AM -05:00)
PlaylistSegmentManager.PlaylistExpiration (11/18/2013 9:03:52 AM -05:00)
PlaylistSegmentManager.PlaylistExpiration is starting ReadSubList (11/18/2013 9:03:52 AM -05:00)
Below here is the juicy parts of the output showing where the HlsView method is failing. The interesting part of this output is it showing the Error 3110. Not sure what error message that is but, I'm hoping you can help me out.
MediaElement State: Playing
Playing
Media MediaStreamSourceAssigned: Idle -> Assigned at 11/18/2013 9:08:58 AM -05:00
MediaElement State: Opening
Opening
TsMediaStreamSource.OpenMediaAsync()
Media OpenMediaAsyncCalled: Assigned -> Opening at 11/18/2013 9:08:58 AM -05:00
MediaElement State: Opening
Opening
MediaElement State: Opening
Opening
Create PES Video stream (AVC video stream conforming to one or more profiles defined in Annex A of ITU-T Rec. H.264 | ISO/IEC 14496-10 or AVC video sub-bitstream as defined in 2.1.78) with PID 256
Create PES Audio stream (ISO/IEC 13818-7 Audio with ADTS transport syntax) with PID 257
Configuration H.264 "Baseline" profile, level 3.1 1280x720
MediParser.CreatePacketHandler: Sync to start position 00:00:00 at 02:04:38.7565556
BufferingManager.UpdateBuffering: 0.77%, 00:00:00 duration, 64414 size, 6763256 memory
Configuration AAC layer 0 profile "AAC LC (Low Complexity), 44.1kHz 2 channels" channels 2 sampling 44.1kHz length 407 CRC False
MediParser.CreatePacketHandler: Sync to start position 00:00:00 at 02:04:38.7758778
TsMediaStreamSource: ReportOpenMediaCompleted (2 streams)
TsMediaStreamSource: ReportOpenMediaCompleted CanSeek = False
MediaElement State: Opening
Media CallingReportOpenMediaCompletedLive: Opening -> Playing at 11/18/2013 9:09:00 AM -05:00
Opening
TsMediaStreamSource.CloseMedia()
Media CloseMediaCalled: Playing -> Draining at 11/18/2013 9:09:00 AM -05:00
Media Failed: 3110 An error has occurred.
TsMediaStreamSource.Dispose()
ValidateEvent Invalid state transition: state Draining event DisposeCalled
The thread 0x980 has exited with code 259 (0x103).
MediaElement State: Closed
Closed
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in SM.Media.DLL and wasn't handled before a managed/native boundary
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
BufferingQueue.ReportFlush(): Video
BufferingManager.UpdateBuffering: 2.92%, 00:00:00.5108333 duration, 10450 size, 7148296 memory
BufferingQueue.ReportFlush(): Audio
BufferingManager.UpdateBuffering done buffering: 10675199.02:48:05.4775807 duration, 0 size, 7148296 memory
An exception of type 'System.Threading.Tasks.TaskCanceledException' occurred in Microsoft.Threading.Tasks.DLL and wasn't handled before a managed/native boundary
MediaElement State: Closed
An exception of type 'System.ObjectDisposedException' occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary
Closed
If at all possible and for my codes sake, I prefer to be able to use the SamplePlayer method. If that isn't possible, then if you could help me understand why the HlsVIew method isn't working, then that would suffice. Either way, thanks for the help.

-Ryan
Coordinator
Nov 18, 2013 at 5:51 PM
I should be able to take a closer look in a day or so, but off the top of my head, MediaPlayer.Close() only starts shutting things down. The code may need to wait for it to finish shutting down before continuing. Take a look at what HlsView does in its navigation handler. This is from memory and not from looking at the code, so I apologize if I'm spewing nonsense.
Nov 20, 2013 at 9:15 AM
Any news about this issue?
Coordinator
Nov 21, 2013 at 11:51 AM
I'm looking at it now. I've set up a timer to automatically swap streams every 25 seconds and I can confirm that this is a problem. Hopefully, it will not be too difficult to fix.
Nov 21, 2013 at 6:37 PM
Edited Nov 21, 2013 at 6:38 PM
I actually managed to get this working correctly for me.

My cleanup method that was used before ever switch looked like this:
if (null != _tsMediaManager)
     _tsMediaManager.Close();

if (null != _playlist)
     await _playlist.StopAsync();

if (null != _mediaElementManager)
     await _mediaElementManager.Close();
Waiting for everything to close seemed to make this work properly.

If this is in the same thread as the new video stream getting started, it should wait for the old to clean out before the new tries to get started.

Does this help?
Coordinator
Nov 21, 2013 at 8:35 PM
That looks reasonable.

Setting the Source property should always be a safe thing to do. I'll hopefully be able to check in some fixes this weekend to get things to that point. My stream swapping test setup has turned up a couple of other close/shutdown problems that I'm going through and fixing.
Coordinator
Dec 4, 2013 at 7:29 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.