Skip to content

Ordering of AnalyticsListener causes assert in PlaybackStatsListener #8048

@stevemayhew

Description

@stevemayhew

Issue description

The PlaybackStatsListener should work correctly no matter what order it is added to the SimpleExoPlayer.addAnalyticsListener() in relation to other AnalyticsListener objects.

Reproduction steps

Sorry I don't have an easy example to share, but here is a code sample that will reproduce the issue:

  1. Create a playlist with an error (404 on a segment for example)
  2. Add code to "recover" this error, as follows:
      player =
          new SimpleExoPlayer.Builder(/* context= */ this, renderersFactory)
              .setTrackSelector(trackSelector)
              .build();
      player.addListener(new PlayerEventListener());
...
      player.addAnalyticsListener(new EventLogger(trackSelector));
      player.addAnalyticsListener(new AnalyticsListener() {
        @Override
        public void onPlayerError(EventTime eventTime, ExoPlaybackException error) {
          player.retry();
          player.seekTo(2000);
        }
      });
      player.addAnalyticsListener(new PlaybackStatsListener(true, null));

The recovery "seek's" past the error (assume something in the error tells it where to seek too).

PlaybackStatsListener now will field the onPlayerError() event after the seek, see the comment in the PlaybackStatsListener commit

The assertion that fails is marked here

Seems this check implies a seek during error handling is a legit thing:

      } else if (isSeeking) {
        // Seeking takes precedence over errors such that we report a seek while in error state.
        return PlaybackStats.PLAYBACK_STATE_SEEKING;

But the assert here assumes events are delivered in order, which in this case they are not:

    private void maybeUpdatePlaybackState(EventTime eventTime, boolean belongsToPlayback) {
      @PlaybackState int newPlaybackState = resolveNewPlaybackState();
      if (newPlaybackState == currentPlaybackState) {
        return;
      }

      Assertions.checkArgument(eventTime.realtimeMs >= currentPlaybackStateStartTimeMs);

Link to test content

Sorry I don't have any, but content that fails with a 404 on a segment would do it. Anything that creates a PlayerError.

A full bug report captured from the device

Probably not that useful.

Version of ExoPlayer being used

r2.11.8

Device(s) and version(s) of Android being used

Arris STB running Android P

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions