ExoPlayer 在 fragment 中屏幕旋转后重新创建

ExoPlayer recreates after screen rotation in fragment

在我的应用程序中,我有一个片段,我在其中与其他人一起在 ExoPlayer 中播放视频。我将其设置得尽可能简单,播放器本身也能完美运行,即使有媒体会话也是如此。
但问题是在设备旋转时,视频再次在后台加载(似乎有两层 - 一层标准,正常运行,加载视频并播放;第二层在后台。我很快就能听到视频的声音activity 重新创建后。
我正在停止并释放播放器和媒体会话,但这没有帮助。

MediaFragment.java

public class StepViewFragment extends Fragment implements Player.EventListener{

//vars


public StepViewFragment() {
}


@Override
public void onAttach(Context context) {
    super.onAttach(context);
//attach callbacks for buttons
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_step_view, container, false);

    //Bind view ButterKnife
    ButterKnife.bind(this, rootView);

    //get Step from Bundle
    Bundle bundle = this.getArguments();
    if (bundle != null) {
        step = bundle.getParcelable(AppConstants.STEP_BUNDLE_KEY);
        recipe = bundle.getParcelable(AppConstants.RECIPE_BUNDLE_KEY);
    }

    mainHandler = new Handler();

//...
//setup ui
//...

    if (step.videoURL.equals("")) {
        mediaCard.setVisibility(View.GONE);
    } else {
        playVideo();
        initMediaSession();

    }

    return rootView;
}

public void initMediaSession (){
    mExoPlayer.addListener(this);

    mMediaSession = new MediaSessionCompat(getContext(), TAG);
    mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
    mMediaSession.setMediaButtonReceiver(null);

    mStateBuilder = new PlaybackStateCompat.Builder()
            .setActions(
                    PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_PLAY_PAUSE
            );
    mMediaSession.setPlaybackState(mStateBuilder.build());
    mMediaSession.setCallback(new MySessionCallback());
    mMediaSession.setActive(true);
}

public void playVideo() {

    if (mExoPlayer == null) {

        DefaultTrackSelector trackSelector = new DefaultTrackSelector();
        LoadControl loadControl = new DefaultLoadControl();

        RenderersFactory renderersFactory = new DefaultRenderersFactory(getContext());

        mExoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
        mPlayerView.setPlayer(mExoPlayer);

        String videoUrl = step.videoURL;

        Uri mp4VideoUri = Uri.parse(videoUrl);

        String userAgent = Util.getUserAgent(getContext(), "BakingApp");

        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(), userAgent);

        ExtractorMediaSource.Factory mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory);

        mExoPlayer.prepare(mediaSource.createMediaSource(mp4VideoUri));
        mPlayerView.hideController();
        mExoPlayer.setPlayWhenReady(true);
    }

}

public void releasePlayer() {
    mExoPlayer.stop();
    mExoPlayer.release();
    mExoPlayer = null;
    mMediaSession.release();
    mPlayerView = null;
}


@Override
public void onStop() {
    if (mExoPlayer != null) {
        releasePlayer();
    }
    super.onStop();
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    if (mExoPlayer != null) {
        releasePlayer();
    }
}

@Override
public void onPause() {
    super.onPause();
    if (mExoPlayer != null) {
        releasePlayer();
    }
}

@Override
public void onDetach() {
    super.onDetach();
    if (mExoPlayer != null) {
        releasePlayer();
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mExoPlayer != null){
        releasePlayer();
    }
}

@Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

}

@Override
public void onLoadingChanged(boolean isLoading) {

}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    if ((playbackState == Player.STATE_READY) && playWhenReady) {
        mStateBuilder.setState(PlaybackStateCompat.STATE_PLAYING, mExoPlayer.getCurrentPosition(), 1f);

    } else if ((playbackState == Player.STATE_READY)){
        mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED, mExoPlayer.getCurrentPosition(), 1f);

    }

    mMediaSession.setPlaybackState(mStateBuilder.build());
    Log.d("HOVNOOOO", "Playback State Changed");
}

@Override
public void onRepeatModeChanged(int repeatMode) {

}

@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

}

@Override
public void onPlayerError(ExoPlaybackException error) {

}

@Override
public void onPositionDiscontinuity(int reason) {

}

@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

}

@Override
public void onSeekProcessed() {

}


private class MySessionCallback extends MediaSessionCompat.Callback {
    @Override
    public void onPlay() {
        mExoPlayer.setPlayWhenReady(true);

    }

    @Override
    public void onPause() {
        mExoPlayer.setPlayWhenReady(false);
    }
}

已解决...
我正在使用 add() 创建片段,因此在旋转时它添加了新片段。
使用 replace 代替解决了问题。