Android VideoView crop_center - android

I have a RelativeLayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:foregroundGravity="center"
android:gravity="center"
android:orientation="horizontal" >
<VideoView
android:id="#+id/videoViewPanel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_centerInParent="true"/>
</RelativeLayout>
And what I need is to show video fullscreen cropped. If I could compare to ImageView, I need to show it as crop_center.
How can I make VideoView not to auto-resize video to fit center, but crop center?

In Android's VideoView, here is a simple and easy way to achieve the same effect as ImageView.ScaleType.CENTER_CROP
xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:id="#+id/videoView"
android:layout_width="#dimen/dimen_0dp"
android:layout_height="#dimen/dimen_0dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
In JAVA:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
float videoRatio = mp.getVideoWidth() / (float) mp.getVideoHeight();
float screenRatio = videoView.getWidth() / (float)
videoView.getHeight();
float scaleX = videoRatio / screenRatio;
if (scaleX >= 1f) {
videoView.setScaleX(scaleX);
} else {
videoView.setScaleY(1f / scaleX);
}
}
});
In Kotlin:
videoView.setOnPreparedListener { mediaPlayer ->
val videoRatio = mediaPlayer.videoWidth / mediaPlayer.videoHeight.toFloat()
val screenRatio = videoView.width / videoView.height.toFloat()
val scaleX = videoRatio / screenRatio
if (scaleX >= 1f) {
videoView.scaleX = scaleX
} else {
videoView.scaleY = 1f / scaleX
}
}
And this worked for me. Hope this will help someone.

The solution is to use TextureView instead of VideoView(SurfaceView).
TextureView does not make any manipulations with the content to fit it ti the screen.
Here is the code sample for the solution:
//store the SurfaceTexture to set surface for MediaPlayer
mTextureView.setSurfaceTextureListener(new SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface,
int width, int height) {
FullScreenActivity.this.mSurface = surface;
}
....
Surface s = new Surface(mSurface);
mPlayer = mp;
mp.setSurface(s);
scaleVideo(mp);//<-- this function scales video to run cropped
....
private void scaleVideo(MediaPlayer mPlayer) {
LayoutParams videoParams = (LayoutParams) mTextureView
.getLayoutParams();
DisplayMetrics dm = new DisplayMetrics();
FullScreenActivity.this.getWindowManager().getDefaultDisplay()
.getMetrics(dm);
final int height = dm.heightPixels;
final int width = dm.widthPixels;
int videoHeight = mPlayer.getVideoHeight();
int videoWidth = mPlayer.getVideoWidth();
double hRatio = 1;
hRatio = (height * 1.0 / videoHeight) / (width * 1.0 / videoWidth);
videoParams.x = (int) (hRatio <= 1 ? 0 : Math.round((-(hRatio - 1) / 2)
* width));
videoParams.y = (int) (hRatio >= 1 ? 0 : Math
.round((((-1 / hRatio) + 1) / 2) * height));
videoParams.width = width - videoParams.x - videoParams.x;
videoParams.height = height - videoParams.y - videoParams.y;
Log.e(TAG, "x:" + videoParams.x + " y:" + videoParams.y);
mTextureView.setScaleX(1.00001f);//<-- this line enables smoothing of the picture in TextureView.
mTextureView.requestLayout();
mTextureView.invalidate();
}

I just put video inside ConstraintLayout with such parameters. This helped stretch video and achieve android:scaleType="centerCrop" effect.
<VideoView
android:id="#+id/video_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_gravity="center_horizontal"
android:layout_width="0dp"
android:layout_height="0dp" />

