【发布时间】:2020-06-10 10:15:39
【问题描述】:
所以 exoplayer 所有设置,工作正常。我正在播放 m3u8 视频。那里没有问题。但是当我点击播放时,播放按钮不会被暂停按钮取代。它只是消失了,但是当我进入全屏模式时会出现暂停按钮。奇怪吗?
顺便说一句,这是在一个反应原生组件中
【问题讨论】:
所以 exoplayer 所有设置,工作正常。我正在播放 m3u8 视频。那里没有问题。但是当我点击播放时,播放按钮不会被暂停按钮取代。它只是消失了,但是当我进入全屏模式时会出现暂停按钮。奇怪吗?
顺便说一句,这是在一个反应原生组件中
【问题讨论】:
这是因为在 react-native 中嵌入 Android Native View 时出现了一些渲染问题。在 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 Instance。
此侦听器应为您提供以下覆盖方法,您可以在其中调用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>
这里我的controlView 是exo_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());
};
}
【讨论】: