Обнаружение паузы/возобновления в ExoPlayer

Я два дня искал этот вопрос в github, но не могу найти правильный ответ. Мне нужен пример для обнаружения pause / resume в ExoPlayer > 2.x . Кто-нибудь может привести мне пример? Я проверил onPlayerStateChanged и проблема не решена.

onPlayerStateChanged   :   STATE_BUFFERING 
onPlayerStateChanged   :   STATE_READY 

Я только что получил этот журнал от onPlayerStateChanged, и он не всегда вызывается!


person MrNadimi    schedule 09.12.2017    source источник


Ответы (8)


РЕДАКТИРОВАТЬ---

Пожалуйста, обратитесь к методу Player.isPlaying(), который предоставляет это как API.

Вместо того, чтобы проверять эти свойства по отдельности, можно вызвать Player.isPlaying.

https://exoplayer.dev/listening-to-player-events.html#playback-state-changes

--- РЕДАКТИРОВАТЬ КОНЕЦ

Вам нужно проверить playWhenReady с помощью Player.EventListener. Состояния воспроизведения ExoPlayer не зависит от того, поставлен проигрыватель на паузу или нет:

player.addListener(new Player.DefaultEventListener() {
  @Override
  public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    if (playWhenReady && playbackState == Player.STATE_READY) {
      // media actually playing
    } else if (playWhenReady) {
      // might be idle (plays after prepare()), 
      // buffering (plays when data available) 
      // or ended (plays when seek away from end)
    } else {
      // player paused in any state
    }
  }
});

Для воспроизведения/паузы проигрывателя ExoPlayer предоставляет

player.setPlayWhenReady(boolean)

Последовательность состояний воспроизведения с ExoPlayer с медиафайлом, который никогда не останавливается для повторной буферизации, находится один раз в каждом из четырех состояний и не выражает воспроизведение/паузу:

Player.STATE_IDLE;
Player.STATE_BUFFERING;
Player.STATE_READY;
Player.STATE_ENDED;

Каждый раз, когда игроку нужно выполнить буферизацию, происходит:

Player.STATE_READY;
Player.STATE_BUFFERING;
Player.STATE_READY;

Установка playWhenReady не влияет на состояние.

Все вместе ваши медиа на самом деле воспроизводятся, когда

playWhenReady && playbackState == Player.STATE_READY

Он играет, когда готов. :)

person marcbaechinger    schedule 02.01.2018
comment
Упомянутые константы теперь помечены как устаревшие, но они все еще работают, что полезно для отладки. - person Ben; 22.03.2018
comment
В ветке dev-2 (предварительная версия) константы STATE_XYZ не устарели. Как вы думаете, почему это так? - person marcbaechinger; 24.03.2018
comment
Я использую Exo Player 2.7.0, и Android Studio говорит мне об этом (нацелен на API 27 и до 16) - я просто хотел оставить некоторую информацию о том, что они все еще работают. Я не уверен насчет ветки dev-2. - person Ben; 24.03.2018
comment
Эта логика не работает, когда мы приостанавливаем видео в ландшафтном режиме и переходим в портретный режим. Любое решение для этого? - person Sandeep; 26.11.2018

Вы можете использовать эту функцию:

public boolean isPlaying() {
    return exoPlayer.getPlaybackState() == Player.STATE_READY && exoPlayer.getPlayWhenReady();
}
person Payam Roozbahani Fard    schedule 04.05.2019

Должно быть, поскольку другие ответы были опубликованы, в Player.EventListener был предоставлен новый метод. Это хорошо работает для меня:

override fun onIsPlayingChanged(isPlaying: Boolean) {
    // your code here
}

Если isPlaying имеет значение false, он приостанавливается, в противном случае воспроизводится.

person Casey Perkins    schedule 26.11.2019

У меня было такое же требование для обнаружения события нажатия кнопки воспроизведения/паузы exoplayer. Приведенные выше ответы в основном говорили о состоянии, а не о событии нажатия кнопки.

