VideoSurfaceView.java 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package org.yczbj.ycvideoplayerlib.view;
  2. import android.content.Context;
  3. import android.util.AttributeSet;
  4. import android.view.SurfaceView;
  5. /**
  6. * <pre>
  7. * @author yangchong
  8. * blog : https://github.com/yangchong211
  9. * time : 2017/10/21
  10. * desc : 重写SurfaceView,适配视频的宽高和旋转
  11. * revise:
  12. * </pre>
  13. */
  14. public class VideoSurfaceView extends SurfaceView {
  15. private int videoHeight;
  16. private int videoWidth;
  17. public VideoSurfaceView(Context context) {
  18. super(context);
  19. }
  20. public VideoSurfaceView(Context context, AttributeSet attrs) {
  21. super(context, attrs);
  22. }
  23. public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
  24. super(context, attrs, defStyleAttr);
  25. }
  26. /**
  27. * 自定义video大小
  28. * @param videoWidth 宽
  29. * @param videoHeight 高
  30. */
  31. public void adaptVideoSize(int videoWidth, int videoHeight) {
  32. if (this.videoWidth != videoWidth && this.videoHeight != videoHeight) {
  33. this.videoWidth = videoWidth;
  34. this.videoHeight = videoHeight;
  35. requestLayout();
  36. }
  37. }
  38. /**
  39. * 记得一定要重新写这个方法,如果角度发生了变化,就重新绘制布局
  40. * 设置视频旋转角度
  41. * @param rotation 角度
  42. */
  43. @Override
  44. public void setRotation(float rotation) {
  45. if (rotation != getRotation()) {
  46. super.setRotation(rotation);
  47. requestLayout();
  48. }
  49. }
  50. @Override
  51. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  52. float viewRotation = getRotation();
  53. // 如果判断成立,则说明显示的TextureView和本身的位置是有90度的旋转的,所以需要交换宽高参数。
  54. if (viewRotation == 90f || viewRotation == 270f) {
  55. int tempMeasureSpec = widthMeasureSpec;
  56. //noinspection SuspiciousNameCombination
  57. widthMeasureSpec = heightMeasureSpec;
  58. heightMeasureSpec = tempMeasureSpec;
  59. }
  60. int width = getDefaultSize(videoWidth, widthMeasureSpec);
  61. int height = getDefaultSize(videoHeight, heightMeasureSpec);
  62. if (videoWidth > 0 && videoHeight > 0) {
  63. int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
  64. int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
  65. int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
  66. int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
  67. if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
  68. // the size is fixed
  69. width = widthSpecSize;
  70. height = heightSpecSize;
  71. // for compatibility, we adjust size based on aspect ratio
  72. if (videoWidth * height < width * videoHeight) {
  73. width = height * videoWidth / videoHeight;
  74. } else if (videoWidth * height > width * videoHeight) {
  75. height = width * videoHeight / videoWidth;
  76. }
  77. } else if (widthSpecMode == MeasureSpec.EXACTLY) {
  78. // only the width is fixed, adjust the height to match aspect ratio if possible
  79. width = widthSpecSize;
  80. height = width * videoHeight / videoWidth;
  81. if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
  82. // couldn't match aspect ratio within the constraints
  83. height = heightSpecSize;
  84. width = height * videoWidth / videoHeight;
  85. }
  86. } else if (heightSpecMode == MeasureSpec.EXACTLY) {
  87. // only the height is fixed, adjust the width to match aspect ratio if possible
  88. height = heightSpecSize;
  89. width = height * videoWidth / videoHeight;
  90. if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
  91. // couldn't match aspect ratio within the constraints
  92. width = widthSpecSize;
  93. height = width * videoHeight / videoWidth;
  94. }
  95. } else {
  96. // neither the width nor the height are fixed, try to use actual video size
  97. width = videoWidth;
  98. height = videoHeight;
  99. if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
  100. // too tall, decrease both width and height
  101. height = heightSpecSize;
  102. width = height * videoWidth / videoHeight;
  103. }
  104. if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
  105. // too wide, decrease both width and height
  106. width = widthSpecSize;
  107. height = width * videoHeight / videoWidth;
  108. }
  109. }
  110. } else {
  111. // no size yet, just adopt the given spec sizes
  112. }
  113. setMeasuredDimension(width, height);
  114. }
  115. }