mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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
This commit is contained in:
parent
fa94fba2cb
commit
464f53373a
4 changed files with 117 additions and 177 deletions
|
|
@ -69,6 +69,13 @@
|
||||||
`com.google.android.exoplayer2.video.VideoListener` instead.
|
`com.google.android.exoplayer2.video.VideoListener` instead.
|
||||||
* `SingleSampleMediaSource.EventListener` and constructors. Use
|
* `SingleSampleMediaSource.EventListener` and constructors. Use
|
||||||
`MediaSourceEventListener` and `SingleSampleMediaSource.Factory`
|
`MediaSourceEventListener` and `SingleSampleMediaSource.Factory`
|
||||||
|
* `SimpleExoPlayer.addVideoDebugListener`,
|
||||||
|
`SimpleExoPlayer.removeVideoDebugListener`,
|
||||||
|
`SimpleExoPlayer.addAudioDebugListener`
|
||||||
|
and `SimpleExoPlayer.removeAudioDebugListener`. Use
|
||||||
|
`SimpleExoPlayer.addAnalyticsListener` and
|
||||||
|
`SimpleExoPlayer.removeAnalyticsListener` instead.
|
||||||
|
* `AdaptiveMediaSourceEventListener`. Use `MediaSourceEventListener`
|
||||||
instead.
|
instead.
|
||||||
* Add a `LivePlaybackSpeedControl` component to control the playback speed
|
* Add a `LivePlaybackSpeedControl` component to control the playback speed
|
||||||
during live playbacks. This allows the player to stay close to the
|
during live playbacks. This allows the player to stay close to the
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.video;
|
package com.google.android.exoplayer2.video;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
|
||||||
/** A listener for metadata corresponding to video being rendered. */
|
/** A listener for metadata corresponding to video being rendered. */
|
||||||
public interface VideoListener {
|
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
|
* Called each time there's a change in the size of the surface onto which the video is being
|
||||||
* rendered.
|
* rendered.
|
||||||
*
|
*
|
||||||
* @param width The surface width in pixels. May be {@link
|
* @param width The surface width in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if the
|
||||||
* com.google.android.exoplayer2.C#LENGTH_UNSET} if unknown, or 0 if the video is not rendered
|
* video is not rendered onto a surface.
|
||||||
* onto a surface.
|
* @param height The surface height in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if
|
||||||
* @param height The surface height in pixels. May be {@link
|
* the video is not rendered onto a surface.
|
||||||
* com.google.android.exoplayer2.C#LENGTH_UNSET} if unknown, or 0 if the video is not rendered
|
|
||||||
* onto a surface.
|
|
||||||
*/
|
*/
|
||||||
default void onSurfaceSizeChanged(int width, int height) {}
|
default void onSurfaceSizeChanged(int width, int height) {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -574,8 +574,6 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
private final CopyOnWriteArraySet<TextOutput> textOutputs;
|
private final CopyOnWriteArraySet<TextOutput> textOutputs;
|
||||||
private final CopyOnWriteArraySet<MetadataOutput> metadataOutputs;
|
private final CopyOnWriteArraySet<MetadataOutput> metadataOutputs;
|
||||||
private final CopyOnWriteArraySet<DeviceListener> deviceListeners;
|
private final CopyOnWriteArraySet<DeviceListener> deviceListeners;
|
||||||
private final CopyOnWriteArraySet<VideoRendererEventListener> videoDebugListeners;
|
|
||||||
private final CopyOnWriteArraySet<AudioRendererEventListener> audioDebugListeners;
|
|
||||||
private final AnalyticsCollector analyticsCollector;
|
private final AnalyticsCollector analyticsCollector;
|
||||||
private final AudioBecomingNoisyManager audioBecomingNoisyManager;
|
private final AudioBecomingNoisyManager audioBecomingNoisyManager;
|
||||||
private final AudioFocusManager audioFocusManager;
|
private final AudioFocusManager audioFocusManager;
|
||||||
|
|
@ -650,8 +648,6 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
textOutputs = new CopyOnWriteArraySet<>();
|
textOutputs = new CopyOnWriteArraySet<>();
|
||||||
metadataOutputs = new CopyOnWriteArraySet<>();
|
metadataOutputs = new CopyOnWriteArraySet<>();
|
||||||
deviceListeners = new CopyOnWriteArraySet<>();
|
deviceListeners = new CopyOnWriteArraySet<>();
|
||||||
videoDebugListeners = new CopyOnWriteArraySet<>();
|
|
||||||
audioDebugListeners = new CopyOnWriteArraySet<>();
|
|
||||||
Handler eventHandler = new Handler(builder.looper);
|
Handler eventHandler = new Handler(builder.looper);
|
||||||
renderers =
|
renderers =
|
||||||
builder.renderersFactory.createRenderers(
|
builder.renderersFactory.createRenderers(
|
||||||
|
|
@ -689,11 +685,6 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
builder.looper,
|
builder.looper,
|
||||||
/* wrappingPlayer= */ this);
|
/* wrappingPlayer= */ this);
|
||||||
player.addListener(componentListener);
|
player.addListener(componentListener);
|
||||||
videoDebugListeners.add(analyticsCollector);
|
|
||||||
videoListeners.add(analyticsCollector);
|
|
||||||
audioDebugListeners.add(analyticsCollector);
|
|
||||||
audioListeners.add(analyticsCollector);
|
|
||||||
addMetadataOutput(analyticsCollector);
|
|
||||||
|
|
||||||
audioBecomingNoisyManager =
|
audioBecomingNoisyManager =
|
||||||
new AudioBecomingNoisyManager(builder.context, eventHandler, componentListener);
|
new AudioBecomingNoisyManager(builder.context, eventHandler, componentListener);
|
||||||
|
|
@ -926,6 +917,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
this.audioAttributes = audioAttributes;
|
this.audioAttributes = audioAttributes;
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_ATTRIBUTES, audioAttributes);
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_ATTRIBUTES, audioAttributes);
|
||||||
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage));
|
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage));
|
||||||
|
analyticsCollector.onAudioAttributesChanged(audioAttributes);
|
||||||
for (AudioListener audioListener : audioListeners) {
|
for (AudioListener audioListener : audioListeners) {
|
||||||
audioListener.onAudioAttributesChanged(audioAttributes);
|
audioListener.onAudioAttributesChanged(audioAttributes);
|
||||||
}
|
}
|
||||||
|
|
@ -964,6 +956,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
this.audioSessionId = audioSessionId;
|
this.audioSessionId = audioSessionId;
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_SESSION_ID, 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);
|
sendRendererMessage(C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
||||||
|
analyticsCollector.onAudioSessionIdChanged(audioSessionId);
|
||||||
for (AudioListener audioListener : audioListeners) {
|
for (AudioListener audioListener : audioListeners) {
|
||||||
audioListener.onAudioSessionIdChanged(audioSessionId);
|
audioListener.onAudioSessionIdChanged(audioSessionId);
|
||||||
}
|
}
|
||||||
|
|
@ -994,6 +987,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
}
|
}
|
||||||
this.audioVolume = audioVolume;
|
this.audioVolume = audioVolume;
|
||||||
sendVolumeToRenderers();
|
sendVolumeToRenderers();
|
||||||
|
analyticsCollector.onVolumeChanged(audioVolume);
|
||||||
for (AudioListener audioListener : audioListeners) {
|
for (AudioListener audioListener : audioListeners) {
|
||||||
audioListener.onVolumeChanged(audioVolume);
|
audioListener.onVolumeChanged(audioVolume);
|
||||||
}
|
}
|
||||||
|
|
@ -1196,44 +1190,6 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
metadataOutputs.remove(listener);
|
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
|
// ExoPlayer implementation
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -1939,6 +1895,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
if (width != surfaceWidth || height != surfaceHeight) {
|
if (width != surfaceWidth || height != surfaceHeight) {
|
||||||
surfaceWidth = width;
|
surfaceWidth = width;
|
||||||
surfaceHeight = height;
|
surfaceHeight = height;
|
||||||
|
analyticsCollector.onSurfaceSizeChanged(width, height);
|
||||||
for (VideoListener videoListener : videoListeners) {
|
for (VideoListener videoListener : videoListeners) {
|
||||||
videoListener.onSurfaceSizeChanged(width, height);
|
videoListener.onSurfaceSizeChanged(width, height);
|
||||||
}
|
}
|
||||||
|
|
@ -1952,14 +1909,8 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
|
|
||||||
@SuppressWarnings("SuspiciousMethodCalls")
|
@SuppressWarnings("SuspiciousMethodCalls")
|
||||||
private void notifySkipSilenceEnabledChanged() {
|
private void notifySkipSilenceEnabledChanged() {
|
||||||
|
analyticsCollector.onSkipSilenceEnabledChanged(skipSilenceEnabled);
|
||||||
for (AudioListener listener : audioListeners) {
|
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);
|
listener.onSkipSilenceEnabledChanged(skipSilenceEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2082,86 +2033,64 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
@Override
|
@Override
|
||||||
public void onVideoEnabled(DecoderCounters counters) {
|
public void onVideoEnabled(DecoderCounters counters) {
|
||||||
videoDecoderCounters = counters;
|
videoDecoderCounters = counters;
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
analyticsCollector.onVideoEnabled(counters);
|
||||||
videoDebugListener.onVideoEnabled(counters);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoDecoderInitialized(
|
public void onVideoDecoderInitialized(
|
||||||
String decoderName, long initializedTimestampMs, long initializationDurationMs) {
|
String decoderName, long initializedTimestampMs, long initializationDurationMs) {
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
analyticsCollector.onVideoDecoderInitialized(
|
||||||
videoDebugListener.onVideoDecoderInitialized(
|
decoderName, initializedTimestampMs, initializationDurationMs);
|
||||||
decoderName, initializedTimestampMs, initializationDurationMs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoInputFormatChanged(
|
public void onVideoInputFormatChanged(
|
||||||
Format format, @Nullable DecoderReuseEvaluation decoderReuseEvaluation) {
|
Format format, @Nullable DecoderReuseEvaluation decoderReuseEvaluation) {
|
||||||
videoFormat = format;
|
videoFormat = format;
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
analyticsCollector.onVideoInputFormatChanged(format, decoderReuseEvaluation);
|
||||||
videoDebugListener.onVideoInputFormatChanged(format, decoderReuseEvaluation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDroppedFrames(int count, long elapsed) {
|
public void onDroppedFrames(int count, long elapsed) {
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
analyticsCollector.onDroppedFrames(count, elapsed);
|
||||||
videoDebugListener.onDroppedFrames(count, elapsed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoSizeChanged(
|
public void onVideoSizeChanged(
|
||||||
int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
|
int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
|
||||||
|
analyticsCollector.onVideoSizeChanged(
|
||||||
|
width, height, unappliedRotationDegrees, pixelWidthHeightRatio);
|
||||||
for (VideoListener videoListener : videoListeners) {
|
for (VideoListener videoListener : videoListeners) {
|
||||||
// Prevent duplicate notification if a listener is both a VideoRendererEventListener and
|
videoListener.onVideoSizeChanged(
|
||||||
// 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(
|
|
||||||
width, height, unappliedRotationDegrees, pixelWidthHeightRatio);
|
width, height, unappliedRotationDegrees, pixelWidthHeightRatio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRenderedFirstFrame(Surface surface) {
|
public void onRenderedFirstFrame(Surface surface) {
|
||||||
|
analyticsCollector.onRenderedFirstFrame(surface);
|
||||||
if (SimpleExoPlayer.this.surface == surface) {
|
if (SimpleExoPlayer.this.surface == surface) {
|
||||||
for (VideoListener videoListener : videoListeners) {
|
for (VideoListener videoListener : videoListeners) {
|
||||||
videoListener.onRenderedFirstFrame();
|
videoListener.onRenderedFirstFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
|
||||||
videoDebugListener.onRenderedFirstFrame(surface);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoDecoderReleased(String decoderName) {
|
public void onVideoDecoderReleased(String decoderName) {
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
analyticsCollector.onVideoDecoderReleased(decoderName);
|
||||||
videoDebugListener.onVideoDecoderReleased(decoderName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoDisabled(DecoderCounters counters) {
|
public void onVideoDisabled(DecoderCounters counters) {
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
analyticsCollector.onVideoDisabled(counters);
|
||||||
videoDebugListener.onVideoDisabled(counters);
|
|
||||||
}
|
|
||||||
videoFormat = null;
|
videoFormat = null;
|
||||||
videoDecoderCounters = null;
|
videoDecoderCounters = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoFrameProcessingOffset(long totalProcessingOffsetUs, int frameCount) {
|
public void onVideoFrameProcessingOffset(long totalProcessingOffsetUs, int frameCount) {
|
||||||
for (VideoRendererEventListener videoDebugListener : videoDebugListeners) {
|
analyticsCollector.onVideoFrameProcessingOffset(totalProcessingOffsetUs, frameCount);
|
||||||
videoDebugListener.onVideoFrameProcessingOffset(totalProcessingOffsetUs, frameCount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AudioRendererEventListener implementation
|
// AudioRendererEventListener implementation
|
||||||
|
|
@ -2169,55 +2098,41 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
@Override
|
@Override
|
||||||
public void onAudioEnabled(DecoderCounters counters) {
|
public void onAudioEnabled(DecoderCounters counters) {
|
||||||
audioDecoderCounters = counters;
|
audioDecoderCounters = counters;
|
||||||
for (AudioRendererEventListener audioDebugListener : audioDebugListeners) {
|
analyticsCollector.onAudioEnabled(counters);
|
||||||
audioDebugListener.onAudioEnabled(counters);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioDecoderInitialized(
|
public void onAudioDecoderInitialized(
|
||||||
String decoderName, long initializedTimestampMs, long initializationDurationMs) {
|
String decoderName, long initializedTimestampMs, long initializationDurationMs) {
|
||||||
for (AudioRendererEventListener audioDebugListener : audioDebugListeners) {
|
analyticsCollector.onAudioDecoderInitialized(
|
||||||
audioDebugListener.onAudioDecoderInitialized(
|
decoderName, initializedTimestampMs, initializationDurationMs);
|
||||||
decoderName, initializedTimestampMs, initializationDurationMs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioInputFormatChanged(
|
public void onAudioInputFormatChanged(
|
||||||
Format format, @Nullable DecoderReuseEvaluation decoderReuseEvaluation) {
|
Format format, @Nullable DecoderReuseEvaluation decoderReuseEvaluation) {
|
||||||
audioFormat = format;
|
audioFormat = format;
|
||||||
for (AudioRendererEventListener audioDebugListener : audioDebugListeners) {
|
analyticsCollector.onAudioInputFormatChanged(format, decoderReuseEvaluation);
|
||||||
audioDebugListener.onAudioInputFormatChanged(format, decoderReuseEvaluation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioPositionAdvancing(long playoutStartSystemTimeMs) {
|
public void onAudioPositionAdvancing(long playoutStartSystemTimeMs) {
|
||||||
for (AudioRendererEventListener audioDebugListener : audioDebugListeners) {
|
analyticsCollector.onAudioPositionAdvancing(playoutStartSystemTimeMs);
|
||||||
audioDebugListener.onAudioPositionAdvancing(playoutStartSystemTimeMs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
|
public void onAudioUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
|
||||||
for (AudioRendererEventListener audioDebugListener : audioDebugListeners) {
|
analyticsCollector.onAudioUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs);
|
||||||
audioDebugListener.onAudioUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioDecoderReleased(String decoderName) {
|
public void onAudioDecoderReleased(String decoderName) {
|
||||||
for (AudioRendererEventListener audioDebugListener : audioDebugListeners) {
|
analyticsCollector.onAudioDecoderReleased(decoderName);
|
||||||
audioDebugListener.onAudioDecoderReleased(decoderName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioDisabled(DecoderCounters counters) {
|
public void onAudioDisabled(DecoderCounters counters) {
|
||||||
for (AudioRendererEventListener audioDebugListener : audioDebugListeners) {
|
analyticsCollector.onAudioDisabled(counters);
|
||||||
audioDebugListener.onAudioDisabled(counters);
|
|
||||||
}
|
|
||||||
audioFormat = null;
|
audioFormat = null;
|
||||||
audioDecoderCounters = null;
|
audioDecoderCounters = null;
|
||||||
audioSessionId = C.AUDIO_SESSION_ID_UNSET;
|
audioSessionId = C.AUDIO_SESSION_ID_UNSET;
|
||||||
|
|
@ -2232,6 +2147,11 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
notifySkipSilenceEnabledChanged();
|
notifySkipSilenceEnabledChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioSinkError(Exception audioSinkError) {
|
||||||
|
analyticsCollector.onAudioSinkError(audioSinkError);
|
||||||
|
}
|
||||||
|
|
||||||
// TextOutput implementation
|
// TextOutput implementation
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -2246,6 +2166,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMetadata(Metadata metadata) {
|
public void onMetadata(Metadata metadata) {
|
||||||
|
analyticsCollector.onMetadata(metadata);
|
||||||
for (MetadataOutput metadataOutput : metadataOutputs) {
|
for (MetadataOutput metadataOutput : metadataOutputs) {
|
||||||
metadataOutput.onMetadata(metadata);
|
metadataOutput.onMetadata(metadata);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,11 @@ import com.google.android.exoplayer2.Timeline.Period;
|
||||||
import com.google.android.exoplayer2.Timeline.Window;
|
import com.google.android.exoplayer2.Timeline.Window;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsListener.EventTime;
|
import com.google.android.exoplayer2.analytics.AnalyticsListener.EventTime;
|
||||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
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.audio.AudioRendererEventListener;
|
||||||
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
||||||
import com.google.android.exoplayer2.decoder.DecoderReuseEvaluation;
|
import com.google.android.exoplayer2.decoder.DecoderReuseEvaluation;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
||||||
import com.google.android.exoplayer2.metadata.Metadata;
|
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.LoadEventInfo;
|
||||||
import com.google.android.exoplayer2.source.MediaLoadData;
|
import com.google.android.exoplayer2.source.MediaLoadData;
|
||||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
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.Clock;
|
||||||
import com.google.android.exoplayer2.util.ListenerSet;
|
import com.google.android.exoplayer2.util.ListenerSet;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoListener;
|
|
||||||
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
@ -64,19 +61,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data collector which is able to forward analytics events to {@link AnalyticsListener}s by
|
* Data collector that forwards analytics events to {@link AnalyticsListener AnalyticsListeners}.
|
||||||
* listening to all available ExoPlayer listeners.
|
|
||||||
*/
|
*/
|
||||||
public class AnalyticsCollector
|
public class AnalyticsCollector
|
||||||
implements Player.EventListener,
|
implements Player.EventListener,
|
||||||
MetadataOutput,
|
|
||||||
AudioRendererEventListener,
|
AudioRendererEventListener,
|
||||||
VideoRendererEventListener,
|
VideoRendererEventListener,
|
||||||
MediaSourceEventListener,
|
MediaSourceEventListener,
|
||||||
BandwidthMeter.EventListener,
|
BandwidthMeter.EventListener,
|
||||||
DrmSessionEventListener,
|
DrmSessionEventListener {
|
||||||
VideoListener,
|
|
||||||
AudioListener {
|
|
||||||
|
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final Period period;
|
private final Period period;
|
||||||
|
|
@ -196,9 +189,13 @@ public class AnalyticsCollector
|
||||||
// TODO: remove method.
|
// 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) {
|
public final void onMetadata(Metadata metadata) {
|
||||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||||
sendEvent(
|
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
|
@Override
|
||||||
public final void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
|
public final void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
|
||||||
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
||||||
|
|
@ -332,12 +300,53 @@ public class AnalyticsCollector
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
||||||
sendEvent(
|
sendEvent(
|
||||||
eventTime,
|
eventTime,
|
||||||
AnalyticsListener.EVENT_VOLUME_CHANGED,
|
AnalyticsListener.EVENT_VOLUME_CHANGED,
|
||||||
listener -> listener.onVolumeChanged(eventTime, audioVolume));
|
listener -> listener.onVolumeChanged(eventTime, volume));
|
||||||
}
|
}
|
||||||
|
|
||||||
// VideoRendererEventListener implementation.
|
// 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
|
@Override
|
||||||
public final void onRenderedFirstFrame(@Nullable Surface surface) {
|
public final void onRenderedFirstFrame(@Nullable Surface surface) {
|
||||||
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
||||||
|
|
@ -434,26 +455,17 @@ public class AnalyticsCollector
|
||||||
listener.onVideoFrameProcessingOffset(eventTime, totalProcessingOffsetUs, frameCount));
|
listener.onVideoFrameProcessingOffset(eventTime, totalProcessingOffsetUs, frameCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
// VideoListener implementation.
|
// Additional video events.
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public final void onRenderedFirstFrame() {
|
* Called each time there's a change in the size of the surface onto which the video is being
|
||||||
// Do nothing. Already reported in VideoRendererEventListener.onRenderedFirstFrame.
|
* rendered.
|
||||||
}
|
*
|
||||||
|
* @param width The surface width in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if the
|
||||||
@Override
|
* video is not rendered onto a surface.
|
||||||
public final void onVideoSizeChanged(
|
* @param height The surface height in pixels. May be {@link C#LENGTH_UNSET} if unknown, or 0 if
|
||||||
int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
|
* the video is not rendered onto a surface.
|
||||||
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
*/
|
||||||
sendEvent(
|
|
||||||
eventTime,
|
|
||||||
AnalyticsListener.EVENT_VIDEO_SIZE_CHANGED,
|
|
||||||
listener ->
|
|
||||||
listener.onVideoSizeChanged(
|
|
||||||
eventTime, width, height, unappliedRotationDegrees, pixelWidthHeightRatio));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurfaceSizeChanged(int width, int height) {
|
public void onSurfaceSizeChanged(int width, int height) {
|
||||||
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
||||||
sendEvent(
|
sendEvent(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue