Exoplayer - 在Fragment内旋转时保存和恢复状态

3

我有一个包含SimpleExoplayer的片段。我希望确保屏幕旋转时能正确处理它。目前,播放器在屏幕旋转时会重置到开头。我已经在onStart()和onResume()方法中实现了一些方法,所以我想知道需要添加哪些额外的代码:

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

初始化:

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

使用ViewModel来存储玩家的值。ViewModel在手机旋转时保持不变,值永远不会改变。 ViewModel是一个Jetpack库:https://developer.android.com/topic/libraries/architecture/viewmodel?gclid=CjwKCAjwkPX0BRBKEiwA7THxiOHZrZiYC4BScBoYexpDJGFWULiLIH9fXptTlzrxsqUcBoZnsRjwHBoCL-kQAvD_BwE&gclsrc=aw.ds - Ivan Šimović
3个回答

3
您不需要更改清单文件。以下代码应该可以正常工作。
override fun onSaveInstanceState(outState: Bundle) {
    outState.putLong(KEY_PLAYER_POSITION, exoPlayer.contentPosition)
    outState.putBoolean(KEY_PLAYER_PLAY_WHEN_READY, exoPlayer.playWhenReady)
}

override fun onViewStateRestored(savedInstanceState: Bundle?) {
    super.onViewStateRestored(savedInstanceState)
    savedInstanceState?.let {
        exoPlayer.seekTo(it.getLong(KEY_PLAYER_POSITION))
        exoPlayer.playWhenReady = it.getBoolean(KEY_PLAYER_PLAY_WHEN_READY)
    }
}

2

我尝试了屏幕方向和Exoplayer,以便在不破坏任何东西或绕开它的情况下正确处理它。据我记得,每次尝试时都遇到了障碍。

我想最后一个问题是,视图重新显示视频需要几毫秒时间,而播放器也需要赶上播放(有趣的是,我的播放器是静态的,并使用应用程序上下文进行初始化)。

最后,我在清单中添加了orientation标志。

现在旋转屏幕非常流畅。


1
我认为您有禁用清单上的配置更改选项(应谨慎处理)。
另一个选项是在重新创建片段时保存视频位置并将其定位到该位置,这是您正在尝试实现的。要做到这一点,您需要:
1)在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) 当Fragment被重新创建时,在您的intitalizePlayer()方法中,检查保存的状态并从中恢复播放:


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

我希望它有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接