If a new stream is assigned to MediaPlayer's Source property while a stream is playing, then the MediaLoaded args will return a deferral with a cancelled cancellation token.
The first thing that MediaPlayer's OnMediaLoadingAsync() does is to check if "IsMediaLoaded" is true, which it is, so OnMediaClosed() gets called. The cancellation token source is then cancelled and the "cts" field gets a "new CancellationTokenSource()".
Since both MediaLoadingEventArgs and MediaPlayerDeferrableOperation were created before the "cts" field was updated, MediaPlayerDeferrableOperation.cts will be the old CancellationTokenSource instance that has just been cancelled.
I have a plugin that creates a MediaStreamSource that does something along the lines of,
deferral = args.DeferrableOperation.GetDeferral();
args.MediaStreamSource = await CreateMssAsync(deferral.CancellationToken);
Since deferral.CancellationToken is already cancelled by the time CreateMssAsync() is called, this doesn't work all that well.
At this point I have a couple of workarounds:
Setting "player.Source = null;" before setting it to the new url works, but requires changes to all the code that uses the plugin.
I can ignore deferral.CancellationToken, but that means leaving the plugin's MediaLoaded handler at the mercy of whatever network timeouts the rest of the system is dealing with. Is there another cancellation token one might look at?
Is there some other way to get around this without any changes to code outside the plugin?