To crop center in fullscreen you can still use a VideoView. Set the VideoView width and height to match the parent inside a RelativeLayout and adjust it to be bigger than the screen and set his position.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rootLayout"
tools:context="com.example.Activity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_height="match_parent">
<VideoView
android:id="#+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_centerVertical="true" />
</RelativeLayout>
</RelativeLayout>
And then in onCreate:
RelativeLayout rootView=(RelativeLayout) findViewById(R.id.rootLayout);
Display display=getWindowManager().getDefaultDisplay();
Point size=new Point();
display.getSize(size);
FrameLayout.LayoutParams rootViewParams = (FrameLayout.LayoutParams) rootView.getLayoutParams();
int videoWidth=864;
int videoHeight=1280;
if ((float)videoWidth/(float)videoHeight<(float)size.x/(float)size.y) {
rootViewParams.width=size.x;
rootViewParams.height=videoHeight*size.x/videoWidth;
rootView.setX(0);
rootView.setY((rootViewParams.height-size.y)/2*-1);
} else {
rootViewParams.width=videoWidth*size.y/videoHeight;
rootViewParams.height=size.y;
rootView.setX((rootViewParams.width-size.x)/2*-1);
rootView.setY(0);
}
rootView.setLayoutParams(rootViewParams);
final VideoView mVideoView=(VideoView)findViewById(R.id.video_view);
mVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.splash));
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mVideoView.start();
}
});

I have found a solution: The default behavior is just like fitCenter , so I compute the video ratio(width/height) and screen ratio, and then scale the VideoView to full screen. The result is just like centerCrop .

Related

how to get width and height of videoview after video added

layout xml of videoview :
<RelativeLayout
android:id="#+id/videoEditorParent"
android:layout_width="match_parent"
android:layout_height="400dp">
<RelativeLayout
android:id="#+id/vidEditorWrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#color/colorAccent">
<VideoView
android:id="#+id/vidEditor"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</RelativeLayout>
when i get height and width of video view it gives me match_parent's width and height, but not aspect ratio width and height of video is playing in videoview(whatever width and height is covered in videoview by video).
here, my code :
viewWidth = vidEditor.getWidth();
viewHeight = vidEditor.getHeight();
ViewGroup.LayoutParams layoutParams = vidEditorWrapper.getLayoutParams();
dpWidthView = utilities.pxToDp(viewWidth);
dpHeightView = utilities.pxToDp(viewHeight);
dpWidthViewPerVal = (dpWidthView * 2) / 100;
layoutParams.width = viewWidth;
layoutParams.height = viewHeight;
vidEditorWrapper.setLayoutParams(layoutParams);
my screen shot :
i want width and height of black area that is video playing in videoview.
but getWidth() or getMeasuredWidth() and getHeight() or getMeasuredHeight() of videoview gives me match_parent width and height.
so, how can i get width and height of video area(only dark area that is visible to us in picture not full width) that is covered in videoview.
Try applying your code inside OnPreparedListener
For eg:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
viewWidth = vidEditor.getWidth();
viewHeight = vidEditor.getHeight();
ViewGroup.LayoutParams layoutParams =
vidEditorWrapper.getLayoutParams();
dpWidthView = utilities.pxToDp(viewWidth);
dpHeightView = utilities.pxToDp(viewHeight);
dpWidthViewPerVal = (dpWidthView * 2) / 100;
layoutParams.width = viewWidth;
layoutParams.height = viewHeight;
vidEditorWrapper.setLayoutParams(layoutParams);
}
});

Increase LinearLayout width from either right or left

