android 如何将视频视图转换为圆形?

dzhpxtsq  于 2022-11-03  发布在  Android
关注(0)|答案(2)|浏览(264)

我想在videoview中全屏播放视频,一段时间后我想将crop转换为circular view
我怎么才能做到呢?

ecfdbz9o

ecfdbz9o1#

有更好的办法。
你可以创建一个自定义的SurfaceView。它实际上将视图剪切成圆形。从这个自定义视图中,你可以设置MediaPlayer对象的显示。

  1. public class VideoSurfaceView extends SurfaceView {
  2. private final static String TAG = "VideoSurfaceView";
  3. private Path clipPath;
  4. private boolean isCircular;
  5. public VideoSurfaceView(Context context) {
  6. super(context);
  7. init();
  8. }
  9. public VideoSurfaceView(Context context, AttributeSet attrs) {
  10. super(context, attrs);
  11. init();
  12. }
  13. public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
  14. super(context, attrs, defStyleAttr);
  15. init();
  16. }
  17. private void init() {
  18. clipPath = new Path();
  19. }
  20. @Override
  21. protected void dispatchDraw(Canvas canvas) {
  22. if (this.isCircular)
  23. canvas.clipPath(clipPath);
  24. super.dispatchDraw(canvas);
  25. }
  26. /**
  27. * Crops the view in circular shape
  28. * @param centerX
  29. * @param centerY
  30. * @param radius
  31. */
  32. public void cropCircle(float centerX, float centerY, int radius) {
  33. Log.i(TAG, "cropCircle: x=" + centerX + " ,y= " + centerY + ", radius=" + radius);
  34. clipPath.addCircle(centerX, centerY, radius, Path.Direction.CW);
  35. }
  36. /**
  37. * Sets the flag for cropping the view in circular shape
  38. * @param isCircular
  39. */
  40. public void setCircular(boolean isCircular) {
  41. this.isCircular = isCircular;
  42. invalidate();
  43. }
  44. }

在您的Activity中,您可以实现SurfaceHolder。回调并设置MediaPlayer的显示。

  1. public class MainActivity extends AppCompatActivity implements MediaPlayer.OnCompletionListener, SurfaceHolder.Callback {
  2. private final static String TAG = "MainActivity";
  3. @BindView(R.id.activity_main_video_surface_view)
  4. protected VideoSurfaceView videoView;
  5. private Handler handler;
  6. private boolean inCircleMode;
  7. private final static int CIRCULAR_INTERVAL = 5000;
  8. private final static int MINIMUM_CARD_HEIGHT = 300;
  9. private final static int MAXIMUM_CARD_HEIGHT = 500;
  10. //Parameters for video view.
  11. private int cropCenterX;
  12. private int cropCenterY;
  13. private int cropRadius;
  14. private int croppedLayoutWidth;
  15. private int croppedLayoutHeight;
  16. private int fullLayoutWidth;
  17. private int fullLayoutHeight;
  18. private MediaPlayer player;
  19. @Override
  20. protected void onCreate(Bundle savedInstanceState) {
  21. super.onCreate(savedInstanceState);
  22. setContentView(R.layout.activity_main);
  23. ButterKnife.bind(this);
  24. initParameters();
  25. }
  26. /**
  27. * Initialise the parameters used.
  28. */
  29. private void initParameters() {
  30. SurfaceHolder holder = videoView.getHolder();
  31. holder.addCallback(this);
  32. player = MediaPlayer.create(this, R.raw.bird_s);
  33. player.setOnCompletionListener(this);
  34. //Setting the video with proper aspect ratio.
  35. DisplayMetrics displayMetrics = new DisplayMetrics();
  36. getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
  37. int height = displayMetrics.heightPixels;
  38. int width = displayMetrics.widthPixels;
  39. int dimenFull[] = Utility.getVideoDimensions(player, width, height);
  40. fullLayoutWidth = dimenFull[0];
  41. fullLayoutHeight = dimenFull[1];
  42. setVideoLayout();
  43. }
  44. //Runnable for switching the views from circular video to full screen video.
  45. private Runnable runnable = new Runnable() {
  46. @Override
  47. public void run() {
  48. inCircleMode = !inCircleMode;
  49. setVideoLayout();
  50. handler.postDelayed(runnable, CIRCULAR_INTERVAL);
  51. }
  52. };
  53. /**
  54. * Calculates the dimensions required for cropped video view.
  55. */
  56. private void calculateCroppedParams() {
  57. int dimen[] = Utility.getVideoDimensions(player, 100, 100);
  58. croppedLayoutWidth = dimen[0];
  59. croppedLayoutHeight = dimen[1];
  60. cropRadius = croppedLayoutWidth / 2;
  61. cropCenterX = cropRadius;
  62. cropCenterY = cropRadius;
  63. }
  64. /**
  65. * Change the layout dimensions for video view.
  66. */
  67. private void setVideoLayout() {
  68. RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) videoView.getLayoutParams();
  69. //Changing the margin, width & height of videoView.
  70. layoutParams.setMargins(0, inCircleMode ? cardView.getVideoMargin() : 0, 0, 0);
  71. layoutParams.width = inCircleMode ? croppedLayoutWidth : fullLayoutWidth;
  72. layoutParams.height = inCircleMode ? croppedLayoutHeight : fullLayoutHeight;
  73. layoutParams.addRule(inCircleMode ? RelativeLayout.CENTER_HORIZONTAL : RelativeLayout.CENTER_IN_PARENT);
  74. videoView.cropCircle(cropCenterX, cropCenterY, cropRadius);
  75. videoView.setCircular(inCircleMode);
  76. videoView.setLayoutParams(layoutParams);
  77. }
  78. @Override
  79. public void onCompletion(MediaPlayer mediaPlayer) {
  80. }
  81. @Override
  82. public void onLayout() {
  83. Log.i(TAG, "onLayout: starting runnable");
  84. calculateCroppedParams();
  85. player.start();
  86. }
  87. @Override
  88. public void surfaceCreated(SurfaceHolder surfaceHolder) {
  89. player.setDisplay(surfaceHolder);
  90. }
  91. @Override
  92. public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
  93. }
  94. @Override
  95. public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
  96. }
  97. @Override
  98. protected void onStop() {
  99. Log.i(TAG, "onStop");
  100. super.onStop();
  101. }
  102. @Override
  103. protected void onRestart() {
  104. super.onRestart();
  105. }
  106. @Override
  107. protected void onPause() {
  108. super.onPause();
  109. if (player != null && player.isPlaying())
  110. player.pause();
  111. }
  112. @Override
  113. protected void onResume() {
  114. super.onResume();
  115. if (player != null && !player.isPlaying())
  116. player.start();
  117. }
  118. }

有关如何将视频裁剪成不同形状的更多细节,请查看我的博客文章VideoInShapes

展开查看全部
db2dz4w8

db2dz4w82#

另一种方法是将这种类型的图像叠加在视频视图的相对或FrameLayout上(循环器是透明的,因此视频视图仅在循环中可见)
默认情况下,使此图像可见性为GONE在运行时根据需要查看和更改其可见性。

相关问题