mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Allow output audio MIME type to be set in TranscodingTransformer.
This introduces a new option `setAudioMimeType` in `TranscodingTransformer.Builder` and a corresponding check whether the selected type is supported. This check is done using `supportsSampleMimeType` which is now part of the `Muxer.Factory` and `MuxerWrapper` rather than `Muxer`. A new field `audioMimeType` is added to `Transformation` and the `TransformerAudioRenderer` uses this instead of the input MIME type if requested. PiperOrigin-RevId: 405367817
This commit is contained in:
parent
17d2f5a0b1
commit
a42d9f36b1
@ -42,7 +42,7 @@ import java.nio.ByteBuffer;
|
|||||||
@Override
|
@Override
|
||||||
public FrameworkMuxer create(String path, String outputMimeType) throws IOException {
|
public FrameworkMuxer create(String path, String outputMimeType) throws IOException {
|
||||||
MediaMuxer mediaMuxer = new MediaMuxer(path, mimeTypeToMuxerOutputFormat(outputMimeType));
|
MediaMuxer mediaMuxer = new MediaMuxer(path, mimeTypeToMuxerOutputFormat(outputMimeType));
|
||||||
return new FrameworkMuxer(mediaMuxer, outputMimeType);
|
return new FrameworkMuxer(mediaMuxer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(26)
|
@RequiresApi(26)
|
||||||
@ -53,7 +53,7 @@ import java.nio.ByteBuffer;
|
|||||||
new MediaMuxer(
|
new MediaMuxer(
|
||||||
parcelFileDescriptor.getFileDescriptor(),
|
parcelFileDescriptor.getFileDescriptor(),
|
||||||
mimeTypeToMuxerOutputFormat(outputMimeType));
|
mimeTypeToMuxerOutputFormat(outputMimeType));
|
||||||
return new FrameworkMuxer(mediaMuxer, outputMimeType);
|
return new FrameworkMuxer(mediaMuxer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,47 +65,46 @@ import java.nio.ByteBuffer;
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsSampleMimeType(
|
||||||
|
@Nullable String sampleMimeType, String containerMimeType) {
|
||||||
|
// MediaMuxer supported sample formats are documented in MediaMuxer.addTrack(MediaFormat).
|
||||||
|
boolean isAudio = MimeTypes.isAudio(sampleMimeType);
|
||||||
|
boolean isVideo = MimeTypes.isVideo(sampleMimeType);
|
||||||
|
if (containerMimeType.equals(MimeTypes.VIDEO_MP4)) {
|
||||||
|
if (isVideo) {
|
||||||
|
return MimeTypes.VIDEO_H263.equals(sampleMimeType)
|
||||||
|
|| MimeTypes.VIDEO_H264.equals(sampleMimeType)
|
||||||
|
|| MimeTypes.VIDEO_MP4V.equals(sampleMimeType)
|
||||||
|
|| (Util.SDK_INT >= 24 && MimeTypes.VIDEO_H265.equals(sampleMimeType));
|
||||||
|
} else if (isAudio) {
|
||||||
|
return MimeTypes.AUDIO_AAC.equals(sampleMimeType)
|
||||||
|
|| MimeTypes.AUDIO_AMR_NB.equals(sampleMimeType)
|
||||||
|
|| MimeTypes.AUDIO_AMR_WB.equals(sampleMimeType);
|
||||||
|
}
|
||||||
|
} else if (containerMimeType.equals(MimeTypes.VIDEO_WEBM) && SDK_INT >= 21) {
|
||||||
|
if (isVideo) {
|
||||||
|
return MimeTypes.VIDEO_VP8.equals(sampleMimeType)
|
||||||
|
|| (Util.SDK_INT >= 24 && MimeTypes.VIDEO_VP9.equals(sampleMimeType));
|
||||||
|
} else if (isAudio) {
|
||||||
|
return MimeTypes.AUDIO_VORBIS.equals(sampleMimeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final MediaMuxer mediaMuxer;
|
private final MediaMuxer mediaMuxer;
|
||||||
private final String outputMimeType;
|
|
||||||
private final MediaCodec.BufferInfo bufferInfo;
|
private final MediaCodec.BufferInfo bufferInfo;
|
||||||
|
|
||||||
private boolean isStarted;
|
private boolean isStarted;
|
||||||
|
|
||||||
private FrameworkMuxer(MediaMuxer mediaMuxer, String outputMimeType) {
|
private FrameworkMuxer(MediaMuxer mediaMuxer) {
|
||||||
this.mediaMuxer = mediaMuxer;
|
this.mediaMuxer = mediaMuxer;
|
||||||
this.outputMimeType = outputMimeType;
|
|
||||||
bufferInfo = new MediaCodec.BufferInfo();
|
bufferInfo = new MediaCodec.BufferInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsSampleMimeType(@Nullable String mimeType) {
|
|
||||||
// MediaMuxer supported sample formats are documented in MediaMuxer.addTrack(MediaFormat).
|
|
||||||
boolean isAudio = MimeTypes.isAudio(mimeType);
|
|
||||||
boolean isVideo = MimeTypes.isVideo(mimeType);
|
|
||||||
if (outputMimeType.equals(MimeTypes.VIDEO_MP4)) {
|
|
||||||
if (isVideo) {
|
|
||||||
return MimeTypes.VIDEO_H263.equals(mimeType)
|
|
||||||
|| MimeTypes.VIDEO_H264.equals(mimeType)
|
|
||||||
|| MimeTypes.VIDEO_MP4V.equals(mimeType)
|
|
||||||
|| (Util.SDK_INT >= 24 && MimeTypes.VIDEO_H265.equals(mimeType));
|
|
||||||
} else if (isAudio) {
|
|
||||||
return MimeTypes.AUDIO_AAC.equals(mimeType)
|
|
||||||
|| MimeTypes.AUDIO_AMR_NB.equals(mimeType)
|
|
||||||
|| MimeTypes.AUDIO_AMR_WB.equals(mimeType);
|
|
||||||
}
|
|
||||||
} else if (outputMimeType.equals(MimeTypes.VIDEO_WEBM) && SDK_INT >= 21) {
|
|
||||||
if (isVideo) {
|
|
||||||
return MimeTypes.VIDEO_VP8.equals(mimeType)
|
|
||||||
|| (Util.SDK_INT >= 24 && MimeTypes.VIDEO_VP9.equals(mimeType));
|
|
||||||
} else if (isAudio) {
|
|
||||||
return MimeTypes.AUDIO_VORBIS.equals(mimeType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int addTrack(Format format) {
|
public int addTrack(Format format) {
|
||||||
String sampleMimeType = checkNotNull(format.sampleMimeType);
|
String sampleMimeType = checkNotNull(format.sampleMimeType);
|
||||||
|
@ -25,11 +25,12 @@ import java.nio.ByteBuffer;
|
|||||||
/**
|
/**
|
||||||
* Abstracts media muxing operations.
|
* Abstracts media muxing operations.
|
||||||
*
|
*
|
||||||
* <p>Query whether {@link #supportsSampleMimeType(String) sample MIME types are supported} and
|
* <p>Query whether {@link Factory#supportsOutputMimeType(String) container MIME type} and {@link
|
||||||
* {@link #addTrack(Format) add all tracks}, then {@link #writeSampleData(int, ByteBuffer, boolean,
|
* Factory#supportsSampleMimeType(String, String) sample MIME types} are supported and {@link
|
||||||
* long) write sample data} to mux samples. Once any sample data has been written, it is not
|
* #addTrack(Format) add all tracks}, then {@link #writeSampleData(int, ByteBuffer, boolean, long)
|
||||||
* possible to add tracks. After writing all sample data, {@link #release(boolean) release} the
|
* write sample data} to mux samples. Once any sample data has been written, it is not possible to
|
||||||
* instance to finish writing to the output and return any resources to the system.
|
* add tracks. After writing all sample data, {@link #release(boolean) release} the instance to
|
||||||
|
* finish writing to the output and return any resources to the system.
|
||||||
*/
|
*/
|
||||||
/* package */ interface Muxer {
|
/* package */ interface Muxer {
|
||||||
|
|
||||||
@ -62,10 +63,13 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
/** Returns whether the {@link MimeTypes MIME type} provided is a supported output format. */
|
/** Returns whether the {@link MimeTypes MIME type} provided is a supported output format. */
|
||||||
boolean supportsOutputMimeType(String mimeType);
|
boolean supportsOutputMimeType(String mimeType);
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether the sample {@link MimeTypes MIME type} is supported. */
|
/**
|
||||||
boolean supportsSampleMimeType(@Nullable String mimeType);
|
* Returns whether the sample {@link MimeTypes MIME type} is supported with the given container
|
||||||
|
* {@link MimeTypes MIME type}.
|
||||||
|
*/
|
||||||
|
boolean supportsSampleMimeType(@Nullable String sampleMimeType, String containerMimeType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a track with the specified format, and returns its index (to be passed in subsequent calls
|
* Adds a track with the specified format, and returns its index (to be passed in subsequent calls
|
||||||
|
@ -45,8 +45,10 @@ import java.nio.ByteBuffer;
|
|||||||
private static final long MAX_TRACK_WRITE_AHEAD_US = C.msToUs(500);
|
private static final long MAX_TRACK_WRITE_AHEAD_US = C.msToUs(500);
|
||||||
|
|
||||||
private final Muxer muxer;
|
private final Muxer muxer;
|
||||||
|
private final Muxer.Factory muxerFactory;
|
||||||
private final SparseIntArray trackTypeToIndex;
|
private final SparseIntArray trackTypeToIndex;
|
||||||
private final SparseLongArray trackTypeToTimeUs;
|
private final SparseLongArray trackTypeToTimeUs;
|
||||||
|
private final String containerMimeType;
|
||||||
|
|
||||||
private int trackCount;
|
private int trackCount;
|
||||||
private int trackFormatCount;
|
private int trackFormatCount;
|
||||||
@ -54,8 +56,10 @@ import java.nio.ByteBuffer;
|
|||||||
private @C.TrackType int previousTrackType;
|
private @C.TrackType int previousTrackType;
|
||||||
private long minTrackTimeUs;
|
private long minTrackTimeUs;
|
||||||
|
|
||||||
public MuxerWrapper(Muxer muxer) {
|
public MuxerWrapper(Muxer muxer, Muxer.Factory muxerFactory, String containerMimeType) {
|
||||||
this.muxer = muxer;
|
this.muxer = muxer;
|
||||||
|
this.muxerFactory = muxerFactory;
|
||||||
|
this.containerMimeType = containerMimeType;
|
||||||
trackTypeToIndex = new SparseIntArray();
|
trackTypeToIndex = new SparseIntArray();
|
||||||
trackTypeToTimeUs = new SparseLongArray();
|
trackTypeToTimeUs = new SparseLongArray();
|
||||||
previousTrackType = C.TRACK_TYPE_NONE;
|
previousTrackType = C.TRACK_TYPE_NONE;
|
||||||
@ -78,7 +82,7 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
/** Returns whether the sample {@link MimeTypes MIME type} is supported. */
|
/** Returns whether the sample {@link MimeTypes MIME type} is supported. */
|
||||||
public boolean supportsSampleMimeType(@Nullable String mimeType) {
|
public boolean supportsSampleMimeType(@Nullable String mimeType) {
|
||||||
return muxer.supportsSampleMimeType(mimeType);
|
return muxerFactory.supportsSampleMimeType(mimeType, containerMimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,6 +100,7 @@ public final class TranscodingTransformer {
|
|||||||
private boolean removeVideo;
|
private boolean removeVideo;
|
||||||
private boolean flattenForSlowMotion;
|
private boolean flattenForSlowMotion;
|
||||||
private String outputMimeType;
|
private String outputMimeType;
|
||||||
|
@Nullable private String audioMimeType;
|
||||||
private TranscodingTransformer.Listener listener;
|
private TranscodingTransformer.Listener listener;
|
||||||
private Looper looper;
|
private Looper looper;
|
||||||
private Clock clock;
|
private Clock clock;
|
||||||
@ -122,6 +123,7 @@ public final class TranscodingTransformer {
|
|||||||
this.removeVideo = transcodingTransformer.transformation.removeVideo;
|
this.removeVideo = transcodingTransformer.transformation.removeVideo;
|
||||||
this.flattenForSlowMotion = transcodingTransformer.transformation.flattenForSlowMotion;
|
this.flattenForSlowMotion = transcodingTransformer.transformation.flattenForSlowMotion;
|
||||||
this.outputMimeType = transcodingTransformer.transformation.outputMimeType;
|
this.outputMimeType = transcodingTransformer.transformation.outputMimeType;
|
||||||
|
this.audioMimeType = transcodingTransformer.transformation.audioMimeType;
|
||||||
this.listener = transcodingTransformer.listener;
|
this.listener = transcodingTransformer.listener;
|
||||||
this.looper = transcodingTransformer.looper;
|
this.looper = transcodingTransformer.looper;
|
||||||
this.clock = transcodingTransformer.clock;
|
this.clock = transcodingTransformer.clock;
|
||||||
@ -212,10 +214,8 @@ public final class TranscodingTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the MIME type of the output. The default value is {@link MimeTypes#VIDEO_MP4}. The
|
* Sets the MIME type of the output. The default value is {@link MimeTypes#VIDEO_MP4}. Supported
|
||||||
* output MIME type should be supported by the {@link
|
* values are:
|
||||||
* Muxer.Factory#supportsOutputMimeType(String) muxer}. Values supported by the default {@link
|
|
||||||
* FrameworkMuxer} are:
|
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link MimeTypes#VIDEO_MP4}
|
* <li>{@link MimeTypes#VIDEO_MP4}
|
||||||
@ -230,6 +230,31 @@ public final class TranscodingTransformer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the audio MIME type of the output. The default value is to use the same MIME type as the
|
||||||
|
* input. Supported values are:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>when the container MIME type is {@link MimeTypes#VIDEO_MP4}:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link MimeTypes#AUDIO_AAC}
|
||||||
|
* <li>{@link MimeTypes#AUDIO_AMR_NB}
|
||||||
|
* <li>{@link MimeTypes#AUDIO_AMR_WB}
|
||||||
|
* </ul>
|
||||||
|
* <li>when the container MIME type is {@link MimeTypes#VIDEO_WEBM}:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link MimeTypes#AUDIO_VORBIS}
|
||||||
|
* </ul>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param audioMimeType The MIME type of the audio samples in the output.
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public Builder setAudioMimeType(String audioMimeType) {
|
||||||
|
this.audioMimeType = audioMimeType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link TranscodingTransformer.Listener} to listen to the transformation events.
|
* Sets the {@link TranscodingTransformer.Listener} to listen to the transformation events.
|
||||||
*
|
*
|
||||||
@ -290,6 +315,7 @@ public final class TranscodingTransformer {
|
|||||||
* @throws IllegalStateException If both audio and video have been removed (otherwise the output
|
* @throws IllegalStateException If both audio and video have been removed (otherwise the output
|
||||||
* would not contain any samples).
|
* would not contain any samples).
|
||||||
* @throws IllegalStateException If the muxer doesn't support the requested output MIME type.
|
* @throws IllegalStateException If the muxer doesn't support the requested output MIME type.
|
||||||
|
* @throws IllegalStateException If the muxer doesn't support the requested audio MIME type.
|
||||||
*/
|
*/
|
||||||
public TranscodingTransformer build() {
|
public TranscodingTransformer build() {
|
||||||
checkStateNotNull(context);
|
checkStateNotNull(context);
|
||||||
@ -303,8 +329,17 @@ public final class TranscodingTransformer {
|
|||||||
checkState(
|
checkState(
|
||||||
muxerFactory.supportsOutputMimeType(outputMimeType),
|
muxerFactory.supportsOutputMimeType(outputMimeType),
|
||||||
"Unsupported output MIME type: " + outputMimeType);
|
"Unsupported output MIME type: " + outputMimeType);
|
||||||
|
if (audioMimeType != null) {
|
||||||
|
checkState(
|
||||||
|
muxerFactory.supportsSampleMimeType(audioMimeType, outputMimeType),
|
||||||
|
"Unsupported sample MIME type "
|
||||||
|
+ audioMimeType
|
||||||
|
+ " for container MIME type "
|
||||||
|
+ outputMimeType);
|
||||||
|
}
|
||||||
Transformation transformation =
|
Transformation transformation =
|
||||||
new Transformation(removeAudio, removeVideo, flattenForSlowMotion, outputMimeType);
|
new Transformation(
|
||||||
|
removeAudio, removeVideo, flattenForSlowMotion, outputMimeType, audioMimeType);
|
||||||
return new TranscodingTransformer(
|
return new TranscodingTransformer(
|
||||||
context, mediaSourceFactory, muxerFactory, transformation, listener, looper, clock);
|
context, mediaSourceFactory, muxerFactory, transformation, listener, looper, clock);
|
||||||
}
|
}
|
||||||
@ -469,7 +504,8 @@ public final class TranscodingTransformer {
|
|||||||
throw new IllegalStateException("There is already a transformation in progress.");
|
throw new IllegalStateException("There is already a transformation in progress.");
|
||||||
}
|
}
|
||||||
|
|
||||||
MuxerWrapper muxerWrapper = new MuxerWrapper(muxer);
|
MuxerWrapper muxerWrapper =
|
||||||
|
new MuxerWrapper(muxer, muxerFactory, transformation.outputMimeType);
|
||||||
this.muxerWrapper = muxerWrapper;
|
this.muxerWrapper = muxerWrapper;
|
||||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
|
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
|
||||||
trackSelector.setParameters(
|
trackSelector.setParameters(
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.google.android.exoplayer2.transformer;
|
package com.google.android.exoplayer2.transformer;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
/** A media transformation configuration. */
|
/** A media transformation configuration. */
|
||||||
/* package */ final class Transformation {
|
/* package */ final class Transformation {
|
||||||
|
|
||||||
@ -23,15 +25,18 @@ package com.google.android.exoplayer2.transformer;
|
|||||||
public final boolean removeVideo;
|
public final boolean removeVideo;
|
||||||
public final boolean flattenForSlowMotion;
|
public final boolean flattenForSlowMotion;
|
||||||
public final String outputMimeType;
|
public final String outputMimeType;
|
||||||
|
@Nullable public final String audioMimeType;
|
||||||
|
|
||||||
public Transformation(
|
public Transformation(
|
||||||
boolean removeAudio,
|
boolean removeAudio,
|
||||||
boolean removeVideo,
|
boolean removeVideo,
|
||||||
boolean flattenForSlowMotion,
|
boolean flattenForSlowMotion,
|
||||||
String outputMimeType) {
|
String outputMimeType,
|
||||||
|
@Nullable String audioMimeType) {
|
||||||
this.removeAudio = removeAudio;
|
this.removeAudio = removeAudio;
|
||||||
this.removeVideo = removeVideo;
|
this.removeVideo = removeVideo;
|
||||||
this.flattenForSlowMotion = flattenForSlowMotion;
|
this.flattenForSlowMotion = flattenForSlowMotion;
|
||||||
this.outputMimeType = outputMimeType;
|
this.outputMimeType = outputMimeType;
|
||||||
|
this.audioMimeType = audioMimeType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,10 +209,8 @@ public final class Transformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the MIME type of the output. The default value is {@link MimeTypes#VIDEO_MP4}. The
|
* Sets the MIME type of the output. The default value is {@link MimeTypes#VIDEO_MP4}. Supported
|
||||||
* output MIME type should be supported by the {@link
|
* values are:
|
||||||
* Muxer.Factory#supportsOutputMimeType(String) muxer}. Values supported by the default {@link
|
|
||||||
* FrameworkMuxer} are:
|
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link MimeTypes#VIDEO_MP4}
|
* <li>{@link MimeTypes#VIDEO_MP4}
|
||||||
@ -301,7 +299,12 @@ public final class Transformer {
|
|||||||
muxerFactory.supportsOutputMimeType(outputMimeType),
|
muxerFactory.supportsOutputMimeType(outputMimeType),
|
||||||
"Unsupported output MIME type: " + outputMimeType);
|
"Unsupported output MIME type: " + outputMimeType);
|
||||||
Transformation transformation =
|
Transformation transformation =
|
||||||
new Transformation(removeAudio, removeVideo, flattenForSlowMotion, outputMimeType);
|
new Transformation(
|
||||||
|
removeAudio,
|
||||||
|
removeVideo,
|
||||||
|
flattenForSlowMotion,
|
||||||
|
outputMimeType,
|
||||||
|
/* audioMimeType= */ null);
|
||||||
return new Transformer(
|
return new Transformer(
|
||||||
context, mediaSourceFactory, muxerFactory, transformation, listener, looper, clock);
|
context, mediaSourceFactory, muxerFactory, transformation, listener, looper, clock);
|
||||||
}
|
}
|
||||||
@ -464,7 +467,8 @@ public final class Transformer {
|
|||||||
throw new IllegalStateException("There is already a transformation in progress.");
|
throw new IllegalStateException("There is already a transformation in progress.");
|
||||||
}
|
}
|
||||||
|
|
||||||
MuxerWrapper muxerWrapper = new MuxerWrapper(muxer);
|
MuxerWrapper muxerWrapper =
|
||||||
|
new MuxerWrapper(muxer, muxerFactory, transformation.outputMimeType);
|
||||||
this.muxerWrapper = muxerWrapper;
|
this.muxerWrapper = muxerWrapper;
|
||||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
|
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
|
||||||
trackSelector.setParameters(
|
trackSelector.setParameters(
|
||||||
|
@ -350,11 +350,15 @@ import java.nio.ByteBuffer;
|
|||||||
throw createRendererException(e, PlaybackException.ERROR_CODE_UNSPECIFIED);
|
throw createRendererException(e, PlaybackException.ERROR_CODE_UNSPECIFIED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String audioMimeType =
|
||||||
|
transformation.audioMimeType == null
|
||||||
|
? checkNotNull(inputFormat).sampleMimeType
|
||||||
|
: transformation.audioMimeType;
|
||||||
try {
|
try {
|
||||||
encoder =
|
encoder =
|
||||||
MediaCodecAdapterWrapper.createForAudioEncoding(
|
MediaCodecAdapterWrapper.createForAudioEncoding(
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setSampleMimeType(checkNotNull(inputFormat).sampleMimeType)
|
.setSampleMimeType(audioMimeType)
|
||||||
.setSampleRate(outputAudioFormat.sampleRate)
|
.setSampleRate(outputAudioFormat.sampleRate)
|
||||||
.setChannelCount(outputAudioFormat.channelCount)
|
.setChannelCount(outputAudioFormat.channelCount)
|
||||||
.setAverageBitrate(DEFAULT_ENCODER_BITRATE)
|
.setAverageBitrate(DEFAULT_ENCODER_BITRATE)
|
||||||
|
@ -52,7 +52,13 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
|||||||
@Nullable String sampleMimeType = format.sampleMimeType;
|
@Nullable String sampleMimeType = format.sampleMimeType;
|
||||||
if (MimeTypes.getTrackType(sampleMimeType) != getTrackType()) {
|
if (MimeTypes.getTrackType(sampleMimeType) != getTrackType()) {
|
||||||
return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE);
|
return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE);
|
||||||
} else if (muxerWrapper.supportsSampleMimeType(sampleMimeType)) {
|
} else if ((MimeTypes.isAudio(sampleMimeType)
|
||||||
|
&& muxerWrapper.supportsSampleMimeType(
|
||||||
|
transformation.audioMimeType == null
|
||||||
|
? sampleMimeType
|
||||||
|
: transformation.audioMimeType))
|
||||||
|
|| (MimeTypes.isVideo(sampleMimeType)
|
||||||
|
&& muxerWrapper.supportsSampleMimeType(sampleMimeType))) {
|
||||||
return RendererCapabilities.create(C.FORMAT_HANDLED);
|
return RendererCapabilities.create(C.FORMAT_HANDLED);
|
||||||
} else {
|
} else {
|
||||||
return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
|
return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
|
||||||
|
@ -26,30 +26,27 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link Muxer} that supports dumping information about all interactions (for
|
* An implementation of {@link Muxer} that supports dumping information about all interactions (for
|
||||||
* testing purposes) and delegates the actual muxing operations to a {@link FrameworkMuxer}.
|
* testing purposes) and delegates the actual muxing operations to another {@link Muxer} created
|
||||||
|
* using the factory provided.
|
||||||
*/
|
*/
|
||||||
public final class TestMuxer implements Muxer, Dumper.Dumpable {
|
public final class TestMuxer implements Muxer, Dumper.Dumpable {
|
||||||
|
|
||||||
private final Muxer frameworkMuxer;
|
private final Muxer muxer;
|
||||||
private final List<Dumper.Dumpable> dumpables;
|
private final List<Dumper.Dumpable> dumpables;
|
||||||
|
|
||||||
/** Creates a new test muxer. */
|
/** Creates a new test muxer. */
|
||||||
public TestMuxer(String path, String outputMimeType) throws IOException {
|
public TestMuxer(String path, String outputMimeType, Muxer.Factory muxerFactory)
|
||||||
frameworkMuxer = new FrameworkMuxer.Factory().create(path, outputMimeType);
|
throws IOException {
|
||||||
|
muxer = muxerFactory.create(path, outputMimeType);
|
||||||
dumpables = new ArrayList<>();
|
dumpables = new ArrayList<>();
|
||||||
dumpables.add(dumper -> dumper.add("containerMimeType", outputMimeType));
|
dumpables.add(dumper -> dumper.add("containerMimeType", outputMimeType));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Muxer implementation.
|
// Muxer implementation.
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsSampleMimeType(String mimeType) {
|
|
||||||
return frameworkMuxer.supportsSampleMimeType(mimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int addTrack(Format format) {
|
public int addTrack(Format format) {
|
||||||
int trackIndex = frameworkMuxer.addTrack(format);
|
int trackIndex = muxer.addTrack(format);
|
||||||
dumpables.add(new DumpableFormat(format, trackIndex));
|
dumpables.add(new DumpableFormat(format, trackIndex));
|
||||||
return trackIndex;
|
return trackIndex;
|
||||||
}
|
}
|
||||||
@ -58,13 +55,13 @@ public final class TestMuxer implements Muxer, Dumper.Dumpable {
|
|||||||
public void writeSampleData(
|
public void writeSampleData(
|
||||||
int trackIndex, ByteBuffer data, boolean isKeyFrame, long presentationTimeUs) {
|
int trackIndex, ByteBuffer data, boolean isKeyFrame, long presentationTimeUs) {
|
||||||
dumpables.add(new DumpableSample(trackIndex, data, isKeyFrame, presentationTimeUs));
|
dumpables.add(new DumpableSample(trackIndex, data, isKeyFrame, presentationTimeUs));
|
||||||
frameworkMuxer.writeSampleData(trackIndex, data, isKeyFrame, presentationTimeUs);
|
muxer.writeSampleData(trackIndex, data, isKeyFrame, presentationTimeUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void release(boolean forCancellation) {
|
public void release(boolean forCancellation) {
|
||||||
dumpables.add(dumper -> dumper.add("released", true));
|
dumpables.add(dumper -> dumper.add("released", true));
|
||||||
frameworkMuxer.release(forCancellation);
|
muxer.release(forCancellation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dumper.Dumpable implementation.
|
// Dumper.Dumpable implementation.
|
||||||
|
@ -562,16 +562,25 @@ public final class TransformerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class TestMuxerFactory implements Muxer.Factory {
|
private final class TestMuxerFactory implements Muxer.Factory {
|
||||||
|
|
||||||
|
private final Muxer.Factory frameworkMuxerFactory;
|
||||||
|
|
||||||
|
public TestMuxerFactory() {
|
||||||
|
frameworkMuxerFactory = new FrameworkMuxer.Factory();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Muxer create(String path, String outputMimeType) throws IOException {
|
public Muxer create(String path, String outputMimeType) throws IOException {
|
||||||
testMuxer = new TestMuxer(path, outputMimeType);
|
testMuxer = new TestMuxer(path, outputMimeType, frameworkMuxerFactory);
|
||||||
return testMuxer;
|
return testMuxer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Muxer create(ParcelFileDescriptor parcelFileDescriptor, String outputMimeType)
|
public Muxer create(ParcelFileDescriptor parcelFileDescriptor, String outputMimeType)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
testMuxer = new TestMuxer("FD:" + parcelFileDescriptor.getFd(), outputMimeType);
|
testMuxer =
|
||||||
|
new TestMuxer(
|
||||||
|
"FD:" + parcelFileDescriptor.getFd(), outputMimeType, frameworkMuxerFactory);
|
||||||
return testMuxer;
|
return testMuxer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,5 +588,10 @@ public final class TransformerTest {
|
|||||||
public boolean supportsOutputMimeType(String mimeType) {
|
public boolean supportsOutputMimeType(String mimeType) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsSampleMimeType(String sampleMimeType, String outputMimeType) {
|
||||||
|
return frameworkMuxerFactory.supportsSampleMimeType(sampleMimeType, outputMimeType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user