I have a LinearLayout which is centered on the screen. It has a width less than the screen width. There are two buttons: Right-Arrow and Left-Arrow.
When the user presses the relevant button, the layout should increase its width from the relevant side. The other side should keep its position there.
Right now setting the width increases the layout from both sides equally. The layout needs to be initially centered and it has to expand from either side by user's input. (Use case is to find the width of relevant part of an image whose right and left sides have unequal borders, so the user has to mark them using my technique).
I am using following to increase width but it has the behaviour described above.
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)
llCropOverlay.getLayoutParams();
params.width = params.width + 1;
PS: This functionality was implemented in Tasker app since its early days; so it is possible.
EDIT:
Here is the layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:gravity="top"
android:layout_gravity="top"
android:id="#+id/iv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible" />
<LinearLayout
android:id="#+id/llRightLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<Button
android:id="#+id/bLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LEFT" />
<Button
android:id="#+id/bRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RIGHT" />
</LinearLayout>
<LinearLayout
android:layout_gravity="center_horizontal"
android:id="#+id/llCropOverlay"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#color/colorCropOverlay"
android:orientation="vertical" />
</FrameLayout>
</LinearLayout>
The last LinearLayout (llCropOverlay) should be resized. Note that I am programatically changing the width to 300 before using resizing the buttons so I can test if the buttons are working.
I have found an almost perfect solution (there is sometimes a problem with one pixel which is annoying - any suggestions will be appreciated).
For this, we need some variables set up. Firstly, the LinearLayout called llCropOverlay must be found and identified.
Here is its xml:
<LinearLayout
android:layout_gravity="center_horizontal"
android:id="#+id/llCropOverlay"
android:layout_width="200dp"
android:layout_height="150dp"
android:background="#color/colorCropOverlay"
android:orientation="vertical" />
Now before allowing user to interact we need to find the original position of the llCropOverlay. So use this in OnCreate():
llCropOverlay.post(new Runnable() {
#Override
public void run() {
orgX = llCropOverlay.getX();
}
});
Now set up all the buttons and set a setOnTouchListener() on these buttons. Then when the listener is called, pass the touched button in the following method. Use a Handler and postDelayed() to keep calling this method till the button is pressed. Or call it once to resize by one pixel row/column.
void handleTouchOrClick(View view) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)
llCropOverlay.getLayoutParams();
switch (view.getId()) {
case R.id.bUp:
params.height = params.height - 1;
break;
case R.id.bDown:
params.height = params.height + 1;
break;
case R.id.bRight:
params.width = params.width + 1;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
case R.id.bRightContract:
params.width = params.width - 1;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
case R.id.bLeft:
params.width = params.width + 1;
orgX--;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
case R.id.bLeftContract:
params.width = params.width - 1;
orgX++;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
}
llCropOverlay.setLayoutParams(params);
}
Now here's how we actually resize the image:
For ease of users I am cropping it in two steps.
Crop from sides:
ViewGroup.MarginLayoutParams params =
(ViewGroup.MarginLayoutParams) llCropOverlay.getLayoutParams();
float eventX = params.width;
float eventY = 0;
float[] eventXY = new float[]{eventX, eventY};
Matrix invertMatrix = new Matrix();
imageView.getImageMatrix().invert(invertMatrix);
invertMatrix.mapPoints(eventXY);
int x = Integer.valueOf((int) eventXY[0]);
int y = Integer.valueOf((int) eventXY[1]);
int height = params.height;
while (height * 3 > originalBitmap.getHeight()) {
height = height - 10;
}
croppedBitmapByWidth = Bitmap.createBitmap(originalBitmap, (int) orgX, 0,
x, height);
imageView.setImageBitmap(croppedBitmapByWidth);
crop from bottom:
float eventX2 = 0;
float eventY2 = params.height;
float[] eventXY2 = new float[]{eventX2, eventY2};
Matrix invertMatrix2 = new Matrix();
imageView.getImageMatrix().invert(invertMatrix2);
invertMatrix2.mapPoints(eventXY2);
int x2 = Integer.valueOf((int) eventXY2[0]);
int y2 = Integer.valueOf((int) eventXY2[1]);
croppedBitmapByHeight = Bitmap.createBitmap(croppedBitmapByWidth, 0, 0,
croppedBitmapByWidth.getWidth(), y2);
imageView.setImageBitmap(croppedBitmapByHeight);

Center Crop an Android VideoView

