Exoplayer - Save and Restore State On Rotation Wit

2019-07-30 17:01发布

I have a fragment that hosts a SimpleExoplayer. I want to ensure I am handling screen rotation properly. Right now, the player resets to the beginning on screen rotation. I already have methods implement in onStart() and onResume(), so I am curious what additional code I would need:

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_recipe_details_three, container,false);

    ............

    mStepDescription.setText(step.getDescription());
    mVideoURL = step.getVideoURL();
    mSimpleExoPlayer = v.findViewById(R.id.exoplayer);
    mExoPlayerPlaceholder = v.findViewById(R.id.exoplayer_placeholder);
    if (mVideoURL == null || mVideoURL.isEmpty()){
        mSimpleExoPlayer.setVisibility(View.GONE);
        mExoPlayerPlaceholder.setVisibility(View.VISIBLE);
    }


    return v;
}

onStart:

    @Override
public void onStart() {
    super.onStart();
    initializePlayer();
}

onPause:

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

Initialize:

private void initializePlayer(){
    // Create a default TrackSelector
    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory =
            new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector =
            new DefaultTrackSelector(videoTrackSelectionFactory);

    //Initialize the player
    mExoPlayer = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector);
    mSimpleExoPlayer.setPlayer(mExoPlayer);


    // Produces DataSource instances through which media data is loaded.
    DataSource.Factory dataSourceFactory =
            new DefaultDataSourceFactory(getContext(), Util.getUserAgent(getContext(), "CloudinaryExoplayer"));

    // Produces Extractor instances for parsing the media data.
    ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();



    // This is the MediaSource representing the media to be played.
    Uri videoUri = Uri.parse(mVideoURL);
    MediaSource videoSource = new ExtractorMediaSource(videoUri,
            dataSourceFactory, extractorsFactory, null, null);

    // Prepare the player with the source.
    mExoPlayer.prepare(videoSource);
}

3条回答
不美不萌又怎样
2楼-- · 2019-07-30 17:25

I played with screen orientation and Exoplayer to properly handle it without hacking anything or going around it. as far as I remember every time I tried something I hit a roadblock.

I guess the last one was it took couple of milliseconds for the view to show the video again and also the player to catch up with the playback (funny that my player was static and used application context for initialization).

lastly, I ended up adding orientation flag to manifest.

it is now very smooth when I rotate the screen

查看更多
一夜七次
3楼-- · 2019-07-30 17:25

I think you have the option of disabling config changes on the manifest (which should be handled with care).

The other option, which you are trying to achieve here, is to save the postion of the video and seek to it when the fragment is re-created. To do that you need to:

1) Save the Video Player position and play state in onSaveInstanceState:


    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putLong(PLAYER_CURRENT_POS_KEY, Math.max(0, mPlayer.getCurrentPosition()));
        outState.putBoolean(PLAYER_IS_READY_KEY, mPlayer.getPlayWhenReady());
    }

2) When the Fragment is re created, in your intitalizePlayer() method, check for saved state and restore playback from it:


    private boolean resumePlaybackFromStateBundle(@Nullable Bundle inState) {
        if (inState != null) {
            mPlayer.setPlayWhenReady(inState.getBoolean(PLAYER_IS_READY_KEY));
            mPlayer.seekTo(inState.getLong(PLAYER_CURRENT_POS_KEY));
            return true;
        }
        return false;
    }

I hope it helps.

查看更多
Emotional °昔
4楼-- · 2019-07-30 17:27

In manifest add configChanges to your activity like this:

<activity android:name="com.google.android.exoplayer.demo.PlayerActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
android:launchMode="singleTop"
android:label="@string/application_name"
android:theme="@style/PlayerTheme">
查看更多
登录 后发表回答