MediaElement 不播放设备内部存储器中的文件
MediaElement doesn't play files from internal memory of device
我正在编写一个简单的应用程序,它在 MediaElement 的帮助下播放 mp3 文件。我的测试设备有 SD 卡。问题是应用程序可以播放 SD 卡中的文件,但不能播放内存中的相同文件。
以下是我的代码的简化部分:
MainPage.xaml
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:TestApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:Key="StorageItemDataTemplate">
<TextBlock Text="{Binding File.Name}" />
</DataTemplate>
</Page.Resources>
<Grid>
<ListView
x:Name="List"
IsItemClickEnabled="True"
ItemClick="List_OnItemClick"
ItemTemplate="{StaticResource StorageItemDataTemplate}" />
<MediaElement x:Name="Media" />
</Grid>
</Page>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
IReadOnlyList<StorageFile> items =
await KnownFolders.MusicLibrary.GetFilesAsync();
List.ItemsSource = items.Select(item => new ItemViewModel(item));
}
private void List_OnItemClick(object sender, ItemClickEventArgs e)
{
var item = (ItemViewModel) e.ClickedItem;
Media.Source = new Uri(item.File.Path);
}
}
ItemViewModel.cs
public class ItemViewModel
{
public StorageFile File { get; private set; }
public ItemViewModel(StorageFile file)
{
File = file;
}
}
单击列表中的项目时,文件路径被提取并传递给 MediaElement。接下来 MediaElement 播放音频。
如果文件在内存中,那么文件路径将如下所示:
C:\Data\Users\Public\Music\file.mp3
如果它在 SD 卡上:
D:\Music\file.mp3
应用的清单有下一个检查的功能:
Music library
Removable storage
哪里有问题?
UPD
订阅 MediaElement 的 MediaOnMediaFailed 事件后,我收到了下一条错误消息:
MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT - 0x80070005
0x80070005
表示 Access Denied
.
我不确定它是否会通过传递 Uri 来工作 - StorageFile 正在与利用声明的文件代理一起工作功能,因此可以访问应用程序外部的文件。如果你这样做应该可以工作:
private async void List_OnItemClick(object sender, ItemClickEventArgs e)
{
var item = (ItemViewModel) e.ClickedItem;
var stream = await item.File.OpenAsync(FileAccessMode.Read);
Media.SetSource(stream, item.File.ContentType);
}
我正在编写一个简单的应用程序,它在 MediaElement 的帮助下播放 mp3 文件。我的测试设备有 SD 卡。问题是应用程序可以播放 SD 卡中的文件,但不能播放内存中的相同文件。
以下是我的代码的简化部分:
MainPage.xaml
<Page x:Class="TestApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:TestApp" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" mc:Ignorable="d"> <Page.Resources> <DataTemplate x:Key="StorageItemDataTemplate"> <TextBlock Text="{Binding File.Name}" /> </DataTemplate> </Page.Resources> <Grid> <ListView x:Name="List" IsItemClickEnabled="True" ItemClick="List_OnItemClick" ItemTemplate="{StaticResource StorageItemDataTemplate}" /> <MediaElement x:Name="Media" /> </Grid> </Page>
MainPage.xaml.cs
public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { IReadOnlyList<StorageFile> items = await KnownFolders.MusicLibrary.GetFilesAsync(); List.ItemsSource = items.Select(item => new ItemViewModel(item)); } private void List_OnItemClick(object sender, ItemClickEventArgs e) { var item = (ItemViewModel) e.ClickedItem; Media.Source = new Uri(item.File.Path); } }
ItemViewModel.cs
public class ItemViewModel { public StorageFile File { get; private set; } public ItemViewModel(StorageFile file) { File = file; } }
单击列表中的项目时,文件路径被提取并传递给 MediaElement。接下来 MediaElement 播放音频。
如果文件在内存中,那么文件路径将如下所示:
C:\Data\Users\Public\Music\file.mp3
如果它在 SD 卡上:
D:\Music\file.mp3
应用的清单有下一个检查的功能:
Music library
Removable storage
哪里有问题?
UPD
订阅 MediaElement 的 MediaOnMediaFailed 事件后,我收到了下一条错误消息:
MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT - 0x80070005
0x80070005
表示 Access Denied
.
我不确定它是否会通过传递 Uri 来工作 - StorageFile 正在与利用声明的文件代理一起工作功能,因此可以访问应用程序外部的文件。如果你这样做应该可以工作:
private async void List_OnItemClick(object sender, ItemClickEventArgs e)
{
var item = (ItemViewModel) e.ClickedItem;
var stream = await item.File.OpenAsync(FileAccessMode.Read);
Media.SetSource(stream, item.File.ContentType);
}