I am looking for something like the CENTER_CROP in ImageView.ScaleType
Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding). The image is then centered in the view. From XML, use this syntax: android:scaleType="centerCrop"
but for a VideoView. Does anything like this exist?
You can only achieve this with a TextureView. (surfaceView won't work either). Here's a lib for playing video in a textureView with center crop function. TextureView can only be used in api level 14 and up unfortunately.
https://github.com/dmytrodanylyk/android-video-crop
Another possibility is to zoom in the videoview just right, but I haven't tried that yet.
The simple and easy way if you are using ConstraintLayout.
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:id="#+id/videoView"
android:layout_width="#dimen/dimen_0dp"
android:layout_height="#dimen/dimen_0dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
then
In Kotlin:
videoView.setOnPreparedListener { mediaPlayer ->
val videoRatio = mediaPlayer.videoWidth / mediaPlayer.videoHeight.toFloat()
val screenRatio = videoView.width / videoView.height.toFloat()
val scaleX = videoRatio / screenRatio
if (scaleX >= 1f) {
videoView.scaleX = scaleX
} else {
videoView.scaleY = 1f / scaleX
}
}
See my Java version answer here:
https://stackoverflow.com/a/59069357/6255841
And this worked for me.
Nabin's answer worked for me.
Here is the Java version:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
float videoRatio = mp.getVideoWidth() / (float) mp.getVideoHeight();
float screenRatio = videoView.getWidth() / (float) videoView.getHeight();
float scaleX = videoRatio / screenRatio;
if (scaleX >= 1f) {
videoView.setScaleX(scaleX);
} else {
videoView.setScaleY(1f / scaleX);
}
}
});
//store the SurfaceTexture to set surface for MediaPlayer
mTextureView.setSurfaceTextureListener(new SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface,
int width, int height) {
FullScreenActivity.this.mSurface = surface;
}
Just manage overhang of the video out of FrameLayout
<FrameLayout
android:id="#+id/videoViewHolder"
android:layout_width="match_parent"
android:layout_height="200dp"
tools:visibility="visible">
<VideoView
android:id="#+id/videoView"
android:layout_width="match_parent"
android:layout_height="1000dp"
android:layout_gravity="center"/>
</FrameLayout>

VideoView audio only, no video?

I have a Video view in my activity used to display a video stored in my res.raw folder like this:
MediaController controller=new MediaController(this);
video.setMediaController(controller);
String filePath="android.resource://" + getPackageName() + "/" + R.raw.video3;
video.setVideoURI(Uri.parse(filePath));
video.requestFocus();
video.start();
The problem is that I can hear the audio only, but the video is not shown.
What can be the reason for this?
Edit: here's my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="#+id/btnPlayAudio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play Audio"
>
</Button>
<Button
android:id="#+id/btnPlayVideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play Video"
>
</Button>
<VideoView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/videoView"
/>
</LinearLayout>
OK I got it,
the problem was that my VideoView had width and height set to wrap_content when I changed to fill_parent, the video appeared
thanks
Your overcomplicating it :-)
MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);
mp.start();
Linky: Play from Raw Resource
Create a custom VideoPlayer by extending VideoView class and use it:
public class VideoPlayer extends VideoView {
public VideoPlayer(Context context) {
super(context);
init();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
TyrooLog.i(TAG, "onMeasure");
int width = getDefaultSize(videoWidth, widthMeasureSpec);
int height = getDefaultSize(videoHeight, heightMeasureSpec);
if (videoWidth > 0 && videoHeight > 0) {
if (videoWidth * height > width * videoHeight) {
TyrooLog.i(TAG, "video too tall, correcting");
height = width * videoHeight / videoWidth;
} else if (videoWidth * height < width * videoHeight) {
TyrooLog.i(TAG, "video too wide, correcting");
width = height * videoWidth / videoHeight;
} else {
TyrooLog.i(TAG, "aspect ratio is correct: " + width+"/"+height+"="+mVideoWidth+"/"+mVideoHeight);
}
}
TyrooLog.i(TAG, "setting size: " + width + 'x' + height);
setMeasuredDimension(width, height);
}
}
}
My issue was only happening when I used an emulator, it worked fine when i tried it on a real device

Position Video Inside a VideoView

