diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java index 6ef3ce6b07..2ff0c7d2fd 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java @@ -15,6 +15,7 @@ */ package androidx.media3.exoplayer; +import static androidx.media3.common.util.Assertions.checkNotNull; import static java.lang.Math.max; import androidx.annotation.Nullable; @@ -25,10 +26,12 @@ import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; import androidx.media3.decoder.DecoderInputBuffer; import androidx.media3.decoder.DecoderInputBuffer.InsufficientCapacityException; +import androidx.media3.exoplayer.analytics.PlayerId; import androidx.media3.exoplayer.source.SampleStream; import androidx.media3.exoplayer.source.SampleStream.ReadDataResult; import androidx.media3.exoplayer.source.SampleStream.ReadFlags; import java.io.IOException; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** An abstract base class suitable for most {@link Renderer} implementations. */ @UnstableApi @@ -39,6 +42,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { @Nullable private RendererConfiguration configuration; private int index; + private @MonotonicNonNull PlayerId playerId; private int state; @Nullable private SampleStream stream; @Nullable private Format[] streamFormats; @@ -69,8 +73,9 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { } @Override - public final void setIndex(int index) { + public final void init(int index, PlayerId playerId) { this.index = index; + this.playerId = playerId; } @Override @@ -332,11 +337,24 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { return Assertions.checkNotNull(configuration); } - /** Returns the index of the renderer within the player. */ + /** + * Returns the index of the renderer within the player. + * + *
Must only be used after the renderer has been initialized by the player. + */ protected final int getIndex() { return index; } + /** + * Returns the {@link PlayerId} of the player using this renderer. + * + *
Must only be used after the renderer has been initialized by the player. + */ + protected final PlayerId getPlayerId() { + return checkNotNull(playerId); + } + /** * Creates an {@link ExoPlaybackException} of type {@link ExoPlaybackException#TYPE_RENDERER} for * this renderer. diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java index 84599fc4dc..870e5fdfd2 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java @@ -22,6 +22,7 @@ import static java.lang.Math.max; import static java.lang.Math.min; import android.annotation.SuppressLint; +import android.media.metrics.LogSessionId; import android.os.Handler; import android.os.Looper; import android.util.Pair; @@ -30,6 +31,7 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.TextureView; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.media3.common.AudioAttributes; import androidx.media3.common.BasePlayer; import androidx.media3.common.C; @@ -60,6 +62,7 @@ import androidx.media3.common.util.Util; import androidx.media3.exoplayer.ExoPlayer.AudioOffloadListener; import androidx.media3.exoplayer.PlayerMessage.Target; import androidx.media3.exoplayer.analytics.AnalyticsCollector; +import androidx.media3.exoplayer.analytics.PlayerId; import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; import androidx.media3.exoplayer.source.MediaSourceFactory; @@ -259,6 +262,7 @@ import java.util.concurrent.CopyOnWriteArraySet; addListener(analyticsCollector); bandwidthMeter.addEventListener(new Handler(applicationLooper), analyticsCollector); } + PlayerId playerId = Util.SDK_INT < 31 ? new PlayerId() : Api31.createPlayerId(); internalPlayer = new ExoPlayerImplInternal( renderers, @@ -275,7 +279,8 @@ import java.util.concurrent.CopyOnWriteArraySet; pauseAtEndOfMediaItems, applicationLooper, clock, - playbackInfoUpdateListener); + playbackInfoUpdateListener, + playerId); } /** @@ -1869,4 +1874,14 @@ import java.util.concurrent.CopyOnWriteArraySet; return timeline; } } + + @RequiresApi(31) + private static final class Api31 { + private Api31() {} + + public static PlayerId createPlayerId() { + // TODO: Create a MediaMetricsListener and obtain LogSessionId from it. + return new PlayerId(LogSessionId.LOG_SESSION_ID_NONE); + } + } } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java index 82d6367ee3..2a766cb49d 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java @@ -52,6 +52,7 @@ import androidx.media3.common.util.Util; import androidx.media3.datasource.DataSourceException; import androidx.media3.exoplayer.DefaultMediaClock.PlaybackParametersListener; import androidx.media3.exoplayer.analytics.AnalyticsCollector; +import androidx.media3.exoplayer.analytics.PlayerId; import androidx.media3.exoplayer.drm.DrmSession; import androidx.media3.exoplayer.source.BehindLiveWindowException; import androidx.media3.exoplayer.source.MediaPeriod; @@ -237,7 +238,8 @@ import java.util.concurrent.atomic.AtomicBoolean; boolean pauseAtEndOfWindow, Looper applicationLooper, Clock clock, - PlaybackInfoUpdateListener playbackInfoUpdateListener) { + PlaybackInfoUpdateListener playbackInfoUpdateListener, + PlayerId playerId) { this.playbackInfoUpdateListener = playbackInfoUpdateListener; this.renderers = renderers; this.trackSelector = trackSelector; @@ -260,7 +262,7 @@ import java.util.concurrent.atomic.AtomicBoolean; playbackInfoUpdate = new PlaybackInfoUpdate(playbackInfo); rendererCapabilities = new RendererCapabilities[renderers.length]; for (int i = 0; i < renderers.length; i++) { - renderers[i].setIndex(i); + renderers[i].init(/* index= */ i, playerId); rendererCapabilities[i] = renderers[i].getCapabilities(); } mediaClock = new DefaultMediaClock(this, clock); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/NoSampleRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/NoSampleRenderer.java index e360da8d2c..95999b5f75 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/NoSampleRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/NoSampleRenderer.java @@ -20,6 +20,7 @@ import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; +import androidx.media3.exoplayer.analytics.PlayerId; import androidx.media3.exoplayer.source.SampleStream; import java.io.IOException; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @@ -48,7 +49,7 @@ public abstract class NoSampleRenderer implements Renderer, RendererCapabilities } @Override - public final void setIndex(int index) { + public final void init(int index, PlayerId playerId) { this.index = index; } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java index a9ccd593ee..0572c04ea8 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java @@ -27,6 +27,7 @@ import androidx.media3.common.Player; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.PlayerMessage.Target; +import androidx.media3.exoplayer.analytics.PlayerId; import androidx.media3.exoplayer.source.SampleStream; import androidx.media3.exoplayer.video.VideoDecoderOutputBufferRenderer; import androidx.media3.exoplayer.video.VideoFrameMetadataListener; @@ -252,11 +253,12 @@ public interface Renderer extends PlayerMessage.Target { RendererCapabilities getCapabilities(); /** - * Sets the index of this renderer within the player. + * Initializes the renderer for playback with a player. * - * @param index The renderer index. + * @param index The renderer index within the player. + * @param playerId The {@link PlayerId} of the player. */ - void setIndex(int index); + void init(int index, PlayerId playerId); /** * If the renderer advances its own playback position then this method returns a corresponding