ExoPlayer воссоздает после поворота экрана во фрагмент - PullRequest
0 голосов
/ 25 июня 2018

В моем приложении есть фрагмент, в котором я, наряду с другими, играю видео в ExoPlayer. Я настроил его как можно проще, и сам проигрыватель работает безупречно, даже с медиа-сессией.
Но проблема в том, что при повороте устройства видео снова загружается в фоновом режиме (кажется, что есть два слоя - один стандартный, нормально функционирующий, загружает видео и воспроизводит его, и второй слой в фоновом режиме. Вскоре я слышу звук видео после того, как активность воссоздается.
Я прекращаю и освобождаю сеанс проигрывателя и медиа, но это не помогло.

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);
    }
}

1 Ответ

0 голосов
/ 25 июня 2018

Решено ...
Я использовал add() для создания фрагмента, поэтому при вращении он добавил новый.
Использование replace вместо этого решило проблему.

...