【问题标题】:ExoPlayer resume on same position on rotate screenExoPlayer 在旋转屏幕上的相同位置恢复
【发布时间】:2018-08-24 11:35:49
【问题描述】:

我在我的活动中使用 ExoPlayer,我想要的是在纵向和横向模式下流畅地播放视频。为此,我正在做的是在 onpause 我保存 currentPlayerPosition 并在 @987654322 中寻找播放器到那个位置@ 但在旋转时它面对一个混蛋,视频会停止一段时间并播放到保存的位置。

我的代码如下,请帮助我如何顺利切换模式纵向和横向。谢谢

     @Override
public void onPause() {

    super.onPause();

    if (mExoPlayerView != null && mExoPlayerView.getPlayer() != null) {
        mResumeWindow = mExoPlayerView.getPlayer().getCurrentWindowIndex();
        mResumePosition = Math.max(0, mExoPlayerView.getPlayer().getContentPosition());
        mExoPlayerView.getPlayer().release();
    }
}


@Override
public void onDestroy() {
    super.onDestroy();
    if (mExoPlayerView.getPlayer() != null)
        mExoPlayerView.getPlayer().release();
}


  @Override
public void onSaveInstanceState(Bundle outState) {

    outState.putInt(STATE_RESUME_WINDOW, mResumeWindow);
    outState.putLong(STATE_RESUME_POSITION, mResumePosition);
    outState.putBoolean(STATE_PLAYER_FULLSCREEN, mExoPlayerFullscreen);
    super.onSaveInstanceState(outState);
}



   @Override
protected void onResume() {

    super.onResume();

    if (mExoPlayerView == null) {

        mExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.exoplayer);

        videoURL = getIntent().getStringExtra("url");
        postID = getIntent().getIntExtra("UserID", 0);

        String userAgent = Util.getUserAgent(Vid.this, getApplicationContext().getApplicationInfo().packageName);
        DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent, null, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true);
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(Vid.this, null, httpDataSourceFactory);
        Uri daUri = Uri.parse(videoURL);

        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

        if (daUri.toString().startsWith("https://player.vimeo"))
            mVideoSource = new HlsMediaSource(daUri, dataSourceFactory, 1, null, null);
        else
            mVideoSource = new ExtractorMediaSource(daUri, dataSourceFactory, extractorsFactory, null, null);

        initExoPlayer();

    } else {
        resumeExoPlayer();
    }

}


   private void resumeExoPlayer() {

    boolean haveResumePosition = mResumeWindow != C.INDEX_UNSET;

    if (haveResumePosition) {
        hideKeyboard();
        hideProgress();
        mExoPlayerView.getPlayer().seekTo(mResumeWindow, mResumePosition);
    }
}

private void initExoPlayer() {
    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    LoadControl loadControl = new DefaultLoadControl();
    SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this), trackSelector, loadControl);
    mExoPlayerView.setPlayer(player);

    boolean haveResumePosition = mResumeWindow != C.INDEX_UNSET;

    if (haveResumePosition) {
        hideKeyboard();
        hideProgress();
        mExoPlayerView.getPlayer().seekTo(mResumeWindow, mResumePosition);

    }

    mExoPlayerView.getPlayer().prepare(mVideoSource);
    mExoPlayerView.getPlayer().setPlayWhenReady(true);

    mExoPlayerView.getPlayer().addListener(new Player.EventListener() {
        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest) {

        }

        @Override
        public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

        }

        @Override
        public void onLoadingChanged(boolean isLoading) {

        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

            if (playbackState == ExoPlayer.STATE_ENDED) {
                hideProgress();
                mExoPlayerView.getPlayer().seekTo(0);
                mExoPlayerView.getPlayer().setPlayWhenReady(false);
            } else if (playbackState == ExoPlayer.STATE_BUFFERING) {
            } else if (playbackState == ExoPlayer.STATE_READY) {
                hideProgress();

                if (preferenceManager.getLoggedIn()) {
                    APIGetComment();
                }
            }
        }

        @Override
        public void onRepeatModeChanged(int repeatMode) {

        }

        @Override
        public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

        }

        @Override
        public void onPlayerError(ExoPlaybackException error) {
            hideProgress();
            finish();
        }

        @Override
        public void onPositionDiscontinuity(int reason) {

        }

        @Override
        public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

        }

        @Override
        public void onSeekProcessed() {

        }
    });
}

