Intereting Posts
Какие форматы видео будут воспроизводиться в эмуляторе? Изменение ориентации экрана программно с помощью кнопки SharedElment переход с использованием фрагментов, не переходящих OnSaveInstanceState () и onRestoreInstanceState (Parcelable state) не вызываются? Добавление нескольких значений в ArrayList по одному индексу Использование onSaveInstanceState с фрагментами в backstack? Ошибка Android Studio: невозможно загрузить проект Android использует NTP для синхронизации времени? Хорошо ли заменить широковещательный приемник с помощью Greenrobot Eventbus для запуска функций на основе событий и передачи данных от службы к активности? Com.crashlytics.android.CrashlyticsMissingDependencyException во время gradle 'testDebug' в проекте студии Android Отображение gif в android Как создать полную функциональность календаря в android? Android – Firebase jobdispatcher Перетащите для динамического изменения пары смежных макетов на Android Использование ActionBar Up Навигация в фрагментах мастера / детали

Android ExoPlayer onProgressChanged

Как я могу отслеживать изменения прогресса на ExoPlayer ?
Я попытался реализовать скрытый MediaController и переопределить методы setOnSeekBarChangeListener , но пока безуспешно. Мне интересно, есть ли другой способ услышать прогресс ExoPlayer .

Solutions Collecting From Web of "Android ExoPlayer onProgressChanged"

Не уверен, что это лучший способ, но я достиг этого, перегрузив TrackRenderer .

Я использую videoPlayer.getBufferedPercentage() , но вы также можете вычислить процент самостоятельно, просто используя TrackRenderer getBufferedPositionUs() и getDurationUs()

 public interface ProgressListener { public void onProgressChange(long progress); } public class CustomVideoRenderer extends MediaCodecVideoTrackRenderer { long progress = 0; private final CopyOnWriteArraySet<ProgressListener> progressListeners = new CopyOnWriteArraySet(); // [...] // Skipped constructors // [...] public void doSomeWork(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { super.doSomeWork(positionUs, elapsedRealtimeUs); long tmpProgress = videoPlayer.getBufferedPercentage(); if (tmpProgress != this.progress) { this.progress = tmpProgress; for (ProgressListener progressListener : this.progressListeners) { progressListener.onProgressChange(progress); } } } public void addProgressListener(ProgressListener listener) { this.progressListeners.add(listener); } } 

Я знаю, что этот вопрос очень старый. Но я приземлился на это при внедрении ExoPlayer . Это поможет другим, кто делает то же самое позже 🙂

Итак, я следил за следующими способами отслеживания хода воспроизведения. Это делается в Документах ExoPlayer Google. Он работает по мере необходимости.

Оформить заказ PlaybackControlView.java в Документах Google ExoPlayer

updateProgressBar() – это функция обновления хода SeekBar :

 private void updateProgressBar() { long duration = player == null ? 0 : player.getDuration(); long position = player == null ? 0 : player.getCurrentPosition(); if (!dragging) { mSeekBar.setProgress(progressBarValue(position)); } long bufferedPosition = player == null ? 0 : player.getBufferedPosition(); mSeekBar.setSecondaryProgress(progressBarValue(bufferedPosition)); // Remove scheduled updates. handler.removeCallbacks(updateProgressAction); // Schedule an update if necessary. int playbackState = player == null ? ExoPlayer.STATE_IDLE : player.getPlaybackState(); if (playbackState != ExoPlayer.STATE_IDLE && playbackState != ExoPlayer.STATE_ENDED) { long delayMs; if (player.getPlayWhenReady() && playbackState == ExoPlayer.STATE_READY) { delayMs = 1000 - (position % 1000); if (delayMs < 200) { delayMs += 1000; } } else { delayMs = 1000; } handler.postDelayed(updateProgressAction, delayMs); } } private final Runnable updateProgressAction = new Runnable() { @Override public void run() { updateProgressBar(); } }; 

Мы updateProgressBar() в updateProgressAction несколько раз, пока воспроизведение не остановится. Функция вызывается в первый раз при изменении состояния. Мы используем removeCallbacks(Runnable runnable) чтобы всегда заботиться об одном updateProgressAction .

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

Надеюсь это поможет!

Это работает, по крайней мере, с Exoplayer 2.

Существует четыре состояния воспроизведения: STATE_IDLE, STATE_BUFFERING, STATE_READY и STATE_ENDED.

Проверка состояния воспроизведения проста. Существует как минимум два решения: if-statement или switch-statement.

Независимо от состояния воспроизведения вы можете выполнить свой метод или установить что-то еще, например, progressbar.

 @Override public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { if (playbackState == ExoPlayer.STATE_ENDED) { showControls(); Toast.makeText(getApplicationContext(), "Playback ended", Toast.LENGTH_LONG).show(); } else if (playbackState == ExoPlayer.STATE_BUFFERING) { progressBar.setVisibility(View.VISIBLE); Toast.makeText(getApplicationContext(), "Buffering..", Toast.LENGTH_SHORT).show(); } else if (playbackState == ExoPlayer.STATE_READY) { progressBar.setVisibility(View.INVISIBLE); } } 

Чтобы было ясно, в EventListener нет события для события прогресса, но вы можете вызвать Handler.postDelayed внутри функции updateProgress (), чтобы получить текущий прогресс

  private void updateProgress(){ //get current progress long position = player == null ? 0 : player.getCurrentPosition(); //updateProgress() will be called repeatedly, you can check //player state to end it handler.postDelayed(updateProgressAction,1000) } private final Runnable updateProgressAction = new Runnable() { @Override public void run() { updateProgress(); } }; 

Для получения дополнительной информации см. Источник PlaybackControlView.java внутри Exoplayer

Расширьте свой текущий класс игрока (SimpleExoPlayer для примера) и добавьте

 public interface PlayerEventsListener { void onSeek(int from, int to); void onProgressUpdate(long progress); } private PlayerEventsListener mListener; private Handler mHandler; private Runnable mProgressUpdater; private boolean isUpdatingProgress = false; public SomePlayersConstructor(Activity activity, /*...*/) { //... mListener = (PlayerEventsListener) activity; mHandler = new Handler(); mProgressUpdater = new ProgressUpdater(); } // Here u gain access to seek events @Override public void seekTo(long positionMs) { mListener.onSeek(-1, (int)positionMs/1000); super.seekTo(positionMs); } @Override public void seekTo(int windowIndex, long positionMs) { mListener.onSeek((int)getCurrentPosition()/1000, (int)positionMs/1000); super.seekTo(windowIndex, positionMs); } // Here u gain access to progress public void startProgressUpdater() { if (!isUpdatingProgress) { mProgressUpdater.run(); isUpdatingProgress = true; } } private class ProgressUpdater implements Runnable { private static final int TIME_UPDATE_MS = 500; @Override public void run() { mListener.onProgressUpdate(getCurrentPosition()); mHandler.postDelayed(mProgressUpdater, TIME_UPDATE_MS); } } 

Затем активность внутри игрока просто реализует интерфейс и запускает обновления с помощью player.startProgressUpdater();

Просто попробуйте это, его работа для меня:

 handler = new Handler(); runnable = new Runnable() { @Override public void run() { progressbar.setProgress((int) ((exoPlayer.getCurrentPosition()*100)/exoPlayer.getDuration())); handler.postDelayed(runnable, 1000); } }; handler.postDelayed(runnable, 0); 

Вот,

  • getCurrentPosition() : return Текущая позиция воспроизведения в миллисекундах.
  • getDuration() : длительность трека в миллисекундах.