mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add AssetLoader.Factory
This is so that apps can customise AssetLoader PiperOrigin-RevId: 494998497
This commit is contained in:
parent
c17c23d1f1
commit
339ce4fced
4 changed files with 244 additions and 11 deletions
|
|
@ -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;
|
||||||
*/
|
*/
|
||||||
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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* 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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
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;
|
||||||
|
|
@ -304,6 +307,20 @@ public final class Transformer {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
*
|
*
|
||||||
|
|
@ -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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
removeVideo,
|
removeVideo,
|
||||||
forceSilentAudio,
|
forceSilentAudio,
|
||||||
mediaSourceFactory,
|
mediaSourceFactory,
|
||||||
|
assetLoaderFactory,
|
||||||
decoderFactory,
|
decoderFactory,
|
||||||
encoderFactory,
|
encoderFactory,
|
||||||
frameProcessorFactory,
|
frameProcessorFactory,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
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();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue