使用Xamarin Forms播放视频
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Xamarin Forms播放视频相关的知识,希望对你有一定的参考价值。
我们正在使用Xamarin.forms
在Xamarin中构建应用程序。在应用程序中我们需要播放视频,因此我们为此编写了一些代码。但是,视频没有播放,在android上应用程序崩溃,同时抛出一般错误。
这是代码:
VideoContainer.cs
using System;
using Xamarin.Forms;
using System.Collections.Generic;
namespace MyApp
{
public class VideoView : View
{
public Action StopAction;
public VideoView ()
{
Console.WriteLine("VideoView loaded");
}
public static readonly BindableProperty FileSourceProperty =
BindableProperty.Create<VideoView,string>(
p => p.FileSource,string.Empty);
public string FileSource {
get { return (string)GetValue (FileSourceProperty); }
set { SetValue (FileSourceProperty, value); }
}
public void Stop(){
if(StopAction != null)
StopAction ();
}
}
}
VideoViewRender.cs
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Media;
using Android.Content.Res;
using Java.Lang;
using MyApp.Droid;
[assembly: ExportRenderer(typeof(VideoView), typeof(VideoViewRenderer))]
//
namespace MyApp.Droid
{
public class VideoViewRenderer : ViewRenderer
{
VideoView videoview;
MediaPlayer player;
MediaController mediaController;
Handler handler = new Handler();
public VideoViewRenderer()
{
Console.WriteLine("VideoViewRenderer loaded");
}
public void SurfaceChanged(ISurfaceHolder holder, global::Android.Graphics.Format format, int width, int height)
{
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
}
void play(string fullPath)
{
AssetFileDescriptor afd = Forms.Context.Assets.OpenFd(fullPath);
if (afd != null)
{
player.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length);
player.Prepare();
player.Start();
Control.Layout(0, 200, 400, 600);
player.Pause();
}
}
public void SurfaceCreated(ISurfaceHolder holder)
{
player.SetDisplay(holder);
}
public override bool OnTouchEvent(MotionEvent e)
{
mediaController.Show();
return false;
}
//--MediaPlayerControl methods----------------------------------------------------
public void Start()
{
player.Start();
}
public void Pause()
{
player.Pause();
}
public int Duration
{
get
{
return player.Duration;
}
}
public int CurrentPosition
{
get
{
return player.CurrentPosition;
}
}
public void SeekTo(int i)
{
player.SeekTo(i);
}
public bool IsPlaying
{
get
{
return player.IsPlaying;
}
}
public int BufferPercentage
{
get
{
return 0;
}
}
public int AudiosessionId
{
get
{
return 0;
}
}
public bool CanPause()
{
return true;
}
public bool CanSeekBackward()
{
return true;
}
public bool CanSeekForward()
{
return true;
}
//--------------------------------------------------------------------------------
}
}
会发生什么是VideoView loaded
登录到控制台,但VideoViewRenderer loaded
不是。我们从the Xamarin forum获得此代码,但无法成功实现它。我们做错了什么?
我认为你的[assembly:...]
错误VideoView
。
有可能ExportRenderer
得到Android.VideoView
。
你应该得到[assembly: ExportRenderer(typeof(MyApp.VideoView), typeof(MyApp.Droid.VideoView))]
。
查看此示例更容易。
https://github.com/logikonline/xamarin-amccorma
请享用!
编辑:请参阅https://github.com/amccorma/xamarin-amccorma最初完成的此实现
[assembly: ExportRenderer(typeof(MyVideoPlayer), typeof(VideoSamples.Droid.MyVideoPlayerRenderer))] namespace VideoSamples.Droid { public class MyVideoPlayerRenderer : ViewRenderer<MyVideoPlayer, Android.Widget.RelativeLayout> { private MediaController _MCController; private MyVideoView _MyVideoView; private bool _AttachedController; private Android.Widget.RelativeLayout _MainLayout; public MyVideoPlayerRenderer () { this._AttachedController = false; } protected override void Dispose (bool disposing) { if (this._MCController != null && this._MyVideoView != null) { this._MyVideoView.SetMediaController (null); } if (this._MCController != null) { this._MCController.Dispose (); this._MCController = null; } if (this._MyVideoView != null) { this._MyVideoView.StopPlayback (); this._MyVideoView.Dispose (); this._MyVideoView = null; } base.Dispose (disposing); } protected override void OnElementChanged (ElementChangedEventArgs<MyVideoPlayer> e) { base.OnElementChanged (e); if (this.Control == null) { var layoutInflater = (LayoutInflater)Context.GetSystemService(global::Android.Content.Context.LayoutInflaterService); this._MainLayout = (Android.Widget.RelativeLayout)layoutInflater.Inflate (VideoSamples.Droid.Resource.Layout.VideoLayout, null); SetNativeControl (this._MainLayout); } this._MyVideoView = this.Control.FindViewById<MyVideoView>(VideoSamples.Droid.Resource.Id.videoView1); // full screen hack? ResizeScreen (true); //this.Element.FullScreen); // must set reference to root element this._MyVideoView.ParentElement = this.Element; // pick controller this._MCController = new MediaController (this.Context); this._MCController.SetMediaPlayer (this._MyVideoView); if (this.Element.AddVideoController) { this._AttachedController = true; this._MyVideoView.SetMediaController (this._MCController); } else { this._AttachedController = false; } // load file this._MyVideoView.LoadFile (this.Element.FileSource); if (this.Element.AutoPlay) { // play if set to autoplay on load this._MyVideoView.Play(); } } protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged (sender, e); var source = this.Element; if (source != null && this._MyVideoView != null) { if (e.PropertyName == MyVideoPlayer.SeekProperty.PropertyName) { this._MyVideoView.SeekTo ((int)this.Element.Seek); } else if (e.PropertyName == MyVideoPlayer.FileSourceProperty.PropertyName) { // load the play file this._MyVideoView.LoadFile (this.Element.FileSource); this._MyVideoView.Play (); } else if (e.PropertyName == MyVideoPlayer.AddVideoControllerProperty.PropertyName) { if (source.AddVideoController && this._AttachedController == false) { this._MyVideoView.SetMediaController (this._MCController); } else { this._MyVideoView.SetMediaController (null); } } else if (e.PropertyName == MyVideoPlayer.FullScreenProperty.PropertyName) { ResizeScreen (source.FullScreen); } else if (e.PropertyName == "OrientationChanged") { ResizeScreen (source.FullScreen); } else if (e.PropertyName == MyVideoPlayer.ActionBarHideProperty.PropertyName) { ResizeScreen (source.FullScreen); } else if (e.PropertyName == MyVideoPlayer.PlayerActionProperty.PropertyName) { if (source.PlayerAction == VideoState.PAUSE) { this._MyVideoView.Pause (); } else if (source.PlayerAction == VideoState.PLAY) { this._MyVideoView.Play (); } else if (source.PlayerAction == VideoState.RESTART) { this._MyVideoView.SeekTo (0); this._MyVideoView.Play (); } else if (source.PlayerAction == VideoState.STOP) { this._MyVideoView.StopPlayback (); } } } } private void ResizeScreen(bool fullscreen) { var a = this.Context as Activity; if (this.Element.ActionBarHide) { a.ActionBar.Hide (); } else { a.ActionBar.Show (); } if (fullscreen) { var p = this._MyVideoView.LayoutParameters as Android.Widget.RelativeLayout.LayoutParams; p.Height = Android.Widget.RelativeLayout.LayoutParams.FillParent; // added works ok for rotation var view = a.Window.DecorView; Rect rect = new Rect (); view.GetWindowVisibleDisplayFrame (rect); var width = (int)this.Element.ContentWidth; var height = (this.Element.ActionBarHide) ? rect.Height() : (int)this.Element.ContentHeight; var holder = this._MyVideoView.Holder; p.Height = height; p.Width = width; holder.SetFixedSize (width, height); // end p.AlignWithParent = true; this._MyVideoView.LayoutParameters = p; } else { var p = this._MyVideoView.LayoutParameters as Android.Widget.RelativeLayout.LayoutParams; if (this.Element.HeightRequest > 0 || this.Element.WidthRequest > 0) { if (this.Element.HeightRequest > 0) { p.Height = (int)this.Element.HeightRequest; } if (this.Element.WidthRequest > 0) { p.Width = (int)this.Element.WidthRequest; } this._MyVideoView.LayoutParameters = p; } p.AlignWithParent = false; this._MyVideoView.LayoutParameters = p; } InvalidLayout (); } private void InvalidLayout() { if (this.Element.Orientation == MyVideoPlayer.ScreenOrientation.LANDSCAPE) { } Xamarin.Forms.Device.BeginInvokeOnMainThread (() => { this._MyVideoView.ForceLayout(); this._MyVideoView.RequestLayout (); this._MyVideoView.Holder.SetSizeFromLayout(); this._MyVideoView.Invalidate (); }); } } }
以上是关于使用Xamarin Forms播放视频的主要内容,如果未能解决你的问题,请参考以下文章Xamarin Forms:使用 webView 播放本地视频(测试 Android ATM)
如何使用 xamarin.forms 在移动设备中选择多个音频和/或视频文件?
Xamarin Forms Webview html 视频不在 iOS 设备上播放
Xamarin Forms 中的视频播放器在最小化和恢复时消失了