Skip to content

Snappy1

  • Home
  • Android
  • What
  • How
  • Is
  • Can
  • Does
  • Do
  • Why
  • Are
  • Who
  • Toggle search form

[FIXED] xaml – Xamarin Forms Video player (Native)

Posted on November 11, 2022 By

Solution 1 :

In Android

Because the demo of link used MediaControllerin VideoPlayerRenderer.cs, MediaController do not provide method about ScrollChangeListener.
https://developer.android.com/reference/android/widget/MediaController#public-methods

Normaly, we should create a custom SeekBarfor VideoView, then add the ScrollChangeListener.

Becuase create a custom SeekBar is a little complicated, we can use context.Resources.GetIdentifier("mediacontroller_progress", "id", "android"); to get the SeekBar of mediacontroller by ID, then set the SetOnSeekBarChangeListener as well.

        int seekbarId = context.Resources.GetIdentifier("mediacontroller_progress", "id", "android");
        SeekBar seekBar = mediaController.FindViewById<SeekBar>(seekbarId);
        seekBar.SetOnSeekBarChangeListener(new MySeekBarChangeListener());

Please Note:the instantiation of the SeekBar must occur in the VideoView.onPrepared(..) Callback method.

Here is running GIF.
enter image description here

Here are all of code about VideoPlayerRenderer

[assembly: ExportRenderer(typeof(FormsVideoLibrary.VideoPlayer),
                          typeof(FormsVideoLibrary.Droid.VideoPlayerRenderer))]

namespace FormsVideoLibrary.Droid
{
    public class VideoPlayerRenderer : ViewRenderer<VideoPlayer, ARelativeLayout>
    {
        VideoView videoView;
        MediaController mediaController;    // Used to display transport controls
        bool isPrepared;
        Context context;
        public VideoPlayerRenderer(Context context) : base(context)
        {
           this.context = 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;

            int seekbarId = context.Resources.GetIdentifier("mediacontroller_progress", "id", "android");
            SeekBar seekBar = mediaController.FindViewById<SeekBar>(seekbarId);
            seekBar.SetOnSeekBarChangeListener(new MySeekBarChangeListener());
            ((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();
        }
    }



    internal class MySeekBarChangeListener : Java.Lang.Object, SeekBar.IOnSeekBarChangeListener
    {
        public void OnProgressChanged(SeekBar seekBar, int progress, bool fromUser)
        {
            var on = "ss";

        }

        public void OnStartTrackingTouch(SeekBar seekBar)
        {
            var on = "ss";

        }

        public void OnStopTrackingTouch(SeekBar seekBar)
        {

        }
      }
    }

Problem :

Hi all I developed xamarin media player by help of this link its working perfectly
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/video-player/
but I want to know how to capture an event when user change position of the seek-bar.
please Help

READ  [FIXED] It is possible to show page in own activity in Xamarin.Forms on Android?
Powered by Inline Related Posts

enter image description here

Thanks in advance

Comments

Comment posted by Maalik

Thanks bro . If you can ,can you please provide me IOS code as well

Comment posted by Maalik

HI this code is working perfectly but I couldn’t able get current position of the slider .can you help get it . thanks in advance

Comment posted by Leon Lu – MSFT

Please see this method

Android Tags:xamarin, xamarin.android, xamarin.forms, xamarin.ios, xaml

Post navigation

Previous Post: [FIXED] java – The Android LoaderManager is deprecated. Now what?
Next Post: [FIXED] android – Is WorkManager the right solution for me?

Related Posts

[FIXED] How to make boardgame for android using flutter Android
[FIXED] android – Camera2 background repeating capture session errors when screen is toggled from off to on Android
[FIXED] android – how can i fix this error of my todo list? Android
[FIXED] How to navigate from Flutter Page to Native Android Page Android
[FIXED] android – ViewModelFactory need Android
[FIXED] android – Difference between Exception and JSONException in try-catch Android

Archives

  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuándo
  • ¿Cuántas
  • ¿Cuánto
  • ¿Qué
  • Android
  • Are
  • At
  • C'est
  • Can
  • Comment
  • Did
  • Do
  • Does
  • Est-ce
  • Est-il
  • For
  • Has
  • Hat
  • How
  • In
  • Is
  • Ist
  • Kann
  • Où
  • Pourquoi
  • Quand
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welchen
  • Welcher
  • Welches
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Who's
  • Why
  • Wie
  • Will
  • Wird
  • Wo
  • Woher
  • you can create a selvedge edge: You can make the edges of garter stitch more smooth by slipping the first stitch of every row.2022-02-04
  • you really only need to know two patterns: garter stitch

Recent Posts

  • What is a good substitute for condensed milk?
  • ¿Como el cuerpo te avisa cuando te va a dar un infarto?
  • What is the luxury brand of Jaguar?
  • Who is Big poppa baseball player?
  • What material are foam runners?

Recent Comments

No comments to show.

Copyright © 2023 Snappy1.

Powered by PressBook Grid Dark theme