GhosT
GhosT

Reputation: 25

Xamarin video player component stretch videos on Android

I have a Xamarin forms projects and I needed to show videos inside a grid, so I have purchased this video player component: Octane VideoPlayer

and it works well on IOS, but in android it not respect the aspect ratio, many videos are stretched.

I tried a custom render for this video player but nothing changes,and when I put breakpoints I discovered that the code for render is never reached.

Have I missed something ?

example

cs:

   public partial class VideoPlayer : ContentPage
{
    public VideoPlayerPage()
    {

        InitializeComponent();
        VideoPlayer.Source = "16/9_video.mp4";
    }
}

custom render:

[assembly: ExportRenderer(typeof(Octane.Xam.VideoPlayer.VideoPlayer), typeof(Assayil.Droid.VideoPlayerExtRenderer))]

**

public  class VideoPlayerExtRenderer : VideoPlayerRenderer
{

    protected override void OnElementChanged(ElementChangedEventArgs<VideoPlayer> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            Control.Started += (s2, e2) =>
            {
                UpdateVideoSize();
                Control.Player.VideoSizeChanged += (s3, e3) => UpdateVideoSize();
            };
        }
    }

    protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        base.OnLayout(changed, l, t, r, b);

        UpdateVideoSize();
    }

    private void UpdateVideoSize()
    {
        if (Element.FillMode == FillMode.Resize)
        {
            Control.Layout(0, 0, Width, Height);
            return;
        }

        // assume video size = view size if the player has not been loaded yet
        var videoWidth = Control.Player?.VideoWidth ?? Width;
        var videoHeight = Control.Player?.VideoHeight ?? Height;

        var scaleWidth = (double)Width / (double)videoWidth;
        var scaleHeight = (double)Height / (double)videoHeight;

        double scale;
        switch (Element.FillMode)
        {
            case FillMode.ResizeAspect:
                scale = Math.Min(scaleWidth, scaleHeight);
                break;
            case FillMode.ResizeAspectFill:
                scale = Math.Max(scaleWidth, scaleHeight);
                break;
            default:
                // should not happen
                scale = 1;
                break;
        }

        var scaledWidth = (int)Math.Round(videoWidth * scale);
        var scaledHeight = (int)Math.Round(videoHeight * scale);

        // center the video
        var l = (Width - scaledWidth) / 2;
        var t = (Height - scaledHeight) / 2;
        var r = l + scaledWidth;
        var b = t + scaledHeight;
        Control.Layout(l, t, r, b);
    }
}

Upvotes: 1

Views: 1739

Answers (2)

NPC
NPC

Reputation: 63

Placing the VideoPlayer within a Frame, then placing that within StackLayout set to CenterAndExpand for VerticalOptions should do the trick. Works perfectly for Android though you may want to make it platform dependent, it will play with container size in iOS (the video will look fine, but the controller looks better without this fix).

Upvotes: 1

Adam
Adam

Reputation: 4780

I am the author of the component. This is a well-known issue and I have spent considerable time trying to correct it but unfortunately I have yet to find a stable solution. The most common suggestion comes from a blog which recommends wrapping the VideoView inside a RelativeLayout as shown below but doing so yielded no improvement during my testing.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <VideoView android:id="@+id/videoViewRelative"
         android:layout_alignParentTop="true"
         android:layout_alignParentBottom="true"
         android:layout_alignParentLeft="true"
         android:layout_alignParentRight="true"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent">
    </VideoView>

</RelativeLayout>

Source: http://blog.kasenlam.com/2012/02/android-how-to-stretch-video-to-fill.html

The code you have pasted above is a workaround that has worked well for some people but again, my testing did not show it to be stable enough for inclusion. As soon as I can identify a proper solution for this I will certainly push it out to all users.

Upvotes: 0

Related Questions