我正在使用Android的视频视图在我的应用中播放视频。当我将来源作为网络链接时,它工作正常,但是当我从本地资源中选择文件时,我在Xamarin Android Player中始终收到“无法播放此视频”消息和黑屏。我遵循了Here中的示例。我已经用Google搜索这个问题,有人说这个问题可能是由于
我不认为这是我的情况,因为示例项目在同一设备上运行良好。此外,我的项目中还播放了来自URL的视频。我相信我可能缺少解决这个问题的方法。 Xaml:-
<StackLayout VerticalOptions="FillAndExpand">
<video:VideoPlayer AutoPlay="True" x:Name="xvideoPlayer" WidthRequest="200" HeightRequest="200" />
<Button Clicked="Button_Clicked" ></Button>
</StackLayout>
Cs:
public VideoPlayerPage(string url)
{
InitializeComponent();
BindingContext = videoPlayerPageViewModel = new VideoPlayerPageViewModel();
NavigationPage.SetHasNavigationBar(this, false);
}
private async void Button_Clicked(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.IsEnabled = false;
var FileOperations = DependencyService.Get<IFileOperations>();
//string pLocalPath = FileOperations.GetFilePath(url, "ErpwebChat");
string pLocalPath = "content://com.android.externalstorage.documents/document/primary%3ADocument%2FErpwebChat%2F1aecb317-8d56-46c4-b29a-182d2e61093c.mp4";
//DownloadVideo(url, "videos");
if (!String.IsNullOrWhiteSpace(pLocalPath))
{
xvideoPlayer.Source = new FileVideoSource
{
File = pLocalPath
};
}
btn.IsEnabled = true;
}
VideoPlayerRenderer.droid类:-
public class VideoPlayerRenderer : ViewRenderer<VideoPlayer, ARelativeLayout>
{
VideoView videoView;
MediaController mediaController; // Used to display transport controls
bool isPrepared;
public VideoPlayerRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<VideoPlayer> args)
{
base.OnElementChanged(args);
if (args.NewElement != null)
{
if (Control == null)
{
// Save the VideoView for future reference
videoView = new VideoView(Context);
// Put the VideoView in a RelativeLayout
ARelativeLayout relativeLayout = new ARelativeLayout(Context);
relativeLayout.AddView(videoView);
// Center the VideoView in the RelativeLayout
ARelativeLayout.LayoutParams layoutParams =
new ARelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
layoutParams.AddRule(LayoutRules.CenterInParent);
videoView.LayoutParameters = layoutParams;
// Handle a VideoView event
videoView.Prepared += OnVideoViewPrepared;
SetNativeControl(relativeLayout);
}
SetAreTransportControlsEnabled();
SetSource();
args.NewElement.UpdateStatus += OnUpdateStatus;
args.NewElement.PlayRequested += OnPlayRequested;
args.NewElement.PauseRequested += OnPauseRequested;
args.NewElement.StopRequested += OnStopRequested;
}
if (args.OldElement != null)
{
args.OldElement.UpdateStatus -= OnUpdateStatus;
args.OldElement.PlayRequested -= OnPlayRequested;
args.OldElement.PauseRequested -= OnPauseRequested;
args.OldElement.StopRequested -= OnStopRequested;
}
}
protected override void Dispose(bool disposing)
{
if (Control != null && videoView != null)
{
videoView.Prepared -= OnVideoViewPrepared;
}
if (Element != null)
{
Element.UpdateStatus -= OnUpdateStatus;
}
base.Dispose(disposing);
}
void OnVideoViewPrepared(object sender, EventArgs args)
{
isPrepared = true;
((IVideoPlayerController)Element).Duration = TimeSpan.FromMilliseconds(videoView.Duration);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(sender, args);
if (args.PropertyName == VideoPlayer.AreTransportControlsEnabledProperty.PropertyName)
{
SetAreTransportControlsEnabled();
}
else if (args.PropertyName == VideoPlayer.SourceProperty.PropertyName)
{
SetSource();
}
else if (args.PropertyName == VideoPlayer.PositionProperty.PropertyName)
{
if (Math.Abs(videoView.CurrentPosition - Element.Position.TotalMilliseconds) > 1000)
{
videoView.SeekTo((int)Element.Position.TotalMilliseconds);
}
}
}
void SetAreTransportControlsEnabled()
{
if (Element.AreTransportControlsEnabled)
{
mediaController = new MediaController(Context);
mediaController.SetMediaPlayer(videoView);
videoView.SetMediaController(mediaController);
}
else
{
videoView.SetMediaController(null);
if (mediaController != null)
{
mediaController.SetMediaPlayer(null);
mediaController = null;
}
}
}
void SetSource()
{
isPrepared = false;
bool hasSetSource = false;
if (Element.Source is UriVideoSource)
{
string uri = (Element.Source as UriVideoSource).Uri;
if (!String.IsNullOrWhiteSpace(uri))
{
videoView.SetVideoURI(Android.Net.Uri.Parse(uri));
hasSetSource = true;
}
}
else if (Element.Source is FileVideoSource)
{
string filename = (Element.Source as FileVideoSource).File;
if (!String.IsNullOrWhiteSpace(filename))
{
videoView.SetVideoPath(filename);
hasSetSource = true;
}
}
else if (Element.Source is ResourceVideoSource)
{
string package = Context.PackageName;
string path = (Element.Source as ResourceVideoSource).Path;
if (!String.IsNullOrWhiteSpace(path))
{
string filename = Path.GetFileNameWithoutExtension(path).ToLowerInvariant();
string uri = "android.resource://" + package + "/raw/" + filename;
videoView.SetVideoURI(Android.Net.Uri.Parse(uri));
hasSetSource = true;
}
}
if (hasSetSource && Element.AutoPlay)
{
videoView.Start();
}
}
// Event handler to update status
void OnUpdateStatus(object sender, EventArgs args)
{
VideoStatus status = VideoStatus.NotReady;
if (isPrepared)
{
status = videoView.IsPlaying ? VideoStatus.Playing : VideoStatus.Paused;
}
((IVideoPlayerController)Element).Status = status;
// Set Position property
TimeSpan timeSpan = TimeSpan.FromMilliseconds(videoView.CurrentPosition);
((IElementController)Element).SetValueFromRenderer(VideoPlayer.PositionProperty, timeSpan);
}
// Event handlers to implement methods
void OnPlayRequested(object sender, EventArgs args)
{
videoView.Start();
}
void OnPauseRequested(object sender, EventArgs args)
{
videoView.Pause();
}
void OnStopRequested(object sender, EventArgs args)
{
videoView.StopPlayback();
}
}
我正在使用.mp4格式 其余所有类均与示例应用程序Here中的类相同 任何帮助将不胜感激 。 !
编辑-设备日志(从按钮单击无法播放错误) Here
答案 0 :(得分:0)
我在ios渲染器中遇到了同样的问题,因此我解决该问题的方法是将SetSource函数中的条件更改为
else if (Element.Source is FileVideoSource)
{
string uri = (Element.Source as FileVideoSource).File;
if (!String.IsNullOrWhiteSpace(uri))
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var path = Path.Combine(documents, uri);
NSUrl url = NSUrl.CreateFileUrl(path, null);
asset = AVAsset.FromUrl(url);
}
}
由于某种原因,无法将整个路径作为字符串传递,因此您可以传递文件名并在customrenderer中编写创建路径的逻辑 这是我的问题的链接 Xamarin video player unable to play video from simulator document folder
答案 1 :(得分:0)
尝试将视频播放器从StackLayout中取出,我一直在运行Xamarins自己的视频播放器示例,复制了系统文件和类结构,但只有黑屏。 把它拿出来堆和宾果游戏