Commit 339ce4fc by kimvde Committed by Ian Baker

Add AssetLoader.Factory

This is so that apps can customise AssetLoader

PiperOrigin-RevId: 494998497
parent c17c23d1
...@@ -16,7 +16,13 @@ ...@@ -16,7 +16,13 @@
package com.google.android.exoplayer2.transformer; package com.google.android.exoplayer2.transformer;
import android.content.Context;
import android.os.Looper;
import com.google.android.exoplayer2.Format; 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;
/** /**
* Provides media data to a {@linkplain Transformer}. * Provides media data to a {@linkplain Transformer}.
...@@ -28,6 +34,82 @@ import com.google.android.exoplayer2.Format; ...@@ -28,6 +34,82 @@ import com.google.android.exoplayer2.Format;
*/ */
public interface AssetLoader { public interface AssetLoader {
/** A factory for {@link AssetLoader} instances. */
interface Factory {
/** Sets the context. */
@CanIgnoreReturnValue
Factory setContext(Context context);
/** Sets the {@link MediaItem} to load. */
@CanIgnoreReturnValue
Factory setMediaItem(MediaItem mediaItem);
/**
* Sets whether to remove the audio samples from the output (if any).
*
* <p>The audio and video cannot both be removed because the output would not contain any
* samples.
*/
@CanIgnoreReturnValue
Factory setRemoveAudio(boolean removeAudio);
/**
* Sets whether to remove the video samples from the output (if any).
*
* <p>The audio and video cannot both be removed because the output would not contain any
* samples.
*/
@CanIgnoreReturnValue
Factory setRemoveVideo(boolean removeVideo);
/**
* Sets whether the video samples should be flattened prior to decoding for media containing
* slow motion markers.
*
* <p>The audio samples are flattened after they are output by the {@link AssetLoader}, because
* this is done on decoded samples.
*
* <p>For more information on slow motion flattening, see {@link
* TransformationRequest.Builder#setFlattenForSlowMotion(boolean)}.
*/
@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);
/**
* Sets the {@link Looper} that's used to access the {@link AssetLoader} after it's been
* created.
*/
@CanIgnoreReturnValue
Factory setLooper(Looper looper);
/** Sets the {@link Listener} on which the {@link AssetLoader} should notify of events. */
@CanIgnoreReturnValue
Factory setListener(AssetLoader.Listener listener);
/**
* The {@link Clock} to use.
*
* <p>Should always be {@link Clock#DEFAULT} except for testing.
*/
@CanIgnoreReturnValue
Factory setClock(Clock clock);
/**
* Creates an {@link AssetLoader} instance. All the setters in this factory must be called
* before creating the {@link AssetLoader}.
*/
AssetLoader createAssetLoader();
}
/** /**
* A listener of asset loader events. * A listener of asset loader events.
* *
......
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
@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 setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
this.mediaSourceFactory = mediaSourceFactory;
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() {
return new ExoPlayerAssetLoader(
checkStateNotNull(context),
checkStateNotNull(mediaItem),
removeAudio,
removeVideo,
flattenVideoForSlowMotion,
checkStateNotNull(mediaSourceFactory),
checkStateNotNull(decoderFactory),
checkStateNotNull(looper),
checkStateNotNull(listener),
checkStateNotNull(clock));
}
}
...@@ -90,6 +90,7 @@ public final class Transformer { ...@@ -90,6 +90,7 @@ public final class Transformer {
private boolean forceSilentAudio; private boolean forceSilentAudio;
private ListenerSet<Transformer.Listener> listeners; private ListenerSet<Transformer.Listener> listeners;
private MediaSource.@MonotonicNonNull Factory mediaSourceFactory; private MediaSource.@MonotonicNonNull Factory mediaSourceFactory;
private AssetLoader.Factory assetLoaderFactory;
private Codec.DecoderFactory decoderFactory; private Codec.DecoderFactory decoderFactory;
private Codec.EncoderFactory encoderFactory; private Codec.EncoderFactory encoderFactory;
private FrameProcessor.Factory frameProcessorFactory; private FrameProcessor.Factory frameProcessorFactory;
...@@ -108,6 +109,7 @@ public final class Transformer { ...@@ -108,6 +109,7 @@ public final class Transformer {
transformationRequest = new TransformationRequest.Builder().build(); transformationRequest = new TransformationRequest.Builder().build();
audioProcessors = ImmutableList.of(); audioProcessors = ImmutableList.of();
videoEffects = ImmutableList.of(); videoEffects = ImmutableList.of();
assetLoaderFactory = new DefaultAssetLoaderFactory();
decoderFactory = new DefaultDecoderFactory(this.context); decoderFactory = new DefaultDecoderFactory(this.context);
encoderFactory = new DefaultEncoderFactory.Builder(this.context).build(); encoderFactory = new DefaultEncoderFactory.Builder(this.context).build();
frameProcessorFactory = new GlEffectsFrameProcessor.Factory(); frameProcessorFactory = new GlEffectsFrameProcessor.Factory();
...@@ -129,6 +131,7 @@ public final class Transformer { ...@@ -129,6 +131,7 @@ public final class Transformer {
this.forceSilentAudio = transformer.forceSilentAudio; this.forceSilentAudio = transformer.forceSilentAudio;
this.listeners = transformer.listeners; this.listeners = transformer.listeners;
this.mediaSourceFactory = transformer.mediaSourceFactory; this.mediaSourceFactory = transformer.mediaSourceFactory;
this.assetLoaderFactory = transformer.assetLoaderFactory;
this.decoderFactory = transformer.decoderFactory; this.decoderFactory = transformer.decoderFactory;
this.encoderFactory = transformer.encoderFactory; this.encoderFactory = transformer.encoderFactory;
this.frameProcessorFactory = transformer.frameProcessorFactory; this.frameProcessorFactory = transformer.frameProcessorFactory;
...@@ -305,6 +308,20 @@ public final class Transformer { ...@@ -305,6 +308,20 @@ public final class Transformer {
} }
/** /**
* Sets the {@link AssetLoader.Factory} to be used to retrieve the samples to transform.
*
* <p>The default value is a {@link DefaultAssetLoaderFactory}.
*
* @param assetLoaderFactory An {@link AssetLoader.Factory}.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setAssetLoaderFactory(AssetLoader.Factory assetLoaderFactory) {
this.assetLoaderFactory = assetLoaderFactory;
return this;
}
/**
* Sets the {@link Codec.DecoderFactory} that will be used by the transformer. * Sets the {@link Codec.DecoderFactory} that will be used by the transformer.
* *
* <p>The default value is a {@link DefaultDecoderFactory} instance. * <p>The default value is a {@link DefaultDecoderFactory} instance.
...@@ -476,6 +493,7 @@ public final class Transformer { ...@@ -476,6 +493,7 @@ public final class Transformer {
forceSilentAudio, forceSilentAudio,
listeners, listeners,
mediaSourceFactory, mediaSourceFactory,
assetLoaderFactory,
decoderFactory, decoderFactory,
encoderFactory, encoderFactory,
frameProcessorFactory, frameProcessorFactory,
...@@ -589,6 +607,7 @@ public final class Transformer { ...@@ -589,6 +607,7 @@ public final class Transformer {
private final boolean forceSilentAudio; private final boolean forceSilentAudio;
private final ListenerSet<Transformer.Listener> listeners; private final ListenerSet<Transformer.Listener> listeners;
private final MediaSource.Factory mediaSourceFactory; private final MediaSource.Factory mediaSourceFactory;
private final AssetLoader.Factory assetLoaderFactory;
private final FrameProcessor.Factory frameProcessorFactory; private final FrameProcessor.Factory frameProcessorFactory;
private final Muxer.Factory muxerFactory; private final Muxer.Factory muxerFactory;
private final Looper looper; private final Looper looper;
...@@ -607,6 +626,7 @@ public final class Transformer { ...@@ -607,6 +626,7 @@ public final class Transformer {
boolean forceSilentAudio, boolean forceSilentAudio,
ListenerSet<Listener> listeners, ListenerSet<Listener> listeners,
MediaSource.Factory mediaSourceFactory, MediaSource.Factory mediaSourceFactory,
AssetLoader.Factory assetLoaderFactory,
Codec.DecoderFactory decoderFactory, Codec.DecoderFactory decoderFactory,
Codec.EncoderFactory encoderFactory, Codec.EncoderFactory encoderFactory,
FrameProcessor.Factory frameProcessorFactory, FrameProcessor.Factory frameProcessorFactory,
...@@ -628,6 +648,7 @@ public final class Transformer { ...@@ -628,6 +648,7 @@ public final class Transformer {
this.forceSilentAudio = forceSilentAudio; this.forceSilentAudio = forceSilentAudio;
this.listeners = listeners; this.listeners = listeners;
this.mediaSourceFactory = mediaSourceFactory; this.mediaSourceFactory = mediaSourceFactory;
this.assetLoaderFactory = assetLoaderFactory;
this.decoderFactory = decoderFactory; this.decoderFactory = decoderFactory;
this.encoderFactory = encoderFactory; this.encoderFactory = encoderFactory;
this.frameProcessorFactory = frameProcessorFactory; this.frameProcessorFactory = frameProcessorFactory;
...@@ -770,6 +791,7 @@ public final class Transformer { ...@@ -770,6 +791,7 @@ public final class Transformer {
removeVideo, removeVideo,
forceSilentAudio, forceSilentAudio,
mediaSourceFactory, mediaSourceFactory,
assetLoaderFactory,
decoderFactory, decoderFactory,
encoderFactory, encoderFactory,
frameProcessorFactory, frameProcessorFactory,
......
...@@ -128,6 +128,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -128,6 +128,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
boolean removeVideo, boolean removeVideo,
boolean forceSilentAudio, boolean forceSilentAudio,
MediaSource.Factory mediaSourceFactory, MediaSource.Factory mediaSourceFactory,
AssetLoader.Factory assetLoaderFactory,
Codec.DecoderFactory decoderFactory, Codec.DecoderFactory decoderFactory,
Codec.EncoderFactory encoderFactory, Codec.EncoderFactory encoderFactory,
FrameProcessor.Factory frameProcessorFactory, FrameProcessor.Factory frameProcessorFactory,
...@@ -152,17 +153,18 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -152,17 +153,18 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Looper internalLooper = internalHandlerThread.getLooper(); Looper internalLooper = internalHandlerThread.getLooper();
ComponentListener componentListener = new ComponentListener(mediaItem, fallbackListener); ComponentListener componentListener = new ComponentListener(mediaItem, fallbackListener);
assetLoader = assetLoader =
new ExoPlayerAssetLoader( assetLoaderFactory
context, .setContext(context)
mediaItem, .setMediaItem(mediaItem)
removeAudio, .setRemoveAudio(removeAudio)
removeVideo, .setRemoveVideo(removeVideo)
transformationRequest.flattenForSlowMotion, .setFlattenVideoForSlowMotion(transformationRequest.flattenForSlowMotion)
mediaSourceFactory, .setMediaSourceFactory(mediaSourceFactory)
decoderFactory, .setDecoderFactory(decoderFactory)
internalLooper, .setLooper(internalLooper)
componentListener, .setListener(componentListener)
clock); .setClock(clock)
.createAssetLoader();
samplePipelines = new ArrayList<>(); samplePipelines = new ArrayList<>();
silentSamplePipelineIndex = C.INDEX_UNSET; silentSamplePipelineIndex = C.INDEX_UNSET;
dequeueBufferConditionVariable = new ConditionVariable(); dequeueBufferConditionVariable = new ConditionVariable();
......
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