如何正确配置 UWP 媒体播放器?

How to dispose correctly an UWP mediaplayer?

我有一段代码用于检查媒体列表是否可播放。问题是,当我 运行 方法并让它完成或使用 CancellationToken 取消它时,MediaPlayer 继续下载内容并且永远不会完成,即使我有 using并致电 Dispose()。也许我做错了什么......非常感谢一点帮助。非常感谢! 这是代码:

CancellationTokenSource tokenSource = new CancellationTokenSource();
private async Task CheckMediaAsync(CancellationToken token)
{
    using (MediaPlayer mediaplayer = new MediaPlayer { IsMuted = true, AutoPlay = true })
    {
        List<Link> links = DataAccess.GetAllMedia();
        for (int i = 0; i < links.Count; i++)
        {
            mediaplayer.Source = MediaSource.CreateFromUri(new Uri(links[i].LinkMed));

            if (await Task.Run(() => CheckUntilTimeout(token, mediaplayer), token))
            {
                OffileMedia.Add(links[i].Name);
            }

            if (tokenSource.IsCancellationRequested)
            {
                mediaplayer.Source = null;
                mediaplayer.Dispose();
                return;
            }
        }
        mediaplayer.Source = null;
        mediaplayer.Dispose();
    }
}

private bool CheckUntilTimeout(CancellationToken ct, MediaPlayer mp)
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    while (stopwatch.Elapsed < TimeSpan.FromSeconds(8))
    {
        if (ct.IsCancellationRequested)
        {
            stopwatch.Stop();
            return false;
        }

        if (mp.PlaybackSession.PlaybackState == MediaPlaybackState.None)
        {
            stopwatch.Stop();
            return true;
        }
        else if (mp.PlaybackSession.PlaybackState == MediaPlaybackState.Playing)
        {
            stopwatch.Stop();
            return false;
        }
    }

    stopwatch.Stop();
    return true;
}

编辑:
经过一些其他检查后,问题似乎确实是 MediaPlayer 对象。例如,如果我尝试将 Source 设置为音频流:

http://icecast.unitedradio.it/Radio105.mp3
http://icecast.unitedradio.it/Virgin.mp3

或任何其他音频流,MediaPlayer 将继续下载它们中的每一个,即使您将 Source 设置为空或 Dispose() 也是如此。奇怪的是,如果尝试任何视频流 (m3u8 or mpd) 似乎都能正常工作。

除了处理 MediaPlayer 之外,您还需要适当地处理底层 MediaSource 以停止下载。

因此,处置当前正在播放从 Uri 创建的 MediaSource 的 MediaPlayer 的正确步骤是...

  1. 暂停 MediaPlayer 上的播放。
  2. 从 MediaPlayer 中分离 MediaSource。
  3. 配置 MediaSource* 和 MediaPlayer。

*由于 MediaSource class 也有 IDisposable 接口,最好将代码块包装在 using(...){ } 子句中。那么您就不需要显式调用 Dispose。

private async Task CheckMediaAsync(CancellationToken token)
{
    using (MediaPlayer mediaplayer = new MediaPlayer { IsMuted = true, AutoPlay = true })
    {
        List<Link> links = DataAccess.GetAllMedia();
        for (int i = 0; i < links.Count; i++)
        {
            using (MediaSource ms = MediaSource.CreateFromUri(new Uri(links[i].LinkMed)))
            {
                mediaplayer.Source = ms;

                if (await Task.Run(() => CheckUntilTimeout(token, mediaplayer), token))
                {
                    OffileMedia.Add(links[i].Name);
                }
                mediaplayer.Pause();
                mediaplayer.Source = null;
            }
            if (tokenSource.IsCancellationRequested)
            {
                //mediaplayer.Source = null;
                //mediaplayer.Dispose();
                return;
            }
        }
        //mediaplayer.Source = null;
        //mediaplayer.Dispose();
    }
}