居中裁剪Exoplayer与SurfaceView

9

我目前正在使用 Exoplayer 完成一个项目,并希望实现类似于 ImageView 中所见的“CenterCrop”类型属性在视频中。基本上它将适应 SurfaceView 的高度,保持相同的宽高比,并裁剪超出屏幕的两侧边缘。我的布局看起来像这样:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/videoPlayerContainer"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="404dp">

    <com.google.android.exoplayer2.ui.SimpleExoPlayerView
        android:id="@+id/videoPlayer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        app:controller_layout_id="@layout/empty_controls">

        <SurfaceView
            android:id="@+id/surfaceView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </com.google.android.exoplayer2.ui.SimpleExoPlayerView>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text"
        android:background="@android:color/white"/>

</FrameLayout>

我的一个同事已经用包装器编写了大部分创建和启动播放器的代码,基本上看起来像下面这样:

BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

LoadControl loadControl = new DefaultLoadControl();
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(this.context, trackSelector, loadControl);

simpleExoplayer.setSurfaceView(surfaceView);

DataSource.Factory mediaDataSourceFactory = new DefaultDataSourceFactory(context, "Agent");

MediaSource videoSource = new HlsMediaSource(uri, mediaDataSourceFactory, new Handler(), null);

simpleExoplayer.addListener(this);
simpleExoplayer.prepare(videoSource);

simpleExoplayer.setPlayWhenReady(true);

//this is supposedly used to set the scaling mode
simpleExoplayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);

这段代码接受一个URI并进行一些设置,播放视频一切正常。在研究了裁剪之后,我找到了“setVideoScalingMode”,并将其添加为上述代码的最后一行。不幸的是,它没有起到任何作用。有谁知道如何操作以及我可以调整什么来使其正常工作吗?谢谢!

你必须使用 SurfaceView 吗?TextureView 具有一个很好的功能 setTransform(Matrix),可以让你完全控制缩放/平移/旋转。 - pskink
@pskink 我可能可以使用TextureView。但是我读到它比SurfaceView更快地耗尽电池。 - Rich Luick
而且你想一箭双雕... - pskink
@pskink嗯,考虑到这个视频的性质,我更倾向于不耗费用户的电池,并且会提出替代的用户体验。问题是,ExoPlayer与surface view明显支持这种缩放,但如何实现却不清楚,因为关于此的信息很少。有一些Github问题讨论了这个问题,但解决方案从未被清晰地解释过。 - Rich Luick
同意,此外VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING的描述有些误导,因为它没有说明如何裁剪内容以适应表面。 - pskink
@pskink 是的,我同意,而且也没有指示什么时候最好调用它。希望有更多知识的人可以帮忙,尽管目前还没有运气。 - Rich Luick
1个回答

29

我知道回答有些晚了。在进行了很多头脑风暴,研究EXOPlayer源代码以实现这个功能后,我自己想出了解决方法,我所做的就是添加下面这行代码,它就像魔法一样奏效:

mVideoView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM); //This will increase video's height or width to fit with maintaining aspect ratios of video.

移除下面提到的另外两个选项:

mExoplayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
mVideoView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL)

希望这能帮助其他人。


事实上,在关于此问题的 GitHub 线程中(https://github.com/brianwernick/ExoMedia/issues/80),最终得出了相同的结论(仅使用 RESIZE_MODE_ZOOM),作者表示他们可能会在 3.x 版本中提供缩放类型的支持。 - Juan José Melero Gómez
1
这个有效。我认为这应该被添加到Exoplayer文档中。 - Manuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接