如果ImageView位置没有超出SeekBar的宽度,则计算坐标并移动,
如果它向外延伸,坐标将设置在ImageView的左侧或右侧。
※ExoPlayer使用ExoPlayer release-v2
java代码
public class ExoPlayerActivity extends FragmentActivity implements TextureView.SurfaceTextureListener {
private ExoPlayerActivityBinding binding;
private SimpleExoPlayer simpleExoPlayer;
// Apple sample HLS
private static final String videoUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
private Timer playerTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.exo_player_activity);
// TextureView设置回调
binding.textureView.setSurfaceTextureListener(this);
// 隐藏状态栏和导航栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
View decor = getWindow().getDecorView();
if (Build.VERSION.SDK_INT > 18) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} else if (Build.VERSION.SDK_INT > 15) {
decor.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);
} else if (Build.VERSION.SDK_INT > 13) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
// Player的比例按照16 : 9 设置
binding.raitoFrameLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (binding.raitoFrameLayout.getWidth() > 0 && binding.raitoFrameLayout.getHeight() > 0) {
int width = binding.raitoFrameLayout.getWidth();
ViewGroup.LayoutParams params = binding.raitoFrameLayout.getLayoutParams();
params.height = width / 16 * 9;
binding.raitoFrameLayout.setLayoutParams(params);
if (Build.VERSION.SDK_INT >= 16) {
binding.raitoFrameLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
binding.raitoFrameLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
}
});
// 显示Progressbar
binding.loadingProgress.setVisibility(View.VISIBLE);
// SeekBar的事件监听
binding.controlSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (progress == 0 || seekBar.getMax() == 0) return;
if (fromUser) {
// 用户手动调节Player进度条
simpleExoPlayer.seekTo(progress * 1000);
setThumbnailX(progress, seekBar.getMax());
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 手动操作开始
binding.loadingProgress.setVisibility(View.VISIBLE);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 手动操作结束
binding.loadingProgress.setVisibility(View.INVISIBLE);
}
});
}
// 播放器监视器计时器更新秒数和SeekBar的位置
private void setTimer() {
stopTimer();
playerTimer = new Timer();
playerTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
final int durationSecond = (int) (simpleExoPlayer.getDuration() / 1000);
final int currentSecond = (int) (simpleExoPlayer.getCurrentPosition() / 1000);
binding.time.post(new Runnable() {
@Override
public void run() {
binding.time.setText(currentSecond + "/" + durationSecond);
binding.controlSeek.setMax(durationSecond); // SeekBar的最大秒数设置
binding.controlSeek.setProgress(currentSecond); // 将SeekBar的旋钮移动到当前秒数
setThumbnailX(currentSecond, durationSecond);
}
});
}
}, 1000, 1000);
}
// 在SeekBar上移动图像的位置从View的大小计算位置
private void setThumbnailX(int currentPosition, int durationPosition) {
int seekWidth = binding.controlSeek.getWidth();
int imageWidth = binding.videoImage.getWidth();
double videoImageX = (double) seekWidth * currentPosition / durationPosition;
if (videoImageX > seekWidth - imageWidth / 2) {
binding.videoImage.setX(seekWidth - imageWidth);
} else if (videoImageX > imageWidth / 2) {
binding.videoImage.setX((int) videoImageX - imageWidth / 2);
} else {
binding.videoImage.setX(0);
}
}
// Player监听Timer删除
private void stopTimer() {
if (playerTimer != null) {
playerTimer.cancel();
playerTimer.purge();
playerTimer = null;
}
}
@Override
protected void onResume() {
super.onResume();
if (simpleExoPlayer != null) {
setTimer();
simpleExoPlayer.setPlayWhenReady(true);
}
}
@Override
protected void onPause() {
super.onPause();
stopTimer();
if (simpleExoPlayer != null) {
simpleExoPlayer.setPlayWhenReady(false);
}
}
// ExoPlayer 2 TextureView设置为ExoPlayer,并在TextureView准备就绪时开始播放
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
Handler mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(mainHandler, videoTrackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl();
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(getApplicationContext(), trackSelector, loadControl);
simpleExoPlayer.setVideoTextureView(binding.textureView);
DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, new WebView(getApplicationContext()).getSettings().getUserAgentString()), defaultBandwidthMeter);
HlsMediaSource hlsMediaSource = new HlsMediaSource(Uri.parse(videoUrl), dataSourceFactory, mainHandler, null);
simpleExoPlayer.prepare(hlsMediaSource);
simpleExoPlayer.setVideoListener(new SimpleExoPlayer.VideoListener() {
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
}
@Override
public void onRenderedFirstFrame() {
// 开始播放
binding.loadingProgress.setVisibility(View.INVISIBLE);
setTimer();
}
@Override
public void onVideoTracksDisabled() {
}
});
simpleExoPlayer.setPlayWhenReady(true);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
// ExoPlayer2
}
<layout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/raito_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
tools:context=".activity.ExoPlayerActivity">
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="8dp"
android:orientation="vertical">
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="8dp"
android:textColor="#FFF"
android:textSize="16sp" />
<ImageView
android:id="@+id/video_image"
android:layout_width="64dp"
android:layout_height="36dp"
android:layout_margin="8dp"
android:background="#FFF" />
<SeekBar
android:id="@+id/control_seek"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</LinearLayout>
<ProgressBar
android:id="@+id/loading_progress"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
</FrameLayout>
</layout>
这样就可以实现在exoplayer中显示视频缩略图了。