mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Move muxer closing logic from Mp4Writer to Mp4Muxer
PiperOrigin-RevId: 646134522
This commit is contained in:
parent
b026271c84
commit
327f728010
@ -24,6 +24,7 @@ import androidx.annotation.IntDef;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.Metadata;
|
import androidx.media3.common.Metadata;
|
||||||
|
import androidx.media3.common.util.Log;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.container.MdtaMetadataEntry;
|
import androidx.media3.container.MdtaMetadataEntry;
|
||||||
import androidx.media3.container.Mp4LocationData;
|
import androidx.media3.container.Mp4LocationData;
|
||||||
@ -38,6 +39,7 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A muxer for creating an MP4 container file.
|
* A muxer for creating an MP4 container file.
|
||||||
@ -176,6 +178,10 @@ public final class Mp4Muxer implements Muxer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String TAG = "Mp4Muxer";
|
||||||
|
|
||||||
|
private final FileOutputStream fileOutputStream;
|
||||||
|
private final FileChannel fileChannel;
|
||||||
private final MetadataCollector metadataCollector;
|
private final MetadataCollector metadataCollector;
|
||||||
private final Mp4Writer mp4Writer;
|
private final Mp4Writer mp4Writer;
|
||||||
|
|
||||||
@ -185,12 +191,14 @@ public final class Mp4Muxer implements Muxer {
|
|||||||
AnnexBToAvccConverter annexBToAvccConverter,
|
AnnexBToAvccConverter annexBToAvccConverter,
|
||||||
boolean sampleCopyEnabled,
|
boolean sampleCopyEnabled,
|
||||||
boolean attemptStreamableOutputEnabled) {
|
boolean attemptStreamableOutputEnabled) {
|
||||||
|
this.fileOutputStream = fileOutputStream;
|
||||||
|
this.fileChannel = fileOutputStream.getChannel();
|
||||||
metadataCollector = new MetadataCollector();
|
metadataCollector = new MetadataCollector();
|
||||||
Mp4MoovStructure moovStructure =
|
Mp4MoovStructure moovStructure =
|
||||||
new Mp4MoovStructure(metadataCollector, lastFrameDurationBehavior);
|
new Mp4MoovStructure(metadataCollector, lastFrameDurationBehavior);
|
||||||
mp4Writer =
|
mp4Writer =
|
||||||
new Mp4Writer(
|
new Mp4Writer(
|
||||||
fileOutputStream,
|
fileChannel,
|
||||||
moovStructure,
|
moovStructure,
|
||||||
annexBToAvccConverter,
|
annexBToAvccConverter,
|
||||||
sampleCopyEnabled,
|
sampleCopyEnabled,
|
||||||
@ -288,10 +296,32 @@ public final class Mp4Muxer implements Muxer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws MuxerException {
|
public void close() throws MuxerException {
|
||||||
|
@Nullable MuxerException exception = null;
|
||||||
try {
|
try {
|
||||||
mp4Writer.close();
|
mp4Writer.finishWritingSamples();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new MuxerException("Failed to close the muxer", e);
|
exception = new MuxerException("Failed to finish writing samples", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fileChannel.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (exception == null) {
|
||||||
|
exception = new MuxerException("Failed to close output channel", e);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Failed to close output channel", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fileOutputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (exception == null) {
|
||||||
|
exception = new MuxerException("Failed to close output stream", e);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Failed to close output stream", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exception != null) {
|
||||||
|
throw exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ import androidx.media3.common.Format;
|
|||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.muxer.Muxer.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.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
@ -43,7 +42,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
private static final int DEFAULT_MOOV_BOX_SIZE_BYTES = 400_000;
|
private static final int DEFAULT_MOOV_BOX_SIZE_BYTES = 400_000;
|
||||||
private static final String FREE_BOX_TYPE = "free";
|
private static final String FREE_BOX_TYPE = "free";
|
||||||
|
|
||||||
private final FileOutputStream outputStream;
|
|
||||||
private final FileChannel output;
|
private final FileChannel output;
|
||||||
private final Mp4MoovStructure moovGenerator;
|
private final Mp4MoovStructure moovGenerator;
|
||||||
private final AnnexBToAvccConverter annexBToAvccConverter;
|
private final AnnexBToAvccConverter annexBToAvccConverter;
|
||||||
@ -66,7 +64,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* Creates an instance.
|
||||||
*
|
*
|
||||||
* @param outputStream The {@link FileOutputStream} to write the data to.
|
* @param fileChannel The {@link FileChannel} to write the data to. The {@link FileChannel} can be
|
||||||
|
* closed after {@link #finishWritingSamples() finishing writing samples}.
|
||||||
* @param moovGenerator An {@link Mp4MoovStructure} instance to generate the moov box.
|
* @param moovGenerator An {@link Mp4MoovStructure} instance to generate the moov box.
|
||||||
* @param annexBToAvccConverter The {@link AnnexBToAvccConverter} to be used to convert H.264 and
|
* @param annexBToAvccConverter The {@link AnnexBToAvccConverter} to be used to convert H.264 and
|
||||||
* H.265 NAL units from the Annex-B format (using start codes to delineate NAL units) to the
|
* H.265 NAL units from the Annex-B format (using start codes to delineate NAL units) to the
|
||||||
@ -75,13 +74,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
* @param attemptStreamableOutputEnabled Whether to attempt to write a streamable output.
|
* @param attemptStreamableOutputEnabled Whether to attempt to write a streamable output.
|
||||||
*/
|
*/
|
||||||
public Mp4Writer(
|
public Mp4Writer(
|
||||||
FileOutputStream outputStream,
|
FileChannel fileChannel,
|
||||||
Mp4MoovStructure moovGenerator,
|
Mp4MoovStructure moovGenerator,
|
||||||
AnnexBToAvccConverter annexBToAvccConverter,
|
AnnexBToAvccConverter annexBToAvccConverter,
|
||||||
boolean sampleCopyEnabled,
|
boolean sampleCopyEnabled,
|
||||||
boolean attemptStreamableOutputEnabled) {
|
boolean attemptStreamableOutputEnabled) {
|
||||||
this.outputStream = outputStream;
|
this.output = fileChannel;
|
||||||
this.output = outputStream.getChannel();
|
|
||||||
this.moovGenerator = moovGenerator;
|
this.moovGenerator = moovGenerator;
|
||||||
this.annexBToAvccConverter = annexBToAvccConverter;
|
this.annexBToAvccConverter = annexBToAvccConverter;
|
||||||
this.sampleCopyEnabled = sampleCopyEnabled;
|
this.sampleCopyEnabled = sampleCopyEnabled;
|
||||||
@ -105,8 +103,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
doInterleave();
|
doInterleave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
/**
|
||||||
try {
|
* Writes all the pending samples and the final moov box to the disk.
|
||||||
|
*
|
||||||
|
* <p>The output {@link FileChannel} can be closed after calling this method.
|
||||||
|
*/
|
||||||
|
public void finishWritingSamples() throws IOException {
|
||||||
for (int i = 0; i < tracks.size(); i++) {
|
for (int i = 0; i < tracks.size(); i++) {
|
||||||
flushPending(tracks.get(i));
|
flushPending(tracks.get(i));
|
||||||
}
|
}
|
||||||
@ -115,10 +117,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
if (hasWrittenSamples.get()) {
|
if (hasWrittenSamples.get()) {
|
||||||
writeMoovAndTrim();
|
writeMoovAndTrim();
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
output.close();
|
|
||||||
outputStream.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeHeader() throws IOException {
|
private void writeHeader() throws IOException {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user