From 0fbd4959fd1c232f99857ca1253b4382bcdbe364 Mon Sep 17 00:00:00 2001 From: huangdarwin Date: Wed, 24 Nov 2021 15:30:07 +0000 Subject: [PATCH] Transformer: Move required Builder context to be a constructor arg. Deprecates setContext() and moves the required Context arg into the constructor. This way, the parameter can later be final and non-null, per the comment at: http://go/https://github.com/google/ExoPlayer/commit/ecb47ba5647a7622fc73c09ac37f4e8b3b450cec/depot/google3/third_party/java_src/android_libs/media/libraries/transformer/src/main/java/androidx/media3/transformer/TranscodingTransformer.java?left=s19&right=r12#97L Also, fixes setOutputMimeType_unsupportedMimeType_throws by providing a context in the builder, and updating the FrameworkMuxer#supportsOutputMimeType to catch IllegalArgumentExceptions thrown by FrameworkMuxer#mimeTypeToMuxerOutputFormat. PiperOrigin-RevId: 412053564 --- docs/transforming-media.md | 6 +-- .../RemoveAudioTransformationTest.java | 3 +- .../RemoveVideoTransformationTest.java | 3 +- .../RepeatedTranscodeTransformationTest.java | 9 ++-- .../transformer/SefTransformationTest.java | 2 +- .../transformer/TransformationTest.java | 2 +- .../transformer/FrameworkMuxer.java | 2 +- .../exoplayer2/transformer/Transformer.java | 38 +++++++++++--- .../transformer/TransformerBuilderTest.java | 13 ++--- .../transformer/TransformerTest.java | 52 ++++++++----------- 10 files changed, 68 insertions(+), 62 deletions(-) diff --git a/docs/transforming-media.md b/docs/transforming-media.md index ec75d6070f..94f2a17037 100644 --- a/docs/transforming-media.md +++ b/docs/transforming-media.md @@ -32,8 +32,7 @@ transformation that removes the audio track from the input: ~~~ // Configure and create a Transformer instance. Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setRemoveAudio(true) .setListener(transformerListener) .build(); @@ -120,8 +119,7 @@ method. ~~~ Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setFlattenForSlowMotion(true) .setListener(transformerListener) .build(); diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveAudioTransformationTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveAudioTransformationTest.java index a1f92decb0..55c1c06336 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveAudioTransformationTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveAudioTransformationTest.java @@ -30,8 +30,7 @@ public class RemoveAudioTransformationTest { @Test public void removeAudioTransform() throws Exception { Context context = ApplicationProvider.getApplicationContext(); - Transformer transformer = - new Transformer.Builder().setContext(context).setRemoveAudio(true).build(); + Transformer transformer = new Transformer.Builder(context).setRemoveAudio(true).build(); runTransformer(context, transformer, MP4_ASSET_URI_STRING, /* timeoutSeconds= */ 120); } } diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveVideoTransformationTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveVideoTransformationTest.java index 98bc01a299..8ded085aa5 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveVideoTransformationTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RemoveVideoTransformationTest.java @@ -30,8 +30,7 @@ public class RemoveVideoTransformationTest { @Test public void removeVideoTransform() throws Exception { Context context = ApplicationProvider.getApplicationContext(); - Transformer transformer = - new Transformer.Builder().setContext(context).setRemoveVideo(true).build(); + Transformer transformer = new Transformer.Builder(context).setRemoveVideo(true).build(); runTransformer(context, transformer, MP4_ASSET_URI_STRING, /* timeoutSeconds= */ 120); } } diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RepeatedTranscodeTransformationTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RepeatedTranscodeTransformationTest.java index 1270ebba67..194483d740 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RepeatedTranscodeTransformationTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/RepeatedTranscodeTransformationTest.java @@ -39,8 +39,7 @@ public final class RepeatedTranscodeTransformationTest { public void repeatedTranscode_givesConsistentLengthOutput() throws Exception { Context context = ApplicationProvider.getApplicationContext(); Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AMR_NB) .build(); @@ -67,8 +66,7 @@ public final class RepeatedTranscodeTransformationTest { public void repeatedTranscodeNoAudio_givesConsistentLengthOutput() throws Exception { Context context = ApplicationProvider.getApplicationContext(); Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setRemoveAudio(true) .build(); @@ -95,8 +93,7 @@ public final class RepeatedTranscodeTransformationTest { public void repeatedTranscodeNoVideo_givesConsistentLengthOutput() throws Exception { Context context = ApplicationProvider.getApplicationContext(); Transformer transcodingTransformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setAudioMimeType(MimeTypes.AUDIO_AMR_NB) .setRemoveVideo(true) .build(); diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/SefTransformationTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/SefTransformationTest.java index 33a6e282d8..c06cfb67fa 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/SefTransformationTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/SefTransformationTest.java @@ -31,7 +31,7 @@ public class SefTransformationTest { public void sefTransform() throws Exception { Context context = ApplicationProvider.getApplicationContext(); Transformer transformer = - new Transformer.Builder().setContext(context).setFlattenForSlowMotion(true).build(); + new Transformer.Builder(context).setFlattenForSlowMotion(true).build(); runTransformer(context, transformer, SEF_ASSET_URI_STRING, /* timeoutSeconds= */ 120); } } diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/TransformationTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/TransformationTest.java index 246b7a4b74..fb84c6f666 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/TransformationTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/TransformationTest.java @@ -30,7 +30,7 @@ public class TransformationTest { @Test public void transform() throws Exception { Context context = ApplicationProvider.getApplicationContext(); - Transformer transformer = new Transformer.Builder().setContext(context).build(); + Transformer transformer = new Transformer.Builder(context).build(); runTransformer(context, transformer, MP4_ASSET_URI_STRING, /* timeoutSeconds= */ 120); } } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FrameworkMuxer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FrameworkMuxer.java index 182f34e114..b4e3912a7a 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FrameworkMuxer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FrameworkMuxer.java @@ -61,7 +61,7 @@ import java.nio.ByteBuffer; public boolean supportsOutputMimeType(String mimeType) { try { mimeTypeToMuxerOutputFormat(mimeType); - } catch (IllegalStateException e) { + } catch (IllegalArgumentException e) { return false; } return true; diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java index 5ed855a56e..ea08c415c7 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java @@ -22,7 +22,6 @@ import static com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_MAX_BUFFE import static com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_MIN_BUFFER_MS; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkState; -import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull; import static java.lang.Math.min; import android.content.Context; @@ -90,6 +89,8 @@ public final class Transformer { public static final class Builder { // Mandatory field. + // TODO(huangdarwin): Update @MonotonicNonNull to final after deprecated {@link + // #setContext(Context)} is removed. private @MonotonicNonNull Context context; // Optional fields. @@ -106,7 +107,12 @@ public final class Transformer { private Looper looper; private Clock clock; - /** Creates a builder with default values. */ + /** + * Creates a builder with default values. + * + * @deprecated Use {@link #Builder(Context)} instead. + */ + @Deprecated public Builder() { muxerFactory = new FrameworkMuxer.Factory(); outputHeight = Transformation.NO_VALUE; @@ -116,6 +122,22 @@ public final class Transformer { clock = Clock.DEFAULT; } + /** + * Creates a builder with default values. + * + * @param context The {@link Context}. + * @throws NullPointerException If the {@link Context} has not been provided. + */ + public Builder(Context context) { + this.context = context.getApplicationContext(); + muxerFactory = new FrameworkMuxer.Factory(); + outputHeight = Transformation.NO_VALUE; + containerMimeType = MimeTypes.VIDEO_MP4; + listener = new Listener() {}; + looper = Util.getCurrentOrMainLooper(); + clock = Clock.DEFAULT; + } + /** Creates a builder with the values of the provided {@link Transformer}. */ private Builder(Transformer transformer) { this.context = transformer.context; @@ -140,7 +162,9 @@ public final class Transformer { * * @param context The {@link Context}. * @return This builder. + * @deprecated Use {@link #Builder(Context)} instead. */ + @Deprecated public Builder setContext(Context context) { this.context = context.getApplicationContext(); return this; @@ -148,8 +172,8 @@ public final class Transformer { /** * Sets the {@link MediaSourceFactory} to be used to retrieve the inputs to transform. The - * default value is a {@link DefaultMediaSourceFactory} built with the context provided in - * {@link #setContext(Context)}. + * default value is a {@link DefaultMediaSourceFactory} built with the context provided in the + * constructor. * * @param mediaSourceFactory A {@link MediaSourceFactory}. * @return This builder. @@ -366,7 +390,7 @@ public final class Transformer { /** * Builds a {@link Transformer} instance. * - * @throws IllegalStateException If the {@link Context} has not been provided. + * @throws NullPointerException If the {@link Context} has not been provided. * @throws IllegalStateException If both audio and video have been removed (otherwise the output * would not contain any samples). * @throws IllegalStateException If the muxer doesn't support the requested container MIME type. @@ -374,7 +398,9 @@ public final class Transformer { * @throws IllegalStateException If the muxer doesn't support the requested video MIME type. */ public Transformer build() { - checkStateNotNull(context); + // TODO(huangdarwin): Remove this checkNotNull after deprecated {@link #setContext(Context)} + // is removed. + checkNotNull(context); if (mediaSourceFactory == null) { DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory(); if (flattenForSlowMotion) { diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerBuilderTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerBuilderTest.java index 8cfba3156d..8796678596 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerBuilderTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerBuilderTest.java @@ -31,14 +31,16 @@ public class TransformerBuilderTest { @Test public void setOutputMimeType_unsupportedMimeType_throws() { + Context context = ApplicationProvider.getApplicationContext(); + assertThrows( IllegalStateException.class, - () -> new Transformer.Builder().setOutputMimeType(MimeTypes.VIDEO_FLV).build()); + () -> new Transformer.Builder(context).setOutputMimeType(MimeTypes.VIDEO_UNKNOWN).build()); } @Test public void build_withoutContext_throws() { - assertThrows(IllegalStateException.class, () -> new Transformer.Builder().build()); + assertThrows(NullPointerException.class, () -> new Transformer.Builder().build()); } @Test @@ -47,11 +49,6 @@ public class TransformerBuilderTest { assertThrows( IllegalStateException.class, - () -> - new Transformer.Builder() - .setContext(context) - .setRemoveAudio(true) - .setRemoveVideo(true) - .build()); + () -> new Transformer.Builder(context).setRemoveAudio(true).setRemoveVideo(true).build()); } } diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerTest.java index 690b6fe2bb..4fea0e999d 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerTest.java @@ -92,8 +92,7 @@ public final class TransformerTest { @Test public void startTransformation_videoOnly_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) .build(); @@ -108,8 +107,7 @@ public final class TransformerTest { @Test public void startTransformation_audioOnly_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) .build(); @@ -124,8 +122,7 @@ public final class TransformerTest { @Test public void startTransformation_audioAndVideo_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) .build(); @@ -140,8 +137,7 @@ public final class TransformerTest { @Test public void startTransformation_withSubtitles_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) .build(); @@ -157,8 +153,7 @@ public final class TransformerTest { public void startTransformation_successiveTransformations_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) .build(); @@ -178,7 +173,7 @@ public final class TransformerTest { @Test public void startTransformation_concurrentTransformations_throwsError() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY); transformer.startTransformation(mediaItem, outputPath); @@ -190,8 +185,7 @@ public final class TransformerTest { @Test public void startTransformation_removeAudio_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setRemoveAudio(true) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) @@ -208,8 +202,7 @@ public final class TransformerTest { @Test public void startTransformation_removeVideo_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setRemoveVideo(true) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) @@ -226,8 +219,7 @@ public final class TransformerTest { @Test public void startTransformation_flattenForSlowMotion_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setFlattenForSlowMotion(true) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) @@ -242,7 +234,7 @@ public final class TransformerTest { @Test public void startTransformation_withPlayerError_completesWithError() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri("asset:///non-existing-path.mp4"); transformer.startTransformation(mediaItem, outputPath); @@ -255,7 +247,7 @@ public final class TransformerTest { @Test public void startTransformation_withAllSampleFormatsUnsupported_completesWithError() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_WITH_ALL_SAMPLE_FORMATS_UNSUPPORTED); transformer.startTransformation(mediaItem, outputPath); @@ -267,8 +259,7 @@ public final class TransformerTest { @Test public void startTransformation_afterCancellation_completesSuccessfully() throws Exception { Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) .build(); @@ -291,8 +282,7 @@ public final class TransformerTest { anotherThread.start(); Looper looper = anotherThread.getLooper(); Transformer transformer = - new Transformer.Builder() - .setContext(context) + new Transformer.Builder(context) .setLooper(looper) .setClock(clock) .setMuxerFactory(new TestMuxerFactory()) @@ -321,7 +311,7 @@ public final class TransformerTest { @Test public void startTransformation_fromWrongThread_throwsError() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_AUDIO_ONLY); HandlerThread anotherThread = new HandlerThread("AnotherThread"); AtomicReference illegalStateException = new AtomicReference<>(); @@ -348,7 +338,7 @@ public final class TransformerTest { @Test public void getProgress_knownDuration_returnsConsistentStates() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY); AtomicInteger previousProgressState = new AtomicInteger(PROGRESS_STATE_WAITING_FOR_AVAILABILITY); @@ -394,7 +384,7 @@ public final class TransformerTest { @Test public void getProgress_knownDuration_givesIncreasingPercentages() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY); List progresses = new ArrayList<>(); Handler progressHandler = @@ -429,7 +419,7 @@ public final class TransformerTest { @Test public void getProgress_noCurrentTransformation_returnsNoTransformation() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY); @Transformer.ProgressState int stateBeforeTransform = transformer.getProgress(progressHolder); @@ -443,7 +433,7 @@ public final class TransformerTest { @Test public void getProgress_unknownDuration_returnsConsistentStates() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_UNKNOWN_DURATION); AtomicInteger previousProgressState = new AtomicInteger(PROGRESS_STATE_WAITING_FOR_AVAILABILITY); @@ -486,7 +476,7 @@ public final class TransformerTest { @Test public void getProgress_fromWrongThread_throwsError() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); HandlerThread anotherThread = new HandlerThread("AnotherThread"); AtomicReference illegalStateException = new AtomicReference<>(); CountDownLatch countDownLatch = new CountDownLatch(1); @@ -510,7 +500,7 @@ public final class TransformerTest { @Test public void cancel_afterCompletion_doesNotThrow() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY); transformer.startTransformation(mediaItem, outputPath); @@ -520,7 +510,7 @@ public final class TransformerTest { @Test public void cancel_fromWrongThread_throwsError() throws Exception { - Transformer transformer = new Transformer.Builder().setContext(context).setClock(clock).build(); + Transformer transformer = new Transformer.Builder(context).setClock(clock).build(); HandlerThread anotherThread = new HandlerThread("AnotherThread"); AtomicReference illegalStateException = new AtomicReference<>(); CountDownLatch countDownLatch = new CountDownLatch(1);