java - 如何在不使用android :configChanges的情况下让ExoPlayer在设备旋转时恢复视频播放

标签 java android exoplayer exoplayer2.x

我正在开发一个使用 ExoPlayer 从 URL 流式传输视频的项目。但是我的代码有问题。旋转设备时,将重新启动整个视频。 使用 android:configChanges 修复它,但我不应该使用它。 我使用 onSaveInstanceState() 来缓存所有必需的数据,例如 playerPosition、currentWindow 和 setPlayWhenReady;我相应地检索它。但它仍然没有按预期工作。我该如何解决这个问题?

这是存在此问题的整个 Fragment 类:

package com.app.shubhamjhunjhunwala.thebakingapp;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.app.shubhamjhunjhunwala.thebakingapp.Objects.Dish;
import com.app.shubhamjhunjhunwala.thebakingapp.Objects.Step;
import com.github.paolorotolo.expandableheightlistview.ExpandableHeightListView;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import com.squareup.picasso.Picasso;

import org.parceler.Parcels;
import org.w3c.dom.Text;

import java.io.IOException;

public class ExtraDetailsFragment extends Fragment {

    public ExtraDetailsFragment() {}

    public boolean twoPaneLayout;

    public Dish dish;
    public int stepID;

    public String videoURL;

    public SimpleExoPlayerView playerView;
    public SimpleExoPlayer player;
    public long playerPosition;
    public boolean playWhenReady;
    public int currentWindow;

    public TextView textView;

    public static boolean hasShownVideoInFullScreen = false;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

        final View rootView;

        rootView = inflater.inflate(R.layout.extra_details_fragment, container, false);

        if (savedInstanceState != null) {
            dish =  Parcels.unwrap(savedInstanceState.getParcelable("Dish"));
            stepID = savedInstanceState.getInt("ID");
            twoPaneLayout = savedInstanceState.getBoolean("TwoPane");

            playerPosition = savedInstanceState.getLong("PlayerPosition", 0);
            playWhenReady = savedInstanceState.getBoolean("PlayWhenReady", true);
            currentWindow = savedInstanceState.getInt("CurrentWindow", 0);
            Log.d("Player Position", Long.toString(playerPosition));
        }

        Log.d("Details Fragment", dish.toString());

        playerView = rootView.findViewById(R.id.video_view);
        textView = rootView.findViewById(R.id.details_text_view);

        Step[] steps = dish.getSteps();
        textView.setText(steps[stepID].getDescription());

        return rootView;
    }

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

        outState.putParcelable("Dish", Parcels.wrap(dish));
        outState.putInt("ID", stepID);
        outState.putBoolean("TwoPane", twoPaneLayout);
        outState.putLong("PlayerPosition", playerPosition);
        outState.putBoolean("PlayWhenReady", playWhenReady);
        outState.putInt("CurrentWindow", currentWindow);
    }

    @Override
    public void onStart() {
        super.onStart();
        if (Util.SDK_INT > 23) {
            initializePlayer();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        /*if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE && !twoPaneLayout && !hasShownVideoInFullScreen) {
            hasShownVideoInFullScreen = true;
            playVideoInFullScreen();
        }*/
        if ((Util.SDK_INT <= 23 || player == null)) {
            initializePlayer();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (Util.SDK_INT <= 23) {
            releasePlayer();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (Util.SDK_INT > 23) {
            releasePlayer();
        }
    }

    public void initializePlayer() {
        player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(getContext()), new DefaultTrackSelector(), new DefaultLoadControl());

        playerView.setPlayer(player);

        Step[] steps = dish.getSteps();
        String imageURL = "";
        videoURL = steps[stepID].getVideoURL();
        imageURL = steps[stepID].getImageURL();

        if (!videoURL.equals("")) {
            Uri uri = Uri.parse(videoURL);
            MediaSource mediaSource = buildMediaSource(uri);
            player.prepare(mediaSource);
            player.seekTo(currentWindow, playerPosition);
            player.setPlayWhenReady(true);
        } else if (videoURL.equals("") && !imageURL.equals("")) {
            final String finalImageURL = imageURL;
            new AsyncTask<Void, Void, Void>() {
                Bitmap bitmap;
                @Override
                protected Void doInBackground(Void... voids) {
                    try {
                        bitmap = Picasso.with(getContext()).load(finalImageURL).get();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    super.onPostExecute(aVoid);
                    if (bitmap != null) {
                        playerView.setDefaultArtwork(bitmap);
                    } else {
                        playerView.setVisibility(View.GONE);
                        Toast.makeText(getContext(), "No Video Available", Toast.LENGTH_SHORT).show();
                    }
                }
            }.execute();
        } else {
            playerView.setVisibility(View.GONE);
            Toast.makeText(getContext(), "No Video Available", Toast.LENGTH_SHORT).show();
        }
    }

    private void playVideoInFullScreen() {
        Intent intent = new Intent(getContext(), FullScreenVideoActivity.class);
        intent.putExtra("Video URL", videoURL);
        startActivity(intent);
    }

    private void releasePlayer() {
        if (player != null) {
            playerPosition = player.getCurrentPosition();
            playWhenReady = player.getPlayWhenReady();
            currentWindow = player.getCurrentWindowIndex();
            player.release();
            player = null;
        }
    }

    private MediaSource buildMediaSource(Uri uri) {
        return new ExtractorMediaSource.Factory(new DefaultHttpDataSourceFactory("exoplayer")).createMediaSource(uri);
    }
}

最佳答案

尝试将 fragment 保留实例设置为真:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    setRetainInstance(true);
}

不再需要使用 onSaveInstanceState() 或 configChanges。

一些有用的信息: https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)https://stackoverflow.com/a/11318942/6193843

关于java - 如何在不使用android :configChanges的情况下让ExoPlayer在设备旋转时恢复视频播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49590509/

相关文章:

Android 在三星设备上保持屏幕开启

android - 来自 appWidget 的网络请求

android - 如何在 android 中实现 Exoplayer 2.11.1?

java - Hibernate 验证整数的数字大小

android -> 无法在 :/opt/android-sdk-linux 中找到哈希字符串 'android-26' 的目标

java - 如何编码(缩短)数字str

java - Android TV Leanback Exoplayer 视频缩放问题

android - ExoPlayer发布后如何重新初始化?

java - 如何替换这些静态 JFrame 变量?

java - JHipster 页面空白