From 464f53373ad109a485d26e2f6c74f9df3bc280b5 Mon Sep 17 00:00:00 2001 From: olly Date: Thu, 14 Jan 2021 19:05:00 +0000 Subject: [PATCH] Remove deprecated debug listener methods from SimpleExoPlayer - Once the ability to add debug listeners is removed, analyticsCollector is the only component that needs to receive the events. Hence it is called directly. - It seemed less confusing to do the same thing for (non-debug) video and audio events, and to have AnalyticsCollector no longer implement VideoListener and AudioListener directly. This clears up confusion that arises as a result of the debug and non-debug interfaces defining the same methods in some cases, and having to be careful not to end up calling the corresponding AnalyticsCollector method twice. PiperOrigin-RevId: 351835491 --- RELEASENOTES.md | 7 + .../exoplayer2/video/VideoListener.java | 12 +- .../android/exoplayer2/SimpleExoPlayer.java | 141 ++++-------------- .../analytics/AnalyticsCollector.java | 134 +++++++++-------- 4 files changed, 117 insertions(+), 177 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e8b0962b90..7a207f03ca 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -69,6 +69,13 @@ `com.google.android.exoplayer2.video.VideoListener` instead. * `SingleSampleMediaSource.EventListener` and constructors. Use `MediaSourceEventListener` and `SingleSampleMediaSource.Factory` + * `SimpleExoPlayer.addVideoDebugListener`, + `SimpleExoPlayer.removeVideoDebugListener`, + `SimpleExoPlayer.addAudioDebugListener` + and `SimpleExoPlayer.removeAudioDebugListener`. Use + `SimpleExoPlayer.addAnalyticsListener` and + `SimpleExoPlayer.removeAnalyticsListener` instead. + * `AdaptiveMediaSourceEventListener`. Use `MediaSourceEventListener` instead. * Add a `LivePlaybackSpeedControl` component to control the playback speed during live playbacks. This allows the player to stay close to the diff --git a/library/common/src/main/java/com/google/android/exoplayer2/video/VideoListener.java b/library/common/src/main/java/com/google/android/exoplayer2/video/VideoListener.java index 589371cde5..eb013ed425 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/video/VideoListener.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/video/VideoListener.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.video; +import com.google.android.exoplayer2.C; + /** A listener for metadata corresponding to video being rendered. */ public interface VideoListener { @@ -41,12 +43,10 @@ public interface VideoListener { * Called each time there's a change in the size of the surface onto which the video is being * rendered. * - * @param width The surface width in pixels. May be {@link - * com.google.android.exoplayer2.C#LENGTH_UNSET} if unknown, or 0 if the video is not rendered - * onto a surface. - * @param height The surface height in pixels. May be {@link - * com.google.android.exoplayer2.C#LENGTH_UNSET} if unknown, or 0 if the video is not rendered - * onto a surface. + * @param width The surface width in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if the + * video is not rendered onto a surface. + * @param height The surface height in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if + * the video is not rendered onto a surface. */ default void onSurfaceSizeChanged(int width, int height) {} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java index 5e6b7a5e01..01716fc0fb 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java @@ -574,8 +574,6 @@ public class SimpleExoPlayer extends BasePlayer private final CopyOnWriteArraySet textOutputs; private final CopyOnWriteArraySet metadataOutputs; private final CopyOnWriteArraySet deviceListeners; - private final CopyOnWriteArraySet videoDebugListeners; - private final CopyOnWriteArraySet audioDebugListeners; private final AnalyticsCollector analyticsCollector; private final AudioBecomingNoisyManager audioBecomingNoisyManager; private final AudioFocusManager audioFocusManager; @@ -650,8 +648,6 @@ public class SimpleExoPlayer extends BasePlayer textOutputs = new CopyOnWriteArraySet<>(); metadataOutputs = new CopyOnWriteArraySet<>(); deviceListeners = new CopyOnWriteArraySet<>(); - videoDebugListeners = new CopyOnWriteArraySet<>(); - audioDebugListeners = new CopyOnWriteArraySet<>(); Handler eventHandler = new Handler(builder.looper); renderers = builder.renderersFactory.createRenderers( @@ -689,11 +685,6 @@ public class SimpleExoPlayer extends BasePlayer builder.looper, /* wrappingPlayer= */ this); player.addListener(componentListener); - videoDebugListeners.add(analyticsCollector); - videoListeners.add(analyticsCollector); - audioDebugListeners.add(analyticsCollector); - audioListeners.add(analyticsCollector); - addMetadataOutput(analyticsCollector); audioBecomingNoisyManager = new AudioBecomingNoisyManager(builder.context, eventHandler, componentListener); @@ -926,6 +917,7 @@ public class SimpleExoPlayer extends BasePlayer this.audioAttributes = audioAttributes; sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_ATTRIBUTES, audioAttributes); streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage)); + analyticsCollector.onAudioAttributesChanged(audioAttributes); for (AudioListener audioListener : audioListeners) { audioListener.onAudioAttributesChanged(audioAttributes); } @@ -964,6 +956,7 @@ public class SimpleExoPlayer extends BasePlayer this.audioSessionId = audioSessionId; sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_SESSION_ID, audioSessionId); sendRendererMessage(C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_AUDIO_SESSION_ID, audioSessionId); + analyticsCollector.onAudioSessionIdChanged(audioSessionId); for (AudioListener audioListener : audioListeners) { audioListener.onAudioSessionIdChanged(audioSessionId); } @@ -994,6 +987,7 @@ public class SimpleExoPlayer extends BasePlayer } this.audioVolume = audioVolume; sendVolumeToRenderers(); + analyticsCollector.onVolumeChanged(audioVolume); for (AudioListener audioListener : audioListeners) { audioListener.onVolumeChanged(audioVolume); } @@ -1196,44 +1190,6 @@ public class SimpleExoPlayer extends BasePlayer metadataOutputs.remove(listener); } - /** - * @deprecated Use {@link #addAnalyticsListener(AnalyticsListener)} to get more detailed debug - * information. - */ - @Deprecated - public void addVideoDebugListener(VideoRendererEventListener listener) { - Assertions.checkNotNull(listener); - videoDebugListeners.add(listener); - } - - /** - * @deprecated Use {@link #addAnalyticsListener(AnalyticsListener)} and {@link - * #removeAnalyticsListener(AnalyticsListener)} to get more detailed debug information. - */ - @Deprecated - public void removeVideoDebugListener(VideoRendererEventListener listener) { - videoDebugListeners.remove(listener); - } - - /** - * @deprecated Use {@link #addAnalyticsListener(AnalyticsListener)} to get more detailed debug - * information. - */ - @Deprecated - public void addAudioDebugListener(AudioRendererEventListener listener) { - Assertions.checkNotNull(listener); - audioDebugListeners.add(listener); - } - - /** - * @deprecated Use {@link #addAnalyticsListener(AnalyticsListener)} and {@link - * #removeAnalyticsListener(AnalyticsListener)} to get more detailed debug information. - */ - @Deprecated - public void removeAudioDebugListener(AudioRendererEventListener listener) { - audioDebugListeners.remove(listener); - } - // ExoPlayer implementation @Override @@ -1939,6 +1895,7 @@ public class SimpleExoPlayer extends BasePlayer if (width != surfaceWidth || height != surfaceHeight) { surfaceWidth = width; surfaceHeight = height; + analyticsCollector.onSurfaceSizeChanged(width, height); for (VideoListener videoListener : videoListeners) { videoListener.onSurfaceSizeChanged(width, height); } @@ -1952,14 +1909,8 @@ public class SimpleExoPlayer extends BasePlayer @SuppressWarnings("SuspiciousMethodCalls") private void notifySkipSilenceEnabledChanged() { + analyticsCollector.onSkipSilenceEnabledChanged(skipSilenceEnabled); for (AudioListener listener : audioListeners) { - // Prevent duplicate notification if a listener is both a AudioRendererEventListener and - // a AudioListener, as they have the same method signature. - if (!audioDebugListeners.contains(listener)) { - listener.onSkipSilenceEnabledChanged(skipSilenceEnabled); - } - } - for (AudioRendererEventListener listener : audioDebugListeners) { listener.onSkipSilenceEnabledChanged(skipSilenceEnabled); } } @@ -2082,86 +2033,64 @@ public class SimpleExoPlayer extends BasePlayer @Override public void onVideoEnabled(DecoderCounters counters) { videoDecoderCounters = counters; - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onVideoEnabled(counters); - } + analyticsCollector.onVideoEnabled(counters); } @Override public void onVideoDecoderInitialized( String decoderName, long initializedTimestampMs, long initializationDurationMs) { - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onVideoDecoderInitialized( - decoderName, initializedTimestampMs, initializationDurationMs); - } + analyticsCollector.onVideoDecoderInitialized( + decoderName, initializedTimestampMs, initializationDurationMs); } @Override public void onVideoInputFormatChanged( Format format, @Nullable DecoderReuseEvaluation decoderReuseEvaluation) { videoFormat = format; - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onVideoInputFormatChanged(format, decoderReuseEvaluation); - } + analyticsCollector.onVideoInputFormatChanged(format, decoderReuseEvaluation); } @Override public void onDroppedFrames(int count, long elapsed) { - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onDroppedFrames(count, elapsed); - } + analyticsCollector.onDroppedFrames(count, elapsed); } @Override public void onVideoSizeChanged( int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { + analyticsCollector.onVideoSizeChanged( + width, height, unappliedRotationDegrees, pixelWidthHeightRatio); for (VideoListener videoListener : videoListeners) { - // Prevent duplicate notification if a listener is both a VideoRendererEventListener and - // a VideoListener, as they have the same method signature. - if (!videoDebugListeners.contains(videoListener)) { - videoListener.onVideoSizeChanged( - width, height, unappliedRotationDegrees, pixelWidthHeightRatio); - } - } - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onVideoSizeChanged( + videoListener.onVideoSizeChanged( width, height, unappliedRotationDegrees, pixelWidthHeightRatio); } } @Override public void onRenderedFirstFrame(Surface surface) { + analyticsCollector.onRenderedFirstFrame(surface); if (SimpleExoPlayer.this.surface == surface) { for (VideoListener videoListener : videoListeners) { videoListener.onRenderedFirstFrame(); } } - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onRenderedFirstFrame(surface); - } } @Override public void onVideoDecoderReleased(String decoderName) { - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onVideoDecoderReleased(decoderName); - } + analyticsCollector.onVideoDecoderReleased(decoderName); } @Override public void onVideoDisabled(DecoderCounters counters) { - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onVideoDisabled(counters); - } + analyticsCollector.onVideoDisabled(counters); videoFormat = null; videoDecoderCounters = null; } @Override public void onVideoFrameProcessingOffset(long totalProcessingOffsetUs, int frameCount) { - for (VideoRendererEventListener videoDebugListener : videoDebugListeners) { - videoDebugListener.onVideoFrameProcessingOffset(totalProcessingOffsetUs, frameCount); - } + analyticsCollector.onVideoFrameProcessingOffset(totalProcessingOffsetUs, frameCount); } // AudioRendererEventListener implementation @@ -2169,55 +2098,41 @@ public class SimpleExoPlayer extends BasePlayer @Override public void onAudioEnabled(DecoderCounters counters) { audioDecoderCounters = counters; - for (AudioRendererEventListener audioDebugListener : audioDebugListeners) { - audioDebugListener.onAudioEnabled(counters); - } + analyticsCollector.onAudioEnabled(counters); } @Override public void onAudioDecoderInitialized( String decoderName, long initializedTimestampMs, long initializationDurationMs) { - for (AudioRendererEventListener audioDebugListener : audioDebugListeners) { - audioDebugListener.onAudioDecoderInitialized( - decoderName, initializedTimestampMs, initializationDurationMs); - } + analyticsCollector.onAudioDecoderInitialized( + decoderName, initializedTimestampMs, initializationDurationMs); } @Override public void onAudioInputFormatChanged( Format format, @Nullable DecoderReuseEvaluation decoderReuseEvaluation) { audioFormat = format; - for (AudioRendererEventListener audioDebugListener : audioDebugListeners) { - audioDebugListener.onAudioInputFormatChanged(format, decoderReuseEvaluation); - } + analyticsCollector.onAudioInputFormatChanged(format, decoderReuseEvaluation); } @Override public void onAudioPositionAdvancing(long playoutStartSystemTimeMs) { - for (AudioRendererEventListener audioDebugListener : audioDebugListeners) { - audioDebugListener.onAudioPositionAdvancing(playoutStartSystemTimeMs); - } + analyticsCollector.onAudioPositionAdvancing(playoutStartSystemTimeMs); } @Override public void onAudioUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { - for (AudioRendererEventListener audioDebugListener : audioDebugListeners) { - audioDebugListener.onAudioUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs); - } + analyticsCollector.onAudioUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs); } @Override public void onAudioDecoderReleased(String decoderName) { - for (AudioRendererEventListener audioDebugListener : audioDebugListeners) { - audioDebugListener.onAudioDecoderReleased(decoderName); - } + analyticsCollector.onAudioDecoderReleased(decoderName); } @Override public void onAudioDisabled(DecoderCounters counters) { - for (AudioRendererEventListener audioDebugListener : audioDebugListeners) { - audioDebugListener.onAudioDisabled(counters); - } + analyticsCollector.onAudioDisabled(counters); audioFormat = null; audioDecoderCounters = null; audioSessionId = C.AUDIO_SESSION_ID_UNSET; @@ -2232,6 +2147,11 @@ public class SimpleExoPlayer extends BasePlayer notifySkipSilenceEnabledChanged(); } + @Override + public void onAudioSinkError(Exception audioSinkError) { + analyticsCollector.onAudioSinkError(audioSinkError); + } + // TextOutput implementation @Override @@ -2246,6 +2166,7 @@ public class SimpleExoPlayer extends BasePlayer @Override public void onMetadata(Metadata metadata) { + analyticsCollector.onMetadata(metadata); for (MetadataOutput metadataOutput : metadataOutputs) { metadataOutput.onMetadata(metadata); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java index f312658473..e4705bd761 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java @@ -34,13 +34,11 @@ import com.google.android.exoplayer2.Timeline.Period; import com.google.android.exoplayer2.Timeline.Window; import com.google.android.exoplayer2.analytics.AnalyticsListener.EventTime; import com.google.android.exoplayer2.audio.AudioAttributes; -import com.google.android.exoplayer2.audio.AudioListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderReuseEvaluation; import com.google.android.exoplayer2.drm.DrmSessionEventListener; import com.google.android.exoplayer2.metadata.Metadata; -import com.google.android.exoplayer2.metadata.MetadataOutput; import com.google.android.exoplayer2.source.LoadEventInfo; import com.google.android.exoplayer2.source.MediaLoadData; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; @@ -52,7 +50,6 @@ import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.Util; -import com.google.android.exoplayer2.video.VideoListener; import com.google.android.exoplayer2.video.VideoRendererEventListener; import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; @@ -64,19 +61,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.RequiresNonNull; /** - * Data collector which is able to forward analytics events to {@link AnalyticsListener}s by - * listening to all available ExoPlayer listeners. + * Data collector that forwards analytics events to {@link AnalyticsListener AnalyticsListeners}. */ public class AnalyticsCollector implements Player.EventListener, - MetadataOutput, AudioRendererEventListener, VideoRendererEventListener, MediaSourceEventListener, BandwidthMeter.EventListener, - DrmSessionEventListener, - VideoListener, - AudioListener { + DrmSessionEventListener { private final Clock clock; private final Period period; @@ -196,9 +189,13 @@ public class AnalyticsCollector // TODO: remove method. } - // MetadataOutput implementation. + // MetadataOutput events. - @Override + /** + * Called when there is metadata associated with current playback time. + * + * @param metadata The metadata. + */ public final void onMetadata(Metadata metadata) { EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime(); sendEvent( @@ -293,35 +290,6 @@ public class AnalyticsCollector }); } - @Override - public final void onAudioSinkError(Exception audioSinkError) { - EventTime eventTime = generateReadingMediaPeriodEventTime(); - sendEvent( - eventTime, - AnalyticsListener.EVENT_AUDIO_SINK_ERROR, - listener -> listener.onAudioSinkError(eventTime, audioSinkError)); - } - - // AudioListener implementation. - - @Override - public final void onAudioSessionIdChanged(int audioSessionId) { - EventTime eventTime = generateReadingMediaPeriodEventTime(); - sendEvent( - eventTime, - AnalyticsListener.EVENT_AUDIO_SESSION_ID, - listener -> listener.onAudioSessionIdChanged(eventTime, audioSessionId)); - } - - @Override - public final void onAudioAttributesChanged(AudioAttributes audioAttributes) { - EventTime eventTime = generateReadingMediaPeriodEventTime(); - sendEvent( - eventTime, - AnalyticsListener.EVENT_AUDIO_ATTRIBUTES_CHANGED, - listener -> listener.onAudioAttributesChanged(eventTime, audioAttributes)); - } - @Override public final void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { EventTime eventTime = generateReadingMediaPeriodEventTime(); @@ -332,12 +300,53 @@ public class AnalyticsCollector } @Override - public final void onVolumeChanged(float audioVolume) { + public final void onAudioSinkError(Exception audioSinkError) { + EventTime eventTime = generateReadingMediaPeriodEventTime(); + sendEvent( + eventTime, + AnalyticsListener.EVENT_AUDIO_SINK_ERROR, + listener -> listener.onAudioSinkError(eventTime, audioSinkError)); + } + + // Additional audio events. + + /** + * Called when the audio session ID changes. + * + * @param audioSessionId The audio session ID. + */ + public final void onAudioSessionIdChanged(int audioSessionId) { + EventTime eventTime = generateReadingMediaPeriodEventTime(); + sendEvent( + eventTime, + AnalyticsListener.EVENT_AUDIO_SESSION_ID, + listener -> listener.onAudioSessionIdChanged(eventTime, audioSessionId)); + } + + /** + * Called when the audio attributes change. + * + * @param audioAttributes The audio attributes. + */ + public final void onAudioAttributesChanged(AudioAttributes audioAttributes) { + EventTime eventTime = generateReadingMediaPeriodEventTime(); + sendEvent( + eventTime, + AnalyticsListener.EVENT_AUDIO_ATTRIBUTES_CHANGED, + listener -> listener.onAudioAttributesChanged(eventTime, audioAttributes)); + } + + /** + * Called when the volume changes. + * + * @param volume The new volume, with 0 being silence and 1 being unity gain. + */ + public final void onVolumeChanged(float volume) { EventTime eventTime = generateReadingMediaPeriodEventTime(); sendEvent( eventTime, AnalyticsListener.EVENT_VOLUME_CHANGED, - listener -> listener.onVolumeChanged(eventTime, audioVolume)); + listener -> listener.onVolumeChanged(eventTime, volume)); } // VideoRendererEventListener implementation. @@ -415,6 +424,18 @@ public class AnalyticsCollector }); } + @Override + public final void onVideoSizeChanged( + int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { + EventTime eventTime = generateReadingMediaPeriodEventTime(); + sendEvent( + eventTime, + AnalyticsListener.EVENT_VIDEO_SIZE_CHANGED, + listener -> + listener.onVideoSizeChanged( + eventTime, width, height, unappliedRotationDegrees, pixelWidthHeightRatio)); + } + @Override public final void onRenderedFirstFrame(@Nullable Surface surface) { EventTime eventTime = generateReadingMediaPeriodEventTime(); @@ -434,26 +455,17 @@ public class AnalyticsCollector listener.onVideoFrameProcessingOffset(eventTime, totalProcessingOffsetUs, frameCount)); } - // VideoListener implementation. + // Additional video events. - @Override - public final void onRenderedFirstFrame() { - // Do nothing. Already reported in VideoRendererEventListener.onRenderedFirstFrame. - } - - @Override - public final void onVideoSizeChanged( - int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { - EventTime eventTime = generateReadingMediaPeriodEventTime(); - sendEvent( - eventTime, - AnalyticsListener.EVENT_VIDEO_SIZE_CHANGED, - listener -> - listener.onVideoSizeChanged( - eventTime, width, height, unappliedRotationDegrees, pixelWidthHeightRatio)); - } - - @Override + /** + * Called each time there's a change in the size of the surface onto which the video is being + * rendered. + * + * @param width The surface width in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if the + * video is not rendered onto a surface. + * @param height The surface height in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if + * the video is not rendered onto a surface. + */ public void onSurfaceSizeChanged(int width, int height) { EventTime eventTime = generateReadingMediaPeriodEventTime(); sendEvent(