带有 SurfaceView 的中心裁剪 Exoplayer

问题描述 投票:0回答:2

我目前正在一个项目中使用 Exoplayer,并希望在视频上实现类似于您在图像视图中看到的“CenterCrop”类型属性。基本上它将适合表面视图的高度,保持相同的纵横比,并裁剪离开屏幕一侧的边缘。我的布局看起来像这样:

<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”,我将其添加为上面代码中的最后一行。不幸的是,这没有任何作用。有谁知道应该如何完成此操作以及我可以调整哪些内容才能使其正常工作?谢谢!

android video-streaming crop exoplayer
2个回答
30
投票

我很晚才知道回答。经过大量的头脑风暴,研究了 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)

愿这对其他人有帮助。


0
投票

要在一个地方提供 ExoPlayer 相关答案(我也没有找到任何对我有用的答案),因此在此发布:

我正在使用 kotlin + compose,所以它看起来像:

val exoPlayer = remember {
    ExoPlayer.Builder(context).build()
        .apply {
            ...
            videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
            ...
        }
}

注意 clipToBounds():

AndroidView(
    modifier = Modifier
        .fillMaxSize()
        .clipToBounds(),
    factory = { _ ->
        PlayerView(context).apply {
            player = exoPlayer
            ...
            resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
        }
    }
)

因此,除了提到的C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPINGAspectRatioFrameLayout.RESIZE_MODE_ZOOM之外,我还需要添加clipToBounds(),这是关键。

© www.soinside.com 2019 - 2024. All rights reserved.