Add Muxer interface in muxer module
The immediate plan is to replace `Transformer Muxer interface` with this one. It was not straight forward to move/change `Transformer Muxer interface` hence this intermediate step. The follow up CL will also remove fragmented MP4 related code from `Mp4Muxer` and move it into `FragmentedMp4Muxer implements Muxer`. PiperOrigin-RevId: 618789265
This commit is contained in:
parent
d165af9a85
commit
483d2bb9e7
@ -25,7 +25,7 @@ import static java.lang.Math.min;
|
|||||||
import android.media.MediaCodec.BufferInfo;
|
import android.media.MediaCodec.BufferInfo;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.muxer.Mp4Muxer.TrackToken;
|
import androidx.media3.muxer.Muxer.TrackToken;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -32,7 +32,7 @@ import android.media.MediaCodec.BufferInfo;
|
|||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.muxer.Mp4Muxer.TrackToken;
|
import androidx.media3.muxer.Muxer.TrackToken;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -70,9 +70,7 @@ import java.nio.ByteBuffer;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class Mp4Muxer {
|
public final class Mp4Muxer implements Muxer {
|
||||||
/** A token representing an added track. */
|
|
||||||
public interface TrackToken {}
|
|
||||||
|
|
||||||
/** Behavior for the last sample duration. */
|
/** Behavior for the last sample duration. */
|
||||||
@Documented
|
@Documented
|
||||||
@ -223,6 +221,22 @@ public final class Mp4Muxer {
|
|||||||
|| metadata instanceof XmpData;
|
|| metadata instanceof XmpData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* <p>Tracks can be added at any point before the muxer is closed, even after writing samples to
|
||||||
|
* other tracks.
|
||||||
|
*
|
||||||
|
* <p>The order of tracks remains same in which they are added.
|
||||||
|
*
|
||||||
|
* @param format The {@link Format} for the track.
|
||||||
|
* @return A unique {@link TrackToken}. It should be used in {@link #writeSampleData}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TrackToken addTrack(Format format) {
|
||||||
|
return addTrack(/* sortKey= */ 1, format);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a track of the given media format.
|
* Adds a track of the given media format.
|
||||||
*
|
*
|
||||||
@ -242,7 +256,7 @@ public final class Mp4Muxer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes encoded sample data.
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* <p>The samples are cached and are written in batches so the caller must not change/release the
|
* <p>The samples are cached and are written in batches so the caller must not change/release the
|
||||||
* {@link ByteBuffer} and the {@link BufferInfo} after calling this method.
|
* {@link ByteBuffer} and the {@link BufferInfo} after calling this method.
|
||||||
@ -254,13 +268,14 @@ public final class Mp4Muxer {
|
|||||||
* @param bufferInfo The {@link BufferInfo} related to this sample.
|
* @param bufferInfo The {@link BufferInfo} related to this sample.
|
||||||
* @throws IOException If there is any error while writing data to the disk.
|
* @throws IOException If there is any error while writing data to the disk.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
|
public void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
mp4Writer.writeSampleData(trackToken, byteBuffer, bufferInfo);
|
mp4Writer.writeSampleData(trackToken, byteBuffer, bufferInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds metadata for the output file.
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* <p>List of supported {@linkplain Metadata.Entry metadata entries}:
|
* <p>List of supported {@linkplain Metadata.Entry metadata entries}:
|
||||||
*
|
*
|
||||||
@ -277,12 +292,13 @@ public final class Mp4Muxer {
|
|||||||
* @param metadata The {@linkplain Metadata.Entry metadata}. An {@link IllegalArgumentException}
|
* @param metadata The {@linkplain Metadata.Entry metadata}. An {@link IllegalArgumentException}
|
||||||
* is throw if the {@linkplain Metadata.Entry metadata} is not supported.
|
* is throw if the {@linkplain Metadata.Entry metadata} is not supported.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void addMetadata(Metadata.Entry metadata) {
|
public void addMetadata(Metadata.Entry metadata) {
|
||||||
checkArgument(isMetadataSupported(metadata), "Unsupported metadata");
|
checkArgument(isMetadataSupported(metadata), "Unsupported metadata");
|
||||||
metadataCollector.addMetadata(metadata);
|
metadataCollector.addMetadata(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Closes the MP4 file. */
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
mp4Writer.close();
|
mp4Writer.close();
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import android.media.MediaCodec.BufferInfo;
|
|||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.muxer.Mp4Muxer.TrackToken;
|
import androidx.media3.muxer.Muxer.TrackToken;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -41,7 +41,7 @@ import java.util.List;
|
|||||||
|
|
||||||
void close() throws IOException;
|
void close() throws IOException;
|
||||||
|
|
||||||
class Track implements Mp4Muxer.TrackToken, Mp4MoovStructure.TrackMetadataProvider {
|
class Track implements TrackToken, Mp4MoovStructure.TrackMetadataProvider {
|
||||||
public final Format format;
|
public final Format format;
|
||||||
public final int sortKey;
|
public final int sortKey;
|
||||||
public final List<BufferInfo> writtenSamples;
|
public final List<BufferInfo> writtenSamples;
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.muxer;
|
||||||
|
|
||||||
|
import android.media.MediaCodec;
|
||||||
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Metadata;
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/** The muxer for producing media container files. */
|
||||||
|
@UnstableApi
|
||||||
|
public interface Muxer {
|
||||||
|
/** A token representing an added track. */
|
||||||
|
interface TrackToken {}
|
||||||
|
|
||||||
|
/** Adds a track of the given media format. */
|
||||||
|
TrackToken addTrack(Format format);
|
||||||
|
|
||||||
|
/** Writes encoded sample data. */
|
||||||
|
void writeSampleData(
|
||||||
|
TrackToken trackToken, ByteBuffer byteBuffer, MediaCodec.BufferInfo bufferInfo)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/** Adds metadata for the output file. */
|
||||||
|
void addMetadata(Metadata.Entry metadata);
|
||||||
|
|
||||||
|
/** Closes the file. */
|
||||||
|
void close() throws IOException;
|
||||||
|
}
|
@ -31,7 +31,7 @@ import androidx.media3.container.Mp4OrientationData;
|
|||||||
import androidx.media3.container.Mp4TimestampData;
|
import androidx.media3.container.Mp4TimestampData;
|
||||||
import androidx.media3.container.XmpData;
|
import androidx.media3.container.XmpData;
|
||||||
import androidx.media3.extractor.mp4.Mp4Extractor;
|
import androidx.media3.extractor.mp4.Mp4Extractor;
|
||||||
import androidx.media3.muxer.Mp4Muxer.TrackToken;
|
import androidx.media3.muxer.Muxer.TrackToken;
|
||||||
import androidx.media3.test.utils.DumpFileAsserts;
|
import androidx.media3.test.utils.DumpFileAsserts;
|
||||||
import androidx.media3.test.utils.DumpableMp4Box;
|
import androidx.media3.test.utils.DumpableMp4Box;
|
||||||
import androidx.media3.test.utils.FakeExtractorOutput;
|
import androidx.media3.test.utils.FakeExtractorOutput;
|
||||||
|
@ -32,7 +32,7 @@ import androidx.media3.container.Mp4TimestampData;
|
|||||||
import androidx.media3.container.XmpData;
|
import androidx.media3.container.XmpData;
|
||||||
import androidx.media3.extractor.mp4.Mp4Extractor;
|
import androidx.media3.extractor.mp4.Mp4Extractor;
|
||||||
import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
|
import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
|
||||||
import androidx.media3.muxer.Mp4Muxer.TrackToken;
|
import androidx.media3.muxer.Muxer.TrackToken;
|
||||||
import androidx.media3.test.utils.DumpFileAsserts;
|
import androidx.media3.test.utils.DumpFileAsserts;
|
||||||
import androidx.media3.test.utils.DumpableMp4Box;
|
import androidx.media3.test.utils.DumpableMp4Box;
|
||||||
import androidx.media3.test.utils.FakeExtractorOutput;
|
import androidx.media3.test.utils.FakeExtractorOutput;
|
||||||
|
@ -26,7 +26,7 @@ import androidx.media3.common.MimeTypes;
|
|||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.container.Mp4OrientationData;
|
import androidx.media3.container.Mp4OrientationData;
|
||||||
import androidx.media3.muxer.Mp4Muxer;
|
import androidx.media3.muxer.Mp4Muxer;
|
||||||
import androidx.media3.muxer.Mp4Muxer.TrackToken;
|
import androidx.media3.muxer.Muxer.TrackToken;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -33,6 +33,7 @@ import java.nio.ByteBuffer;
|
|||||||
* finish writing to the output and return any resources to the system.
|
* finish writing to the output and return any resources to the system.
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
|
// TODO: b/330695864 - Replace with the Muxer interface from the Muxer module.
|
||||||
public interface Muxer {
|
public interface Muxer {
|
||||||
|
|
||||||
/** Thrown when a muxing failure occurs. */
|
/** Thrown when a muxing failure occurs. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user