locked
Play Video RRS feed

  • Question

  • User302481 posted

    Hi, Im trying to play a video from xamarin forms through MessagingCenter. In iOS I use:

    `private void HandleShowVideoPlayerMessage(Page page, ShowVideoPlayerArguments arguments) { var presentingViewController = GetMostPresentedViewController(); var filename = arguments.Url;

            var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var filename2 = Path.Combine(documents, filename);
    
            var url = new NSUrl(filename2, false);
    
    
            var avp = new AVPlayer(url);
            var avpvc = new AVPlayerViewController();
            avpvc.Player = avp;
            avp.Play();
    
            presentingViewController.PresentViewController(avpvc, animated: true, completionHandler: null);
        }
    
        private UIViewController GetMostPresentedViewController()
        {
            var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
    
            while (viewController.PresentedViewController != null)
            {
                viewController = viewController.PresentedViewController;
            }
    
            return viewController;
        }`
    

    But on Android I can't seem to make it work. Im trying this: ` private void HandleShowVideoPlayerMessage(Page page, ShowVideoPlayerArguments arguments) { VideoView videoView = FindViewById(Resource.Id.SampleVideoView);

            var uri = Android.Net.Uri.Parse("https://www.youtube.com/watch?v=pR30knJs4Xk");
            videoView.SetMediaController(new MediaController(this));
            videoView.SetVideoURI(uri);
            videoView.RequestFocus();
            videoView.Start();
        }
    

    ` But it trows an exception.

    Wednesday, April 5, 2017 10:17 AM

Answers

  • User146025 posted

    Something like that. I put the iOS renderer, but for Android it should be the same.

    The view for Forms.

    public class VideoView : View
     {
        #region Actions
    
        public Action PauseAction;
    
        public Action<bool> PlayAction;
    
        public Action<string> UpdateVideo;
    
        public Action<string> UpdateLocalVideo;
    
        public Action MuteAction;
    
        public Action UnmuteAction;
    
        #endregion
    
        #region Fields
    
        public static BindableProperty FileSourceProperty =
    BindableProperty.Create("FileSource", typeof(string),
    typeof(VideoView),
    string.Empty,
    BindingMode.TwoWay
            );
    
        public string FileSource
        {
            get { return (string)GetValue(FileSourceProperty);
    }
            set { SetValue(FileSourceProperty, value); }
        }
    
        /// <summary>
        /// Gets or sets the current file.
        /// </summary>
        /// <value>The current file.</value>
        public string CurrentFile { get; set; }
    
        #endregion
    
        #region Public Methods
    
        /// <summary>
        /// Play the video
        /// </summary>
        public void Play(bool muted = false)
        {
            if (this.PlayAction != null)
            {
    this.PlayAction(muted);
                }
        }
    
        /// <summary>
        /// Stop the video
        /// </summary>
        public void Pause()
        {
            if (this.PauseAction != null)
            {
    this.PauseAction();
                }
        }
    
        /// <summary>
        /// Changes the video.
        /// </summary>
        /// <param name="url">URL.</param>
        public void ChangeVideo(string url)
        {
            if (this.UpdateVideo != null)
            {
    this.UpdateVideo(url);
    this.CurrentFile = url;
                }
        }
    
        /// <summary>
        /// Changes the local video.
        /// </summary>
        /// <param name="path">Path.</param>
        public void ChangeLocalVideo(string path)
        {
            if (this.UpdateLocalVideo != null)
            {
    this.UpdateLocalVideo(path);
    this.CurrentFile = path;
                }
        }
    
        /// <summary>
        /// Mute this instance.
        /// </summary>
        public void Mute()
        {
            if (this.MuteAction != null)
            {
    this.MuteAction();
                }
        }
    
        /// <summary>
        /// Uns the mute.
        /// </summary>
        public void UnMute()
        {
            if (this.UnmuteAction != null)
            {
    this.UnmuteAction();
                }
        }
    
        #endregion
    }
    

    Video view renderer for iOS.

    [assembly: ExportRenderer(typeof(VideoView), typeof(VideoViewRenderer))]
    namespace 
    {
            /// <summary>
            /// Video view renderer.
            /// </summary>
            public class VideoViewRenderer : ViewRenderer<VideoView, UIVideoView>
            {
                /// <summary>
                /// Ons the element changed.
                /// </summary>
                /// <param name="e">E.</param>
                protected override void OnElementChanged(ElementChangedEventArgs<VideoView> e)
            {
                base.OnElementChanged(e);
    
                if (e.NewElement != null)
                {
                    e.NewElement.PlayAction = (bool mute) => this.DoAction("PlayAction", mute, "");
                    e.NewElement.PauseAction = () => this.DoAction(this.Control.Pause);
                    e.NewElement.UpdateVideo = (string url) => this.DoAction("UpdateVideo", false, url);
                    e.NewElement.UpdateLocalVideo = (string path) => this.DoAction("UpdateLocalVideo", false, path);
                    e.NewElement.MuteAction = () => this.DoAction(this.Control.Mute);
                    e.NewElement.UnmuteAction = () => this.DoAction(this.Control.Unmute);
    
                    // The layout has a 1 pixel problem.
                    this.SetNativeControl(new UIVideoView(e.NewElement.FileSource, new CGSize(e.NewElement.WidthRequest  1, e.NewElement.HeightRequest)));
                    e.NewElement.CurrentFile = this.Control.CurrentFile();
                }
            }
    
            #region Private Methods
            private void DoAction(Action action)
            {
                if (this.Control != null)
                {
        action.Invoke();
                    }
            }
    
            private void DoAction(string actionType, bool mute, string url)
            {
                if (this.Control != null)
                {
                        switch (actionType)
                    {
                                case "PlayAction":
    this.Control.Play(mute);
                                    break;
                                case "UpdateVideo":
    this.Control.UpdateVideo(url);
                                    break;
                                case "UpdateLocalVideo":
    this.Control.UpdateLocalVideo(url);
                                    break;
                            }
                    }
            }
            #endregion
    
        }
    }
    

    The Video view for iOS.

    public class UIVideoView : UIView
    {
        #region Attributes
    
        private readonly Timer timer;
    
        private bool isPlaying;
    
        private AVPlayer player;
    
        private string currentFile;
    
        private AVPlayerLayer playerLayer;
    
        #endregion
    
        #region Public Methods
    
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Eyetime.Services.iOS.Controls.UIVideoView"/> class.
        /// </summary>
        /// <param name="file">File.</param>
        /// <param name="frame">Frame.</param>
        public UIVideoView(string file, CGSize size)
        {
            AVAsset asset = AVAsset.FromUrl(new NSUrl(file));
            AVPlayerItem playerItem = new AVPlayerItem(asset);
    
            this.player = new AVPlayer(playerItem);
            this.playerLayer = AVPlayerLayer.FromPlayer(player);
            this.playerLayer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill;
            this.playerLayer.Frame = new CGRect(new CGPoint(0, 0), size);
            this.Frame = new CGRect(new CGPoint(0, 0), size);
            this.Layer.BackgroundColor = UIColor.Black.CGColor;
    
            this.Layer.AddSublayer(this.playerLayer);
    
            UITapGestureRecognizer tap = new UITapGestureRecognizer(this.ProcessPlayPause);
            this.AddGestureRecognizer(tap);
            this.currentFile = ((AVUrlAsset)this.player.CurrentItem.Asset).Url.AbsoluteString;
    
            this.timer = new Timer(250);
            timer.AutoReset = false;
            timer.Elapsed += this.OnTimeElapsed;
        }
    
        /// <summary>
        /// Play the specified muted.
        /// </summary>
        /// <param name="muted">If set to <c>true</c> muted.</param>
        public void Play(bool muted = false)
        {
            this.player.Muted = muted;
            this.player.Play();
    
            this.isPlaying = true;
    
            if (!this.player.CurrentItem.PlaybackLikelyToKeepUp)
            {
                this.timer.Start();
            }
        }
    
        /// <summary>
        /// Stops the current video
        /// </summary>
        public void Pause()
        {
            this.timer.Stop();
            this.player.Pause();
            this.isPlaying = false;
        }
    
        /// <summary>
        /// Updates the video.
        /// </summary>
        /// <param name="url">URL.</param>
        public void UpdateVideo(string url)
        {
            AVAsset asset = AVAsset.FromUrl(new NSUrl(url));
            AVPlayerItem playerItem = new AVPlayerItem(asset);
    
            this.player.ReplaceCurrentItemWithPlayerItem(playerItem);
            this.currentFile = ((AVUrlAsset)this.player.CurrentItem.Asset).Url.AbsoluteString;
        }
    
        /// <summary>
        /// Updates the local video.
        /// </summary>
        /// <param name="path">Path.</param>
        public void UpdateLocalVideo(string path)
        {
            NSUrl url = NSUrl.CreateFileUrl(path, null);
            AVPlayerItem playerItem = new AVPlayerItem(url);
    
            this.player.ReplaceCurrentItemWithPlayerItem(playerItem);
            this.currentFile = ((AVUrlAsset)this.player.CurrentItem.Asset).Url.AbsoluteString;
        }
    
        /// <summary>
        /// Mute this instance.
        /// </summary>
        public void Mute()
        {
            this.player.Muted = true;
        }
    
        /// <summary>
        /// Unmute this instance.
        /// </summary>
        public void Unmute()
        {
            this.player.Muted = false;
        }
    
        /// <summary>
        /// Currents the file.
        /// </summary>
        /// <returns>The file.</returns>
        public string CurrentFile()
        {
            return this.currentFile;
        }
    
        /// <summary>
        /// Release this instance.
        /// </summary>
        public void Release()
        {
            if (this.player != null)
            {
                this.player.Pause();
                this.player = null;
                this.Layer.RemoveFromSuperLayer();
            }
        }
    
        #endregion
    
        #region Private Methods
    
        private void ProcessPlayPause()
        {
            if (this.isPlaying)
            {
                this.Pause();
            }
            else
            {
                this.Play();
            }
        }
    
        private void OnTimeElapsed(object sender, ElapsedEventArgs e)
        {
            if (this.player.CurrentItem.PlaybackLikelyToKeepUp)
            {
                this.player.Play();
            }
            else
            {
                this.timer.Start();
            }
        }
    
        #endregion
    }
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, April 5, 2017 11:10 AM
  • User302481 posted

    @DarioOrgaz Hi, I have found a solution more simple than yours. Check it if it works. I have only make it work in iOS.

    `public class VideoView : View { public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: "Uri", returnType: typeof(string), declaringType: typeof(VideoView), defaultValue: default(string));

        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }
    
    
    }`
    

    And the renderer:

    `public class VideoViewRenderer : ViewRenderer {

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);
    
    
            var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
    
            while (viewController.PresentedViewController != null)
            {
                viewController = viewController.PresentedViewController;
            }
    
            var customView = Element as VideoView;
    
            var filename = customView.Uri;
    
            var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var filename2 = Path.Combine(documents, filename);
    
            var url = new NSUrl(filename2, false);
    
    
            var avp = new AVPlayer(url);
            var avpvc = new AVPlayerViewController();
            avpvc.Player = avp;
            avp.Play();
    
            viewController.PresentViewController(avpvc, animated: true, completionHandler: null);
        }
    }`
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, April 7, 2017 10:27 AM

All replies

  • User66163 posted

    Hi @carlasampaio01

    The best way to play media in XF is to use the Media Manager Plugin. Please see here for further information.

    Hope this helps,

    Tim

    Wednesday, April 5, 2017 10:32 AM
  • User146025 posted

    Could you try invoking on main thread the logic related with video?

    On the other hand, I think is not a good practice work with videos using MessagingCenter. I've implemented a custom control in forms and render the specific methods and logic for each platform.

    Wednesday, April 5, 2017 10:33 AM
  • User302481 posted

    @DarioOrgaz could you show me what control renderer did you use in forms?

    Wednesday, April 5, 2017 10:42 AM
  • User146025 posted

    Something like that. I put the iOS renderer, but for Android it should be the same.

    The view for Forms.

    public class VideoView : View
     {
        #region Actions
    
        public Action PauseAction;
    
        public Action<bool> PlayAction;
    
        public Action<string> UpdateVideo;
    
        public Action<string> UpdateLocalVideo;
    
        public Action MuteAction;
    
        public Action UnmuteAction;
    
        #endregion
    
        #region Fields
    
        public static BindableProperty FileSourceProperty =
    BindableProperty.Create("FileSource", typeof(string),
    typeof(VideoView),
    string.Empty,
    BindingMode.TwoWay
            );
    
        public string FileSource
        {
            get { return (string)GetValue(FileSourceProperty);
    }
            set { SetValue(FileSourceProperty, value); }
        }
    
        /// <summary>
        /// Gets or sets the current file.
        /// </summary>
        /// <value>The current file.</value>
        public string CurrentFile { get; set; }
    
        #endregion
    
        #region Public Methods
    
        /// <summary>
        /// Play the video
        /// </summary>
        public void Play(bool muted = false)
        {
            if (this.PlayAction != null)
            {
    this.PlayAction(muted);
                }
        }
    
        /// <summary>
        /// Stop the video
        /// </summary>
        public void Pause()
        {
            if (this.PauseAction != null)
            {
    this.PauseAction();
                }
        }
    
        /// <summary>
        /// Changes the video.
        /// </summary>
        /// <param name="url">URL.</param>
        public void ChangeVideo(string url)
        {
            if (this.UpdateVideo != null)
            {
    this.UpdateVideo(url);
    this.CurrentFile = url;
                }
        }
    
        /// <summary>
        /// Changes the local video.
        /// </summary>
        /// <param name="path">Path.</param>
        public void ChangeLocalVideo(string path)
        {
            if (this.UpdateLocalVideo != null)
            {
    this.UpdateLocalVideo(path);
    this.CurrentFile = path;
                }
        }
    
        /// <summary>
        /// Mute this instance.
        /// </summary>
        public void Mute()
        {
            if (this.MuteAction != null)
            {
    this.MuteAction();
                }
        }
    
        /// <summary>
        /// Uns the mute.
        /// </summary>
        public void UnMute()
        {
            if (this.UnmuteAction != null)
            {
    this.UnmuteAction();
                }
        }
    
        #endregion
    }
    

    Video view renderer for iOS.

    [assembly: ExportRenderer(typeof(VideoView), typeof(VideoViewRenderer))]
    namespace 
    {
            /// <summary>
            /// Video view renderer.
            /// </summary>
            public class VideoViewRenderer : ViewRenderer<VideoView, UIVideoView>
            {
                /// <summary>
                /// Ons the element changed.
                /// </summary>
                /// <param name="e">E.</param>
                protected override void OnElementChanged(ElementChangedEventArgs<VideoView> e)
            {
                base.OnElementChanged(e);
    
                if (e.NewElement != null)
                {
                    e.NewElement.PlayAction = (bool mute) => this.DoAction("PlayAction", mute, "");
                    e.NewElement.PauseAction = () => this.DoAction(this.Control.Pause);
                    e.NewElement.UpdateVideo = (string url) => this.DoAction("UpdateVideo", false, url);
                    e.NewElement.UpdateLocalVideo = (string path) => this.DoAction("UpdateLocalVideo", false, path);
                    e.NewElement.MuteAction = () => this.DoAction(this.Control.Mute);
                    e.NewElement.UnmuteAction = () => this.DoAction(this.Control.Unmute);
    
                    // The layout has a 1 pixel problem.
                    this.SetNativeControl(new UIVideoView(e.NewElement.FileSource, new CGSize(e.NewElement.WidthRequest  1, e.NewElement.HeightRequest)));
                    e.NewElement.CurrentFile = this.Control.CurrentFile();
                }
            }
    
            #region Private Methods
            private void DoAction(Action action)
            {
                if (this.Control != null)
                {
        action.Invoke();
                    }
            }
    
            private void DoAction(string actionType, bool mute, string url)
            {
                if (this.Control != null)
                {
                        switch (actionType)
                    {
                                case "PlayAction":
    this.Control.Play(mute);
                                    break;
                                case "UpdateVideo":
    this.Control.UpdateVideo(url);
                                    break;
                                case "UpdateLocalVideo":
    this.Control.UpdateLocalVideo(url);
                                    break;
                            }
                    }
            }
            #endregion
    
        }
    }
    

    The Video view for iOS.

    public class UIVideoView : UIView
    {
        #region Attributes
    
        private readonly Timer timer;
    
        private bool isPlaying;
    
        private AVPlayer player;
    
        private string currentFile;
    
        private AVPlayerLayer playerLayer;
    
        #endregion
    
        #region Public Methods
    
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Eyetime.Services.iOS.Controls.UIVideoView"/> class.
        /// </summary>
        /// <param name="file">File.</param>
        /// <param name="frame">Frame.</param>
        public UIVideoView(string file, CGSize size)
        {
            AVAsset asset = AVAsset.FromUrl(new NSUrl(file));
            AVPlayerItem playerItem = new AVPlayerItem(asset);
    
            this.player = new AVPlayer(playerItem);
            this.playerLayer = AVPlayerLayer.FromPlayer(player);
            this.playerLayer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill;
            this.playerLayer.Frame = new CGRect(new CGPoint(0, 0), size);
            this.Frame = new CGRect(new CGPoint(0, 0), size);
            this.Layer.BackgroundColor = UIColor.Black.CGColor;
    
            this.Layer.AddSublayer(this.playerLayer);
    
            UITapGestureRecognizer tap = new UITapGestureRecognizer(this.ProcessPlayPause);
            this.AddGestureRecognizer(tap);
            this.currentFile = ((AVUrlAsset)this.player.CurrentItem.Asset).Url.AbsoluteString;
    
            this.timer = new Timer(250);
            timer.AutoReset = false;
            timer.Elapsed += this.OnTimeElapsed;
        }
    
        /// <summary>
        /// Play the specified muted.
        /// </summary>
        /// <param name="muted">If set to <c>true</c> muted.</param>
        public void Play(bool muted = false)
        {
            this.player.Muted = muted;
            this.player.Play();
    
            this.isPlaying = true;
    
            if (!this.player.CurrentItem.PlaybackLikelyToKeepUp)
            {
                this.timer.Start();
            }
        }
    
        /// <summary>
        /// Stops the current video
        /// </summary>
        public void Pause()
        {
            this.timer.Stop();
            this.player.Pause();
            this.isPlaying = false;
        }
    
        /// <summary>
        /// Updates the video.
        /// </summary>
        /// <param name="url">URL.</param>
        public void UpdateVideo(string url)
        {
            AVAsset asset = AVAsset.FromUrl(new NSUrl(url));
            AVPlayerItem playerItem = new AVPlayerItem(asset);
    
            this.player.ReplaceCurrentItemWithPlayerItem(playerItem);
            this.currentFile = ((AVUrlAsset)this.player.CurrentItem.Asset).Url.AbsoluteString;
        }
    
        /// <summary>
        /// Updates the local video.
        /// </summary>
        /// <param name="path">Path.</param>
        public void UpdateLocalVideo(string path)
        {
            NSUrl url = NSUrl.CreateFileUrl(path, null);
            AVPlayerItem playerItem = new AVPlayerItem(url);
    
            this.player.ReplaceCurrentItemWithPlayerItem(playerItem);
            this.currentFile = ((AVUrlAsset)this.player.CurrentItem.Asset).Url.AbsoluteString;
        }
    
        /// <summary>
        /// Mute this instance.
        /// </summary>
        public void Mute()
        {
            this.player.Muted = true;
        }
    
        /// <summary>
        /// Unmute this instance.
        /// </summary>
        public void Unmute()
        {
            this.player.Muted = false;
        }
    
        /// <summary>
        /// Currents the file.
        /// </summary>
        /// <returns>The file.</returns>
        public string CurrentFile()
        {
            return this.currentFile;
        }
    
        /// <summary>
        /// Release this instance.
        /// </summary>
        public void Release()
        {
            if (this.player != null)
            {
                this.player.Pause();
                this.player = null;
                this.Layer.RemoveFromSuperLayer();
            }
        }
    
        #endregion
    
        #region Private Methods
    
        private void ProcessPlayPause()
        {
            if (this.isPlaying)
            {
                this.Pause();
            }
            else
            {
                this.Play();
            }
        }
    
        private void OnTimeElapsed(object sender, ElapsedEventArgs e)
        {
            if (this.player.CurrentItem.PlaybackLikelyToKeepUp)
            {
                this.player.Play();
            }
            else
            {
                this.timer.Start();
            }
        }
    
        #endregion
    }
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, April 5, 2017 11:10 AM
  • User302481 posted

    @Hunuman How can I use the plugin to show a modal?

    Im trying this but the video won't start:

    `public partial class MediaFormsPage : ContentPage { private IPlaybackController PlaybackController => CrossMediaManager.Current.PlaybackController;

        ProgressBar progress;
        Label duration;
    
        public MediaFormsPage()
        {
    
            Grid grid = new Grid();
    
            grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(4, GridUnitType.Star) });
            grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
    
            VideoView video = new VideoView { 
    
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                Source = "https://www.youtube.com/watch?v=pR30knJs4Xk"
            };
    
            grid.Children.Add(video, 0, 0);
    
            Grid gridInterna = new Grid {
                HorizontalOptions = LayoutOptions.FillAndExpand,
                Margin = 20
            };
            gridInterna.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            gridInterna.RowDefinitions.Add(new RowDefinition { Height = new GridLength(6, GridUnitType.Star) });
    
            gridInterna.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            gridInterna.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star)  });
            gridInterna.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
    
    
            progress = new ProgressBar();
            duration = new Label { 
    
                Text = "Duration: "
    
            };
    
            StackLayout botoes = new StackLayout {
    
                Orientation = StackOrientation.Vertical,
                Children = { 
                    new StackLayout{
                        Orientation = StackOrientation.Horizontal,
                        Children = {
                            duration,
    
                        }
                    },
                    progress
    
                }
            };
            gridInterna.Children.Add(botoes, 3, 0);
    
            grid.Children.Add(gridInterna, 0, 1);
    
    
            Button btn1 = new Button { 
    
                TextColor = Color.White,
                BackgroundColor = Color.Gray ,
                HeightRequest = 50,
                VerticalOptions = LayoutOptions.Center,
                Text = "Play",
                WidthRequest = 100
            };
    
            btn1.Clicked += PlayClicked;
    
            gridInterna.Children.Add(btn1, 0, 1);
    
    
            Content = grid;
    
    
            CrossMediaManager.Current.PlayingChanged += (sender, e) =>
            {
                progress.Progress = e.Progress;
                duration.Text = "" + e.Duration.TotalSeconds.ToString() + " seconds";
            };
    
        }
    
        void PlayClicked(object sender, System.EventArgs e)
        {
            PlaybackController.Play();
        }
    
        void PauseClicked(object sender, System.EventArgs e)
        {
            PlaybackController.Pause();
        }
    
        void StopClicked(object sender, System.EventArgs e)
        {
            PlaybackController.Stop();
        }
    }
    

    `

    Wednesday, April 5, 2017 2:03 PM
  • User302481 posted

    @DarioOrgaz Hi, I have found a solution more simple than yours. Check it if it works. I have only make it work in iOS.

    `public class VideoView : View { public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: "Uri", returnType: typeof(string), declaringType: typeof(VideoView), defaultValue: default(string));

        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }
    
    
    }`
    

    And the renderer:

    `public class VideoViewRenderer : ViewRenderer {

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);
    
    
            var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
    
            while (viewController.PresentedViewController != null)
            {
                viewController = viewController.PresentedViewController;
            }
    
            var customView = Element as VideoView;
    
            var filename = customView.Uri;
    
            var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var filename2 = Path.Combine(documents, filename);
    
            var url = new NSUrl(filename2, false);
    
    
            var avp = new AVPlayer(url);
            var avpvc = new AVPlayerViewController();
            avpvc.Player = avp;
            avp.Play();
    
            viewController.PresentViewController(avpvc, animated: true, completionHandler: null);
        }
    }`
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, April 7, 2017 10:27 AM
  • User146025 posted

    Hi @carlasampaio01

    You solution should work. The only thing, is if you want to add media controls like play and pause, you should create different actions.

    Friday, April 7, 2017 10:40 AM
  • User302481 posted

    @DarioOrgaz You don't need to create them. It already adds all of them. Like a youtube video.

    In android i used :

    `Android.Widget.VideoView videoPlayer; MediaController mediaController; string filename; private Activity activity;

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        {
            base.OnElementChanged(e);
    
    
            if (e.OldElement != null || Element == null)
            {
                return;
            }
    
            var customView = Element as VideoView;
    
            filename = customView.Uri;
    
            activity = Context as Activity;
            activity.SetContentView(Resource.Layout.Main);
    
            videoPlayer = activity.FindViewById<Android.Widget.VideoView>(Resource.Id.PlayerVideoView);
    
            var documents = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
            var filename2 = Path.Combine(documents, filename);
    
            videoPlayer.SetVideoURI(Android.Net.Uri.Parse(filename2));
    
            videoPlayer.SetMediaController(new MediaController(Context));
            videoPlayer.RequestFocus();
    
            videoPlayer.Prepared += (sender, preparedE) => videoPlayer.Start();
    
            videoPlayer.Start();
    
        }
    
        protected void OnStop()
        {
            videoPlayer.Prepared -= OnVideoPlayerPrepared;
        }
    
        private void OnVideoPlayerPrepared(object sender, EventArgs e)
        {   
            mediaController.Show(3000);
        }
    

    `

    But if I press back button it crashes.

    Friday, April 7, 2017 10:52 AM
  • User10457 posted

    @DarioOrgaz I have followed your sample. But it doens't play the video file at all. Sample video file is a url: https://archive.org/download/BigBuckBunny328/BigBuckBunny512kb.mp4

    Could you please post the sample of how you consume it from Xamarin.Forms?

    Thanks,.

    Thursday, September 20, 2018 3:25 PM
  • User130627 posted

    If using an emulator/simulator to test the video, those have shown in testing to have problems playing the video and in lots of cases, unable to play the video at all. I would suggest using a real device if at all possible.

    Thursday, September 20, 2018 3:53 PM
  • User10457 posted

    @TaylorD Hi,.. I am using physical device for my development. Btw,.. how do I call the Play Action from xaml? Do you have any sample?

    Friday, September 21, 2018 9:57 AM
  • User10457 posted

    @DarioOrgaz hmmm.... only managed to hear the audio of the video, but not the video image. I am using Xamarin.Forms.

    Friday, September 21, 2018 10:33 AM
  • User130627 posted

    @JeffLim I do it slightly different than @DarioOrgaz does it. I am using the AVPlayerLayer and AVPlayer in my VideoRenderer and also using my own video controls such as Play, Pause and such. I want to change it soon to the native video controls, but haven't gotten around to it yet. This solution works for me though.

    My renderer definition is of type:

    ViewRenderer<VideoPlayer, UIView>
    

    I construct the video player like below:

    _avPlayer = AVPlayer.FromUrl(NSUrl.FromString(Element.VideoUrl));
    _avPlayerLayer = AVPlayerLayer.FromPlayer(_AvPlayer);
    _avPlayerLayer.VideoGravity = AVLayerVideoGravity.ResizeAspect;
    
    Layer.AddSublayer(_avPlayerLayer);
    

    Then when I want to call Play or Pause, all I do is:

    _avPlayer?.Play();
    _avPlayer?.Pause();
    

    I do a null reference check just in case a button in the video might get hit before the control is initialized.

    Friday, September 21, 2018 1:22 PM