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>
这里我的 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());
};
}
所以 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>
这里我的 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());
};
}