В моем приложении есть фрагмент, в котором я, наряду с другими, играю видео в 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);
}
}