Replace Transformer.Muxer interface with Muxer.Muxer

PiperOrigin-RevId: 633193701
This commit is contained in:
sheenachhabra 2024-05-13 06:51:54 -07:00 committed by Copybara-Service
parent 5950e884f6
commit 3a3145521b
23 changed files with 156 additions and 185 deletions

View File

@ -32,6 +32,9 @@
at stereo when handling PCM input.
* When selecting tracks in `ExoPlayerAssetLoader`, ignore audio channel
count constraints as they only apply for playback.
* Replace `androidx.media3.transformer.Muxer` interface with
`androidx.media3.muxer.Muxer` and remove
`androidx.media3.transformer.Muxer`.
* Track Selection:
* Extractors:
* MPEG-TS: Roll forward the change ensuring the last frame is rendered by

View File

@ -83,6 +83,7 @@ dependencies {
implementation project(modulePrefix + 'lib-exoplayer')
implementation project(modulePrefix + 'lib-exoplayer-dash')
implementation project(modulePrefix + 'lib-transformer')
implementation project(modulePrefix + 'lib-muxer')
implementation project(modulePrefix + 'lib-ui')
// For MediaPipe and its dependencies:

View File

@ -80,6 +80,7 @@ import androidx.media3.effect.TextureOverlay;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.audio.SilenceSkippingAudioProcessor;
import androidx.media3.exoplayer.util.DebugTextViewHelper;
import androidx.media3.muxer.Muxer;
import androidx.media3.transformer.Composition;
import androidx.media3.transformer.DefaultEncoderFactory;
import androidx.media3.transformer.DefaultMuxer;
@ -90,7 +91,6 @@ import androidx.media3.transformer.ExportException;
import androidx.media3.transformer.ExportResult;
import androidx.media3.transformer.InAppMuxer;
import androidx.media3.transformer.JsonUtil;
import androidx.media3.transformer.Muxer;
import androidx.media3.transformer.ProgressHolder;
import androidx.media3.transformer.Transformer;
import androidx.media3.ui.AspectRatioFrameLayout;

View File

@ -19,6 +19,7 @@ import android.content.Context;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import androidx.media3.common.util.MediaFormatUtil;
import androidx.media3.muxer.Muxer.MuxerException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@ -37,7 +38,7 @@ import java.util.List;
}
public static void feedInputDataToMuxer(Context context, Muxer muxer, String inputFileName)
throws IOException {
throws IOException, MuxerException {
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(
context.getResources().getAssets().openFd(MP4_FILE_ASSET_DIRECTORY + inputFileName));

View File

@ -62,7 +62,7 @@ public class FragmentedMp4MuxerEndToEndAndroidTest {
}
@Test
public void createFragmentedMp4File_fromInputFileSampleData_matchesExpected() throws IOException {
public void createFragmentedMp4File_fromInputFileSampleData_matchesExpected() throws Exception {
@Nullable Muxer fragmentedMp4Muxer = null;
try {
@ -89,7 +89,7 @@ public class FragmentedMp4MuxerEndToEndAndroidTest {
@Test
public void createFragmentedMp4File_fromInputFileSampleData_matchesExpectedBoxStructure()
throws IOException {
throws Exception {
@Nullable Muxer fragmentedMp4Muxer = null;
try {

View File

@ -73,7 +73,7 @@ public class Mp4MuxerEndToEndAndroidTest {
}
@Test
public void createMp4File_fromInputFileSampleData_matchesExpected() throws IOException {
public void createMp4File_fromInputFileSampleData_matchesExpected() throws Exception {
@Nullable Mp4Muxer mp4Muxer = null;
try {
@ -96,7 +96,7 @@ public class Mp4MuxerEndToEndAndroidTest {
}
@Test
public void createMp4File_muxerNotClosed_createsPartiallyWrittenValidFile() throws IOException {
public void createMp4File_muxerNotClosed_createsPartiallyWrittenValidFile() throws Exception {
// Skip for all parameter values except when the input is a large file. The muxer writes samples
// in batches (and flushes data only when it's closed), so a large input file is needed to
// ensure some data has been written after taking all the inputs but before closing the muxer.

View File

@ -156,12 +156,21 @@ public final class FragmentedMp4Muxer implements Muxer {
* Builder#setSampleCopyEnabled(boolean) sample copying} is disabled. Otherwise, the position
* of the buffer is updated but the caller retains ownership.
* @param bufferInfo The {@link BufferInfo} related to this sample.
* @throws IOException If there is any error while writing data to the disk.
* @throws MuxerException If there is any error while writing data to the disk.
*/
@Override
public void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
throws IOException {
fragmentedMp4Writer.writeSampleData(trackToken, byteBuffer, bufferInfo);
throws MuxerException {
try {
fragmentedMp4Writer.writeSampleData(trackToken, byteBuffer, bufferInfo);
} catch (IOException e) {
throw new MuxerException(
"Failed to write sample for presentationTimeUs="
+ bufferInfo.presentationTimeUs
+ ", size="
+ bufferInfo.size,
e);
}
}
/**
@ -190,7 +199,11 @@ public final class FragmentedMp4Muxer implements Muxer {
}
@Override
public void close() throws IOException {
fragmentedMp4Writer.close();
public void close() throws MuxerException {
try {
fragmentedMp4Writer.close();
} catch (IOException e) {
throw new MuxerException("Failed to close the muxer", e);
}
}
}

View File

@ -221,12 +221,21 @@ public final class Mp4Muxer implements Muxer {
* Builder#setSampleCopyEnabled(boolean) sample copying} is disabled. Otherwise, the position
* of the buffer is updated but the caller retains ownership.
* @param bufferInfo The {@link BufferInfo} related to this sample.
* @throws IOException If there is any error while writing data to the disk.
* @throws MuxerException If there is any error while writing data to the disk.
*/
@Override
public void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
throws IOException {
mp4Writer.writeSampleData(trackToken, byteBuffer, bufferInfo);
throws MuxerException {
try {
mp4Writer.writeSampleData(trackToken, byteBuffer, bufferInfo);
} catch (IOException e) {
throw new MuxerException(
"Failed to write sample for presentationTimeUs="
+ bufferInfo.presentationTimeUs
+ ", size="
+ bufferInfo.size,
e);
}
}
/**
@ -255,7 +264,11 @@ public final class Mp4Muxer implements Muxer {
}
@Override
public void close() throws IOException {
mp4Writer.close();
public void close() throws MuxerException {
try {
mp4Writer.close();
} catch (IOException e) {
throw new MuxerException("Failed to close the muxer", e);
}
}
}

View File

@ -16,28 +16,81 @@
package androidx.media3.muxer;
import android.media.MediaCodec.BufferInfo;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.UnstableApi;
import java.io.IOException;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
/** The muxer for producing media container files. */
@UnstableApi
public interface Muxer {
/** Thrown when a muxer failure occurs. */
final class MuxerException extends Exception {
/**
* Creates an instance.
*
* @param message See {@link #getMessage()}.
* @param cause See {@link #getCause()}.
*/
public MuxerException(String message, Throwable cause) {
super(message, cause);
}
}
/** Factory for muxers. */
interface Factory {
/**
* Returns a new {@link Muxer}.
*
* @param path The path to the output file.
* @throws MuxerException If an error occurs opening the output file for writing.
*/
Muxer create(String path) throws MuxerException;
/**
* Returns the supported sample {@linkplain MimeTypes MIME types} for the given {@link
* C.TrackType}.
*/
ImmutableList<String> getSupportedSampleMimeTypes(@C.TrackType int trackType);
}
/** A token representing an added track. */
interface TrackToken {}
/** Adds a track of the given media format. */
TrackToken addTrack(Format format);
/**
* Adds a track of the given media format.
*
* @param format The {@link Format} of the track.
* @return The {@link TrackToken} for this track, which should be passed to {@link
* #writeSampleData}.
* @throws MuxerException If the muxer encounters a problem while adding the track.
*/
TrackToken addTrack(Format format) throws MuxerException;
/** Writes encoded sample data. */
/**
* Writes encoded sample data.
*
* @param trackToken The {@link TrackToken} of the track, previously returned by {@link
* #addTrack(Format)}.
* @param byteBuffer A buffer containing the sample data to write to the container.
* @param bufferInfo The {@link BufferInfo} of the sample.
* @throws MuxerException If the muxer fails to write the sample.
*/
void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
throws IOException;
throws MuxerException;
/** Adds {@linkplain Metadata.Entry metadata} about the output file. */
void addMetadataEntry(Metadata.Entry metadataEntry);
/** Closes the file. */
void close() throws IOException;
/**
* Closes the file.
*
* <p>The muxer cannot be used anymore once this method returns.
*
* @throws MuxerException If the muxer fails to finish writing the output.
*/
void close() throws MuxerException;
}

View File

@ -39,7 +39,6 @@ import androidx.media3.test.utils.TestUtil;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.junit.Rule;
import org.junit.Test;
@ -54,7 +53,7 @@ public class Mp4MuxerEndToEndTest {
private final Context context = ApplicationProvider.getApplicationContext();
@Test
public void createMp4File_addTrackAndMetadataButNoSamples_createsEmptyFile() throws IOException {
public void createMp4File_addTrackAndMetadataButNoSamples_createsEmptyFile() throws Exception {
String outputFilePath = temporaryFolder.newFile().getPath();
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
@ -75,7 +74,7 @@ public class Mp4MuxerEndToEndTest {
}
@Test
public void createMp4File_withSameTracksOffset_matchesExpected() throws IOException {
public void createMp4File_withSameTracksOffset_matchesExpected() throws Exception {
String outputFilePath = temporaryFolder.newFile().getPath();
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
mp4Muxer.addMetadataEntry(
@ -118,7 +117,7 @@ public class Mp4MuxerEndToEndTest {
}
@Test
public void createMp4File_withDifferentTracksOffset_matchesExpected() throws IOException {
public void createMp4File_withDifferentTracksOffset_matchesExpected() throws Exception {
String outputFilePath = temporaryFolder.newFile().getPath();
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
mp4Muxer.addMetadataEntry(
@ -157,7 +156,7 @@ public class Mp4MuxerEndToEndTest {
}
@Test
public void writeSampleData_withOutOfOrderSampleTimestamps_throws() throws IOException {
public void writeSampleData_withOutOfOrderSampleTimestamps_throws() throws Exception {
String outputFilePath = temporaryFolder.newFile().getPath();
Mp4Muxer mp4Muxer = new Mp4Muxer.Builder(new FileOutputStream(outputFilePath)).build();
Pair<ByteBuffer, BufferInfo> track1Sample1 =

View File

@ -36,7 +36,8 @@ import androidx.media3.common.audio.AudioProcessor;
import androidx.media3.common.audio.SonicAudioProcessor;
import androidx.media3.common.util.Util;
import androidx.media3.effect.RgbFilter;
import androidx.media3.muxer.Muxer.TrackToken;
import androidx.media3.muxer.Muxer;
import androidx.media3.muxer.Muxer.MuxerException;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import com.google.common.base.Ascii;
@ -418,7 +419,7 @@ public class TransformerPauseResumeTest {
}
@Override
public Muxer create(String path) throws Muxer.MuxerException {
public Muxer create(String path) throws MuxerException {
return new FrameBlockingMuxer(wrappedMuxerFactory.create(path), listener);
}
@ -473,8 +474,8 @@ public class TransformerPauseResumeTest {
}
@Override
public void release() throws MuxerException {
wrappedMuxer.release();
public void close() throws MuxerException {
wrappedMuxer.close();
}
}
}

View File

@ -20,6 +20,7 @@ import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.muxer.Muxer;
import androidx.media3.muxer.Muxer.TrackToken;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
@ -71,9 +72,9 @@ public final class DefaultMuxer implements Muxer {
}
@Override
public void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
public void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
throws MuxerException {
muxer.writeSampleData(trackToken, data, bufferInfo);
muxer.writeSampleData(trackToken, byteBuffer, bufferInfo);
}
@Override
@ -82,7 +83,7 @@ public final class DefaultMuxer implements Muxer {
}
@Override
public void release() throws MuxerException {
muxer.release();
public void close() throws MuxerException {
muxer.close();
}
}

View File

@ -32,7 +32,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.MediaFormatUtil;
import androidx.media3.common.util.Util;
import androidx.media3.container.Mp4LocationData;
import androidx.media3.muxer.Muxer.TrackToken;
import androidx.media3.muxer.Muxer;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.lang.reflect.Field;
@ -199,7 +199,7 @@ import java.util.Map;
}
@Override
public void release() throws MuxerException {
public void close() throws MuxerException {
if (isReleased) {
return;
}

View File

@ -25,12 +25,12 @@ import androidx.media3.container.Mp4OrientationData;
import androidx.media3.muxer.FragmentedMp4Muxer;
import androidx.media3.muxer.Mp4Muxer;
import androidx.media3.muxer.Mp4Utils;
import androidx.media3.muxer.Muxer;
import androidx.media3.muxer.Muxer.TrackToken;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedHashSet;
import java.util.Set;
@ -170,7 +170,7 @@ public final class InAppMuxer implements Muxer {
}
@Override
public TrackToken addTrack(Format format) {
public TrackToken addTrack(Format format) throws MuxerException {
TrackToken trackToken = muxer.addTrack(format);
if (MimeTypes.isVideo(format.sampleMimeType)) {
muxer.addMetadataEntry(new Mp4OrientationData(format.rotationDegrees));
@ -179,19 +179,9 @@ public final class InAppMuxer implements Muxer {
}
@Override
public void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
public void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
throws MuxerException {
try {
muxer.writeSampleData(trackToken, data, bufferInfo);
} catch (IOException e) {
throw new MuxerException(
"Failed to write sample for presentationTimeUs="
+ bufferInfo.presentationTimeUs
+ ", size="
+ bufferInfo.size,
e);
}
muxer.writeSampleData(trackToken, byteBuffer, bufferInfo);
}
@Override
@ -202,14 +192,9 @@ public final class InAppMuxer implements Muxer {
}
@Override
public void release() throws MuxerException {
public void close() throws MuxerException {
writeMetadata();
try {
muxer.close();
} catch (IOException e) {
throw new MuxerException("Error closing muxer", e);
}
muxer.close();
}
private void writeMetadata() {

View File

@ -1,106 +0,0 @@
/*
* Copyright 2021 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 androidx.media3.transformer;
import android.media.MediaCodec.BufferInfo;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.muxer.Muxer.TrackToken;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
/**
* Abstracts media muxing operations.
*
* <p>Query whether {@linkplain Factory#getSupportedSampleMimeTypes(int) sample MIME types} are
* supported and {@linkplain #addTrack(Format) add all tracks}, then {@linkplain #writeSampleData
* write sample data} to mux samples. Once any sample data has been written, it is not possible to
* add tracks. After writing all sample data, {@linkplain #release() release} the instance to finish
* writing to the output and return any resources to the system.
*/
@UnstableApi
// TODO: b/330695864 - Replace with the Muxer interface from the Muxer module.
public interface Muxer {
/** Thrown when a muxing failure occurs. */
final class MuxerException extends Exception {
/**
* Creates an instance.
*
* @param message See {@link #getMessage()}.
* @param cause See {@link #getCause()}.
*/
public MuxerException(String message, Throwable cause) {
super(message, cause);
}
}
/** Factory for muxers. */
interface Factory {
/**
* Returns a new muxer writing to a file.
*
* @param path The path to the output file.
* @throws IllegalArgumentException If the path is invalid.
* @throws MuxerException If an error occurs opening the output file for writing.
*/
Muxer create(String path) throws MuxerException;
/**
* Returns the supported sample {@linkplain MimeTypes MIME types} for the given {@link
* C.TrackType}.
*/
ImmutableList<String> getSupportedSampleMimeTypes(@C.TrackType int trackType);
}
/**
* Adds a track with the specified format.
*
* @param format The {@link Format} of the track.
* @return The {@link TrackToken} for this track, which should be passed to {@link
* #writeSampleData}.
* @throws MuxerException If the muxer encounters a problem while adding the track.
*/
TrackToken addTrack(Format format) throws MuxerException;
/**
* Writes the specified sample.
*
* @param trackToken The {@link TrackToken} of the track, previously returned by {@link
* #addTrack(Format)}.
* @param data A buffer containing the sample data to write to the container.
* @param bufferInfo The {@link BufferInfo} of the sample.
* @throws MuxerException If the muxer fails to write the sample.
*/
void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
throws MuxerException;
/** Adds {@linkplain Metadata.Entry metadata} about the output file. */
void addMetadataEntry(Metadata.Entry metadataEntry);
/**
* Finishes writing the output and releases any resources associated with muxing.
*
* <p>The muxer cannot be used anymore once this method has been called.
*
* @throws MuxerException If the muxer fails to finish writing the output and {@code
* forCancellation} is false.
*/
void release() throws MuxerException;
}

View File

@ -48,6 +48,8 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Util;
import androidx.media3.container.NalUnitUtil;
import androidx.media3.effect.DebugTraceUtil;
import androidx.media3.muxer.Muxer;
import androidx.media3.muxer.Muxer.MuxerException;
import androidx.media3.muxer.Muxer.TrackToken;
import com.google.common.collect.ImmutableList;
import java.io.File;
@ -374,11 +376,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* @throws IllegalStateException If the number of formats added exceeds the {@linkplain
* #setTrackCount track count}, if {@link #setTrackCount(int)} has not been called or if there
* is already a track of that {@link C.TrackType}.
* @throws Muxer.MuxerException If the underlying {@link Muxer} encounters a problem while adding
* the track.
* @throws MuxerException If the underlying {@link Muxer} encounters a problem while adding the
* track.
*/
public void addTrackFormat(Format format)
throws AppendTrackFormatException, Muxer.MuxerException {
public void addTrackFormat(Format format) throws AppendTrackFormatException, MuxerException {
@Nullable String sampleMimeType = format.sampleMimeType;
@C.TrackType int trackType = MimeTypes.getTrackType(sampleMimeType);
checkArgument(
@ -521,11 +522,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* received a format} for every {@linkplain #setTrackCount(int) track}.
* @throws IllegalArgumentException If the muxer doesn't have a {@linkplain #endTrack(int)
* non-ended} track of the given {@link C.TrackType}.
* @throws Muxer.MuxerException If the underlying {@link Muxer} fails to write the sample.
* @throws MuxerException If the underlying {@link Muxer} fails to write the sample.
*/
public boolean writeSample(
@C.TrackType int trackType, ByteBuffer data, boolean isKeyFrame, long presentationTimeUs)
throws Muxer.MuxerException {
throws MuxerException {
checkArgument(contains(trackTypeToInfo, trackType));
TrackInfo trackInfo = trackTypeToInfo.get(trackType);
boolean canWriteSample = canWriteSample(trackType, presentationTimeUs);
@ -653,11 +654,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* #MUXER_RELEASE_REASON_CANCELLED} or {@link #MUXER_RELEASE_REASON_ERROR}.
*
* @param releaseReason The reason to release the muxer.
* @throws Muxer.MuxerException If the underlying {@link Muxer} fails to finish writing the output
* and the {@code releaseReason} is not {@link #MUXER_RELEASE_REASON_CANCELLED}.
* @throws MuxerException If the underlying {@link Muxer} fails to finish writing the output and
* the {@code releaseReason} is not {@link #MUXER_RELEASE_REASON_CANCELLED}.
*/
public void finishWritingAndMaybeRelease(@MuxerReleaseReason int releaseReason)
throws Muxer.MuxerException {
throws MuxerException {
if (releaseReason == MUXER_RELEASE_REASON_COMPLETED && muxerMode == MUXER_MODE_MUX_PARTIAL) {
return;
}
@ -665,8 +666,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
abortScheduledExecutorService.shutdownNow();
if (muxer != null) {
try {
muxer.release();
} catch (Muxer.MuxerException e) {
muxer.close();
} catch (MuxerException e) {
if (releaseReason == MUXER_RELEASE_REASON_CANCELLED
&& checkNotNull(e.getMessage())
.equals(FrameworkMuxer.MUXER_STOPPING_FAILED_ERROR_MESSAGE)) {
@ -736,7 +737,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
@EnsuresNonNull("muxer")
private void ensureMuxerInitialized() throws Muxer.MuxerException {
private void ensureMuxerInitialized() throws MuxerException {
if (muxer == null) {
muxer = muxerFactory.create(outputPath);
}

View File

@ -30,6 +30,7 @@ import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
import androidx.media3.common.MimeTypes;
import androidx.media3.decoder.DecoderInputBuffer;
import androidx.media3.muxer.Muxer.MuxerException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.List;
@ -110,7 +111,7 @@ import java.util.List;
}
try {
muxerWrapper.addTrackFormat(inputFormat);
} catch (Muxer.MuxerException e) {
} catch (MuxerException e) {
throw ExportException.createForMuxer(e, ExportException.ERROR_CODE_MUXING_FAILED);
} catch (MuxerWrapper.AppendTrackFormatException e) {
throw ExportException.createForMuxer(e, ExportException.ERROR_CODE_MUXING_APPEND);
@ -136,7 +137,7 @@ import java.util.List;
muxerInputBuffer.timeUs)) {
return false;
}
} catch (Muxer.MuxerException e) {
} catch (MuxerException e) {
throw ExportException.createForMuxer(e, ExportException.ERROR_CODE_MUXING_FAILED);
}

View File

@ -59,6 +59,7 @@ import androidx.media3.effect.DebugTraceUtil;
import androidx.media3.effect.DefaultVideoFrameProcessor;
import androidx.media3.effect.Presentation;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.muxer.Muxer;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;

View File

@ -62,6 +62,7 @@ import androidx.media3.common.util.Clock;
import androidx.media3.common.util.ConditionVariable;
import androidx.media3.common.util.HandlerWrapper;
import androidx.media3.common.util.Util;
import androidx.media3.muxer.Muxer.MuxerException;
import androidx.media3.transformer.AssetLoader.CompositionSettings;
import com.google.common.collect.ImmutableList;
import java.lang.annotation.Documented;
@ -436,7 +437,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
try {
muxerWrapper.finishWritingAndMaybeRelease(getMuxerReleaseReason(endReason));
} catch (Muxer.MuxerException e) {
} catch (MuxerException e) {
if (releaseExportException == null) {
releaseExportException = ExportException.createForMuxer(e, ERROR_CODE_MUXING_FAILED);
}

View File

@ -26,7 +26,7 @@ import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
import androidx.media3.common.util.Util;
import androidx.media3.muxer.Muxer.TrackToken;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.DumpableFormat;
import androidx.media3.test.utils.Dumper;
import androidx.media3.test.utils.Dumper.Dumpable;
@ -72,7 +72,7 @@ public final class CapturingMuxer implements Muxer, Dumpable {
}
@Override
public Muxer create(String path) throws Muxer.MuxerException {
public Muxer create(String path) throws MuxerException {
muxer = new CapturingMuxer(wrappedFactory.create(path), handleAudioAsPcm);
return muxer;
}
@ -142,9 +142,9 @@ public final class CapturingMuxer implements Muxer, Dumpable {
}
@Override
public void release() throws MuxerException {
public void close() throws MuxerException {
released = true;
wrappedMuxer.release();
wrappedMuxer.close();
}
// Dumper.Dumpable implementation.

View File

@ -30,6 +30,7 @@ import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.ColorInfo;
import androidx.media3.common.Format;
import androidx.media3.muxer.Muxer.MuxerException;
import androidx.media3.test.utils.DumpFileAsserts;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@ -74,7 +75,7 @@ public class MuxerWrapperTest {
@Nullable private MuxerWrapper muxerWrapper;
@After
public void tearDown() throws Muxer.MuxerException {
public void tearDown() throws MuxerException {
if (muxerWrapper != null) {
// Release with reason cancellation so that underlying resources are always released.
muxerWrapper.finishWritingAndMaybeRelease(MuxerWrapper.MUXER_RELEASE_REASON_CANCELLED);

View File

@ -24,6 +24,7 @@ import androidx.media3.common.audio.ChannelMixingMatrix;
import androidx.media3.common.audio.SonicAudioProcessor;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.FakeClock;
import androidx.test.core.app.ApplicationProvider;
import com.google.common.collect.ImmutableList;

View File

@ -34,6 +34,7 @@ import androidx.media3.container.Mp4TimestampData;
import androidx.media3.container.XmpData;
import androidx.media3.extractor.mp4.Mp4Extractor;
import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.DumpFileAsserts;
import androidx.media3.test.utils.FakeClock;
import androidx.media3.test.utils.FakeExtractorOutput;