Package com.google.android.exoplayer2.analytics

## Class AnalyticsCollector

- java.lang.Object
- - com.google.android.exoplayer2.analytics.AnalyticsCollector

- All Implemented Interfaces:
    `AudioListener`, `AudioRendererEventListener`, `DeviceListener`, `DrmSessionEventListener`, `MetadataOutput`, `Player.EventListener`, `Player.Listener`, `MediaSourceEventListener`, `TextOutput`, `BandwidthMeter.EventListener`, `VideoListener`, `VideoRendererEventListener`

      public class AnalyticsCollector
      extends Object
      implements Player.Listener, AudioRendererEventListener, VideoRendererEventListener, MediaSourceEventListener, BandwidthMeter.EventListener, DrmSessionEventListener

  Data collector that forwards analytics events to `AnalyticsListeners`.

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from interface com.google.android.exoplayer2.audio.AudioRendererEventListener

      `AudioRendererEventListener.EventDispatcher`

    - ### Nested classes/interfaces inherited from interface com.google.android.exoplayer2.upstream.BandwidthMeter.EventListener

      `BandwidthMeter.EventListener.EventDispatcher`

    - ### Nested classes/interfaces inherited from interface com.google.android.exoplayer2.drm.DrmSessionEventListener

      `DrmSessionEventListener.EventDispatcher`

    - ### Nested classes/interfaces inherited from interface com.google.android.exoplayer2.source.MediaSourceEventListener

      `MediaSourceEventListener.EventDispatcher`

    - ### Nested classes/interfaces inherited from interface com.google.android.exoplayer2.video.VideoRendererEventListener

      `VideoRendererEventListener.EventDispatcher`

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `AnalyticsCollector​(Clock clock)` | Creates an analytics collector.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `void` | `addListener​(AnalyticsListener listener)` | Adds a listener for analytics events.
    `protected AnalyticsListener.EventTime` | `generateCurrentPlayerMediaPeriodEventTime()` | Generates an `AnalyticsListener.EventTime` for the currently playing item in the player.
    `protected AnalyticsListener.EventTime` | `generateEventTime​(Timeline timeline, int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)` | Returns a new `AnalyticsListener.EventTime` for the specified timeline, window and media period id.
    `void` | `notifySeekStarted()` | Notify analytics collector that a seek operation will start.
    `void` | `onAudioAttributesChanged​(AudioAttributes audioAttributes)` | Called when the audio attributes change.
    `void` | `onAudioCodecError​(Exception audioCodecError)` | Called when an audio decoder encounters an error.
    `void` | `onAudioDecoderInitialized​(String decoderName, long initializedTimestampMs, long initializationDurationMs)` | Called when a decoder is created.
    `void` | `onAudioDecoderReleased​(String decoderName)` | Called when a decoder is released.
    `void` | `onAudioDisabled​(DecoderCounters counters)` | Called when the renderer is disabled.
    `void` | `onAudioEnabled​(DecoderCounters counters)` | Called when the renderer is enabled.
    `void` | `onAudioInputFormatChanged​(Format format, DecoderReuseEvaluation decoderReuseEvaluation)` | Called when the format of the media being consumed by the renderer changes.
    `void` | `onAudioPositionAdvancing​(long playoutStartSystemTimeMs)` | Called when the audio position has increased for the first time since the last pause or position reset.
    `void` | `onAudioSessionIdChanged​(int audioSessionId)` | Called when the audio session ID changes.
    `void` | `onAudioSinkError​(Exception audioSinkError)` | Called when `AudioSink` has encountered an error.
    `void` | `onAudioUnderrun​(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs)` | Called when an audio underrun occurs.
    `void` | `onBandwidthSample​(int elapsedMs, long bytes, long bitrate)` | Called periodically to indicate that bytes have been transferred or the estimated bitrate has changed.
    `void` | `onDownstreamFormatChanged​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData)` | Called when a downstream format change occurs (i.e.
    `void` | `onDrmKeysLoaded​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)` | Called each time keys are loaded.
    `void` | `onDrmKeysRemoved​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)` | Called each time offline keys are removed.
    `void` | `onDrmKeysRestored​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)` | Called each time offline keys are restored.
    `void` | `onDrmSessionAcquired​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, int state)` | Called each time a drm session is acquired.
    `void` | `onDrmSessionManagerError​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, Exception error)` | Called when a drm error occurs.
    `void` | `onDrmSessionReleased​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId)` | Called each time a drm session is released.
    `void` | `onDroppedFrames​(int count, long elapsedMs)` | Called to report the number of frames dropped by the renderer.
    `void` | `onIsLoadingChanged​(boolean isLoading)` | Called when the player starts or stops loading the source.
    `void` | `onIsPlayingChanged​(boolean isPlaying)` | Called when the value of `Player.isPlaying()` changes.
    `void` | `onLoadCanceled​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)` | Called when a load is canceled.
    `void` | `onLoadCompleted​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)` | Called when a load ends.
    `void` | `onLoadError​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, boolean wasCanceled)` | Called when a load error occurs.
    `void` | `onLoadStarted​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)` | Called when a load begins.
    `void` | `onMediaItemTransition​(MediaItem mediaItem, int reason)` | Called when playback transitions to a media item or starts repeating a media item according to the current `repeat mode`.
    `void` | `onMediaMetadataChanged​(MediaMetadata mediaMetadata)` | Called when the combined `MediaMetadata` changes.
    `void` | `onMetadata​(Metadata metadata)` | Called when there is metadata associated with current playback time.
    `void` | `onPlaybackParametersChanged​(PlaybackParameters playbackParameters)` | Called when the current playback parameters change.
    `void` | `onPlaybackStateChanged​(int state)` | Called when the value returned from `Player.getPlaybackState()` changes.
    `void` | `onPlaybackSuppressionReasonChanged​(int playbackSuppressionReason)` | Called when the value returned from `Player.getPlaybackSuppressionReason()` changes.
    `void` | `onPlayerError​(ExoPlaybackException error)` | Called when an error occurs.
    `void` | `onPlayerStateChanged​(boolean playWhenReady, int playbackState)` |
    `void` | `onPlayWhenReadyChanged​(boolean playWhenReady, int reason)` | Called when the value returned from `Player.getPlayWhenReady()` changes.
    `void` | `onPositionDiscontinuity​(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason)` | Called when a position discontinuity occurs.
    `void` | `onRenderedFirstFrame​(Object output, long renderTimeMs)` | Called when a frame is rendered for the first time since setting the output, or since the renderer was reset, or since the stream being rendered was changed.
    `void` | `onRepeatModeChanged​(int repeatMode)` | Called when the value of `Player.getRepeatMode()` changes.
    `void` | `onSeekProcessed()` |
    `void` | `onShuffleModeEnabledChanged​(boolean shuffleModeEnabled)` | Called when the value of `Player.getShuffleModeEnabled()` changes.
    `void` | `onSkipSilenceEnabledChanged​(boolean skipSilenceEnabled)` | Called when skipping silences is enabled or disabled in the audio stream.
    `void` | `onStaticMetadataChanged​(List<Metadata> metadataList)` | Called when the static metadata changes.
    `void` | `onSurfaceSizeChanged​(int width, int height)` | Called each time there's a change in the size of the surface onto which the video is being rendered.
    `void` | `onTimelineChanged​(Timeline timeline, int reason)` | Called when the timeline has been refreshed.
    `void` | `onTracksChanged​(TrackGroupArray trackGroups, TrackSelectionArray trackSelections)` | Called when the available or selected tracks change.
    `void` | `onUpstreamDiscarded​(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData)` | Called when data is removed from the back of a media buffer, typically so that it can be re-buffered in a different format.
    `void` | `onVideoCodecError​(Exception videoCodecError)` | Called when a video decoder encounters an error.
    `void` | `onVideoDecoderInitialized​(String decoderName, long initializedTimestampMs, long initializationDurationMs)` | Called when a decoder is created.
    `void` | `onVideoDecoderReleased​(String decoderName)` | Called when a decoder is released.
    `void` | `onVideoDisabled​(DecoderCounters counters)` | Called when the renderer is disabled.
    `void` | `onVideoEnabled​(DecoderCounters counters)` | Called when the renderer is enabled.
    `void` | `onVideoFrameProcessingOffset​(long totalProcessingOffsetUs, int frameCount)` | Called to report the video processing offset of video frames processed by the video renderer.
    `void` | `onVideoInputFormatChanged​(Format format, DecoderReuseEvaluation decoderReuseEvaluation)` | Called when the format of the media being consumed by the renderer changes.
    `void` | `onVideoSizeChanged​(VideoSize videoSize)` | Called each time there's a change in the size of the video being rendered.
    `void` | `onVolumeChanged​(float volume)` | Called when the volume changes.
    `void` | `release()` | Releases the collector.
    `void` | `removeListener​(AnalyticsListener listener)` | Removes a previously added analytics event listener.
    `protected void` | `sendEvent​(AnalyticsListener.EventTime eventTime, int eventFlag, ListenerSet.Event<AnalyticsListener> eventInvocation)` | Sends an event to registered listeners.
    `void` | `setPlayer​(Player player, Looper looper)` | Sets the player for which data will be collected.
    `void` | `updateMediaPeriodQueueInfo​(List<MediaSource.MediaPeriodId> queue, MediaSource.MediaPeriodId readingPeriod)` | Updates the playback queue information used for event association.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

    - ### Methods inherited from interface com.google.android.exoplayer2.audio.AudioRendererEventListener

      `onAudioInputFormatChanged`

    - ### Methods inherited from interface com.google.android.exoplayer2.device.DeviceListener

      `onDeviceInfoChanged, onDeviceVolumeChanged`

    - ### Methods inherited from interface com.google.android.exoplayer2.drm.DrmSessionEventListener

      `onDrmSessionAcquired`

    - ### Methods inherited from interface com.google.android.exoplayer2.Player.EventListener

      `onAvailableCommandsChanged, onEvents, onLoadingChanged, onPositionDiscontinuity, onTimelineChanged`

    - ### Methods inherited from interface com.google.android.exoplayer2.Player.Listener

      `onCues`

    - ### Methods inherited from interface com.google.android.exoplayer2.video.VideoListener

      `onRenderedFirstFrame, onVideoSizeChanged`

    - ### Methods inherited from interface com.google.android.exoplayer2.video.VideoRendererEventListener

      `onVideoInputFormatChanged`

- - ### Constructor Detail

    - #### AnalyticsCollector

          public AnalyticsCollector​(Clock clock)

      Creates an analytics collector.
      Parameters:
        `clock` - A `Clock` used to generate timestamps.

  - ### Method Detail

    - #### addListener

          @CallSuper
          public void addListener​(AnalyticsListener listener)

      Adds a listener for analytics events.
      Parameters:
        `listener` - The listener to add.

    - #### removeListener

          @CallSuper
          public void removeListener​(AnalyticsListener listener)

      Removes a previously added analytics event listener.
      Parameters:
        `listener` - The listener to remove.

    - #### setPlayer

          @CallSuper
          public void setPlayer​(Player player,
                                Looper looper)

      Sets the player for which data will be collected. Must only be called if no player has been set yet or the current player is idle.
      Parameters:
        `player` - The `Player` for which data will be collected.
        `looper` - The `Looper` used for listener callbacks.

    - #### release

          @CallSuper
          public void release()

      Releases the collector. Must be called after the player for which data is collected has been released.

    - #### updateMediaPeriodQueueInfo

          public final void updateMediaPeriodQueueInfo​(List<MediaSource.MediaPeriodId> queue,
                                                       @Nullable
                                                       MediaSource.MediaPeriodId readingPeriod)

      Updates the playback queue information used for event association.

      Should only be called by the player controlling the queue and not from app code.

      Parameters:
        `queue` - The playback queue of media periods identified by their `MediaSource.MediaPeriodId`.
        `readingPeriod` - The media period in the queue that is currently being read by renderers, or null if the queue is empty.

    - #### notifySeekStarted

          public final void notifySeekStarted()

      Notify analytics collector that a seek operation will start. Should be called before the player adjusts its state and position to the seek.

    - #### onMetadata

          public final void onMetadata​(Metadata metadata)

      Called when there is metadata associated with current playback time.
      Specified by:
        `onMetadata` in interface `MetadataOutput`
      Specified by:
        `onMetadata` in interface `Player.Listener`
      Parameters:
        `metadata` - The metadata.

    - #### onAudioEnabled

          public final void onAudioEnabled​(DecoderCounters counters)

      Description copied from interface: `AudioRendererEventListener`
      Called when the renderer is enabled.
      Specified by:
        `onAudioEnabled` in interface `AudioRendererEventListener`
      Parameters:
        `counters` - `DecoderCounters` that will be updated by the renderer for as long as it remains enabled.

    - #### onAudioDecoderInitialized

          public final void onAudioDecoderInitialized​(String decoderName,
                                                      long initializedTimestampMs,
                                                      long initializationDurationMs)

      Description copied from interface: `AudioRendererEventListener`
      Called when a decoder is created.
      Specified by:
        `onAudioDecoderInitialized` in interface `AudioRendererEventListener`
      Parameters:
        `decoderName` - The decoder that was created.
        `initializedTimestampMs` - `SystemClock.elapsedRealtime()` when initialization finished.
        `initializationDurationMs` - The time taken to initialize the decoder in milliseconds.

    - #### onAudioInputFormatChanged

          public final void onAudioInputFormatChanged​(Format format,
                                                      @Nullable
                                                      DecoderReuseEvaluation decoderReuseEvaluation)

      Description copied from interface: `AudioRendererEventListener`
      Called when the format of the media being consumed by the renderer changes.
      Specified by:
        `onAudioInputFormatChanged` in interface `AudioRendererEventListener`
      Parameters:
        `format` - The new format.
        `decoderReuseEvaluation` - The result of the evaluation to determine whether an existing decoder instance can be reused for the new format, or `null` if the renderer did not have a decoder.

    - #### onAudioPositionAdvancing

          public final void onAudioPositionAdvancing​(long playoutStartSystemTimeMs)

      Description copied from interface: `AudioRendererEventListener`
      Called when the audio position has increased for the first time since the last pause or position reset.
      Specified by:
        `onAudioPositionAdvancing` in interface `AudioRendererEventListener`
      Parameters:
        `playoutStartSystemTimeMs` - The approximate derived `System.currentTimeMillis()` at which playout started.

    - #### onAudioUnderrun

          public final void onAudioUnderrun​(int bufferSize,
                                            long bufferSizeMs,
                                            long elapsedSinceLastFeedMs)

      Description copied from interface: `AudioRendererEventListener`
      Called when an audio underrun occurs.
      Specified by:
        `onAudioUnderrun` in interface `AudioRendererEventListener`
      Parameters:
        `bufferSize` - The size of the audio output buffer, in bytes.
        `bufferSizeMs` - The size of the audio output buffer, in milliseconds, if it contains PCM encoded audio. `C.TIME_UNSET` if the output buffer contains non-PCM encoded audio.
        `elapsedSinceLastFeedMs` - The time since audio was last written to the output buffer.

    - #### onAudioDecoderReleased

          public final void onAudioDecoderReleased​(String decoderName)

      Description copied from interface: `AudioRendererEventListener`
      Called when a decoder is released.
      Specified by:
        `onAudioDecoderReleased` in interface `AudioRendererEventListener`
      Parameters:
        `decoderName` - The decoder that was released.

    - #### onAudioDisabled

          public final void onAudioDisabled​(DecoderCounters counters)

      Description copied from interface: `AudioRendererEventListener`
      Called when the renderer is disabled.
      Specified by:
        `onAudioDisabled` in interface `AudioRendererEventListener`
      Parameters:
        `counters` - `DecoderCounters` that were updated by the renderer.

    - #### onSkipSilenceEnabledChanged

          public final void onSkipSilenceEnabledChanged​(boolean skipSilenceEnabled)

      Description copied from interface: `AudioListener`
      Called when skipping silences is enabled or disabled in the audio stream.
      Specified by:
        `onSkipSilenceEnabledChanged` in interface `AudioListener`
      Specified by:
        `onSkipSilenceEnabledChanged` in interface `AudioRendererEventListener`
      Parameters:
        `skipSilenceEnabled` - Whether skipping silences in the audio stream is enabled.

    - #### onAudioSinkError

          public final void onAudioSinkError​(Exception audioSinkError)

      Description copied from interface: `AudioRendererEventListener`
      Called when `AudioSink` has encountered an error.

      If the sink writes to a platform `AudioTrack`, this will called for all `AudioTrack` errors.

      This method being called does not indicate that playback has failed, or that it will fail. The player may be able to recover from the error. Hence applications should not implement this method to display a user visible error or initiate an application level retry. `Player.EventListener.onPlayerError(com.google.android.exoplayer2.ExoPlaybackException)` is the appropriate place to implement such behavior. This method is called to provide the application with an opportunity to log the error if it wishes to do so.

      Specified by:
        `onAudioSinkError` in interface `AudioRendererEventListener`
      Parameters:
        `audioSinkError` - The error that occurred. Typically an `AudioSink.InitializationException`, a `AudioSink.WriteException`, or an `AudioSink.UnexpectedDiscontinuityException`.

    - #### onAudioCodecError

          public final void onAudioCodecError​(Exception audioCodecError)

      Description copied from interface: `AudioRendererEventListener`
      Called when an audio decoder encounters an error.

      This method being called does not indicate that playback has failed, or that it will fail. The player may be able to recover from the error. Hence applications should not implement this method to display a user visible error or initiate an application level retry. `Player.EventListener.onPlayerError(com.google.android.exoplayer2.ExoPlaybackException)` is the appropriate place to implement such behavior. This method is called to provide the application with an opportunity to log the error if it wishes to do so.

      Specified by:
        `onAudioCodecError` in interface `AudioRendererEventListener`
      Parameters:
        `audioCodecError` - The error. Typically a `MediaCodec.CodecException` if the renderer uses `MediaCodec`, or a `DecoderException` if the renderer uses a software decoder.

    - #### onAudioSessionIdChanged

          public final void onAudioSessionIdChanged​(int audioSessionId)

      Called when the audio session ID changes.
      Specified by:
        `onAudioSessionIdChanged` in interface `AudioListener`
      Parameters:
        `audioSessionId` - The audio session ID.

    - #### onAudioAttributesChanged

          public final void onAudioAttributesChanged​(AudioAttributes audioAttributes)

      Called when the audio attributes change.
      Specified by:
        `onAudioAttributesChanged` in interface `AudioListener`
      Parameters:
        `audioAttributes` - The audio attributes.

    - #### onVolumeChanged

          public final void onVolumeChanged​(float volume)

      Called when the volume changes.
      Specified by:
        `onVolumeChanged` in interface `AudioListener`
      Parameters:
        `volume` - The new volume, with 0 being silence and 1 being unity gain.

    - #### onVideoEnabled

          public final void onVideoEnabled​(DecoderCounters counters)

      Description copied from interface: `VideoRendererEventListener`
      Called when the renderer is enabled.
      Specified by:
        `onVideoEnabled` in interface `VideoRendererEventListener`
      Parameters:
        `counters` - `DecoderCounters` that will be updated by the renderer for as long as it remains enabled.

    - #### onVideoDecoderInitialized

          public final void onVideoDecoderInitialized​(String decoderName,
                                                      long initializedTimestampMs,
                                                      long initializationDurationMs)

      Description copied from interface: `VideoRendererEventListener`
      Called when a decoder is created.
      Specified by:
        `onVideoDecoderInitialized` in interface `VideoRendererEventListener`
      Parameters:
        `decoderName` - The decoder that was created.
        `initializedTimestampMs` - `SystemClock.elapsedRealtime()` when initialization finished.
        `initializationDurationMs` - The time taken to initialize the decoder in milliseconds.

    - #### onVideoInputFormatChanged

          public final void onVideoInputFormatChanged​(Format format,
                                                      @Nullable
                                                      DecoderReuseEvaluation decoderReuseEvaluation)

      Description copied from interface: `VideoRendererEventListener`
      Called when the format of the media being consumed by the renderer changes.
      Specified by:
        `onVideoInputFormatChanged` in interface `VideoRendererEventListener`
      Parameters:
        `format` - The new format.
        `decoderReuseEvaluation` - The result of the evaluation to determine whether an existing decoder instance can be reused for the new format, or `null` if the renderer did not have a decoder.

    - #### onDroppedFrames

          public final void onDroppedFrames​(int count,
                                            long elapsedMs)

      Description copied from interface: `VideoRendererEventListener`
      Called to report the number of frames dropped by the renderer. Dropped frames are reported whenever the renderer is stopped having dropped frames, and optionally, whenever the count reaches a specified threshold whilst the renderer is started.
      Specified by:
        `onDroppedFrames` in interface `VideoRendererEventListener`
      Parameters:
        `count` - The number of dropped frames.
        `elapsedMs` - The duration in milliseconds over which the frames were dropped. This duration is timed from when the renderer was started or from when dropped frames were last reported (whichever was more recent), and not from when the first of the reported drops occurred.

    - #### onVideoDecoderReleased

          public final void onVideoDecoderReleased​(String decoderName)

      Description copied from interface: `VideoRendererEventListener`
      Called when a decoder is released.
      Specified by:
        `onVideoDecoderReleased` in interface `VideoRendererEventListener`
      Parameters:
        `decoderName` - The decoder that was released.

    - #### onVideoDisabled

          public final void onVideoDisabled​(DecoderCounters counters)

      Description copied from interface: `VideoRendererEventListener`
      Called when the renderer is disabled.
      Specified by:
        `onVideoDisabled` in interface `VideoRendererEventListener`
      Parameters:
        `counters` - `DecoderCounters` that were updated by the renderer.

    - #### onVideoSizeChanged

          public final void onVideoSizeChanged​(VideoSize videoSize)

      Description copied from interface: `VideoListener`
      Called each time there's a change in the size of the video being rendered.
      Specified by:
        `onVideoSizeChanged` in interface `VideoListener`
      Specified by:
        `onVideoSizeChanged` in interface `VideoRendererEventListener`
      Parameters:
        `videoSize` - The new size of the video.

    - #### onRenderedFirstFrame

          public final void onRenderedFirstFrame​(Object output,
                                                 long renderTimeMs)

      Description copied from interface: `VideoRendererEventListener`
      Called when a frame is rendered for the first time since setting the output, or since the renderer was reset, or since the stream being rendered was changed.
      Specified by:
        `onRenderedFirstFrame` in interface `VideoRendererEventListener`
      Parameters:
        `output` - The output of the video renderer. Normally a `Surface`, however some video renderers may have other output types (e.g., a `VideoDecoderOutputBufferRenderer`).
        `renderTimeMs` - The `SystemClock.elapsedRealtime()` when the frame was rendered.

    - #### onVideoFrameProcessingOffset

          public final void onVideoFrameProcessingOffset​(long totalProcessingOffsetUs,
                                                         int frameCount)

      Description copied from interface: `VideoRendererEventListener`
      Called to report the video processing offset of video frames processed by the video renderer.

      Video processing offset represents how early a video frame is processed compared to the player's current position. For each video frame, the offset is calculated as Pvf - Ppl where Pvf is the presentation timestamp of the video frame and Ppl is the current position of the player. Positive values indicate the frame was processed early enough whereas negative values indicate that the player's position had progressed beyond the frame's timestamp when the frame was processed (and the frame was probably dropped).

      The renderer reports the sum of video processing offset samples (one sample per processed video frame: dropped, skipped or rendered) and the total number of samples.

      Specified by:
        `onVideoFrameProcessingOffset` in interface `VideoRendererEventListener`
      Parameters:
        `totalProcessingOffsetUs` - The sum of all video frame processing offset samples for the video frames processed by the renderer in microseconds.
        `frameCount` - The number of samples included in the `totalProcessingOffsetUs`.

    - #### onVideoCodecError

          public final void onVideoCodecError​(Exception videoCodecError)

      Description copied from interface: `VideoRendererEventListener`
      Called when a video decoder encounters an error.

      This method being called does not indicate that playback has failed, or that it will fail. The player may be able to recover from the error. Hence applications should not implement this method to display a user visible error or initiate an application level retry. `Player.EventListener.onPlayerError(com.google.android.exoplayer2.ExoPlaybackException)` is the appropriate place to implement such behavior. This method is called to provide the application with an opportunity to log the error if it wishes to do so.

      Specified by:
        `onVideoCodecError` in interface `VideoRendererEventListener`
      Parameters:
        `videoCodecError` - The error. Typically a `MediaCodec.CodecException` if the renderer uses `MediaCodec`, or a `DecoderException` if the renderer uses a software decoder.

    - #### onSurfaceSizeChanged

          public void onSurfaceSizeChanged​(int width,
                                           int height)

      Called each time there's a change in the size of the surface onto which the video is being rendered.
      Specified by:
        `onSurfaceSizeChanged` in interface `VideoListener`
      Parameters:
        `width` - The surface width in pixels. May be `C.LENGTH_UNSET` if unknown, or 0 if the video is not rendered onto a surface.
        `height` - The surface height in pixels. May be `C.LENGTH_UNSET` if unknown, or 0 if the video is not rendered onto a surface.

    - #### onLoadStarted

          public final void onLoadStarted​(int windowIndex,
                                          @Nullable
                                          MediaSource.MediaPeriodId mediaPeriodId,
                                          LoadEventInfo loadEventInfo,
                                          MediaLoadData mediaLoadData)

      Description copied from interface: `MediaSourceEventListener`
      Called when a load begins.
      Specified by:
        `onLoadStarted` in interface `MediaSourceEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline of the media source this load belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` this load belongs to. Null if the load does not belong to a specific media period.
        `loadEventInfo` - The `LoadEventInfo` corresponding to the event. The value of `LoadEventInfo.uri` won't reflect potential redirection yet and `LoadEventInfo.responseHeaders` will be empty.
        `mediaLoadData` - The `MediaLoadData` defining the data being loaded.

    - #### onLoadCompleted

          public final void onLoadCompleted​(int windowIndex,
                                            @Nullable
                                            MediaSource.MediaPeriodId mediaPeriodId,
                                            LoadEventInfo loadEventInfo,
                                            MediaLoadData mediaLoadData)

      Description copied from interface: `MediaSourceEventListener`
      Called when a load ends.
      Specified by:
        `onLoadCompleted` in interface `MediaSourceEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline of the media source this load belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` this load belongs to. Null if the load does not belong to a specific media period.
        `loadEventInfo` - The `LoadEventInfo` corresponding to the event. The values of `LoadEventInfo.elapsedRealtimeMs` and `LoadEventInfo.bytesLoaded` are relative to the corresponding `MediaSourceEventListener.onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)` event.
        `mediaLoadData` - The `MediaLoadData` defining the data being loaded.

    - #### onLoadCanceled

          public final void onLoadCanceled​(int windowIndex,
                                           @Nullable
                                           MediaSource.MediaPeriodId mediaPeriodId,
                                           LoadEventInfo loadEventInfo,
                                           MediaLoadData mediaLoadData)

      Description copied from interface: `MediaSourceEventListener`
      Called when a load is canceled.
      Specified by:
        `onLoadCanceled` in interface `MediaSourceEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline of the media source this load belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` this load belongs to. Null if the load does not belong to a specific media period.
        `loadEventInfo` - The `LoadEventInfo` corresponding to the event. The values of `LoadEventInfo.elapsedRealtimeMs` and `LoadEventInfo.bytesLoaded` are relative to the corresponding `MediaSourceEventListener.onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)` event.
        `mediaLoadData` - The `MediaLoadData` defining the data being loaded.

    - #### onLoadError

          public final void onLoadError​(int windowIndex,
                                        @Nullable
                                        MediaSource.MediaPeriodId mediaPeriodId,
                                        LoadEventInfo loadEventInfo,
                                        MediaLoadData mediaLoadData,
                                        IOException error,
                                        boolean wasCanceled)

      Description copied from interface: `MediaSourceEventListener`
      Called when a load error occurs.

      The error may or may not have resulted in the load being canceled, as indicated by the `wasCanceled` parameter. If the load was canceled, `MediaSourceEventListener.onLoadCanceled(int, com.google.android.exoplayer2.source.MediaSource.MediaPeriodId, com.google.android.exoplayer2.source.LoadEventInfo, com.google.android.exoplayer2.source.MediaLoadData)` will not be called in addition to this method.

      This method being called does not indicate that playback has failed, or that it will fail. The player may be able to recover from the error. Hence applications should not implement this method to display a user visible error or initiate an application level retry. `Player.EventListener.onPlayerError(com.google.android.exoplayer2.ExoPlaybackException)` is the appropriate place to implement such behavior. This method is called to provide the application with an opportunity to log the error if it wishes to do so.

      Specified by:
        `onLoadError` in interface `MediaSourceEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline of the media source this load belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` this load belongs to. Null if the load does not belong to a specific media period.
        `loadEventInfo` - The `LoadEventInfo` corresponding to the event. The values of `LoadEventInfo.elapsedRealtimeMs` and `LoadEventInfo.bytesLoaded` are relative to the corresponding `MediaSourceEventListener.onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)` event.
        `mediaLoadData` - The `MediaLoadData` defining the data being loaded.
        `error` - The load error.
        `wasCanceled` - Whether the load was canceled as a result of the error.

    - #### onUpstreamDiscarded

          public final void onUpstreamDiscarded​(int windowIndex,
                                                @Nullable
                                                MediaSource.MediaPeriodId mediaPeriodId,
                                                MediaLoadData mediaLoadData)

      Description copied from interface: `MediaSourceEventListener`
      Called when data is removed from the back of a media buffer, typically so that it can be re-buffered in a different format.
      Specified by:
        `onUpstreamDiscarded` in interface `MediaSourceEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline of the media source this load belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` the media belongs to.
        `mediaLoadData` - The `MediaLoadData` defining the media being discarded.

    - #### onDownstreamFormatChanged

          public final void onDownstreamFormatChanged​(int windowIndex,
                                                      @Nullable
                                                      MediaSource.MediaPeriodId mediaPeriodId,
                                                      MediaLoadData mediaLoadData)

      Description copied from interface: `MediaSourceEventListener`
      Called when a downstream format change occurs (i.e. when the format of the media being read from one or more `SampleStream`s provided by the source changes).
      Specified by:
        `onDownstreamFormatChanged` in interface `MediaSourceEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline of the media source this load belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` the media belongs to.
        `mediaLoadData` - The `MediaLoadData` defining the newly selected downstream data.

    - #### onTimelineChanged

          public final void onTimelineChanged​(Timeline timeline,
                                              @TimelineChangeReason
                                              int reason)

      Description copied from interface: `Player.EventListener`
      Called when the timeline has been refreshed.

      Note that the current window or period index may change as a result of a timeline change. If playback can't continue smoothly because of this timeline change, a separate `Player.EventListener.onPositionDiscontinuity(PositionInfo, PositionInfo, int)` callback will be triggered.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onTimelineChanged` in interface `Player.EventListener`
      Parameters:
        `timeline` - The latest timeline. Never null, but may be empty.
        `reason` - The `Player.TimelineChangeReason` responsible for this timeline change.

    - #### onMediaItemTransition

          public final void onMediaItemTransition​(@Nullable
                                                  MediaItem mediaItem,
                                                  @MediaItemTransitionReason
                                                  int reason)

      Description copied from interface: `Player.EventListener`
      Called when playback transitions to a media item or starts repeating a media item according to the current `repeat mode`.

      Note that this callback is also called when the playlist becomes non-empty or empty as a consequence of a playlist change.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onMediaItemTransition` in interface `Player.EventListener`
      Parameters:
        `mediaItem` - The `MediaItem`. May be null if the playlist becomes empty.
        `reason` - The reason for the transition.

    - #### onTracksChanged

          public final void onTracksChanged​(TrackGroupArray trackGroups,
                                            TrackSelectionArray trackSelections)

      Description copied from interface: `Player.EventListener`
      Called when the available or selected tracks change.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onTracksChanged` in interface `Player.EventListener`
      Parameters:
        `trackGroups` - The available tracks. Never null, but may be of length zero.
        `trackSelections` - The selected tracks. Never null, but may contain null elements. A concrete implementation may include null elements if it has a fixed number of renderer components, wishes to report a TrackSelection for each of them, and has one or more renderer components that is not assigned any selected tracks.

    - #### onStaticMetadataChanged

          public final void onStaticMetadataChanged​(List<Metadata> metadataList)

      Description copied from interface: `Player.EventListener`
      Called when the static metadata changes.

      The provided `metadataList` is an immutable list of `Metadata` instances, where the elements correspond to the `current track selections`, or an empty list if there are no track selections or the selected tracks contain no static metadata.

      The metadata is considered static in the sense that it comes from the tracks' declared Formats, rather than being timed (or dynamic) metadata, which is represented within a metadata track.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onStaticMetadataChanged` in interface `Player.EventListener`
      Parameters:
        `metadataList` - The static metadata.

    - #### onIsLoadingChanged

          public final void onIsLoadingChanged​(boolean isLoading)

      Description copied from interface: `Player.EventListener`
      Called when the player starts or stops loading the source.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onIsLoadingChanged` in interface `Player.EventListener`
      Parameters:
        `isLoading` - Whether the source is currently being loaded.

    - #### onPlayerStateChanged

          public final void onPlayerStateChanged​(boolean playWhenReady,
                                                 @State
                                                 int playbackState)

      Specified by:
        `onPlayerStateChanged` in interface `Player.EventListener`

    - #### onPlaybackStateChanged

          public final void onPlaybackStateChanged​(@State
                                                   int state)

      Description copied from interface: `Player.EventListener`
      Called when the value returned from `Player.getPlaybackState()` changes.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onPlaybackStateChanged` in interface `Player.EventListener`
      Parameters:
        `state` - The new playback `state`.

    - #### onPlayWhenReadyChanged

          public final void onPlayWhenReadyChanged​(boolean playWhenReady,
                                                   @PlayWhenReadyChangeReason
                                                   int reason)

      Description copied from interface: `Player.EventListener`
      Called when the value returned from `Player.getPlayWhenReady()` changes.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onPlayWhenReadyChanged` in interface `Player.EventListener`
      Parameters:
        `playWhenReady` - Whether playback will proceed when ready.
        `reason` - The `reason` for the change.

    - #### onPlaybackSuppressionReasonChanged

          public final void onPlaybackSuppressionReasonChanged​(@PlaybackSuppressionReason
                                                               int playbackSuppressionReason)

      Description copied from interface: `Player.EventListener`
      Called when the value returned from `Player.getPlaybackSuppressionReason()` changes.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onPlaybackSuppressionReasonChanged` in interface `Player.EventListener`
      Parameters:
        `playbackSuppressionReason` - The current `Player.PlaybackSuppressionReason`.

    - #### onIsPlayingChanged

          public void onIsPlayingChanged​(boolean isPlaying)

      Description copied from interface: `Player.EventListener`
      Called when the value of `Player.isPlaying()` changes.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onIsPlayingChanged` in interface `Player.EventListener`
      Parameters:
        `isPlaying` - Whether the player is playing.

    - #### onRepeatModeChanged

          public final void onRepeatModeChanged​(@RepeatMode
                                                int repeatMode)

      Description copied from interface: `Player.EventListener`
      Called when the value of `Player.getRepeatMode()` changes.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onRepeatModeChanged` in interface `Player.EventListener`
      Parameters:
        `repeatMode` - The `Player.RepeatMode` used for playback.

    - #### onShuffleModeEnabledChanged

          public final void onShuffleModeEnabledChanged​(boolean shuffleModeEnabled)

      Description copied from interface: `Player.EventListener`
      Called when the value of `Player.getShuffleModeEnabled()` changes.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onShuffleModeEnabledChanged` in interface `Player.EventListener`
      Parameters:
        `shuffleModeEnabled` - Whether shuffling of windows is enabled.

    - #### onPlayerError

          public final void onPlayerError​(ExoPlaybackException error)

      Description copied from interface: `Player.EventListener`
      Called when an error occurs. The playback state will transition to `Player.STATE_IDLE` immediately after this method is called. The player instance can still be used, and `Player.release()` must still be called on the player should it no longer be required.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onPlayerError` in interface `Player.EventListener`
      Parameters:
        `error` - The error.

    - #### onPositionDiscontinuity

          public final void onPositionDiscontinuity​(Player.PositionInfo oldPosition,
                                                    Player.PositionInfo newPosition,
                                                    @DiscontinuityReason
                                                    int reason)

      Description copied from interface: `Player.EventListener`
      Called when a position discontinuity occurs.

      A position discontinuity occurs when the playing period changes, the playback position jumps within the period currently being played, or when the playing period has been skipped or removed.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onPositionDiscontinuity` in interface `Player.EventListener`
      Parameters:
        `oldPosition` - The position before the discontinuity.
        `newPosition` - The position after the discontinuity.
        `reason` - The `Player.DiscontinuityReason` responsible for the discontinuity.

    - #### onPlaybackParametersChanged

          public final void onPlaybackParametersChanged​(PlaybackParameters playbackParameters)

      Description copied from interface: `Player.EventListener`
      Called when the current playback parameters change. The playback parameters may change due to a call to `Player.setPlaybackParameters(PlaybackParameters)`, or the player itself may change them (for example, if audio playback switches to passthrough or offload mode, where speed adjustment is no longer possible).

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onPlaybackParametersChanged` in interface `Player.EventListener`
      Parameters:
        `playbackParameters` - The playback parameters.

    - #### onMediaMetadataChanged

          public void onMediaMetadataChanged​(MediaMetadata mediaMetadata)

      Description copied from interface: `Player.EventListener`
      Called when the combined `MediaMetadata` changes.

      The provided `MediaMetadata` is a combination of the `MediaItem.mediaMetadata` and the static and dynamic metadata sourced from `Player.EventListener.onStaticMetadataChanged(List)` and `MetadataOutput.onMetadata(Metadata)`.

      `Player.EventListener.onEvents(Player, Events)` will also be called to report this event along with other events that happen in the same `Looper` message queue iteration.

      Specified by:
        `onMediaMetadataChanged` in interface `Player.EventListener`
      Parameters:
        `mediaMetadata` - The combined `MediaMetadata`.

    - #### onSeekProcessed

          public final void onSeekProcessed()

      Specified by:
        `onSeekProcessed` in interface `Player.EventListener`

    - #### onBandwidthSample

          public final void onBandwidthSample​(int elapsedMs,
                                              long bytes,
                                              long bitrate)

      Description copied from interface: `BandwidthMeter.EventListener`
      Called periodically to indicate that bytes have been transferred or the estimated bitrate has changed.

      Note: The estimated bitrate is typically derived from more information than just `bytesTransferred` and `elapsedMs`.

      Specified by:
        `onBandwidthSample` in interface `BandwidthMeter.EventListener`
      Parameters:
        `elapsedMs` - The time taken to transfer `bytesTransferred`, in milliseconds. This is at most the elapsed time since the last callback, but may be less if there were periods during which data was not being transferred.
        `bytes` - The number of bytes transferred since the last callback.
        `bitrate` - The estimated bitrate in bits/sec.

    - #### onDrmSessionAcquired

          public final void onDrmSessionAcquired​(int windowIndex,
                                                 @Nullable
                                                 MediaSource.MediaPeriodId mediaPeriodId,
                                                 @State
                                                 int state)

      Description copied from interface: `DrmSessionEventListener`
      Called each time a drm session is acquired.
      Specified by:
        `onDrmSessionAcquired` in interface `DrmSessionEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline this media period belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` associated with the drm session.
        `state` - The `DrmSession.State` of the session when the acquisition completed.

    - #### onDrmKeysLoaded

          public final void onDrmKeysLoaded​(int windowIndex,
                                            @Nullable
                                            MediaSource.MediaPeriodId mediaPeriodId)

      Description copied from interface: `DrmSessionEventListener`
      Called each time keys are loaded.
      Specified by:
        `onDrmKeysLoaded` in interface `DrmSessionEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline this media period belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` associated with the drm session.

    - #### onDrmSessionManagerError

          public final void onDrmSessionManagerError​(int windowIndex,
                                                     @Nullable
                                                     MediaSource.MediaPeriodId mediaPeriodId,
                                                     Exception error)

      Description copied from interface: `DrmSessionEventListener`
      Called when a drm error occurs.

      This method being called does not indicate that playback has failed, or that it will fail. The player may be able to recover from the error and continue. Hence applications should not implement this method to display a user visible error or initiate an application level retry (`Player.EventListener.onPlayerError(com.google.android.exoplayer2.ExoPlaybackException)` is the appropriate place to implement such behavior). This method is called to provide the application with an opportunity to log the error if it wishes to do so.

      Specified by:
        `onDrmSessionManagerError` in interface `DrmSessionEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline this media period belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` associated with the drm session.
        `error` - The corresponding exception.

    - #### onDrmKeysRestored

          public final void onDrmKeysRestored​(int windowIndex,
                                              @Nullable
                                              MediaSource.MediaPeriodId mediaPeriodId)

      Description copied from interface: `DrmSessionEventListener`
      Called each time offline keys are restored.
      Specified by:
        `onDrmKeysRestored` in interface `DrmSessionEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline this media period belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` associated with the drm session.

    - #### onDrmKeysRemoved

          public final void onDrmKeysRemoved​(int windowIndex,
                                             @Nullable
                                             MediaSource.MediaPeriodId mediaPeriodId)

      Description copied from interface: `DrmSessionEventListener`
      Called each time offline keys are removed.
      Specified by:
        `onDrmKeysRemoved` in interface `DrmSessionEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline this media period belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` associated with the drm session.

    - #### onDrmSessionReleased

          public final void onDrmSessionReleased​(int windowIndex,
                                                 @Nullable
                                                 MediaSource.MediaPeriodId mediaPeriodId)

      Description copied from interface: `DrmSessionEventListener`
      Called each time a drm session is released.
      Specified by:
        `onDrmSessionReleased` in interface `DrmSessionEventListener`
      Parameters:
        `windowIndex` - The window index in the timeline this media period belongs to.
        `mediaPeriodId` - The `MediaSource.MediaPeriodId` associated with the drm session.

    - #### sendEvent

          protected final void sendEvent​(AnalyticsListener.EventTime eventTime,
                                         int eventFlag,
                                         ListenerSet.Event<AnalyticsListener> eventInvocation)

      Sends an event to registered listeners.
      Parameters:
        `eventTime` - The `AnalyticsListener.EventTime` to report.
        `eventFlag` - An integer flag indicating the type of the event, or `C.INDEX_UNSET` to report this event without flag.
        `eventInvocation` - The event.

    - #### generateCurrentPlayerMediaPeriodEventTime

          protected final AnalyticsListener.EventTime generateCurrentPlayerMediaPeriodEventTime()

      Generates an `AnalyticsListener.EventTime` for the currently playing item in the player.

    - #### generateEventTime

          @RequiresNonNull("player")
          protected final AnalyticsListener.EventTime generateEventTime​(Timeline timeline,
                                                                        int windowIndex,
                                                                        @Nullable
                                                                        MediaSource.MediaPeriodId mediaPeriodId)

      Returns a new `AnalyticsListener.EventTime` for the specified timeline, window and media period id.