Commit cd70a5ce by kimvde Committed by Tianyi Feng

Move setMediaSourceFactory to ExoPlayerAssetLoader

The MediaSourceFactory won't be used by the other AssetLoaders

In order to do that, ExoPlayerAssetLoader has been made public, and the
DefaultAssetLoaderFactory has become a wrapper around
ExoPlayerAssetLoader.

PiperOrigin-RevId: 496386853
parent ce766d76
......@@ -20,7 +20,6 @@ import android.content.Context;
import android.os.Looper;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Clock;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
......@@ -34,10 +33,15 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
*/
public interface AssetLoader {
/** A factory for {@link AssetLoader} instances. */
/**
* A factory for {@link AssetLoader} instances.
*
* <p>The setters in this interface will be called with the values used to build and start the
* {@link Transformer}.
*/
interface Factory {
/** Sets the context. */
/** Sets the {@link Context}. */
@CanIgnoreReturnValue
Factory setContext(Context context);
......@@ -76,10 +80,6 @@ public interface AssetLoader {
@CanIgnoreReturnValue
Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion);
/** Sets the {@link MediaSource.Factory} to be used to retrieve the samples. */
@CanIgnoreReturnValue
Factory setMediaSourceFactory(MediaSource.Factory mediaSourceFactory);
/** Sets the {@link Codec.DecoderFactory} to be used to decode the samples (if necessary). */
@CanIgnoreReturnValue
Factory setDecoderFactory(Codec.DecoderFactory decoderFactory);
......@@ -111,7 +111,7 @@ public interface AssetLoader {
}
/**
* A listener of asset loader events.
* A listener of {@link AssetLoader} events.
*
* <p>This listener is typically used in the following way:
*
......
......@@ -16,112 +16,79 @@
package com.google.android.exoplayer2.transformer;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import android.content.Context;
import android.os.Looper;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Clock;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
/** The default {@link AssetLoader.Factory} implementation. */
public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
@Nullable private Context context;
@Nullable private MediaItem mediaItem;
private boolean removeAudio;
private boolean removeVideo;
private boolean flattenVideoForSlowMotion;
@Nullable private MediaSource.Factory mediaSourceFactory;
@Nullable private Codec.DecoderFactory decoderFactory;
@Nullable private Looper looper;
@Nullable private AssetLoader.Listener listener;
@Nullable private Clock clock;
private final AssetLoader.Factory assetLoaderFactory;
/** Creates an instance. */
public DefaultAssetLoaderFactory() {
assetLoaderFactory = new ExoPlayerAssetLoader.Factory();
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setContext(Context context) {
this.context = context;
return this;
return assetLoaderFactory.setContext(context);
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setMediaItem(MediaItem mediaItem) {
this.mediaItem = mediaItem;
return this;
return assetLoaderFactory.setMediaItem(mediaItem);
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setRemoveAudio(boolean removeAudio) {
this.removeAudio = removeAudio;
return this;
return assetLoaderFactory.setRemoveAudio(removeAudio);
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setRemoveVideo(boolean removeVideo) {
this.removeVideo = removeVideo;
return this;
return assetLoaderFactory.setRemoveVideo(removeVideo);
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion) {
this.flattenVideoForSlowMotion = flattenVideoForSlowMotion;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
this.mediaSourceFactory = mediaSourceFactory;
assetLoaderFactory.setFlattenVideoForSlowMotion(flattenVideoForSlowMotion);
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setDecoderFactory(Codec.DecoderFactory decoderFactory) {
this.decoderFactory = decoderFactory;
return this;
return assetLoaderFactory.setDecoderFactory(decoderFactory);
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setLooper(Looper looper) {
this.looper = looper;
return this;
return assetLoaderFactory.setLooper(looper);
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setListener(AssetLoader.Listener listener) {
this.listener = listener;
return this;
return assetLoaderFactory.setListener(listener);
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setClock(Clock clock) {
this.clock = clock;
return this;
return assetLoaderFactory.setClock(clock);
}
@Override
public AssetLoader createAssetLoader() {
return new ExoPlayerAssetLoader(
checkStateNotNull(context),
checkStateNotNull(mediaItem),
removeAudio,
removeVideo,
flattenVideoForSlowMotion,
checkStateNotNull(mediaSourceFactory),
checkStateNotNull(decoderFactory),
checkStateNotNull(looper),
checkStateNotNull(listener),
checkStateNotNull(clock));
return assetLoaderFactory.createAssetLoader();
}
}
......@@ -24,11 +24,13 @@ import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STA
import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_NO_TRANSFORMATION;
import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_UNAVAILABLE;
import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_WAITING_FOR_AVAILABILITY;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static java.lang.Math.min;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlayer;
......@@ -40,21 +42,146 @@ import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
import com.google.android.exoplayer2.metadata.MetadataOutput;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
/* package */ final class ExoPlayerAssetLoader implements AssetLoader {
/** An {@link AssetLoader} implementation that uses an {@link ExoPlayer} to load samples. */
public final class ExoPlayerAssetLoader implements AssetLoader {
/** An {@link AssetLoader.Factory} for {@link ExoPlayerAssetLoader} instances. */
public static final class Factory implements AssetLoader.Factory {
@Nullable private Context context;
@Nullable private MediaItem mediaItem;
private boolean removeAudio;
private boolean removeVideo;
private boolean flattenVideoForSlowMotion;
@Nullable private MediaSource.Factory mediaSourceFactory;
@Nullable private Codec.DecoderFactory decoderFactory;
@Nullable private Looper looper;
@Nullable private AssetLoader.Listener listener;
@Nullable private Clock clock;
/**
* Creates an instance.
*
* <p>The {@link ExoPlayerAssetLoader} instances produced use a {@link
* DefaultMediaSourceFactory} built with the context provided in {@linkplain
* #setContext(Context)}.
*/
public Factory() {}
/**
* Creates an instance.
*
* @param mediaSourceFactory The {@link MediaSource.Factory} to be used to retrieve the samples
* to transform.
*/
public Factory(MediaSource.Factory mediaSourceFactory) {
this.mediaSourceFactory = mediaSourceFactory;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setContext(Context context) {
this.context = context;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setMediaItem(MediaItem mediaItem) {
this.mediaItem = mediaItem;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setRemoveAudio(boolean removeAudio) {
this.removeAudio = removeAudio;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setRemoveVideo(boolean removeVideo) {
this.removeVideo = removeVideo;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion) {
this.flattenVideoForSlowMotion = flattenVideoForSlowMotion;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setDecoderFactory(Codec.DecoderFactory decoderFactory) {
this.decoderFactory = decoderFactory;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setLooper(Looper looper) {
this.looper = looper;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setListener(AssetLoader.Listener listener) {
this.listener = listener;
return this;
}
@Override
@CanIgnoreReturnValue
public AssetLoader.Factory setClock(Clock clock) {
this.clock = clock;
return this;
}
@Override
public AssetLoader createAssetLoader() {
Context context = checkStateNotNull(this.context);
if (mediaSourceFactory == null) {
DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
if (flattenVideoForSlowMotion) {
defaultExtractorsFactory.setMp4ExtractorFlags(Mp4Extractor.FLAG_READ_SEF_DATA);
}
mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory);
}
return new ExoPlayerAssetLoader(
context,
checkStateNotNull(mediaItem),
removeAudio,
removeVideo,
flattenVideoForSlowMotion,
mediaSourceFactory,
checkStateNotNull(decoderFactory),
checkStateNotNull(looper),
checkStateNotNull(listener),
checkStateNotNull(clock));
}
}
private final MediaItem mediaItem;
private final ExoPlayer player;
private @Transformer.ProgressState int progressState;
public ExoPlayerAssetLoader(
private ExoPlayerAssetLoader(
Context context,
MediaItem mediaItem,
boolean removeAudio,
......
......@@ -140,10 +140,10 @@ public final class TransformationRequest {
* <li>The recording frame rate of the video is 120 or 240 fps.
* </ul>
*
* <p>If specifying a {@link MediaSource.Factory} using {@link
* Transformer.Builder#setMediaSourceFactory(MediaSource.Factory)}, make sure that {@link
* Mp4Extractor#FLAG_READ_SEF_DATA} is set on the {@link Mp4Extractor} used. Otherwise, the slow
* motion metadata will be ignored and the input won't be flattened.
* <p>If using an {@link ExoPlayerAssetLoader.Factory} with a provided {@link
* MediaSource.Factory}, make sure that {@link Mp4Extractor#FLAG_READ_SEF_DATA} is set on the
* {@link Mp4Extractor} used. Otherwise, the slow motion metadata will be ignored and the input
* won't be flattened.
*
* <p>Using slow motion flattening together with {@link
* com.google.android.exoplayer2.MediaItem.ClippingConfiguration} is not supported yet.
......
......@@ -34,9 +34,6 @@ import com.google.android.exoplayer2.audio.SonicAudioProcessor;
import com.google.android.exoplayer2.effect.GlEffect;
import com.google.android.exoplayer2.effect.GlEffectsFrameProcessor;
import com.google.android.exoplayer2.effect.GlMatrixTransformation;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.DebugViewProvider;
......@@ -53,7 +50,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/**
* A transformer to transform media inputs.
......@@ -89,7 +85,6 @@ public final class Transformer {
private boolean removeVideo;
private boolean forceSilentAudio;
private ListenerSet<Transformer.Listener> listeners;
private MediaSource.@MonotonicNonNull Factory mediaSourceFactory;
private AssetLoader.Factory assetLoaderFactory;
private Codec.DecoderFactory decoderFactory;
private Codec.EncoderFactory encoderFactory;
......@@ -130,7 +125,6 @@ public final class Transformer {
this.removeVideo = transformer.removeVideo;
this.forceSilentAudio = transformer.forceSilentAudio;
this.listeners = transformer.listeners;
this.mediaSourceFactory = transformer.mediaSourceFactory;
this.assetLoaderFactory = transformer.assetLoaderFactory;
this.decoderFactory = transformer.decoderFactory;
this.encoderFactory = transformer.encoderFactory;
......@@ -293,21 +287,6 @@ public final class Transformer {
}
/**
* Sets the {@link MediaSource.Factory} to be used to retrieve the inputs to transform.
*
* <p>The default value is a {@link DefaultMediaSourceFactory} built with the context provided
* in {@linkplain #Builder(Context) the constructor}.
*
* @param mediaSourceFactory A {@link MediaSource.Factory}.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
this.mediaSourceFactory = mediaSourceFactory;
return this;
}
/**
* Sets the {@link AssetLoader.Factory} to be used to retrieve the samples to transform.
*
* <p>The default value is a {@link DefaultAssetLoaderFactory}.
......@@ -476,13 +455,6 @@ public final class Transformer {
if (transformationRequest.videoMimeType != null) {
checkSampleMimeType(transformationRequest.videoMimeType);
}
if (mediaSourceFactory == null) {
DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
if (transformationRequest.flattenForSlowMotion) {
defaultExtractorsFactory.setMp4ExtractorFlags(Mp4Extractor.FLAG_READ_SEF_DATA);
}
mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory);
}
return new Transformer(
context,
transformationRequest,
......@@ -492,7 +464,6 @@ public final class Transformer {
removeVideo,
forceSilentAudio,
listeners,
mediaSourceFactory,
assetLoaderFactory,
decoderFactory,
encoderFactory,
......@@ -618,7 +589,6 @@ public final class Transformer {
private final boolean removeVideo;
private final boolean forceSilentAudio;
private final ListenerSet<Transformer.Listener> listeners;
private final MediaSource.Factory mediaSourceFactory;
private final AssetLoader.Factory assetLoaderFactory;
private final FrameProcessor.Factory frameProcessorFactory;
private final Muxer.Factory muxerFactory;
......@@ -637,7 +607,6 @@ public final class Transformer {
boolean removeVideo,
boolean forceSilentAudio,
ListenerSet<Listener> listeners,
MediaSource.Factory mediaSourceFactory,
AssetLoader.Factory assetLoaderFactory,
Codec.DecoderFactory decoderFactory,
Codec.EncoderFactory encoderFactory,
......@@ -659,7 +628,6 @@ public final class Transformer {
this.removeVideo = removeVideo;
this.forceSilentAudio = forceSilentAudio;
this.listeners = listeners;
this.mediaSourceFactory = mediaSourceFactory;
this.assetLoaderFactory = assetLoaderFactory;
this.decoderFactory = decoderFactory;
this.encoderFactory = encoderFactory;
......@@ -802,7 +770,6 @@ public final class Transformer {
removeAudio,
removeVideo,
forceSilentAudio,
mediaSourceFactory,
assetLoaderFactory,
decoderFactory,
encoderFactory,
......
......@@ -35,7 +35,6 @@ import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.mp4.SlowMotionData;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.ConditionVariable;
import com.google.android.exoplayer2.util.DebugViewProvider;
......@@ -126,7 +125,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
boolean removeAudio,
boolean removeVideo,
boolean forceSilentAudio,
MediaSource.Factory mediaSourceFactory,
AssetLoader.Factory assetLoaderFactory,
Codec.DecoderFactory decoderFactory,
Codec.EncoderFactory encoderFactory,
......@@ -158,7 +156,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
.setRemoveAudio(removeAudio)
.setRemoveVideo(removeVideo)
.setFlattenVideoForSlowMotion(transformationRequest.flattenForSlowMotion)
.setMediaSourceFactory(mediaSourceFactory)
.setDecoderFactory(this.decoderFactory)
.setLooper(internalLooper)
.setListener(componentListener)
......
......@@ -533,10 +533,11 @@ public final class TransformerEndToEndTest {
MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(
context, new SlowExtractorsFactory(/* delayBetweenReadsMs= */ 10));
AssetLoader.Factory assetLoaderFactory = new ExoPlayerAssetLoader.Factory(mediaSourceFactory);
Muxer.Factory muxerFactory = new TestMuxerFactory(/* maxDelayBetweenSamplesMs= */ 1);
Transformer transformer =
createTransformerBuilder(/* enableFallback= */ false)
.setMediaSourceFactory(mediaSourceFactory)
.setAssetLoaderFactory(assetLoaderFactory)
.setMuxerFactory(muxerFactory)
.build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment