Xamarin Forms MediaElement:使用 CrossMedia 插件播放从图库中选择的视频
Xamarin Forms MediaElement: Playing video selected from gallery with CrossMedia plugin
我正在尝试使用 MediaElement 播放从图库中选择的视频。视频的路径保存在应用程序中,然后绑定到 MediaElement 源。
<xct:MediaElement Source="{Binding VideoUri, Converter={StaticResource VideoSourceConverter}}"
AutoPlay="False"
ShowsPlaybackControls="True"
Aspect="AspectFit"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
我正在使用文档中所述的转换器:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
if (string.IsNullOrWhiteSpace(value.ToString()))
return null;
if (value.ToString().StartsWith("http"))
return value;
return new Uri($"ms-appdata:///{value}");
}
https://docs.microsoft.com/en-gb/xamarin/community-toolkit/views/mediaelement#play-local-media
但出现错误:无效的 UriParameter 名称:来源
Android上保存的路径是:
"/storage/emulated/0/Android/data/[应用标识符]/files/Movies/temp/[文件名].mp4"
尚未在 iOS 中测试。
任何指导将不胜感激。
谢谢。
您不需要转换器,只需要 return 媒体播放器控件的路径。
mediaFile = await this._mediaPicker.PickVideoAsync();
VideoUri = mediaFile.Path;
您使用的转换器用于 UWP。 UWP 可以播放位于应用的 xxxx 文件夹中的媒体文件,方法是在媒体文件前加上 ms-appdata:///xxxx/
.
对于移动设备,当您使用 CrossMedia
到 select 视频时,您可以直接从文件中获取流。
我使用按钮执行 select 操作,然后使用 INotifyPropertyChanged
更新绑定。这是供您参考的代码。
Xaml:
<Button Clicked="Button_Clicked" Text="Select"/>
<xct:MediaElement Source="{Binding VideoUri}"
AutoPlay="False"
ShowsPlaybackControls="True"
Aspect="AspectFit"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
代码:
public partial class Page29 : ContentPage
{
Page29ViewModel viewModel = new Page29ViewModel();
public Page29()
{
InitializeComponent();
this.BindingContext = viewModel;
}
private async void Button_Clicked(object sender, EventArgs e)
{
string path = string.Empty;
MediaFile video = null;
if (CrossMedia.Current.IsPickVideoSupported)
{
video = await CrossMedia.Current.PickVideoAsync();
}
var fileName = "sample";
var newFile = Path.Combine(FileSystem.AppDataDirectory, fileName + ".mp4");
if (!File.Exists(newFile))
{
using (var inputStream = video.GetStream())
{
using (FileStream outputStream = File.Create(newFile))
{
await inputStream.CopyToAsync(outputStream);
}
}
}
viewModel.VideoUri = newFile;
}
}
public class Page29ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string _videoUri;
public string VideoUri
{
get { return _videoUri; }
set { _videoUri = value; NotifyPropertyChanged(nameof(VideoUri)); }
}
public Page29ViewModel()
{
}
}
我正在尝试使用 MediaElement 播放从图库中选择的视频。视频的路径保存在应用程序中,然后绑定到 MediaElement 源。
<xct:MediaElement Source="{Binding VideoUri, Converter={StaticResource VideoSourceConverter}}"
AutoPlay="False"
ShowsPlaybackControls="True"
Aspect="AspectFit"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
我正在使用文档中所述的转换器:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
if (string.IsNullOrWhiteSpace(value.ToString()))
return null;
if (value.ToString().StartsWith("http"))
return value;
return new Uri($"ms-appdata:///{value}");
}
https://docs.microsoft.com/en-gb/xamarin/community-toolkit/views/mediaelement#play-local-media
但出现错误:无效的 UriParameter 名称:来源
Android上保存的路径是:
"/storage/emulated/0/Android/data/[应用标识符]/files/Movies/temp/[文件名].mp4"
尚未在 iOS 中测试。
任何指导将不胜感激。
谢谢。
您不需要转换器,只需要 return 媒体播放器控件的路径。
mediaFile = await this._mediaPicker.PickVideoAsync();
VideoUri = mediaFile.Path;
您使用的转换器用于 UWP。 UWP 可以播放位于应用的 xxxx 文件夹中的媒体文件,方法是在媒体文件前加上 ms-appdata:///xxxx/
.
对于移动设备,当您使用 CrossMedia
到 select 视频时,您可以直接从文件中获取流。
我使用按钮执行 select 操作,然后使用 INotifyPropertyChanged
更新绑定。这是供您参考的代码。
Xaml:
<Button Clicked="Button_Clicked" Text="Select"/>
<xct:MediaElement Source="{Binding VideoUri}"
AutoPlay="False"
ShowsPlaybackControls="True"
Aspect="AspectFit"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
代码:
public partial class Page29 : ContentPage
{
Page29ViewModel viewModel = new Page29ViewModel();
public Page29()
{
InitializeComponent();
this.BindingContext = viewModel;
}
private async void Button_Clicked(object sender, EventArgs e)
{
string path = string.Empty;
MediaFile video = null;
if (CrossMedia.Current.IsPickVideoSupported)
{
video = await CrossMedia.Current.PickVideoAsync();
}
var fileName = "sample";
var newFile = Path.Combine(FileSystem.AppDataDirectory, fileName + ".mp4");
if (!File.Exists(newFile))
{
using (var inputStream = video.GetStream())
{
using (FileStream outputStream = File.Create(newFile))
{
await inputStream.CopyToAsync(outputStream);
}
}
}
viewModel.VideoUri = newFile;
}
}
public class Page29ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string _videoUri;
public string VideoUri
{
get { return _videoUri; }
set { _videoUri = value; NotifyPropertyChanged(nameof(VideoUri)); }
}
public Page29ViewModel()
{
}
}