代码之家  ›  专栏  ›  技术社区  ›  yalematta

具有多个视图的RecyclerView中的Exoplayer

  •  0
  • yalematta  · 技术社区  · 6 年前

    我有一个多视图的回收视图。其中一个视图有播放按钮和SeekBar,用于播放音频文件。作为最佳实践,您是否在AudioViewHolder中实现ExoPlayer?或者在回收视图所在的活动中?

    如果我在活动中实现了它,我将在单击“播放/暂停”按钮时从AudioViewHolder(适配器中的接口)向活动发送回调。这个ExoPlayer.onplayerstate已更改(状态\结束)将无法访问“播放按钮”视图并更新按钮图像。

    如何将ExoPlayer发送到AudioViewHolder以便更新播放/暂停按钮图像?

    音频聊天项目

    private void initPlayButton(File file) {
        playButton.requestFocus();
        playButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isPlaying) {
                    isPlaying = false;
                    playButton.setImageResource(R.drawable.ic_play);
                    audioControllerCallback.onStop();
                } else {
                    isPlaying = true;
                    playButton.setImageResource(R.drawable.ic_stop);
                    audioControllerCallback.onPlay(file);
                }
            }
        });
    }
    

        private ChatMessagesAdapter.AudioControllerCallback audioControllerCallback =    new ChatMessagesAdapter.AudioControllerCallback() {
            @Override
            public void onPlay(File file) {
                prepareExoPlayerFromUri(Uri.parse(file.getAbsolutePath()));
                mExoPlayer.setPlayWhenReady(true);
            }
    
            @Override
            public void onStop() {
                mExoPlayer.setPlayWhenReady(false);
            }
    
            @Override
            public void onSeek(int progress) {
                mExoPlayer.seekTo(progress * 1000);
            }
        };
    
     private Player.EventListener eventListener = new Player.EventListener() {
    
             @Override
                 public void onPlayerStateChanged(boolean playWhenReady, int     playbackState) {
                  Log.i("EXO", "onPlayerStateChanged: playWhenReady = " +         String.valueOf(playWhenReady)
                        + " playbackState = " + playbackState);
    
                switch (playbackState) {
                    case Player.STATE_ENDED:
                        Log.i("EXO", "Playback ended!");
                        //Here I need to access the playButton in my ViewHolder
                        audioControllerCallback.onStop();
                        mExoPlayer.seekTo(0);
                        break;
                    case Player.STATE_READY:
                            Log.i("EXO", "ExoPlayer ready! pos: " +   mExoPlayer.getCurrentPosition()
                                + " max: " + stringForTime((int)  mExoPlayer.getDuration()));
    //                  setProgress();
                        break;
                    case Player.STATE_BUFFERING:
                        Log.i("EXO", "Playback buffering!");
                        break;
                    case Player.STATE_IDLE:
                        Log.i("EXO", "ExoPlayer idle!");
                        break;
                }
            }
              ...
          }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   yalematta    6 年前

    Pode-ser-na活性。 你觉得你的节奏如何,康科达?

    事实上,在同一时间运行多个音频是没有意义的,你同意吗?

    public class StepDetailFragment extends Fragment implements StepsViewModel.PlayerLifeCycle,
            StepsViewModel.StepsEventHandler {
    
        public static final String STEP_SELECTED = StepDetailFragment.class.getName().concat(".STEP_SELECTED");
        private static final String PLAYER_STATE = StepDetailFragment.class.getName().concat(".PLAYER_STATE");
    
    
        private FragmentStepsDetailBinding mBinding;
        private StepsViewModel mViewModel;
    
        private ExoPlayer mExoPlayer;
        private MediaSessionCompat mMediaSession;
        private PlaybackStateCompat.Builder mStateBuilder;
        private Long mPlayerPosition;
    
        public StepDetailFragment(){}
    
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
            mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_steps_detail, container,
                    false);
            if(getActivity() != null)
                mViewModel = StepsDetailsActivity.obtainViewModel(getActivity());
            return mBinding.getRoot();
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            if (getArguments() != null) {
                if (getArguments().containsKey(STEP_SELECTED)) {
                    Step mCurrentStep = getArguments().getParcelable(STEP_SELECTED);
                    if (mViewModel != null){
                        mViewModel.getCurrentStep().setValue(mCurrentStep);
                    }
                }
            }
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            if(getActivity() != null && mViewModel == null)
                mViewModel = StepsDetailsActivity.obtainViewModel(getActivity());
    
            mViewModel.setPlayerLifeCycle(this);
            mViewModel.setStepsEventHandler(this);
    
            mBinding.setViewModel(mViewModel);
            mBinding.setEventHandler(new WeakReference<StepsViewModel.StepsEventHandler>(this));
    
    
            if (getArguments() != null) {
                if (getArguments().containsKey(STEP_SELECTED)) {
                    Step mCurrentStep = getArguments().getParcelable(STEP_SELECTED);
                    mViewModel.getCurrentStep().setValue(mCurrentStep);
                }
            }
    
            if (savedInstanceState != null) {
                if (savedInstanceState.containsKey(STEP_SELECTED)) {
                    Step mCurrentStep = savedInstanceState.getParcelable(STEP_SELECTED);
                    mViewModel.getCurrentStep().setValue(mCurrentStep);
                }
                if (savedInstanceState.containsKey(PLAYER_STATE)) {
                    mPlayerPosition = savedInstanceState.getLong(PLAYER_STATE);
                }
            }
    
            mViewModel.getCurrentStep().observe(this, new Observer<Step>() {
                @Override
                public void onChanged(@Nullable Step step) {
                    if (step != null) {
    
                        mBinding.setViewModel(mViewModel);
                        mBinding.setEventHandler(new WeakReference<StepsViewModel.StepsEventHandler>(
                                StepDetailFragment.this));
    
                        setupToolbar();
                        releasePlayer();
    
                    }
    
                }
            });
    
            setupToolbar();
        }
    
        private void setupToolbar() {
            if (mViewModel.getCurrentStep().getValue() != null) {
                AppCompatActivity activity = (AppCompatActivity) this.getActivity();
                if (activity != null) {
                    activity.setTitle(mViewModel.getCurrentStep().getValue().getShortDescription());
                }
            }
        }
    
        @Override
        public void onSaveInstanceState(@NonNull Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putParcelable(STEP_SELECTED, mViewModel.getCurrentStep().getValue());
            if (mExoPlayer != null) {
                outState.putLong(PLAYER_STATE, mExoPlayer.getCurrentPosition());
            }
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
            releasePlayer();
        }
    
        @Override
        public void onSetupPlayer(SimpleExoPlayer exoPlayer) {
            if (isAdded()) {
                mExoPlayer = exoPlayer;
                mExoPlayer.addListener(new MyPlayerListener());
                if (mMediaSession == null) {
                    initializeMediaSession();
                }
                if (mPlayerPosition != null) {
                    mExoPlayer.seekTo(mPlayerPosition);
                    mPlayerPosition = null;
                }
            }
        }
    
        @Override
        public void nextPositionClick() {
            mViewModel.nextStep();
        }
    
        @Override
        public void previousPositionClick() {
            mViewModel.prevStep();
        }
    
        private class MyPlayerListener implements Player.EventListener {
    
            @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 (mExoPlayer != null) {
                    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());
                }
            }
    
            @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 void initializeMediaSession() {
            if (getContext() != null) {
                mMediaSession = new MediaSessionCompat(getContext(), this.getClass().getSimpleName());
                mMediaSession.setFlags(
                        MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
                                MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
                mMediaSession.setMediaButtonReceiver(null);
    
                mStateBuilder = new PlaybackStateCompat.Builder()
                        .setActions(
                                PlaybackStateCompat.ACTION_PLAY |
                                        PlaybackStateCompat.ACTION_PAUSE |
                                        PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
                                        PlaybackStateCompat.ACTION_PLAY_PAUSE);
    
                mMediaSession.setPlaybackState(mStateBuilder.build());
                mMediaSession.setCallback(new MySessionCallback());
                mMediaSession.setActive(true);
            }
        }
    
        private class MySessionCallback extends MediaSessionCompat.Callback {
            @Override
            public void onPlay() {
                if (mExoPlayer != null) {
                    mExoPlayer.setPlayWhenReady(true);
                }
            }
    
            @Override
            public void onPause() {
                if (mExoPlayer != null) {
                    mExoPlayer.setPlayWhenReady(false);
                }
            }
    
            @Override
            public void onSkipToPrevious() {
                if (mExoPlayer != null) {
                    mExoPlayer.seekTo(0);
                }
            }
        }
    
        private void releasePlayer() {
            if (mExoPlayer != null) {
                mExoPlayer.stop();
                mExoPlayer.release();
            }
            mExoPlayer = null;
        }
    
    }