package org.yczbj.ycvideoplayerlib.view; import android.content.Context; import android.util.AttributeSet; import android.view.SurfaceView; /** *
* @author yangchong * blog : https://github.com/yangchong211 * time : 2017/10/21 * desc : 重写SurfaceView,适配视频的宽高和旋转 * revise: **/ public class VideoSurfaceView extends SurfaceView { private int videoHeight; private int videoWidth; public VideoSurfaceView(Context context) { super(context); } public VideoSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); } public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } /** * 自定义video大小 * @param videoWidth 宽 * @param videoHeight 高 */ public void adaptVideoSize(int videoWidth, int videoHeight) { if (this.videoWidth != videoWidth && this.videoHeight != videoHeight) { this.videoWidth = videoWidth; this.videoHeight = videoHeight; requestLayout(); } } /** * 记得一定要重新写这个方法,如果角度发生了变化,就重新绘制布局 * 设置视频旋转角度 * @param rotation 角度 */ @Override public void setRotation(float rotation) { if (rotation != getRotation()) { super.setRotation(rotation); requestLayout(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { float viewRotation = getRotation(); // 如果判断成立,则说明显示的TextureView和本身的位置是有90度的旋转的,所以需要交换宽高参数。 if (viewRotation == 90f || viewRotation == 270f) { int tempMeasureSpec = widthMeasureSpec; //noinspection SuspiciousNameCombination widthMeasureSpec = heightMeasureSpec; heightMeasureSpec = tempMeasureSpec; } int width = getDefaultSize(videoWidth, widthMeasureSpec); int height = getDefaultSize(videoHeight, heightMeasureSpec); if (videoWidth > 0 && videoHeight > 0) { int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) { // the size is fixed width = widthSpecSize; height = heightSpecSize; // for compatibility, we adjust size based on aspect ratio if (videoWidth * height < width * videoHeight) { width = height * videoWidth / videoHeight; } else if (videoWidth * height > width * videoHeight) { height = width * videoHeight / videoWidth; } } else if (widthSpecMode == MeasureSpec.EXACTLY) { // only the width is fixed, adjust the height to match aspect ratio if possible width = widthSpecSize; height = width * videoHeight / videoWidth; if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) { // couldn't match aspect ratio within the constraints height = heightSpecSize; width = height * videoWidth / videoHeight; } } else if (heightSpecMode == MeasureSpec.EXACTLY) { // only the height is fixed, adjust the width to match aspect ratio if possible height = heightSpecSize; width = height * videoWidth / videoHeight; if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) { // couldn't match aspect ratio within the constraints width = widthSpecSize; height = width * videoHeight / videoWidth; } } else { // neither the width nor the height are fixed, try to use actual video size width = videoWidth; height = videoHeight; if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) { // too tall, decrease both width and height height = heightSpecSize; width = height * videoWidth / videoHeight; } if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) { // too wide, decrease both width and height width = widthSpecSize; height = width * videoHeight / videoWidth; } } } else { // no size yet, just adopt the given spec sizes } setMeasuredDimension(width, height); } }