diff --git a/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/MediaExtractorCompatTest.java b/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/MediaExtractorCompatTest.java index 1493e666f4..5812db4381 100644 --- a/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/MediaExtractorCompatTest.java +++ b/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/MediaExtractorCompatTest.java @@ -31,6 +31,7 @@ import android.media.metrics.LogSessionId; import android.media.metrics.MediaMetricsManager; import android.media.metrics.PlaybackSession; import android.net.Uri; +import android.os.PersistableBundle; import androidx.media3.common.C; import androidx.media3.common.DrmInitData; import androidx.media3.common.Format; @@ -49,6 +50,7 @@ import androidx.media3.extractor.SeekMap; import androidx.media3.extractor.SeekMap.SeekPoints; import androidx.media3.extractor.SeekPoint; import androidx.media3.extractor.TrackOutput; +import androidx.media3.extractor.mp4.Mp4Extractor; import androidx.media3.test.utils.TestUtil; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -1002,6 +1004,27 @@ public class MediaExtractorCompatTest { assertThat(mediaExtractorCompat.hasCacheReachedEndOfStream()).isTrue(); } + @Test + public void getMetrics_withMp4DataSource_returnsExpectedMetricsBundle() throws IOException { + assumeTrue(Util.SDK_INT >= 26); + // Needed to keep lint happy (it doesn't understand the assumeTrue call alone) + if (Util.SDK_INT < 26) { + return; + } + Context context = ApplicationProvider.getApplicationContext(); + Uri contentUri = Uri.parse("asset:///media/mp4/sample.mp4"); + MediaExtractorCompat mediaExtractorCompat = new MediaExtractorCompat(context); + mediaExtractorCompat.setDataSource(context, contentUri, /* headers= */ null); + + PersistableBundle bundle = mediaExtractorCompat.getMetrics(); + + assertThat(bundle.getString(MediaExtractor.MetricsConstants.FORMAT)) + .isEqualTo(Mp4Extractor.class.getSimpleName()); + assertThat(bundle.getString(MediaExtractor.MetricsConstants.MIME_TYPE)) + .isEqualTo(MimeTypes.VIDEO_MP4); + assertThat(bundle.getInt(MediaExtractor.MetricsConstants.TRACKS)).isEqualTo(2); + } + // Internal methods. private void assertReadSample(int trackIndex, long timeUs, int size, byte... sampleData) { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaExtractorCompat.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaExtractorCompat.java index 06ceaabdec..a651c39f7e 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaExtractorCompat.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaExtractorCompat.java @@ -30,6 +30,7 @@ import android.media.MediaExtractor; import android.media.MediaFormat; import android.media.metrics.LogSessionId; import android.net.Uri; +import android.os.PersistableBundle; import android.util.SparseArray; import androidx.annotation.IntDef; import androidx.annotation.Nullable; @@ -657,6 +658,30 @@ public final class MediaExtractorCompat { return getCachedDuration() == 0; } + /** + * Returns a {@link PersistableBundle} containing metrics data for the current media container. + * + *

The bundle includes attributes and values for the media container, as described in {@link + * MediaExtractor.MetricsConstants}. + */ + @RequiresApi(26) + public PersistableBundle getMetrics() { + PersistableBundle bundle = new PersistableBundle(); + if (currentExtractor != null) { + bundle.putString( + MediaExtractor.MetricsConstants.FORMAT, + currentExtractor.getUnderlyingImplementation().getClass().getSimpleName()); + } + if (!tracks.isEmpty()) { + Format format = tracks.get(0).getFormat(formatHolder, noDataBuffer); + if (format.containerMimeType != null) { + bundle.putString(MediaExtractor.MetricsConstants.MIME_TYPE, format.containerMimeType); + } + } + bundle.putInt(MediaExtractor.MetricsConstants.TRACKS, tracks.size()); + return bundle; + } + @VisibleForTesting(otherwise = NONE) public Allocator getAllocator() { return allocator;