【问题讨论】:

  • 玩家准备需要时间。您对此无能为力。

标签: android video android-activity exoplayer landscape-portrait


【解决方案1】:

如果您希望视频在方向更改时恢复,您可以将其添加到您的清单 android:configChanges="keyboardHidden|orientation|screenSize"

     <activity
     <activity
         android:name=".MainActivity"
         android:name=".MainActivity"
         android:label="@string/app_name"
         android:label="@string/app_name"
+            android:configChanges="keyboardHidden|orientation|screenSize"
         android:theme="@style/AppTheme.NoActionBar"
         android:theme="@style/AppTheme.NoActionBar"
         android:icon="@mipmap/ic_launcher_2">
         android:icon="@mipmap/ic_launcher_2">
         <intent-filter>
         <intent-filter>

【讨论】:

    【解决方案2】:

    终于,在浪费了 2 天之后,我找到了它。 只需将其添加到清单中即可适用于所有 android 版本?

    android:configChanges="orientation|screenSize|layoutDirection"
    

    干杯!

    【讨论】:

    • 谢谢你,是的,它解决了问题,对于像我这样的新手,你需要在'AndroidManifest.xml'中寻找你的视频活动并将其放在“
    • 是的,请不要这样做。这种“解决方法”会导致您的应用出现许多其他问题,包括在旋转设备或启用分屏时显示错误的布局。
    • 您无需阻止配置更改即可使其正常工作。这个解决方案应该可以工作stackoverflow.com/a/62427122/4052264
    【解决方案3】:

    不需要任何额外的编码,只需添加这一行

    android:configChanges="keyboardHidden|orientation|screenSize"
    

    在您的AndroidManifest.xml 的活动部分。

    【讨论】:

      【解决方案4】:

      我在这方面也浪费了很多时间。看看EXO PLAYER 2.11.2

          implementation 'com.google.android.exoplayer:exoplayer:2.11.2'
      

      STEP - 1 创建一个活动,其中字符串 url 作为意图传递。

        public class VideoPlayerActivity extends Activity {
      
        public static final String sURL_KEY = "STREAMING_URL_KEY";
        public static final String sTOAST_TEXT = "Unable to stream, no media found";
        static final String LOADING = "PLAYER_LOADING";
        static final String STOPPED = "PLAYER_STOPPED";
        static final String PAUSED = "PLAYER_PAUSED";
        static final String PLAYING = "PLAYER_PLAYING";
        static final String IDLE = "PLAYER_IDLE";
        private static final String TAG = "StreamMediaActivity";
        int orientation;
        private Uri streamUrl;
        private SimpleExoPlayer mPlayer;
        private PlayerView playerView;
        private ProgressBar progressBar;
        private String mPlayerStatus;
        private long mPlaybackPosition = 0L;
        private boolean mIsPlayWhenReady = true;
        private int mCurrentWindow = 0;
        private Display display;
        private String STATE_RESUME_WINDOW = "resumeWindow";
        private String STATE_RESUME_POSITION = "resumePosition";
        private String STATE_PLAYER_FULLSCREEN = "playerFullscreen";
        private boolean mExoPlayerFullscreen = false;
      
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          fullScreen();
          display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
          orientation = display.getRotation();
          setContentView(R.layout.activity_video_player);
          playerView = findViewById(R.id.player_view);
          progressBar = findViewById(R.id.progressBar_player);
      
      // Pass a string uri to this class
          String urlString = getIntent().getStringExtra(sURL_KEY);
          if (urlString != null) {
            streamUrl = Uri.parse(urlString);
          } else {
            Toast.makeText(this, sTOAST_TEXT, Toast.LENGTH_LONG).show();
            finish();
          }
        }
      
        @Override
        protected void onStart() {
          super.onStart();
          initPlayer();
        }
      
        @Override
        protected void onResume() {
          super.onResume();
          if (mPlaybackPosition != 0L && mPlayer != null) {
            mPlayer.seekTo(mCurrentWindow, mPlaybackPosition);
          }
        }
      
        @Override
        protected void onStop() {
          super.onStop();
        }
      
        @Override protected void onPause() {
          super.onPause();
          releasePlayer();
        }
      
      
      
          private void initPlayer() {
              // ESTABLISH THE DATA SOURCE FROM URL
          // here i'm playing local video file that's
       // why using the DefaultDataSourceFactory but you 
      //may use DefaultHttpDataSourceFactory to stream 
      //online videos 
              DataSource.Factory dataSourceFactory =
                  new DefaultDataSourceFactory(this, Util.getUserAgent(this, getApplicationInfo().name));
      
          MediaSource mediaSource =
              new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(
                  streamUrl);
      
      
          // CREATE A NEW INSTANCE OF EXO PLAYER
          if (mPlayer == null) {
            mPlayer = new SimpleExoPlayer.Builder(this, new DefaultRenderersFactory(this)).build();
            playerView.setPlayer(mPlayer);
            progressBar.setVisibility(View.VISIBLE);
          }
          mPlayer.setPlayWhenReady(mIsPlayWhenReady);
          mPlayer.seekTo(mCurrentWindow, mPlaybackPosition);
      
          // PREPARE MEDIA PLAYER
          mPlayer.prepare(mediaSource, true, false);
          mPlayer.addListener(new Player.EventListener() {
            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
              switch (playbackState) {
                case Player.STATE_BUFFERING:
                  mPlayerStatus = LOADING;
                  runOnUiThread(() -> progressBar.setVisibility(View.VISIBLE));
                  break;
                case Player.STATE_ENDED:
                  mPlayerStatus = STOPPED;
                  break;
                case Player.STATE_READY:
                  mPlayerStatus = (playWhenReady) ? PLAYING : PAUSED;
                  runOnUiThread(() -> progressBar.setVisibility(View.INVISIBLE));
                  break;
                default:
                  mPlayerStatus = IDLE;
                  break;
              }
            }
      
            @Override
            public void onPlayerError(ExoPlaybackException error) {
              Toast.makeText(VideoPlayerActivity.this, "Something went wrong", Toast.LENGTH_SHORT).show();
              finish();
            }
          });
        }
      
        @Override protected void onSaveInstanceState(Bundle outState) {
          mExoPlayerFullscreen = !mExoPlayerFullscreen;
          super.onSaveInstanceState(outState);
          outState.putInt(STATE_RESUME_WINDOW, mCurrentWindow);
          outState.putLong(STATE_RESUME_POSITION, mPlaybackPosition);
          outState.putBoolean(STATE_PLAYER_FULLSCREEN, mExoPlayerFullscreen);
          super.onSaveInstanceState(outState);
        }
      
        public void fullScreen() {
          View decorView = getWindow().getDecorView();
          decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
        }
      
        private void releasePlayer() {
          if (mPlayer != null) {
            mPlayer.stop();
            mPlaybackPosition = mPlayer.getCurrentPosition();
            mCurrentWindow = mPlayer.getCurrentWindowIndex();
            mIsPlayWhenReady = mPlayer.getPlayWhenReady();
            playerView.setPlayer(null);
            mPlayer.release();
            mPlayer = null;
          }
        }
      }
      

      第 2 步:制作 XML 布局

      <?xml version="1.0" encoding="utf-8"?>
      <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@android:color/black">
      
        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
      
          <com.google.android.exoplayer2.ui.PlayerView
              android:id="@+id/player_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              app:layout_constraintBottom_toBottomOf="parent"
              android:keepScreenOn="true"
              app:use_controller="true"
              app:resize_mode="fit"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
      
          <ProgressBar
              android:id="@+id/progressBar_player"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center" />
      
        </FrameLayout>
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      第 3 步:使用来自另一个 Activity 的 Intent 启动 VideoPlayerActivity

      Intent streamVideoIntent = new Intent(context, VideoPlayerActivity.class);
                              streamVideoIntent.putExtra(sURL_KEY, stringUrl);
                              context.startActivity(streamVideoIntent);
      

      第 4 步:最后将活动添加到清单

      <activity android:name=".ui.videoplayer.VideoPlayerActivity"
              android:configChanges="orientation|screenSize|layoutDirection"
              />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-12
        • 2011-01-31
        相关资源
        最近更新 更多