mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add getDrmInitData()
API to MediaExtractorCompat
Note: `androidx.media3.common.DrmInitData` is returned instead of the platform `android.media.DrmInitData` because the platform class has a package-private constructor, making it impossible to implement the abstract class outside the platform. PiperOrigin-RevId: 694096542
This commit is contained in:
parent
19d71266ec
commit
91dfaab93f
@ -15,6 +15,11 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer;
|
||||
|
||||
import static androidx.media3.common.C.PLAYREADY_UUID;
|
||||
import static androidx.media3.common.C.WIDEVINE_UUID;
|
||||
import static androidx.media3.common.MimeTypes.AUDIO_AAC;
|
||||
import static androidx.media3.common.MimeTypes.VIDEO_H264;
|
||||
import static androidx.media3.test.utils.TestUtil.buildTestData;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
@ -27,6 +32,7 @@ import android.media.metrics.MediaMetricsManager;
|
||||
import android.media.metrics.PlaybackSession;
|
||||
import android.net.Uri;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.DrmInitData;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.ParserException;
|
||||
@ -719,6 +725,74 @@ public class MediaExtractorCompatTest {
|
||||
assertThat(mediaExtractorCompat.getLogSessionId()).isEqualTo(logSessionId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDrmInitData_withNoTracksHavingDrmInitData_returnsNull() throws IOException {
|
||||
TrackOutput[] outputs = new TrackOutput[1];
|
||||
fakeExtractor.addReadAction(
|
||||
(input, seekPosition) -> {
|
||||
outputs[0] = extractorOutput.track(/* id= */ 0, C.TRACK_TYPE_VIDEO);
|
||||
outputs[0].format(PLACEHOLDER_FORMAT_VIDEO);
|
||||
extractorOutput.endTracks();
|
||||
return Extractor.RESULT_CONTINUE;
|
||||
});
|
||||
|
||||
mediaExtractorCompat.setDataSource(PLACEHOLDER_URI, /* offset= */ 0);
|
||||
|
||||
assertThat(mediaExtractorCompat.getDrmInitData()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDrmInitData_withSingleTrackHavingDrmInitData_returnsDrmInitData()
|
||||
throws IOException {
|
||||
TrackOutput[] outputs = new TrackOutput[1];
|
||||
DrmInitData.SchemeData schemeData =
|
||||
new DrmInitData.SchemeData(
|
||||
WIDEVINE_UUID, VIDEO_H264, buildTestData(128, 1 /* data seed */));
|
||||
DrmInitData drmInitData = new DrmInitData(schemeData);
|
||||
fakeExtractor.addReadAction(
|
||||
(input, seekPosition) -> {
|
||||
outputs[0] = extractorOutput.track(/* id= */ 0, C.TRACK_TYPE_VIDEO);
|
||||
outputs[0].format(
|
||||
PLACEHOLDER_FORMAT_VIDEO.buildUpon().setDrmInitData(drmInitData).build());
|
||||
extractorOutput.endTracks();
|
||||
return Extractor.RESULT_CONTINUE;
|
||||
});
|
||||
|
||||
mediaExtractorCompat.setDataSource(PLACEHOLDER_URI, /* offset= */ 0);
|
||||
|
||||
assertThat(mediaExtractorCompat.getDrmInitData()).isEqualTo(drmInitData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDrmInitData_withMultipleTracksHavingDrmInitData_returnsFirstNonNullDrmInitData()
|
||||
throws IOException {
|
||||
TrackOutput[] outputs = new TrackOutput[3];
|
||||
DrmInitData.SchemeData firstSchemeData =
|
||||
new DrmInitData.SchemeData(WIDEVINE_UUID, AUDIO_AAC, buildTestData(128, 1 /* data seed */));
|
||||
DrmInitData firstDrmInitData = new DrmInitData(firstSchemeData);
|
||||
DrmInitData.SchemeData secondSchemeData =
|
||||
new DrmInitData.SchemeData(
|
||||
PLAYREADY_UUID, AUDIO_AAC, buildTestData(128, 2 /* data seed */));
|
||||
DrmInitData secondDrmInitData = new DrmInitData(secondSchemeData);
|
||||
fakeExtractor.addReadAction(
|
||||
(input, seekPosition) -> {
|
||||
outputs[0] = extractorOutput.track(/* id= */ 0, C.TRACK_TYPE_VIDEO);
|
||||
outputs[0].format(PLACEHOLDER_FORMAT_VIDEO);
|
||||
outputs[1] = extractorOutput.track(/* id= */ 1, C.TRACK_TYPE_AUDIO);
|
||||
outputs[1].format(
|
||||
PLACEHOLDER_FORMAT_AUDIO.buildUpon().setDrmInitData(firstDrmInitData).build());
|
||||
outputs[2] = extractorOutput.track(/* id= */ 2, C.TRACK_TYPE_AUDIO);
|
||||
outputs[2].format(
|
||||
PLACEHOLDER_FORMAT_AUDIO.buildUpon().setDrmInitData(secondDrmInitData).build());
|
||||
extractorOutput.endTracks();
|
||||
return Extractor.RESULT_CONTINUE;
|
||||
});
|
||||
|
||||
mediaExtractorCompat.setDataSource(PLACEHOLDER_URI, /* offset= */ 0);
|
||||
|
||||
assertThat(mediaExtractorCompat.getDrmInitData()).isEqualTo(firstDrmInitData);
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private void assertReadSample(int trackIndex, long timeUs, int size, byte... sampleData) {
|
||||
|
@ -35,6 +35,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.DrmInitData;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.ParserException;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
@ -588,6 +589,24 @@ public final class MediaExtractorCompat {
|
||||
return logSessionId != null ? logSessionId : LogSessionId.LOG_SESSION_ID_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the DRM initialization data from the available tracks, if it exists.
|
||||
*
|
||||
* @return The {@link DrmInitData} in the content, or {@code null} if no recognizable DRM format
|
||||
* is found.
|
||||
*/
|
||||
@Nullable
|
||||
public DrmInitData getDrmInitData() {
|
||||
for (int i = 0; i < tracks.size(); i++) {
|
||||
Format format = tracks.get(i).getFormat(formatHolder, noDataBuffer);
|
||||
if (format.drmInitData == null) {
|
||||
continue;
|
||||
}
|
||||
return format.drmInitData;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = NONE)
|
||||
public Allocator getAllocator() {
|
||||
return allocator;
|
||||
@ -832,15 +851,8 @@ public final class MediaExtractorCompat {
|
||||
|
||||
public MediaFormat createDownstreamMediaFormat(
|
||||
FormatHolder scratchFormatHolder, DecoderInputBuffer scratchNoDataDecoderInputBuffer) {
|
||||
scratchFormatHolder.clear();
|
||||
sampleQueue.read(
|
||||
scratchFormatHolder,
|
||||
scratchNoDataDecoderInputBuffer,
|
||||
FLAG_REQUIRE_FORMAT,
|
||||
/* loadingFinished= */ false);
|
||||
Format result = checkNotNull(scratchFormatHolder.format);
|
||||
MediaFormat mediaFormatResult = MediaFormatUtil.createMediaFormatFromFormat(result);
|
||||
scratchFormatHolder.clear();
|
||||
Format format = getFormat(scratchFormatHolder, scratchNoDataDecoderInputBuffer);
|
||||
MediaFormat mediaFormatResult = MediaFormatUtil.createMediaFormatFromFormat(format);
|
||||
if (compatibilityTrackMimeType != null) {
|
||||
if (Util.SDK_INT >= 29) {
|
||||
mediaFormatResult.removeKey(MediaFormat.KEY_CODECS_STRING);
|
||||
@ -850,6 +862,19 @@ public final class MediaExtractorCompat {
|
||||
return mediaFormatResult;
|
||||
}
|
||||
|
||||
private Format getFormat(
|
||||
FormatHolder scratchFormatHolder, DecoderInputBuffer scratchNoDataDecoderInputBuffer) {
|
||||
scratchFormatHolder.clear();
|
||||
sampleQueue.read(
|
||||
scratchFormatHolder,
|
||||
scratchNoDataDecoderInputBuffer,
|
||||
FLAG_REQUIRE_FORMAT,
|
||||
/* loadingFinished= */ false);
|
||||
Format format = checkNotNull(scratchFormatHolder.format);
|
||||
scratchFormatHolder.clear();
|
||||
return format;
|
||||
}
|
||||
|
||||
public void discardFrontSample() {
|
||||
sampleQueue.skip(/* count= */ 1);
|
||||
sampleQueue.discardToRead();
|
||||
|
Loading…
x
Reference in New Issue
Block a user