Это то, что я сделал, чтобы обнаружить нажатие кнопки «Воспроизведение / Пауза», работает отлично.

Шаг 1. Создайте класс диспетчера пользовательского элемента управления и переопределите метод dispatchSetPlayWhenReady

class PlayerControlDispatcher : DefaultControlDispatcher() {
    override fun dispatchSetPlayWhenReady(player: Player?, playWhenReady: Boolean): Boolean {
        if(playWhenReady) {
           // Play button clicked
        } else {
          // Paused button clicked
        }
        return super.dispatchSetPlayWhenReady(player, playWhenReady)
    }
}

Шаг 2. Установите класс диспетчера пользовательского элемента управления PlayerControlDispatcher в представление проигрывателя.

playerView.setControlDispatcher(PlayerControlDispatcher())

Где playerView — это экземпляр com.google.android.exoplayer2.ui.PlayerView, который мы объявляем в нашем файле макета.

person Krishna Sharma    schedule 30.07.2019
comment
Это правильный ответ, просто отлично работает! Спасибо @krishna-sharma! - person renatoarg; 17.10.2019
comment
Рад видеть, что это сработало для вас @renatoarg, теперь это поможет другим ответить на этот вопрос. - person Krishna Sharma; 17.10.2019
comment
Привет @KrishnaSharma Я попробовал твой код, но получил ошибку. Не могли бы вы объяснить, где я должен указать местоположение/позицию кода? - person HiDayurie Dave; 22.04.2020
comment
@HiDayurieDave, вы можете поместить это куда угодно, либо создать отдельный класс, либо внутренний класс. Важная строка: playerView.setControlDispatcher(PlayerControlDispatcher()) - person Krishna Sharma; 02.06.2021

Подход к решению Kotlin 2020 ОБНОВЛЕНИЕ

О таких событиях, как изменения состояния и ошибки воспроизведения, сообщается зарегистрированным Player.EventListener экземплярам.

Player.EventListener имеет пустые методы по умолчанию, поэтому вам нужно реализовать только те методы, которые вас интересуют.

Во-первых, ваш класс, скажем, ваша деятельность, должен соответствовать интерфейсу Player.EventListener.

Затем вы переопределяете метод onIsPlayingChanged в классе. Внешний метод onCreate...

Добавьте прослушиватель в экземпляр вашего проигрывателя:

// Adding player listener for tracking events
player?.addListener(this)

Вы можете проверить, играет ли игрок (т.е. продвигается ли позиция) с помощью Player.isPlaying:

//Listening to player events
override fun onIsPlayingChanged(isPlaying: Boolean){
    if (isPlaying) {
        // Active playback.
    } else {
        // Not playing because playback is paused, ended, suppressed, or the player
        // is buffering, stopped or failed. Check player.getPlaybackState,
        // player.getPlayWhenReady, player.getPlaybackError and
        // player.getPlaybackSuppressionReason for details.
    }
}

Вот и все. Очень просто.

person Helen Wood    schedule 07.05.2020

Вы можете использовать exoplayer.getPlayWhenReady(), чтобы проверить, находится ли проигрыватель в настоящее время в состоянии паузы или в состоянии воспроизведения.

person Rohan Seth    schedule 09.03.2019

Пожалуйста, попробуйте код ниже. Прослушиватель проигрывателя (onPlayerStateChanged) не подходит для наблюдения за действием воспроизведения/паузы, которое вызывается несколько раз, а также вызывается при настройке проигрывателя.

videoView.setControlDispatcher(object : DefaultControlDispatcher() {
            override fun dispatchSetPlayWhenReady(player: Player, playWhenReady: Boolean): Boolean {
                if (playWhenReady)
                  // Tap on Play button  
                else
                 // Tap on Pause button
                return super.dispatchSetPlayWhenReady(player, playWhenReady)
            }
        })
person M.Muzammil    schedule 08.06.2020

для котлина

private fun ExoPlayer.isPlaying() =
    playbackState == Player.STATE_READY && playWhenReady
person William Reed    schedule 24.03.2021