Exoplayer 暂停按钮最初没有出现

Exoplayer pause button does not appear initially

所以 exoplayer 所有设置,工作正常。我正在播放 m3u8 视频。那里没有问题。但是当我点击播放时,播放按钮并没有被暂停按钮取代。它只是消失了,但是当我进入全屏模式时,暂停按钮出现了。奇数没有?

顺便说一句,这是在一个 React Native 组件中

这是因为在 react-native 中嵌入 Android 本机视图时出现一些渲染问题。在 Android studio 中使用布局检查器,我发现按钮大小为 0。因此,每当播放器状态发生变化时,重新测量和调用视图布局应该可以解决问题。

有如下重新测量和布局的方法:

private fun reLayout(controlView: View?, controlViewsParent: View?) {
    controlView?.measure(MeasureSpec.makeMeasureSpec(controlViewsParent.measuredWidth, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(controlViewsParent.measuredHeight, MeasureSpec.EXACTLY))
    controlView?.layout(view.left, view.top, view.measuredWidth, view.measuredHeight)
}

添加 Player.EventListener 到 exoplayer 实例。
此侦听器应为您提供以下调用 relayout() 的覆盖方法。每当 ExoPlayer 状态发生变化以及您暂停和播放时,都会调用这两个重写的方法。因此重新测量和渲染视图修复了按钮问题。

override fun onPlaybackStateChanged(state: Int) {
    relayout(controlView, controlViewsParent)
}

override fun onIsPlayingChanged(isPlaying: Boolean) {
    relayout(controlView, controlViewsParent)
}

我的暂停和播放按钮位于 FrameLayout 内,例如:

<FrameLayout
        android:id="@+id/exo_play_pause_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center">

        <ImageButton
            android:id="@id/exo_play"
            style="@style/ExoMediaButton.Play" />

        <ImageButton
            android:id="@id/exo_pause"
            style="@style/ExoMediaButton.Pause" />
</FrameLayout>

这里我的 controlViewexo_play_pause_container 并且 controlViewsParent 是这个布局文件的根。

我不知道它是否有帮助,但这是我基于 Ankshay Bhat 回复的解决方案:

VideoPlayer.java

import android.content.Context;

import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.Player.EventListener;

public class VideoPlayer extends PlayerView {

    private SimpleExoPlayer player;

    @Override
    public SimpleExoPlayer getPlayer() {
        return player;
    }

    public void setFile(String url) {
        preparePlayer(url);
    }

    public VideoPlayer(Context context) {
        super(context);
        player = new SimpleExoPlayer.Builder(context).build();
        this.setPlayer(player);
    }

    private void preparePlayer(String url) {
        MediaItem mediaItem = MediaItem.fromUri(url);
        // Set the media item to be played.
        player.setMediaItem(mediaItem);
        // Prepare the player.
        player.prepare();
    }

    public void addOnAttachStateChangeListener(EventListener listener) {
        this.player.addListener(listener);
    }
}

VideoPlayerView.java

import android.content.Context;
import android.widget.FrameLayout;
import com.google.android.exoplayer2.Player.EventListener;
import androidx.annotation.NonNull;

public class VideoPlayerView extends FrameLayout {
    private Context context;
    public VideoPlayer videoPlayer;

    public VideoPlayerView(@NonNull Context context) {
        super(context);
        this.context = context;
        this.init();
    }

    private void init(){
        videoPlayer = new VideoPlayer(context);
        videoPlayer.addOnAttachStateChangeListener(new EventListener() {
            @Override
            public void onPlaybackStateChanged(int state) {
                post(measureAndLayout);
            }

            @Override
            public void onIsPlayingChanged(boolean isPlaying) {
                post(measureAndLayout);
            }
        });
        this.addView(videoPlayer);
    }

    private final Runnable measureAndLayout = () -> {
        measure(
                MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
        layout(getLeft(), getTop(), getRight(), getBottom());
    };

}