繁体   English   中英

使用Xamarin Forms播放视频

[英]Play video with 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 我们从Xamarin论坛获得了此代码,但无法成功实现它。 我们做错了什么?

我认为你的[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 ();

            });
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM