【问题标题】:Android - Displaying ExoPlayer in a circleAndroid - 在一个圆圈中显示 ExoPlayer
【发布时间】:2017-10-18 17:28:33
【问题描述】:

我试图在一个圆圈内显示一个 ExoPlayerView,覆盖另一个 ExoPlayer(画中画):

我尝试将第二个播放器放在圆角框架内(this answerthis one),但播放器总是会避开父框架并绘制视频的完整矩形。

我发现 this solution 使用 GLSurfaceView,但此解决方案使用经典的 MediaPlayer 而不是 ExoPlayer。

【问题讨论】:

  • 您是否尝试过使用您链接的解决方案并使用 GLSurfaceView,就像使用带有 ExoPlayer 的 SurfaceView 一样? (设置表面监听器并将表面传递给 ExoPlayer)
  • 其他人遇到这个问题,解决方案是使用 TextureViews 而不是 SurfaceViews

标签: android exoplayer


【解决方案1】:

对于应该有圆角的,你可以在布局 XML 文件中设置它:

app:surface_type="texture_view"

找到了这个解决方案here

使用这个的缺点主要是性能和电池使用(写here):

我应该使用 SurfaceView 还是 TextureView? SurfaceView 有许多 在视频播放方面优于 TextureView:

在许多设备上显着降低了功耗。更准确的 帧定时,从而实现更流畅的视频播放。支持安全 播放受 DRM 保护的内容时输出。 SurfaceView 应该 因此在可能的情况下优先于 TextureView。纹理视图 只有在 SurfaceView 不能满足您的需求时才应使用。一 例如平滑的动画或视频表面的滚动 在 Android N 之前是必需的(请参阅How do I get smooth animation/scrolling of video?)。对于这种情况,最好使用 仅当 SDK_INT 小于 24 (Android N) 和 SurfaceView 否则。

【讨论】:

    【解决方案2】:

    您需要为其创建一个自定义容器。试试这个,然后把你的玩家视图放进去。

    public class RoundFrameLayout extends FrameLayout {
    
    private final Path clip = new Path();
    
    private int posX;
    private int posY;
    private int radius;
    
    public RoundFrameLayout(Context context) {
        this(context,null);
    
    }
    
    public RoundFrameLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    
    public RoundFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // We can use outlines on 21 and up for anti-aliased clipping.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setClipToOutline(true);
        }
    }
    
    @Override
    protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
        posX = Math.round((float) width / 2);
        posY = Math.round((float) height / 2);
    
        // noinspection NumericCastThatLosesPrecision
        radius = (int) Math.floor((float) Math.min(width, height) / 2);
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setOutlineProvider(new OutlineProvider(posX, posY, radius));
        } else {
            clip.reset();
            clip.addCircle(posX, posY, radius, Direction.CW);
        }
    }
    
    @Override
    protected void dispatchDraw(Canvas canvas) {
        // Not needed on 21 and up since we're clipping to the outline instead.
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            canvas.clipPath(clip);
        }
    
        super.dispatchDraw(canvas);
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Don't pass touch events that occur outside of our clip to the children.
        float distanceX = Math.abs(event.getX() - posX);
        float distanceY = Math.abs(event.getY() - posY);
        double distance = Math.hypot(distanceX, distanceY);
    
        return distance > radius;
    }
    
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    static class OutlineProvider extends ViewOutlineProvider {
    
        final int left;
        final int top;
        final int right;
        final int bottom;
    
        OutlineProvider(int posX, int posY, int radius) {
            left = posX - radius;
            top = posY - radius;
            right = posX + radius;
            bottom = posY + radius;
        }
    
        @Override
        public void getOutline(View view, Outline outline) {
            outline.setOval(left, top, right, bottom);
        }
    
    }
    

    }

    【讨论】:

    • 如问题中所述,此解决方案不起作用,因为播放器不尊重父框架的圆角。
    猜你喜欢
    • 2013-03-01
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 2020-08-09
    • 1970-01-01
    • 2021-05-16
    • 2012-11-12
    相关资源
    最近更新 更多