Xamarin.Forms.VideoPlayer
Xamarin.Forms.VideoPlayer copied to clipboard
The FillMode / Aspect Ratio doesn't seem to work on Android
I have a single Video component inside a grid on the main page. Using Chill Player as the example. No matter what value this is set, the video (using included video.mp4) always stretches. I realized that there's a default Width and Height set to the component, so specifying HorizontalOptions and VerticalOptions as Center reveals this. If I set those explicitly (e.g. 400x100), the video stretches to those dimensions regardless of the value of FillMode.
There are some workarounds for this but it is a well-known and unfortunately not easy to address issue. Android is just not very nice when it comes to supporting aspect ratios properly.
Android's resolution appears stretched for some videos. Need to identify a fix to optimize resolutions for different device orientations (http://blog.kasenlam.com/2012/02/android-how-to-stretch-video-to-fill.html)
Wrap the native video player in a layout manager according to the FillMode property:
- Resize - No layout manager
- ResizeAspect - LinearLayout
- ResizeAspectFill - RelativeLayout
Is there any way I can get access to that link? its telling my access denied.. I have the same issue and its quite frustrating to pay and a keyfeature like this is not working.
Sorry, the issue queue was migrated to GitHub and didn't want people posting there. This solution is originally from Dominik Weber but has not been integrated since testing has shown there are still some stability issues but YMMV.
class VideoPlayerExtRenderer : VideoPlayerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<VideoPlayer> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Control.Prepared += (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);
}
}
WARNING: this code is not heavily tested, so if you want to use it please run some tests first. Might need some null checks for Element and Control properties.
I have called UpdateVideoSize and attached the VideoSizeChanged event handler in the VideoView.Prepared event, but you might want to find a better place to put these calls, ensuring the Player property is set BEFORE Player.VideoSizeChanged is set. UpdateVideoSize also should be invoked when the FillMode property is changed to resize the video.
Applying a custom layout to the video view will cause a transparent background on the letterbox area, which can be solved by setting the background color of the VideoPlayer XForms view to black (maybe set this as default to be consistent across platforms?)
A version of Dominik's code was included in 1.2.1 but I'm thinking it only works for simple scenarios based on my testing. IllegalStateExceptions
seem to be the most common issue in 1.2.1 if orientation changes happen at incorrect times and the video width is retrieved.
The incremental fix mentioned in my previous comment has been removed in 1.2.2 as it caused issue another issue. Dominik's code has been very helpful but I have found not to work in every case.
Since this appears to be native/platform behavior I will leave it as optional if users wish to incorporate the code mentioned above as a solution to see if it works for their specific case. Any future updates to the Android platform will be monitored for changes to support a resolution for this issue
Been bumping into this problem again. Has any driod changes made this possible yet?
Still a Problem in Android Version 2.2.0, but works fine in iOS.
It looks like there were some efforts to fix this in 2017, but I am still running into this issue. What is the recommended resolution for preserving the aspect ratio on Android?
I am experiencing this as well. I tried implementing the custom renderer above, but it isn't being picked up. I don't think I'm doing it wrong. I've got several custom renderers in my project. But none of the events are firing - like I forgot to put in the ExportRenderer statement or something.
I do have to say that this is pretty disappointing. I paid money for this plugin, and this has been sitting unaddressed for two years. This makes the Android version unusable.
@hauteur Same here; paid for the plugin, and still waiting for a response
I cannot use this plugin because it doesnt show video in proper ratio. Please fix it.
Fork to code, include in your solution and add above code https://github.com/adamfisher/Xamarin.Forms.VideoPlayer/issues/3#issuecomment-324187000 to your Droid renderer, worked for me.
The above code worked for me too.