C# UWP MediaPlaybackList添加MediaSource工作太慢
我对MediaPlaybackList有一个问题,如下所示:C# UWP MediaPlaybackList添加MediaSource工作太慢,c#,windows-phone,win-universal-app,C#,Windows Phone,Win Universal App,我对MediaPlaybackList有一个问题,如下所示: playbackList = new MediaPlaybackList(); playbackList.AutoRepeatEnabled = true; for (int i = 0; i < songs.Count();i++) { var song = songs.ElementAt(i); var source = MediaSource.CreateFromStorageFile(
playbackList = new MediaPlaybackList();
playbackList.AutoRepeatEnabled = true;
for (int i = 0; i < songs.Count();i++)
{
var song = songs.ElementAt(i);
var source = MediaSource.CreateFromStorageFile(
await StorageFile.GetFileFromPathAsync(song.File));
source.CustomProperties[TrackIdKey] = null;
source.CustomProperties[TitleKey] = song.Title;
source.CustomProperties[AlbumArtKey] = song.AlbumArtUri;
source.CustomProperties[AuthorKey] = song.Author;
source.CustomProperties[TrackNumber] = (uint)(i+1);
playbackList.Items.Add(new MediaPlaybackItem(source));
}
playbackList=新媒体播放列表();
playbackList.autorepeatabled=true;
对于(int i=0;i
当我尝试将
MediaSource
添加到我的播放列表时,会花费太多时间。开始播放700首歌曲大约需要3分钟。也许有另一种方法可以将MediaSource
添加到MediaPlaybackList
中,这会更快?使用irandomaccesstreamreference。
这样一来,它只需在到达项目时加载文件,速度明显加快
不过,您必须编写自己的抽象类。
可能看起来有点像这样:
public class MyStreamReference : IRandomAccessStreamReference
{
private string path;
public MyStreamReference(string path)
{
this.path = path;
}
public IAsyncOperation<IRandomAccessStreamWithContentType> OpenReadAsync()
=> Open().AsAsyncOperation();
// private async helper task that is necessary if you need to use await.
private async Task<IRandomAccessStreamWithContentType> Open()
=> await (await StorageFile.GetFileFromPathAsync(path)).OpenReadAsync();
}
公共类MyStreamReference:irandomaccesstreamreference
{
私有字符串路径;
公共MyStreamReference(字符串路径)
{
this.path=path;
}
公共IAsyncOperation OpenReadAsync()
=>Open().AsAsyncOperation();
//私有异步助手任务,如果需要使用wait,则该任务是必需的。
私有异步任务Open()
=>await(await-StorageFile.getfilefrompathsync(path)).OpenReadAsync();
}
首先,我会在获取任何文件之前设置MediaElement的PlaybackSource,然后我会启动一个任务来处理另一个线程上的加载
这样,第一个文件的播放将在加载后立即开始(或可以开始),在我的测试中这不到一秒钟
var playbackList = new MediaPlaybackList();
playbackList.AutoRepeatEnabled = true;
mediaElement.SetPlaybackSource(playbackList);
await Task.Run(async () =>
{
for (int i = 0; i < songs.Count(); i++)
{
var song = songs.ElementAt(i);
var source = MediaSource.CreateFromStorageFile(await StorageFile.GetFileFromPathAsync(song.File));
source.CustomProperties["TrackIdKey"] = null;
source.CustomProperties["TitleKey"] = song.Title;
source.CustomProperties["AlbumArtKey"] = song.AlbumArtUri;
source.CustomProperties["AuthorKey"] = song.Author;
source.CustomProperties["TrackNumber"] = (uint)(i + 1);
playbackList.Items.Add(new MediaPlaybackItem(source));
Debug.WriteLine($"[{i}] {song.Title} added to playlist");
}
});
var playbackList=new MediaPlaybackList();
playbackList.autorepeatabled=true;
mediaElement.SetPlaybackSource(播放列表);
等待任务。运行(异步()=>
{
对于(int i=0;i
作为一个辅助项目,我稍微调整了一下,以便从一个可移动驱动器加载和播放所有曲目。代码的第一部分从驱动器中获取文件,按子文件夹对其进行过滤,并创建歌曲对象
其余的都是一样的,除了从KnownFolders.RemovableStorage检索存储文件的轻微修改
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
IReadOnlyList<StorageFile> files = await KnownFolders.RemovableDevices.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName);
var songs = new List<Song>();
string root = $@"{Path.GetPathRoot(files.FirstOrDefault()?.Path)}Tracks\";
foreach (StorageFile file in files)
if (file.Path.StartsWith(root))
songs.Add(new Song { File = file.Path, Title = Path.GetFileNameWithoutExtension(file.Path) });
var playbackList = new MediaPlaybackList();
playbackList.AutoRepeatEnabled = true;
mediaElement.SetPlaybackSource(playbackList);
await Task.Run(async () =>
{
for (int i = 0; i < songs.Count(); i++)
{
var song = songs.ElementAt(i);
var source = MediaSource.CreateFromStorageFile(await KnownFolders.RemovableDevices.GetFileAsync(song.File));
source.CustomProperties["TrackIdKey"] = null;
source.CustomProperties["TitleKey"] = song.Title;
source.CustomProperties["AlbumArtKey"] = song.AlbumArtUri;
source.CustomProperties["AuthorKey"] = song.Author;
source.CustomProperties["TrackNumber"] = (uint)(i + 1);
playbackList.Items.Add(new MediaPlaybackItem(source));
Debug.WriteLine($"[{i}] {song.Title} added to playlist");
}
});
}
受保护的异步覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
基地。导航到(e);
IReadOnlyList files=await KnownFolders.RemovableDevices.getfileasync(Windows.Storage.Search.CommonFileQuery.OrderByName);
var songs=新列表();
字符串root=$@“{Path.GetPathRoot(files.FirstOrDefault()?.Path)}跟踪\”;
foreach(文件中的存储文件)
if(file.Path.StartsWith(root))
添加(新歌曲{File=File.Path,Title=Path.GetFileNameWithoutExtension(File.Path)});
var playbackList=new MediaPlaybackList();
playbackList.autorepeatabled=true;
mediaElement.SetPlaybackSource(播放列表);
等待任务。运行(异步()=>
{
对于(int i=0;i
我在中找到,它使用var source=MediaSource.CreateFromUri(song.MediaUri)代码>以获取歌曲。我使用的是这个示例,但在这个示例中,音频源在包中,而不是在外部驱动器中