Make MediaParser available for use in progressive media

PiperOrigin-RevId: 358379167
This commit is contained in:
aquilescanta 2021-02-19 12:29:27 +00:00 committed by bachinger
parent 36cbcb30b6
commit ecb109dad8
5 changed files with 55 additions and 20 deletions

View File

@ -336,7 +336,7 @@ public final class ExtractorMediaSource extends CompositeMediaSource<Void> {
.setTag(tag)
.build(),
dataSourceFactory,
extractorsFactory,
() -> new BundledExtractorsAdapter(extractorsFactory),
DrmSessionManager.DRM_UNSUPPORTED,
loadableLoadErrorHandlingPolicy,
continueLoadingCheckIntervalBytes);

View File

@ -26,7 +26,14 @@ import java.util.List;
import java.util.Map;
/** Extracts the contents of a container file from a progressive media stream. */
/* package */ interface ProgressiveMediaExtractor {
public interface ProgressiveMediaExtractor {
/** Creates {@link ProgressiveMediaExtractor} instances. */
interface Factory {
/** Returns a new {@link ProgressiveMediaExtractor} instance. */
ProgressiveMediaExtractor createProgressiveMediaExtractor();
}
/**
* Initializes the underlying infrastructure for reading from the input.

View File

@ -31,7 +31,6 @@ import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.extractor.SeekMap.SeekPoints;
@ -147,7 +146,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/**
* @param uri The {@link Uri} of the media stream.
* @param dataSource The data source to read the media.
* @param extractorsFactory The {@link ExtractorsFactory} to use to read the data source.
* @param progressiveMediaExtractor The {@link ProgressiveMediaExtractor} to use to read the data
* source.
* @param drmSessionManager A {@link DrmSessionManager} to allow DRM interactions.
* @param drmEventDispatcher A dispatcher to notify of {@link DrmSessionEventListener} events.
* @param loadErrorHandlingPolicy The {@link LoadErrorHandlingPolicy}.
@ -168,7 +168,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public ProgressiveMediaPeriod(
Uri uri,
DataSource dataSource,
ExtractorsFactory extractorsFactory,
ProgressiveMediaExtractor progressiveMediaExtractor,
DrmSessionManager drmSessionManager,
DrmSessionEventListener.EventDispatcher drmEventDispatcher,
LoadErrorHandlingPolicy loadErrorHandlingPolicy,
@ -188,7 +188,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
this.customCacheKey = customCacheKey;
this.continueLoadingCheckIntervalBytes = continueLoadingCheckIntervalBytes;
loader = new Loader("ProgressiveMediaPeriod");
this.progressiveMediaExtractor = new BundledExtractorsAdapter(extractorsFactory);
this.progressiveMediaExtractor = progressiveMediaExtractor;
loadCondition = new ConditionVariable();
maybeFinishPrepareRunnable = this::maybeFinishPrepare;
onContinueLoadingRequestedRunnable =

View File

@ -54,7 +54,7 @@ public final class ProgressiveMediaSource extends BaseMediaSource
private final DataSource.Factory dataSourceFactory;
private ExtractorsFactory extractorsFactory;
private ProgressiveMediaExtractor.Factory progressiveMediaExtractorFactory;
private boolean usingCustomDrmSessionManagerProvider;
private DrmSessionManagerProvider drmSessionManagerProvider;
private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
@ -72,15 +72,26 @@ public final class ProgressiveMediaSource extends BaseMediaSource
this(dataSourceFactory, new DefaultExtractorsFactory());
}
/**
* Equivalent to {@link #Factory(DataSource.Factory, ProgressiveMediaExtractor.Factory) new
* Factory(dataSourceFactory, () -> new BundledExtractorsAdapter(extractorsFactory)}.
*/
public Factory(DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) {
this(dataSourceFactory, () -> new BundledExtractorsAdapter(extractorsFactory));
}
/**
* Creates a new factory for {@link ProgressiveMediaSource}s.
*
* @param dataSourceFactory A factory for {@link DataSource}s to read the media.
* @param extractorsFactory A factory for extractors used to extract media from its container.
* @param progressiveMediaExtractorFactory A factory for the {@link ProgressiveMediaExtractor}
* to extract media from its container.
*/
public Factory(DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) {
public Factory(
DataSource.Factory dataSourceFactory,
ProgressiveMediaExtractor.Factory progressiveMediaExtractorFactory) {
this.dataSourceFactory = dataSourceFactory;
this.extractorsFactory = extractorsFactory;
this.progressiveMediaExtractorFactory = progressiveMediaExtractorFactory;
drmSessionManagerProvider = new DefaultDrmSessionManagerProvider();
loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
continueLoadingCheckIntervalBytes = DEFAULT_LOADING_CHECK_INTERVAL_BYTES;
@ -93,8 +104,10 @@ public final class ProgressiveMediaSource extends BaseMediaSource
*/
@Deprecated
public Factory setExtractorsFactory(@Nullable ExtractorsFactory extractorsFactory) {
this.extractorsFactory =
extractorsFactory != null ? extractorsFactory : new DefaultExtractorsFactory();
this.progressiveMediaExtractorFactory =
() ->
new BundledExtractorsAdapter(
extractorsFactory != null ? extractorsFactory : new DefaultExtractorsFactory());
return this;
}
@ -220,7 +233,7 @@ public final class ProgressiveMediaSource extends BaseMediaSource
return new ProgressiveMediaSource(
mediaItem,
dataSourceFactory,
extractorsFactory,
progressiveMediaExtractorFactory,
drmSessionManagerProvider.get(mediaItem),
loadErrorHandlingPolicy,
continueLoadingCheckIntervalBytes);
@ -241,7 +254,7 @@ public final class ProgressiveMediaSource extends BaseMediaSource
private final MediaItem mediaItem;
private final MediaItem.PlaybackProperties playbackProperties;
private final DataSource.Factory dataSourceFactory;
private final ExtractorsFactory extractorsFactory;
private final ProgressiveMediaExtractor.Factory progressiveMediaExtractorFactory;
private final DrmSessionManager drmSessionManager;
private final LoadErrorHandlingPolicy loadableLoadErrorHandlingPolicy;
private final int continueLoadingCheckIntervalBytes;
@ -256,14 +269,14 @@ public final class ProgressiveMediaSource extends BaseMediaSource
/* package */ ProgressiveMediaSource(
MediaItem mediaItem,
DataSource.Factory dataSourceFactory,
ExtractorsFactory extractorsFactory,
ProgressiveMediaExtractor.Factory progressiveMediaExtractorFactory,
DrmSessionManager drmSessionManager,
LoadErrorHandlingPolicy loadableLoadErrorHandlingPolicy,
int continueLoadingCheckIntervalBytes) {
this.playbackProperties = checkNotNull(mediaItem.playbackProperties);
this.mediaItem = mediaItem;
this.dataSourceFactory = dataSourceFactory;
this.extractorsFactory = extractorsFactory;
this.progressiveMediaExtractorFactory = progressiveMediaExtractorFactory;
this.drmSessionManager = drmSessionManager;
this.loadableLoadErrorHandlingPolicy = loadableLoadErrorHandlingPolicy;
this.continueLoadingCheckIntervalBytes = continueLoadingCheckIntervalBytes;
@ -308,7 +321,7 @@ public final class ProgressiveMediaSource extends BaseMediaSource
return new ProgressiveMediaPeriod(
playbackProperties.uri,
dataSource,
extractorsFactory,
progressiveMediaExtractorFactory.createProgressiveMediaExtractor(),
drmSessionManager,
createDrmEventDispatcher(id),
loadableLoadErrorHandlingPolicy,

View File

@ -24,22 +24,37 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.upstream.AssetDataSource;
import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
/** Unit test for {@link ProgressiveMediaPeriod}. */
@RunWith(AndroidJUnit4.class)
public final class ProgressiveMediaPeriodTest {
@Test
public void prepare_updatesSourceInfoBeforeOnPreparedCallback() throws Exception {
public void prepareUsingBundledExtractors_updatesSourceInfoBeforeOnPreparedCallback()
throws TimeoutException {
testExtractorsUpdatesSourceInfoBeforeOnPreparedCallback(
new BundledExtractorsAdapter(Mp4Extractor.FACTORY));
}
@Test
@Config(sdk = 30)
public void prepareUsingMediaParser_updatesSourceInfoBeforeOnPreparedCallback()
throws TimeoutException {
testExtractorsUpdatesSourceInfoBeforeOnPreparedCallback(new MediaParserExtractorAdapter());
}
private static void testExtractorsUpdatesSourceInfoBeforeOnPreparedCallback(
ProgressiveMediaExtractor extractor) throws TimeoutException {
AtomicBoolean sourceInfoRefreshCalled = new AtomicBoolean(false);
ProgressiveMediaPeriod.Listener sourceInfoRefreshListener =
(durationUs, isSeekable, isLive) -> sourceInfoRefreshCalled.set(true);
@ -48,7 +63,7 @@ public final class ProgressiveMediaPeriodTest {
new ProgressiveMediaPeriod(
Uri.parse("asset://android_asset/media/mp4/sample.mp4"),
new AssetDataSource(ApplicationProvider.getApplicationContext()),
() -> new Extractor[] {new Mp4Extractor()},
extractor,
DrmSessionManager.DRM_UNSUPPORTED,
new DrmSessionEventListener.EventDispatcher()
.withParameters(/* windowIndex= */ 0, mediaPeriodId),