Forum Libraries, Components, and Plugins

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Xamarin - Forms - Show a Lottie Animation on top fo VideoPlayer not synchronized

I'm working on a Xammarin project that shows a Lottie Animation on top of a Video and I need it Synchronized on time.

I have tried to make sync inside the Video Player renderer in Android passing the animation view:

 void OnUpdateStatus(object sender, EventArgs args)
    {
        VideoStatus status = VideoStatus.NotReady;
        var startTime = new TimeSpan(0, 0, 0);
        if (isPrepared)
        {
            status = videoView.IsPlaying ? VideoStatus.Playing : VideoStatus.Paused;
            if (_animationView != null)
            {
                Device.StartTimer(TimeSpan.FromMilliseconds(mentalPlay.Constants.ANIMATION_DELAY), () =>
                {
                    if (videoView.IsPlaying)
                    {
                        _animationView.Progress =     (float)TimeSpan.FromMilliseconds(videoView.CurrentPosition).TotalMilliseconds /     (float)videoView.Duration;

                        return true;
                    }
                    _animationView.Stop();
                    return false;
                });

            }
        }

        ((IVideoPlayerController)Element).Status = status;

        // Set Position property
        TimeSpan timeSpan = TimeSpan.FromMilliseconds(videoView.CurrentPosition);
        ((IElementController)Element).SetValueFromRenderer(VideoPlayer.PositionProperty, timeSpan);

    }

I have also tried to sync from the Lottie Animation Renderer creating a new Method:

 private void OnSincronize(object sender, LottieAnimationEventArgs e)
    {
        if (_animationView != null
            && _animationView.Handle != IntPtr.Zero)
        {
            if (e.MVDuration > 0)
            {
                //  Console.WriteLine($"progress lottieantes: {_animationView.Progress.ToString()}");
                var timeElapsed = (e.VideoPlayer.Duration.Ticks - e.VideoPlayer.Position.Ticks) / TimeSpan.TicksPerMillisecond;
                float percentage = (float)(timeElapsed) / (float)e.VideoPlayer.Duration;
                _animationView.Progress = percentage;
                //Console.WriteLine($"progress lottie después: {_animationView.Progress.ToString()}");
            }

        }
    }

The LottieAnimationEventArgs was created to pass VideoPlayer to de LottieAnimation:

public class LottieAnimationEventArgs:EventArgs
{
    private readonly VideoPlayer _videoPlayer;

    public LottieAnimationEventArgs(VideoPlayer videoPlayer)
    {
        _videoPlayer = videoPlayer;
    }

    public VideoPlayer VideoPlayer
    {
        get { return _videoPlayer; }
    }

}

This is the code in the PCL project:

 videoPlayer.Play();
        Device.StartTimer(TimeSpan.FromMilliseconds(100), () =>
        {
            if (videoPlayer.Status == VideoStatus.NotReady)
            {
                return true;
            }
            if (videoPlayer.TimeToEnd <= (TimeSpan.FromMilliseconds(100)))
            {
                animationView.Play(videoPlayer);
                Device.StartTimer(TimeSpan.FromMilliseconds(100), () =>
                {
                    if (animationView.IsPlaying)
                    {
                        animationView.Sincronize(videoPlayer);
                        return true;
                    }
                    return false;
                });
                return false;
            }
            return true;
        });

Finally I have usede MVVC to pass Progress to the Lottie Animation View

  <video:VideoPlayer 
                    Grid.Row="0"
                    x:Name="videoPlayer"
                    VerticalOptions="FillAndExpand"
                    HeightRequest="200"
                    AreTransportControlsEnabled="False" />
                <controls:MyAnimationLayout 
                    Grid.Row="0"
                    Progress="{Binding AnimationProgress}"
                    x:Name="animationView"
                    BackgroundColor="Transparent"  />

videoPlayer.Play();
Device.StartTimer(TimeSpan.FromMilliseconds(100), () =>
            {
                if (videoPlayer.Status == VideoStatus.NotReady)
                {
                    return true;
                }
                if (mainVM.AnimationProgress <= 1f)
                {

                    try
                    {
                        if (primer)
                        {
                            //To play from the progress to end of the animation
animationView.PlayProgressSegment(MainViewModel.GetInstance().AnimationProgress, 1f);
                            primer = false;
                        }                        
                    }
                    catch (Exception)
                    {
                    }
                }
                else
                {
                    return false;
                }
                return true;
            });
        }

In the Method OnUpdateStatus of the Video Player Renderer:

    // Set Position property
        TimeSpan timeSpan = TimeSpan.FromMilliseconds(videoView.CurrentPosition);
        ((IElementController)Element).SetValueFromRenderer(VideoPlayer.PositionProperty, timeSpan);
        MainViewModel.GetInstance().AnimationProgress = (float)(timeSpan.TotalMilliseconds)/ videoView.Duration;

I think that the solution would be to sync Frame by Frame getting the current Frame in the Video Player and then playing that frame in the Lottie Animation. Both video and animation have the same duration and fps.

Any help would be appreciated.

Thanks in advance.

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    Xamarin forms doesn't have a control called VideoPlayer. And I can't fully understand what you want to achieve from the code snippet you posted.
    Could you please share an entire sample here? I need it to get how you consume the custom renderer and how you synchronize this animation.

  • msegcedmsegced ESMember

    Sorry, you are right, I ment FormsVideoLibrary (I cannot post the link but I got it from the Xamarin page)

    I am preparing a POC to post here but in short, what i am trying to achieve is to play a Lottie Animation View over a VideoView in Android by now and synchronize both players.

    Thanks

  • LandLuLandLu Member, Xamarin Team Xamurai

    I got what your wanted to achieve now.
    I will look into it and try my best to find out the root cause after you post the sample here.

Sign In or Register to comment.