Android Exoplayer,在屏幕旋转时恢复视频
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Exoplayer,在屏幕旋转时恢复视频相关的知识,希望对你有一定的参考价值。
我使用FragmentStatePagerAdapter来实例化一些片段,每个片段都包含SimpleExoPlayerView。在屏幕旋转,我希望视频自动恢复。我在saveInstantState中保存playbackPosition和currentWindow,并在onActivityCreated上恢复它们。问题是当我旋转设备时,我正确恢复了playbackPosition,但是再次实例化了SimpleExoPlayerView并且视频没有自动恢复,似乎片段在屏幕旋转时再次被实例化
StepInfoActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_step_info);
...
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), recipeModel.getSteps(), recipes_json);
mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
包含ExoPlayerView的片段
public class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
SimpleExoPlayer player;
long playbackPosition;
int currentWindow;
boolean playWhenReady = true;
RecipeModel recipeModel;
int received_index;
@BindView(R.id.simple_exp_view)
SimpleExoPlayerView playerView;
@BindView(R.id.step_long_desc)
TextView step_desc;
@BindView(R.id.video_thumbnail)
ImageView videoThumbnail;
public PlaceholderFragment() {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String recipes_json = getArguments().getString(DetailFragment.STEP_INFO_EXTRA);
received_index = getArguments().getInt(DetailFragment.STEP_INFO_POSITION, 0);
recipeModel = new Gson().fromJson(recipes_json, RecipeModel.class);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("current_window", currentWindow);
savedInstanceState.putLong("play_back_pos", playbackPosition);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_step_info, container, false);
ButterKnife.bind(this, rootView);
setPlayerVisibility();
StepModel stepModel = recipeModel.getSteps().get(getArguments().getInt(ARG_SECTION_NUMBER) - 1);
if (stepModel.getDescription() != null) {
step_desc.setText(stepModel.getDescription());
}
return rootView;
}
private void setPlayerVisibility() {
StepModel stepModel = recipeModel.getSteps().get(getArguments().getInt(ARG_SECTION_NUMBER) - 1);
if (stepModel.getVideoURL().isEmpty()) {
playerView.setVisibility(View.GONE);
} else if (!stepModel.getThumbnailURL().isEmpty()) {
videoThumbnail.setVisibility(View.VISIBLE);
Picasso.with(getContext()).load(stepModel.getThumbnailURL()).into(videoThumbnail);
} else {
playerView.setVisibility(View.VISIBLE);
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
playbackPosition = savedInstanceState.getLong("play_back_pos");
currentWindow = savedInstanceState.getInt("current_window");
}
}
@Override
public void onStart() {
super.onStart();
initializePlayer();
}
@Override
public void onResume() {
super.onResume();
if ((Util.SDK_INT <= 23 || player == null)) {
initializePlayer();
}
}
@Override
public void onPause() {
super.onPause();
if (Util.SDK_INT <= 23) {
releasePlayer();
}
}
@Override
public void onStop() {
super.onStop();
if (Util.SDK_INT > 23) {
releasePlayer();
}
}
private void releasePlayer() {
if (player != null) {
playbackPosition = player.getCurrentPosition();
currentWindow = player.getCurrentWindowIndex();
playWhenReady = player.getPlayWhenReady();
player.release();
player = null;
}
}
private void initializePlayer() {
if (player == null) {
player = ExoPlayerFactory.newSimpleInstance(
new DefaultRenderersFactory(getContext()),
new DefaultTrackSelector(), new DefaultLoadControl());
playerView.setPlayer(player);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
Uri uri = Uri.parse(recipeModel.getSteps().get(getArguments().getInt(ARG_SECTION_NUMBER) - 1).getVideoURL()); //todo
MediaSource mediaSource = buildMediaSource(uri);
player.prepare(mediaSource, true, false);
videoThumbnail.setVisibility(View.GONE);
}
}
private MediaSource buildMediaSource(Uri uri) {
return new ExtractorMediaSource.Factory(
new DefaultHttpDataSourceFactory("Baking_app")).
createMediaSource(uri);
}
public static PlaceholderFragment newInstance(int sectionNumber, String recipeModel) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putString(DetailFragment.STEP_INFO_EXTRA, recipeModel);
fragment.setArguments(args);
return fragment;
}
}
FragmentStatePagerAdapter
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
List<StepModel> steps;
String recipeModel;
public SectionsPagerAdapter(FragmentManager fm, List<StepModel> steps, String recipeModel) {
super(fm);
this.steps = steps;
this.recipeModel = recipeModel;
}
@Override
public Fragment getItem(int position) {
return PlaceholderFragment.newInstance(position + 1, recipeModel);
}
@Override
public int getCount() {
return steps.size();
}
@Override
public CharSequence getPageTitle(int position) {
if (position == 0) return "intro";
else return "step " + position;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
}
答案
我设法通过在清单中添加一行来让视频继续播放:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
this line -> android:configChanges="keyboardHidden|orientation|screenSize"
android:icon="@drawable/appicon"
android:launchMode="singleTop">
以上是关于Android Exoplayer,在屏幕旋转时恢复视频的主要内容,如果未能解决你的问题,请参考以下文章
如何在 android 中实现 Exoplayer 2.11.1?