So I have extended VideoView's onMeasure to scale up the video to fit inside a fullscreen view.
here is how:
public void setVideoAspect(int w,int h){
wVideo=w;
hVideo=h;
onMeasure(w, h);
}
#Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(wVideo!=0 && hVideo!=0)
setMeasuredDimension(wVideo,hVideo);
}
I call setVideoAspect() with the display metrics (width, hight) of the screen. The problem is that this method stretches the video to fit inside the screen. I want to be able to keep the aspect ratio. (I have 4:3 video and 3:2 screen size.) I used the folowing code to give the retained ratio measurements to the view:
int height = (int) (metrics.widthPixels*3/(float)4);
int width= metrics.widthPixels;
mVideoView.setVideoAspect(width,height);
So this does the job but there is an issue: it gives me a 4:3 video with the width of the screen and scales the height correctly, but it doesn't center the video. (It just crops the bottom part of the video instead of the top and the bottom equally.) I have a relative layout containing the VideoView with the gravity of the VideoView set to center.
Try using a FrameLayout instead. I'm not sure why, but if I use a Linear or Relative in my code it won't center, but FrameLayout does. Here is the XML that fit my video to the screen, preserving the ratio and centering it:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg">
<!-- Video player -->
<VideoView
android:id="#+id/surface_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"/>
</FrameLayout>
In order to center the video in the RelativeLayout I added both layout_gravity="center" ad layout_centerInParent="true". It works on my Android 4.3 phone.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView android:id="#+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_centerInParent="true" />
</RelativeLayout>
Cameron's Answer in a programmatic way(in case someone like me needs it) This code is inside onCreate of an activity in my code( 'this' below refers to the activity)
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
FrameLayout fl = new FrameLayout(this);
fl.setLayoutParams(lp);
VideoView vv = new VideoView(this);
FrameLayout.LayoutParams lp2 = new FrameLayout.LayoutParams(lp);
lp2.gravity = Gravity.CENTER;
vv.setLayoutParams(lp2);
fl.addView(vv);
setContentView(fl);
This works for any video keeping the video's aspect ratio. It positions the video inside the VideoView and performs a Center Crop or a Center Inside just like an ImageView.
I am using a VideoView to cover the whole ConstraintLayout. You can use any other layout probably with match_parent as width and height.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:id="#+id/videoView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
In onCreate:
Uri uri = //The uri of your video.
VideoView videoView = findViewById(R.id.videoView);
videoView.setVideoURI(uri);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
//Get your video's width and height
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
//Get VideoView's current width and height
int videoViewWidth = videoView.getWidth();
int videoViewHeight = videoView.getHeight();
float xScale = (float) videoViewWidth / videoWidth;
float yScale = (float) videoViewHeight / videoHeight;
//For Center Crop use the Math.max to calculate the scale
//float scale = Math.max(xScale, yScale);
//For Center Inside use the Math.min scale.
//I prefer Center Inside so I am using Math.min
float scale = Math.min(xScale, yScale);
float scaledWidth = scale * videoWidth;
float scaledHeight = scale * videoHeight;
//Set the new size for the VideoView based on the dimensions of the video
ViewGroup.LayoutParams layoutParams = videoView.getLayoutParams();
layoutParams.width = (int)scaledWidth;
layoutParams.height = (int)scaledHeight;
videoView.setLayoutParams(layoutParams);
}
});
Hope it helps someone!
If you are looking for the same effect as ImageView.ScaleType.CENTER_CROP feature in VideoView then
Here is a simple and easy solution
See my XML and Kotlin version answer here:
https://stackoverflow.com/a/59069292/6255841
In JAVA:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
float videoRatio = mp.getVideoWidth() / (float) mp.getVideoHeight();
float screenRatio = videoView.getWidth() / (float)
videoView.getHeight();
float scaleX = videoRatio / screenRatio;
if (scaleX >= 1f) {
videoView.setScaleX(scaleX);
} else {
videoView.setScaleY(1f / scale);
}
}
});

Categories

Resources