如何正确配置 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 的正确步骤是...
- 暂停 MediaPlayer 上的播放。
- 从 MediaPlayer 中分离 MediaSource。
- 配置 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();
}
}
我有一段代码用于检查媒体列表是否可播放。问题是,当我 运行 方法并让它完成或使用 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 的正确步骤是...
- 暂停 MediaPlayer 上的播放。
- 从 MediaPlayer 中分离 MediaSource。
- 配置 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();
}
}